Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_sch_cmn.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_cmn.c
28
29 **********************************************************************/
30
31 /** @file rg_sch_cmn.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_FILE_ID=187;
37 static int RLOG_MODULE_ID=4096;
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 "cm5.h"
50 #include "lrg.h"
51 #include "rgr.h"
52 #include "tfu.h"
53 #include "rgm.h"
54 #include "rg_env.h"
55 #include "rg_sch_err.h"
56 #include "rg_sch_inf.h"
57 #include "rg_sch.h"
58 #include "rg_sch_cmn.h"
59 #include "rl_interface.h"
60 #include "rl_common.h"
61
62 /* header/extern include files (.x) */
63 #include "gen.x"           /* general layer typedefs */
64 #include "ssi.x"           /* system services typedefs */
65 #include "cm5.x"           /* common timers */
66 #include "cm_hash.x"       /* common hash list */
67 #include "cm_lib.x"        /* common library */
68 #include "cm_llist.x"      /* common linked list */
69 #include "cm_mblk.x"       /* memory management */
70 #include "cm_tkns.x"       /* common tokens */
71 #include "cm_lte.x"       /* common tokens */
72 #include "tfu.x"           /* TFU types */
73 #include "lrg.x"           /* layer management typedefs for MAC */
74 #include "rgr.x"           /* layer management typedefs for MAC */
75 #include "rgm.x"           /* layer management typedefs for MAC */
76 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
77 #include "rg_sch.x"        /* typedefs for Scheduler */
78 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
79 #ifdef MAC_SCH_STATS
80 #include "lrg.x"            /* Stats Structures */
81 #endif /* MAC_SCH_STATS */
82 #ifdef __cplusplus
83 extern "C" {
84 #endif /* __cplusplus */
85
86 #ifdef EMTC_ENABLE
87 EXTERN U32 emtcStatsUlTomSrInd;
88 EXTERN U32 emtcStatsUlBsrTmrTxp;
89 #endif
90
91 #define RG_ITBS_DIFF(_x, _y) ((_x) > (_y) ? (_x) - (_y) : (_y) - (_x))
92 EXTERN Void rgSCHSc1UlInit ARGS((RgUlSchdApis *apis));
93 #ifdef RG_PHASE2_SCHED
94 EXTERN Void rgSCHRrUlInit ARGS((RgUlSchdApis *apis));
95 #ifdef EMTC_ENABLE
96 EXTERN Void rgSCHEmtcHqInfoFree ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP));
97 EXTERN Void rgSCHEmtcRrUlInit ARGS((RgUlSchdApis *apis));
98 EXTERN Void rgSCHEmtcCmnDlInit ARGS((Void));
99 EXTERN Void rgSCHEmtcCmnUlInit ARGS((Void));
100 EXTERN Void rgSCHEmtcCmnUeNbReset ARGS((RgSchUeCb *ueCb));
101 EXTERN RgSchCmnCqiToTbs *rgSchEmtcCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
102 #endif
103 EXTERN Void rgSCHMaxciUlInit ARGS((RgUlSchdApis *apis));
104 EXTERN Void rgSCHPfsUlInit ARGS((RgUlSchdApis *apis));
105 #endif
106 EXTERN Void rgSCHSc1DlInit ARGS((RgDlSchdApis *apis));
107 #ifdef RG_PHASE2_SCHED
108 EXTERN Void rgSCHRrDlInit ARGS((RgDlSchdApis *apis));
109 #ifdef EMTC_ENABLE
110 EXTERN Void rgSCHEmtcRrDlInit ARGS((RgDlEmtcSchdApis *apis));
111 #endif
112 EXTERN Void rgSCHMaxciDlInit ARGS((RgDlSchdApis *apis));
113 EXTERN Void rgSCHPfsDlInit ARGS((RgDlSchdApis *apis));
114 #ifdef TFU_UPGRADE
115 EXTERN Void rgSCHDlfsInit ARGS((RgDlfsSchdApis *apis));
116 #endif
117 #endif
118 #ifdef EMTC_ENABLE
119 EXTERN Void rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl ARGS((RgSchCellCb *cell));
120 EXTERN Void rgSCHCmnGetEmtcDciFrmtSizes ARGS((RgSchCellCb *cell));
121 EXTERN Void rgSCHEmtcRrUlProcRmvFrmRetx ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *proc));
122 EXTERN S16 rgSCHCmnPrecompEmtcMsg3Vars
123 ARGS((
124 RgSchCmnUlCell *cellUl,
125 U8           ccchCqi,
126 U16          msgSzA,
127 U8           sbSize,
128 Bool         isEcp
129 ));
130 PUBLIC Void rgSCHEmtcCmnUeCcchSduDel
131 (
132 RgSchCellCb  *cell,
133 RgSchUeCb    *ueCb
134 );
135 EXTERN Void rgSCHEmtcRmvFrmTaLst
136 (
137 RgSchCmnDlCell  *cellDl,
138 RgSchUeCb       *ue
139 );
140 EXTERN Void rgSCHEmtcInitTaLst
141 (
142 RgSchCmnDlCell  *cellDl
143 );
144 EXTERN Void rgSCHEmtcAddToTaLst
145 (
146 RgSchCmnDlCell  *cellDl,
147 RgSchUeCb       *ue
148 );
149
150 #endif
151
152 #ifdef RGR_SI_SCH
153 PRIVATE Void rgSCHDlSiSched ARGS((RgSchCellCb  *cell,
154                       RgSchCmnDlRbAllocInfo *allocInfo,
155                       RgInfSfAlloc  *subfrmAlloc));
156 PRIVATE Void rgSCHChkNUpdSiCfg ARGS((RgSchCellCb  *cell));
157 PRIVATE Void rgSCHSelectSi ARGS((RgSchCellCb *cell));
158 #endif /*RGR_SI_SCH*/
159 /* LTE_ADV_FLAG_REMOVED_START */
160 #ifndef LTE_TDD
161 PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
162 (
163 RgSchCellCb        *cell,
164 RgSchUeCb          *ue,
165 RgSchDlSf          *dlSf,
166 U8                 rbStrt,
167 U8                 numRb
168 );
169 PRIVATE S16 rgSCHCmnBuildRntpInfo (
170 RgSchCellCb        *cell,
171 U8                 *rntpPtr,
172 U8                  startRb,
173 U8                  nmbRb,
174 U16                 bw
175 );
176 #endif
177
178 PUBLIC Void rgSCHCmnDlSpsSch
179 (
180  RgSchCellCb        *cell
181 );
182 /* LTE_ADV_FLAG_REMOVED_END */
183
184 PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc ARGS((
185 RgSchCellCb           *cell,
186 RgSchCmnDlRbAllocInfo *allocInfo
187 ));
188 PRIVATE Void rgSCHBcchPcchDlRbAlloc ARGS((
189 RgSchCellCb           *cell,
190 RgSchCmnDlRbAllocInfo *allocInfo
191 ));
192 PRIVATE Void rgSCHCmnDlBcchPcchAlloc ARGS((
193 RgSchCellCb  *cell
194 ));
195 #ifdef RGR_CQI_REPT
196 PRIVATE Void rgSCHCmnDlCqiOnPucchInd ARGS ((
197  RgSchCellCb        *cell,
198  RgSchUeCb          *ue,
199  TfuDlCqiPucch      *pucchCqi,
200  RgrUeCqiRept       *ueCqiRept,
201  Bool               *isCqiAvail,
202  Bool               *is2ndCwCqiAvail
203  ));
204 PRIVATE Void rgSCHCmnDlCqiOnPuschInd ARGS ((
205  RgSchCellCb        *cell,
206  RgSchUeCb          *ue,
207  TfuDlCqiPusch      *puschCqi,
208  RgrUeCqiRept       *ueCqiRept,
209  Bool               *isCqiAvail,
210  Bool               *is2ndCwCqiAvail
211  ));
212 #else
213 PRIVATE Void rgSCHCmnDlCqiOnPucchInd ARGS ((
214  RgSchCellCb        *cell,
215  RgSchUeCb          *ue,
216  TfuDlCqiPucch      *pucchCqi
217  ));
218 PRIVATE Void rgSCHCmnDlCqiOnPuschInd ARGS ((
219  RgSchCellCb        *cell,
220  RgSchUeCb          *ue,
221  TfuDlCqiPusch      *puschCqi
222  ));
223 #endif
224 /* ccpu00117452 - MOD - Changed macro name from
225    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
226 #ifdef RGR_CQI_REPT
227 PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept ARGS((
228    RgSchCellCb        *cell,
229    RgSchUeCb          *ue,
230    RgrUeCqiRept        *ueCqiRept));
231 #endif /* End of RGR_CQI_REPT */
232 /* Fix: syed align multiple UEs to refresh at same time */
233 PRIVATE Void rgSCHCmnGetRefreshPer ARGS((
234    RgSchCellCb  *cell,
235    RgSchUeCb    *ue,
236    U32          *waitPer));
237 PRIVATE S16 rgSCHCmnApplyUeRefresh ARGS((
238 RgSchCellCb     *cell,
239 RgSchUeCb       *ue));
240 #ifdef DL_LA
241 PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa ARGS
242 ((
243 RgSchCellCb   *cell,
244 RgSchUeCb     *ue
245 ));
246 PRIVATE Void rgSCHCheckAndSetTxScheme ARGS
247 ((
248 RgSchCellCb   *cell,
249 RgSchUeCb     *ue
250 ));
251 #endif
252
253 #ifdef LTE_TDD
254 PRIVATE U32 rgSCHCmnCalcDwPtsTbSz ARGS
255 ((
256 RgSchCellCb    *cell,
257 U32             bo,
258 U8             *rb,
259 U8             *iTbs,
260 U8              lyr,
261 U8              cfi
262 ));
263
264 PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw ARGS
265 ((
266 RgSchCellCb    *cell,
267 U32             bo,
268 U8             *rb,
269 U8              maxRb,
270 U8             *iTbs1,
271 U8             *iTbs2,
272 U8              lyr1,
273 U8              lyr2,
274 U32            *tb1Sz, 
275 U32            *tb2Sz, 
276 U8              cfi
277 ));
278
279 #endif
280 PRIVATE Void rgSCHCmnNonDlfsType0Alloc
281 (
282 RgSchCellCb        *cell,
283 RgSchDlSf          *dlSf,
284 RgSchDlRbAlloc     *allocInfo,
285 RgSchUeCb          *ue
286 );
287 PRIVATE Void  rgSCHCmnInitRbAlloc ARGS 
288 ((
289 RgSchCellCb        *cell
290 ));
291 #ifdef __cplusplus
292 }
293 #endif /* __cplusplus */
294
295
296 /* local defines */
297 PUBLIC  RgSchdApis          rgSchCmnApis;
298 PRIVATE RgUlSchdApis        rgSchUlSchdTbl[RGSCH_NUM_SCHEDULERS];
299 PRIVATE RgDlSchdApis        rgSchDlSchdTbl[RGSCH_NUM_SCHEDULERS];
300 #ifdef EMTC_ENABLE
301 PRIVATE RgUlSchdApis        rgSchEmtcUlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
302 PRIVATE RgDlEmtcSchdApis        rgSchEmtcDlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
303 #endif
304 #ifdef RG_PHASE2_SCHED
305 PRIVATE RgDlfsSchdApis      rgSchDlfsSchdTbl[RGSCH_NUM_DLFS_SCHEDULERS];
306 #endif
307 PRIVATE RgUlSchdInits       rgSchUlSchdInits = RGSCH_ULSCHED_INITS;
308 PRIVATE RgDlSchdInits       rgSchDlSchdInits = RGSCH_DLSCHED_INITS;
309 #ifdef EMTC_ENABLE
310 PRIVATE RgEmtcUlSchdInits       rgSchEmtcUlSchdInits = RGSCH_EMTC_ULSCHED_INITS;
311 PRIVATE RgEmtcDlSchdInits       rgSchEmtcDlSchdInits = RGSCH_EMTC_DLSCHED_INITS;
312 #endif
313 #if (defined (RG_PHASE2_SCHED) && defined (TFU_UPGRADE))
314 PRIVATE RgDlfsSchdInits     rgSchDlfsSchdInits = RGSCH_DLFSSCHED_INITS;
315 #endif
316
317 typedef Void (*RgSchCmnDlAllocRbFunc) ARGS((RgSchCellCb *cell, RgSchDlSf *subFrm,
318 RgSchUeCb *ue, U32 bo, U32 *effBo, RgSchDlHqProcCb *proc,
319 RgSchCmnDlRbAllocInfo *cellWdAllocInfo));
320 typedef U8 (*RgSchCmnDlGetPrecInfFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, 
321       U8 numLyrs, Bool bothCwEnbld));
322
323 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1 ARGS((
324 RgSchCellCb                *cell,
325 RgSchDlRbAlloc             *rbAllocInfo,
326 RgSchDlHqProcCb            *hqP,
327 RgSchPdcch                 *pdcch,
328 U8                         tpc
329 ));
330 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A ARGS((
331 RgSchCellCb                *cell,
332 RgSchDlRbAlloc             *rbAllocInfo,
333 RgSchDlHqProcCb            *hqP,
334 RgSchPdcch                 *pdcch,
335 U8                         tpc
336 ));
337 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B ARGS((
338 RgSchCellCb                *cell,
339 RgSchDlRbAlloc             *rbAllocInfo,
340 RgSchDlHqProcCb            *hqP,
341 RgSchPdcch                 *pdcch,
342 U8                         tpc
343 ));
344 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2 ARGS((
345 RgSchCellCb                *cell,
346 RgSchDlRbAlloc             *rbAllocInfo,
347 RgSchDlHqProcCb            *hqP,
348 RgSchPdcch                 *pdcch,
349 U8                         tpc
350 ));
351 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A ARGS((
352 RgSchCellCb                *cell,
353 RgSchDlRbAlloc             *rbAllocInfo,
354 RgSchDlHqProcCb            *hqP,
355 RgSchPdcch                 *pdcch,
356 U8                         tpc
357 ));
358 PRIVATE Void rgSCHCmnDlAllocTxRbTM1 ARGS((
359 RgSchCellCb                *cell,
360 RgSchDlSf                  *subFrm,
361 RgSchUeCb                  *ue,
362 U32                        bo,
363 U32                        *effBo,
364 RgSchDlHqProcCb            *proc,
365 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
366 ));
367 PRIVATE Void rgSCHCmnDlAllocTxRbTM2 ARGS((
368 RgSchCellCb                *cell,
369 RgSchDlSf                  *subFrm,
370 RgSchUeCb                  *ue,
371 U32                        bo,
372 U32                        *effBo,
373 RgSchDlHqProcCb            *proc,
374 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
375 ));
376 PRIVATE Void rgSCHCmnDlAllocTxRbTM3 ARGS((
377 RgSchCellCb                *cell,
378 RgSchDlSf                  *subFrm,
379 RgSchUeCb                  *ue,
380 U32                        bo,
381 U32                        *effBo,
382 RgSchDlHqProcCb            *proc,
383 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
384 ));
385 PRIVATE Void rgSCHCmnDlAllocTxRbTM4 ARGS((
386 RgSchCellCb                *cell,
387 RgSchDlSf                  *subFrm,
388 RgSchUeCb                  *ue,
389 U32                        bo,
390 U32                        *effBo,
391 RgSchDlHqProcCb            *proc,
392 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
393 ));
394 #ifdef RG_UNUSED
395 PRIVATE Void rgSCHCmnDlAllocTxRbTM5 ARGS((
396 RgSchCellCb                *cell,
397 RgSchDlSf                  *subFrm,
398 RgSchUeCb                  *ue,
399 U32                        bo,
400 U32                        *effBo,
401 RgSchDlHqProcCb            *proc,
402 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
403 ));
404 #endif
405 PRIVATE Void rgSCHCmnDlAllocTxRbTM6 ARGS((
406 RgSchCellCb                *cell,
407 RgSchDlSf                  *subFrm,
408 RgSchUeCb                  *ue,
409 U32                        bo,
410 U32                        *effBo,
411 RgSchDlHqProcCb            *proc,
412 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
413 ));
414 PRIVATE Void rgSCHCmnDlAllocTxRbTM7 ARGS((
415 RgSchCellCb                *cell,
416 RgSchDlSf                  *subFrm,
417 RgSchUeCb                  *ue,
418 U32                        bo,
419 U32                        *effBo,
420 RgSchDlHqProcCb            *proc,
421 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
422 ));
423 PRIVATE Void rgSCHCmnDlAllocRetxRbTM1 ARGS((
424 RgSchCellCb                *cell,
425 RgSchDlSf                  *subFrm,
426 RgSchUeCb                  *ue,
427 U32                        bo,
428 U32                        *effBo,
429 RgSchDlHqProcCb            *proc,
430 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
431 ));
432 PRIVATE Void rgSCHCmnDlAllocRetxRbTM2 ARGS((
433 RgSchCellCb                *cell,
434 RgSchDlSf                  *subFrm,
435 RgSchUeCb                  *ue,
436 U32                        bo,
437 U32                        *effBo,
438 RgSchDlHqProcCb            *proc,
439 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
440 ));
441 PRIVATE Void rgSCHCmnDlAllocRetxRbTM3 ARGS((
442 RgSchCellCb                *cell,
443 RgSchDlSf                  *subFrm,
444 RgSchUeCb                  *ue,
445 U32                        bo,
446 U32                        *effBo,
447 RgSchDlHqProcCb            *proc,
448 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
449 ));
450 PRIVATE Void rgSCHCmnDlAllocRetxRbTM4 ARGS((
451 RgSchCellCb                *cell,
452 RgSchDlSf                  *subFrm,
453 RgSchUeCb                  *ue,
454 U32                        bo,
455 U32                        *effBo,
456 RgSchDlHqProcCb            *proc,
457 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
458 ));
459 #ifdef RG_UNUSED
460 PRIVATE Void rgSCHCmnDlAllocRetxRbTM5 ARGS((
461 RgSchCellCb                *cell,
462 RgSchDlSf                  *subFrm,
463 RgSchUeCb                  *ue,
464 U32                        bo,
465 U32                        *effBo,
466 RgSchDlHqProcCb            *proc,
467 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
468 ));
469 #endif
470 PRIVATE Void rgSCHCmnDlAllocRetxRbTM6 ARGS((
471 RgSchCellCb                *cell,
472 RgSchDlSf                  *subFrm,
473 RgSchUeCb                  *ue,
474 U32                        bo,
475 U32                        *effBo,
476 RgSchDlHqProcCb            *proc,
477 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
478 ));
479 PRIVATE Void rgSCHCmnDlAllocRetxRbTM7 ARGS((
480 RgSchCellCb                *cell,
481 RgSchDlSf                  *subFrm,
482 RgSchUeCb                  *ue,
483 U32                        bo,
484 U32                        *effBo,
485 RgSchDlHqProcCb            *proc,
486 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
487 ));
488
489 #ifdef LTE_ADV 
490 PRIVATE U8 rgSchGetN1ResCount ARGS ((
491  RgSchUeCb *ue,
492  U16       servCellId 
493 ));
494 PUBLIC Bool rgSchCmnChkDataOnlyOnPcell 
495 (
496  RgSchUeCb         *ue,
497  RgSchDlSf         *dlSf
498 );
499 #endif /*LTE_ADV */
500 PUBLIC U8 rgSCHCmnCalcPcqiBitSz
501 (
502  RgSchUeCb    *ueCb, 
503  U8           numTxAnt
504 );
505
506 #ifndef LTE_ADV
507 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
508 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[7] = {rgSCHCmnDlAllocTxRbTM1,
509 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
510 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7};
511
512 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
513 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[7] = {rgSCHCmnDlAllocRetxRbTM1,
514 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
515 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7};
516 #else
517 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
518 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[9] = {rgSCHCmnDlAllocTxRbTM1,
519 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
520 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7, NULLP, NULLP};
521
522 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
523 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[9] = {rgSCHCmnDlAllocRetxRbTM1,
524 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
525 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7, NULLP, NULLP};
526
527 #endif
528
529
530 PRIVATE U8 rgSCHCmnDlTM3PrecInf2 ARGS((
531 RgSchCellCb                *cell,
532 RgSchUeCb                  *ue,
533 U8                         numTxLyrs,
534 Bool                       bothCwEnbld
535 ));
536 PRIVATE U8 rgSCHCmnDlTM3PrecInf4 ARGS((
537 RgSchCellCb                *cell,
538 RgSchUeCb                  *ue,
539 U8                         numTxLyrs,
540 Bool                       bothCwEnbld
541 ));
542 PRIVATE U8 rgSCHCmnDlTM4PrecInf2 ARGS((
543 RgSchCellCb                *cell,
544 RgSchUeCb                  *ue,
545 U8                         numTxLyrs,
546 Bool                       bothCwEnbld
547 ));
548 PRIVATE U8 rgSCHCmnDlTM4PrecInf4 ARGS((
549 RgSchCellCb                *cell,
550 RgSchUeCb                  *ue,
551 U8                         numTxLyrs,
552 Bool                       bothCwEnbld
553 ));
554 /* Functions specific to each transmission mode for DL RB Allocation*/
555 RgSchCmnDlGetPrecInfFunc getPrecInfoFunc[2][2] = {
556 {rgSCHCmnDlTM3PrecInf2, rgSCHCmnDlTM3PrecInf4},
557 {rgSCHCmnDlTM4PrecInf2, rgSCHCmnDlTM4PrecInf4}
558 };
559
560 PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb ARGS((
561 RgSchCellCb                *cell,
562 RgSchDlSf                  *subFrm,
563 RgSchUeCb                  *ue,
564 RgSchDlHqTbCb              *tbInfo,
565 U8                         noLyr,
566 U8                         *numRb,
567 U32                        *effBo
568 ));
569 PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb ARGS((
570 RgSchCellCb                *cell,
571 RgSchDlSf                  *subFrm,
572 RgSchUeCb                  *ue,
573 RgSchDlHqProcCb            *proc,
574 U8                         *numRb,
575 Bool                       *swpFlg,
576 U32                        *effBo
577 ));
578 PRIVATE Void rgSCHCmnDlTM3TxTx ARGS((
579 RgSchCellCb                *cell,
580 RgSchDlSf                  *subFrm,
581 RgSchUeCb                  *ue,
582 U32                        bo,
583 U32                        *effBo,
584 RgSchDlHqProcCb            *proc,
585 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
586 ));
587 PRIVATE Void rgSCHCmnDlTM3TxRetx ARGS((
588 RgSchCellCb                *cell,
589 RgSchDlSf                  *subFrm,
590 RgSchUeCb                  *ue,
591 U32                        bo,
592 U32                        *effBo,
593 RgSchDlHqProcCb            *proc,
594 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
595 ));
596 PRIVATE Void rgSCHCmnDlTM3RetxRetx ARGS((
597 RgSchCellCb                *cell,
598 RgSchDlSf                  *subFrm,
599 RgSchUeCb                  *ue,
600 U32                        bo,
601 U32                        *effBo,
602 RgSchDlHqProcCb            *proc,
603 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
604 ));
605
606 PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc ARGS((
607 RgSchCellCb        *cell,
608 RgSchDlSf          *dlSf,
609 U8                 rbStrt,
610 U8                 numRb
611 ));
612 /* LTE_ADV_FLAG_REMOVED_START */
613 #ifndef LTE_TDD
614 PRIVATE Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc ARGS((
615 RgSchCellCb        *cell,
616 RgSchDlSf          *dlSf,
617 U8                 rbStrt,
618 U8                 numRb
619 ));
620 #endif
621 /* LTE_ADV_FLAG_REMOVED_END */
622 PRIVATE Void rgSCHCmnDlRbInfoAddUeTx ARGS((
623 RgSchCellCb        *cell,
624 RgSchCmnDlRbAllocInfo *allocInfo,
625 RgSchUeCb             *ue,
626 RgSchDlHqProcCb       *proc
627 ));
628 PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx ARGS((
629 RgSchCellCb        *cell,
630 RgSchCmnDlRbAllocInfo *allocInfo,
631 RgSchUeCb             *ue,
632 RgSchDlHqProcCb       *hqP
633 ));
634 PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst ARGS((
635 RgSchCmnDlRbAllocInfo *allocInfo,
636 RgSchUeCb             *ue,
637 RgSchDlHqProcCb       *proc
638 ));
639 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb ARGS((
640 RgSchCellCb                *cell,
641 RgSchDlSf                  *subFrm,
642 RgSchUeCb                  *ue,
643 RgSchDlHqTbCb              *reTxTb,
644 RgSchDlHqTbCb              *txTb,
645 U8                         *numRb,
646 U32                        *effBo
647 ));
648 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb ARGS((
649 RgSchCellCb                *cell,
650 RgSchDlSf                  *subFrm,
651 RgSchUeCb                  *ue,
652 RgSchDlHqProcCb            *proc,
653 U32                        bo,
654 U8                         *numRb,
655 U32                        *effBo
656 ));
657 PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb ARGS((
658 RgSchCellCb                *cell,
659 RgSchDlSf                  *subFrm,
660 RgSchUeCb                  *ue,
661 RgSchDlHqTbCb              *tbInfo,
662 U32                        bo,
663 U8                         *numRb,
664 U32                        *effBo
665 ));
666 #ifndef LTEMAC_SPS
667 PRIVATE Void rgSCHCmnFillHqPTb ARGS((
668 RgSchCellCb                *cell,
669 RgSchDlRbAlloc             *rbAllocInfo,
670 U8                         tbAllocIdx,
671 RgSchPdcch                 *pdcch
672 ));
673 #endif
674 #ifdef LTEMAC_SPS
675 PRIVATE Void rgSCHCmnDlGetBestFitHole ARGS((
676 U32         *allocMask,
677 U8          numMaskRbs,
678 U32         *crntAllocMask,
679 U8          rbsReq,
680 U8          *allocStart,
681 U8          *allocNumRbs,
682 Bool        isPartialAlloc
683 ));
684 #ifdef RGSCH_SPS_UNUSED
685 PRIVATE U32 rgSCHCmnGetRaType1Mask ARGS((
686 U8                rbIdx,
687 U8                rbgSize,
688 U8                *type1Subset
689 ));
690 #endif
691 PRIVATE U32 rgSCHCmnGetRaType0Mask ARGS((
692 U8                rbIdx,
693 U8                rbgSize
694 ));
695 PRIVATE U32 rgSCHCmnGetRaType2Mask ARGS((
696 U8                rbIdx,
697 U8                *maskIdx
698 ));
699 #endif
700
701 PUBLIC Bool rgSCHCmnRetxAllocAvoid ARGS(( 
702 RgSchDlSf                  *subFrm,
703 RgSchCellCb                *cell,
704 RgSchDlHqProcCb            *proc
705 ));
706
707 PUBLIC U16 rgSCHCmnGetSiSetId ARGS((
708 U16    sfn,
709 U8     sf,
710 U16    minPeriodicity
711 ));
712
713 #ifdef TFU_UPGRADE
714 PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi ARGS((
715 RgSchCellCb  *cell,
716 RgSchUeCb    *ue,
717 U32          maxRb,
718 U32          *numSb,
719 U8           *iTbs,
720 U32          hqSz,
721 U32          stepDownItbs,
722 U32          effTgt
723 ));
724 #endif
725
726 #ifdef RG_5GTF
727 //TODO_SID: Currenly table is only for 100 Prbs. Need to modify wrt VRBG table 8.1.5.2.1-1 V5G_213
728 U32 rgSch5gtfTbSzTbl[MAX_5GTF_MCS] = 
729     {1864, 5256, 8776, 13176, 17576, 21976, 26376, 31656, 35176, 39576, 43976, 47496, 52776, 59376, 66392};
730 U32 g5gtfTtiCnt = 0;
731 U32 gUl5gtfSrRecv = 0;
732 U32 gUl5gtfBsrRecv = 0;
733 U32 gUl5gtfUeSchPick = 0;
734 U32 gUl5gtfPdcchSchd = 0;
735 U32 gUl5gtfAllocAllocated = 0;
736 U32 gUl5gtfUeRbAllocDone = 0;
737 U32 gUl5gtfUeRmvFnlzZeroBo = 0;
738 U32 gUl5gtfUeFnlzReAdd = 0;
739 U32 gUl5gtfPdcchSend = 0;
740 U32 gUl5gtfRbAllocFail = 0;
741 U32 ul5gtfsidUlMarkUl = 0;
742 U32 ul5gtfsidDlSchdPass = 0;
743 U32 ul5gtfsidDlAlreadyMarkUl = 0;
744 U32 ul5gtfTotSchdCnt = 0;
745 #endif
746
747 /* CQI Offset Index to Beta CQI Offset value mapping,
748  * stored as parts per 1000. Reserved is set to 0.
749  * Refer 36.213 sec 8.6.3 Tbl 8.6.3-3 */
750 PUBLIC U32 rgSchCmnBetaCqiOffstTbl[16] = {0, 0, 1125,
751    1250, 1375, 1625, 1750, 2000, 2250, 2500, 2875,
752    3125, 3500, 4000, 5000, 6250};
753 PUBLIC U32 rgSchCmnBetaHqOffstTbl[16] =  {2000, 2500, 3125, 
754    4000, 5000, 6250, 8000,10000, 12625, 15875, 20000, 
755    31000, 50000,80000,126000,0};
756 PUBLIC U32 rgSchCmnBetaRiOffstTbl[16] = {1250, 1625, 2000, 
757    2500, 3125, 4000, 5000, 6250, 8000, 10000,12625,
758    15875,20000,0,0,0};
759 PUBLIC S8 rgSchCmnDlCqiDiffOfst[8] = {0, 1, 2, 3, -4, -3, -2, -1};
760
761 /* Include CRS REs while calculating Efficiency */
762 CONSTANT PRIVATE U8 rgSchCmnAntIdx[5] = {0,0,1,0,2};
763 CONSTANT PRIVATE U8 rgSchCmnNumResForCrs[5] = {0,6,12,0,16};
764 U32 cfiSwitchCnt ;
765 U32 cfiIncr ;
766 U32 cfiDecr ;
767
768
769 #ifdef TFU_UPGRADE
770 PUBLIC S8 rgSchCmnApUeSelDiffCqi[4] = {1, 2, 3, 4};
771 PUBLIC S8 rgSchCmnApEnbConfDiffCqi[4] = {0, 1, 2, -1};
772 #endif
773
774 typedef struct rgSchCmnDlUeDciFrmtOptns
775 {
776   TfuDciFormat spfcDciFrmt;   /* TM(Transmission Mode) specific DCI format.
777                                * Search space : UE Specific by C-RNTI only. */
778   U8           spfcDciRAType; /* Resource Alloctn(RA) type for spfcDciFrmt */
779   TfuDciFormat prfrdDciFrmt;  /* Preferred DCI format among the available
780                                * options for TD (Transmit Diversity) */
781   U8           prfrdDciRAType; /* Resource Alloctn(RA) type for prfrdDciFrmt */
782 }RgSchCmnDlUeDciFrmtOptns;
783 #ifndef LTE_ADV
784
785 /* DCI Format options for each Transmission Mode */
786 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[7] = {
787    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
788    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
789    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
790    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
791    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
792    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
793    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
794 };
795
796 #else
797 /* DCI Format options for each Transmission Mode */
798 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[9] = {
799    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
800    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
801    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
802    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
803    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
804    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
805    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
806 };
807 #endif
808
809
810 typedef struct rgSchCmnDlImcsTbl
811 {
812   U8   modOdr; /* Modulation Order */
813   U8   iTbs;   /* ITBS */
814 }RgSchCmnDlImcsTbl[29];
815
816 CONSTANT struct rgSchCmnMult235Info
817 {
818    U8   match;    /* Closest number satisfying 2^a.3^b.5^c, with a bias
819                   * towards the smaller number */
820    U8   prvMatch; /* Closest number not greater than array index
821                   * satisfying 2^a.3^b.5^c */
822 } rgSchCmnMult235Tbl[110+1] = {
823    {0, 0},  /* dummy */
824    {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {6, 6}, {8, 8},
825    {9, 9}, {10, 10}, {10, 10}, {12, 12}, {12, 12}, {15, 12}, {15, 15},
826    {16, 16}, {16, 16}, {18, 18}, {18, 18}, {20, 20}, {20, 20}, {20, 20},
827    {24, 20}, {24, 24}, {25, 25}, {25, 25}, {27, 27}, {27, 27}, {30, 27},
828    {30, 30}, {30, 30}, {32, 32}, {32, 32}, {32, 32}, {36, 32}, {36, 36},
829    {36, 36}, {36, 36}, {40, 36}, {40, 40}, {40, 40}, {40, 40}, {45, 40},
830    {45, 40}, {45, 45}, {45, 45}, {48, 45}, {48, 48}, {48, 48}, {50, 50},
831    {50, 50}, {50, 50}, {54, 50}, {54, 54}, {54, 54}, {54, 54}, {54, 54},
832    {60, 54}, {60, 54}, {60, 60}, {60, 60}, {60, 60}, {64, 60}, {64, 64},
833    {64, 64}, {64, 64}, {64, 64}, {64, 64}, {72, 64}, {72, 64}, {72, 64},
834    {72, 72}, {72, 72}, {75, 72}, {75, 75}, {75, 75}, {75, 75}, {80, 75},
835    {80, 75}, {80, 80}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, {81, 81},
836    {90, 81}, {90, 81}, {90, 81}, {90, 81}, {90, 90}, {90, 90}, {90, 90},
837    {90, 90}, {96, 90}, {96, 90}, {96, 96}, {96, 96}, {96, 96}, {100, 96},
838    {100, 100}, {100, 100}, {100, 100}, {100, 100}, {100, 100}, {108, 100},
839    {108, 100}, {108, 100}, {108, 108}, {108, 108}, {108, 108}
840 };
841
842 /* R8 Upgrade */
843 /* BI table from 36.321 Table 7.2.1 */
844 CONSTANT PRIVATE S16 rgSchCmnBiTbl[RG_SCH_CMN_NUM_BI_VAL] = {
845       0, 10, 20, 30,40,60,80,120,160,240,320,480,960};
846 PUBLIC RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI] = {
847  {     0,                0              },
848  {RGSCH_CMN_QM_CQI_1,RGSCH_CMN_UL_EFF_CQI_1 },
849  {RGSCH_CMN_QM_CQI_2,RGSCH_CMN_UL_EFF_CQI_2 },
850  {RGSCH_CMN_QM_CQI_3,RGSCH_CMN_UL_EFF_CQI_3 },
851  {RGSCH_CMN_QM_CQI_4,RGSCH_CMN_UL_EFF_CQI_4 },
852  {RGSCH_CMN_QM_CQI_5,RGSCH_CMN_UL_EFF_CQI_5 },
853  {RGSCH_CMN_QM_CQI_6,RGSCH_CMN_UL_EFF_CQI_6 },
854  {RGSCH_CMN_QM_CQI_7,RGSCH_CMN_UL_EFF_CQI_7 },
855  {RGSCH_CMN_QM_CQI_8,RGSCH_CMN_UL_EFF_CQI_8 },
856  {RGSCH_CMN_QM_CQI_9,RGSCH_CMN_UL_EFF_CQI_9 },
857  {RGSCH_CMN_QM_CQI_10,RGSCH_CMN_UL_EFF_CQI_10 },
858  {RGSCH_CMN_QM_CQI_11,RGSCH_CMN_UL_EFF_CQI_11 },
859  {RGSCH_CMN_QM_CQI_12,RGSCH_CMN_UL_EFF_CQI_12 },
860  {RGSCH_CMN_QM_CQI_13,RGSCH_CMN_UL_EFF_CQI_13 },
861  {RGSCH_CMN_QM_CQI_14,RGSCH_CMN_UL_EFF_CQI_14 },
862  {RGSCH_CMN_QM_CQI_15,RGSCH_CMN_UL_EFF_CQI_15 },
863 };
864
865 #ifdef RG_UNUSED
866 /* This table maps a (delta_offset * 2 + 2) to a (beta * 8)
867  * where beta is 10^-(delta_offset/10) rounded off to nearest 1/8
868  */
869 PRIVATE U16 rgSchCmnUlBeta8Tbl[29] = {
870    6, RG_SCH_CMN_UL_INVALID_BETA8, 8, 9, 10, 11, 13, 14, 16, 18, 20, 23,
871    25, 28, 32, RG_SCH_CMN_UL_INVALID_BETA8, 40, RG_SCH_CMN_UL_INVALID_BETA8,
872    50, RG_SCH_CMN_UL_INVALID_BETA8, 64, RG_SCH_CMN_UL_INVALID_BETA8, 80,
873    RG_SCH_CMN_UL_INVALID_BETA8, 101, RG_SCH_CMN_UL_INVALID_BETA8, 127,
874    RG_SCH_CMN_UL_INVALID_BETA8, 160
875 };
876 #endif
877
878 /* QCI to SVC priority mapping. Index specifies the Qci*/
879 PRIVATE U8 rgSchCmnDlQciPrio[RG_SCH_CMN_MAX_QCI] = RG_SCH_CMN_QCI_TO_PRIO;
880
881 /* The configuration is efficiency measured per 1024 REs.  */
882 /* The first element stands for when CQI is not known      */
883 /* This table is used to translate CQI to its corrospoding */
884 /* allocation parameters. These are currently from 36.213  */
885 /* Just this talbe needs to be edited for modifying the    */
886 /* the resource allocation behaviour                       */
887
888 /* ADD CQI to MCS mapping correction
889  * single dimensional array is replaced by 2 dimensions for different CFI*/
890 PRIVATE U16 rgSchCmnCqiPdschEff[4][16] = {RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1,
891     RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3};
892
893 PRIVATE U16 rgSchCmn2LyrCqiPdschEff[4][16] = {RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1,
894     RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2, RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3};
895
896 /* This configuration determines the transalation of a UEs CQI to its    */
897 /* PDCCH coding efficiency. This may be edited based on the installation */
898 PRIVATE U8 rgSchCmnDlRvTbl[4] = {0, 2, 3, 1}; /* RVIdx sequence is corrected*/
899
900 /* Indexed by [DciFrmt].
901  * Considering the following definition in determining the dciFrmt index.
902  * typedef enum
903 {
904    TFU_DCI_FORMAT_0,
905    TFU_DCI_FORMAT_1,
906    TFU_DCI_FORMAT_1A,
907    TFU_DCI_FORMAT_1B,
908    TFU_DCI_FORMAT_1C,
909    TFU_DCI_FORMAT_1D,
910    TFU_DCI_FORMAT_2,
911    TFU_DCI_FORMAT_2A,
912    TFU_DCI_FORMAT_3,
913    TFU_DCI_FORMAT_3A
914 } TfuDciFormat;
915 */
916 PRIVATE U16 rgSchCmnDciFrmtSizes[10];
917
918
919 PRIVATE U16 rgSchCmnCqiPdcchEff[16] = RG_SCH_CMN_CQI_TO_PDCCH_EFF;
920
921 #ifdef LTE_TDD
922
923 PUBLIC RgSchTddUlDlSubfrmTbl rgSchTddUlDlSubfrmTbl = {
924    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME},
925    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
926    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
927    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,   RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
928    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME,   RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
929    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME,   RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
930    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME}
931 };
932
933 /* SPS_INTG_FIX */
934 #ifdef LTEMAC_SPS
935 PUBLIC U8 rgSchTddSpsDlMaxRetxTbl[RGSCH_MAX_TDD_UL_DL_CFG] = {
936    /* 0 */ 6,
937    /* 1 */ 7,
938    /* 2 */ 8,
939    /* 3 */ 11,
940    /* 4 */ 12,
941    /* 5 */ 13,
942    /* 6 */ 7};
943
944 #endif
945
946
947 /* Special Subframes in OFDM symbols */
948 /* ccpu00134197-MOD-Correct the number of symbols */
949 PUBLIC RgSchTddSplSubfrmInfoTbl rgSchTddSplSubfrmInfoTbl = {
950         {3,  1, 1, 3,   1, 1},
951         {9,  1, 1, 8,   1, 1},
952         {10, 1, 1, 9,   1, 1},
953         {11, 1, 1, 10,  1, 1},
954         {12, 1, 1, 3,   2, 2},
955         {3,  2, 2, 8,   2, 2},
956         {9,  2, 2, 9,   2, 2},
957         {10, 2, 2, 0,   0, 0},
958         {11, 2, 2, 0,   0, 0}
959 };
960
961 /* PHICH 'm' value Table */
962 PUBLIC RgSchTddPhichMValTbl rgSchTddPhichMValTbl = {
963         {2, 1, 0, 0, 0, 2, 1, 0, 0, 0},
964         {0, 1, 0, 0, 1, 0, 1, 0, 0, 1},
965         {0, 0, 0, 1, 0, 0, 0, 0, 1, 0},
966         {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
967         {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
968         {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
969         {1, 1, 0, 0, 0, 1, 1, 0, 0, 1}
970 };
971
972 /* PHICH 'K' value Table */
973 PUBLIC RgSchTddKPhichTbl rgSchTddKPhichTbl = {
974         {0, 0, 4, 7, 6, 0, 0, 4, 7, 6},
975         {0, 0, 4, 6, 0, 0, 0, 4, 6, 0},
976         {0, 0, 6, 0, 0, 0, 0, 6, 0, 0},
977         {0, 0, 6, 6, 6, 0, 0, 0, 0, 0},
978         {0, 0, 6, 6, 0, 0, 0, 0, 0, 0},
979         {0, 0, 6, 0, 0, 0, 0, 0, 0, 0},
980         {0, 0, 4, 6, 6, 0, 0, 4, 7, 0}
981 };
982
983 /* Uplink association index 'K' value Table */
984 PUBLIC RgSchTddUlAscIdxKDashTbl rgSchTddUlAscIdxKDashTbl = {
985         {0, 0, 6, 4, 0, 0, 0, 6, 4, 0},
986         {0, 0, 4, 0, 0, 0, 0, 4, 0, 0},
987         {0, 0, 4, 4, 4, 0, 0, 0, 0, 0},
988         {0, 0, 4, 4, 0, 0, 0, 0, 0, 0},
989         {0, 0, 4, 0, 0, 0, 0, 0, 0, 0},
990         {0, 0, 7, 7, 5, 0, 0, 7, 7, 0}
991 };
992
993
994 /* PUSCH 'K' value Table */
995 PUBLIC RgSchTddPuschTxKTbl rgSchTddPuschTxKTbl = {
996         {4, 6, 0, 0, 0, 4, 6, 0, 0, 0},
997         {0, 6, 0, 0, 4, 0, 6, 0, 0, 4},
998         {0, 0, 0, 4, 0, 0, 0, 0, 4, 0},
999         {4, 0, 0, 0, 0, 0, 0, 0, 4, 4},
1000         {0, 0, 0, 0, 0, 0, 0, 0, 4, 4},
1001         {0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
1002         {7, 7, 0, 0, 0, 7, 7, 0, 0, 5}
1003 };
1004
1005 /* PDSCH to PUCCH Table for DL Harq Feed back. Based on the 
1006    Downlink association set index 'K' table */
1007 PUBLIC U8 rgSchTddPucchTxTbl[7][10] = {
1008         {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1009         {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1010         {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1011         {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1012         {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1013         {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1014         {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1015 };
1016
1017 /* Table to fetch the next DL sf idx for applying the 
1018    new CFI. The next Dl sf Idx at which the new CFI 
1019    is applied is always the starting Sf of the next ACK/NACK
1020    Fdbk bundle. 
1021    
1022    Ex: In Cfg-2, sf4 and sf9 are the only subframes at which 
1023        a new ACK/NACK bundle of DL subframes can start
1024        
1025    D  S  U  D  D  D  S  U  D  D  D  S  U  D  D  D  S  U  D  D    
1026                4              9
1027    
1028    dlSf Array for Cfg-2:
1029    sfNum:  0  1  3  4  5  6  8  9  0  1   3  4  5  6  8  9 
1030    sfIdx:  0  1  2  3  4  5  6  7  8  9  10 11 12 12 14 15 
1031     
1032    If CFI changes at sf0,  nearest DL SF bundle >= 4 TTI is sf4
1033    So at sf4 the new CFI can be applied. To arrive at sf4 from
1034    sf0, the sfIdx has to be increased by 3 */  
1035                  
1036 PUBLIC U8 rgSchTddPdcchSfIncTbl[7][10] = {
1037  /* A/N Bundl: 0,1,5,6*/   {2,  1,  0, 0, 0, 2, 1,  0,  0,  0},
1038  /* A/N Bundl: 0,4,5,9*/   {2,  2,  0, 0, 3, 2, 2,  0,  0,  3},
1039  /* A/N Bundl: 4,9*/       {3,  6,  0, 5, 4, 3, 6,  0,  5,  4},
1040  /* A/N Bundl: 1,7,9*/     {4,  3,  0, 0, 0, 4, 5,  4,  6,  5},
1041  /* A/N Bundl: 0,6*/       {4,  3,  0, 0, 6, 5, 4,  7,  6,  5},
1042  /* A/N Bundl: 9*/         {8,  7,  0, 6, 5, 4, 12, 11, 10, 9},
1043  /* A/N Bundl: 0,1,5,6,9*/ {2,  1,  0, 0, 0, 2, 2,  0,  0,  3}
1044 };
1045    
1046
1047 /* combine compilation fixes */
1048 #ifdef LTEMAC_SPS
1049 /* subframe offset values to be used when twoIntervalsConfig is enabled in UL
1050  * SPS for a UE */
1051 PUBLIC RgSchTddSfOffTbl rgSchTddSfOffTbl = {
1052         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1053         {0, 0, 1, -1,  0, 0, 0,  1, -1, 0},
1054         {0, 0, 5,  0,  0, 0, 0, -5,  0, 0},
1055         {0, 0, 1,  1, -2, 0, 0,  0,  0, 0},
1056         {0, 0, 1, -1,  0, 0, 0,  0,  0, 0},
1057         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1058         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0}
1059 };
1060
1061
1062 /* Table to determine when uplink SPS configured grants should
1063  * explicitly be reserved in a subframe. When enries are same
1064  * as that of Msg3SubfrmTbl, indicates competition with msg3.
1065  * As of now, this is same as Msg3SubfrmTbl (leaving out uldlcfg 2),
1066  * except that all 255s are now zeros. */
1067 PUBLIC RgSchTddSpsUlRsrvTbl rgSchTddSpsUlRsrvTbl = {
1068         {0,    0,  0,  6,  8,  0, 0,  0,  6,  8},
1069         {0,    0,  6,  9,  0,  0, 0,  6,  9,  0},
1070         {0,    0,  10,  0,  0,  0, 0,  10,  0,  0},
1071         {0,   0,  0,  0,  8,  0, 7,  7,  14,  0},
1072         {0,   0,  0,  9,  0,  0, 7,  15,  0, 0},
1073         {0,   0,  10,  0,  0,  0, 16,  0, 0, 0},
1074         {0,    0,  0,  0,  8,  0, 0,  0,  9,  0}
1075 };
1076
1077 /* Inverse DL Assoc Set index Table */
1078 PUBLIC RgSchTddInvDlAscSetIdxTbl rgSchTddInvDlAscSetIdxTbl = {
1079        {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1080        {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1081        {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1082        {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1083        {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1084        {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1085        {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1086 };
1087
1088 #endif /* (LTEMAC_SPS ) */
1089
1090 /* Number of Uplink subframes Table */
1091 PRIVATE U8 rgSchTddNumUlSf[] = {6, 4, 2, 3, 2, 1, 5};
1092
1093 /* Downlink HARQ processes Table */
1094 PUBLIC RgSchTddUlNumHarqProcTbl rgSchTddUlNumHarqProcTbl = { 7, 4, 2, 3, 2, 1, 6};
1095
1096 /* Uplink HARQ processes Table */
1097 PUBLIC RgSchTddDlNumHarqProcTbl rgSchTddDlNumHarqProcTbl = { 4, 7, 10, 9, 12, 15, 6};
1098
1099 /* Downlink association index set 'K' value Table */
1100 PUBLIC RgSchTddDlAscSetIdxKTbl rgSchTddDlAscSetIdxKTbl = {
1101         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1102
1103         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1104
1105         { {0, {0}}, {0, {0}}, {4, {8, 7, 4, 6}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {4, {8, 7, 4, 6}}, {0, {0}}, {0, {0}} },
1106
1107         { {0, {0}}, {0, {0}}, {3, {7, 6, 11}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1108
1109         { {0, {0}}, {0, {0}}, {4, {12, 8, 7, 11}}, {4, {6, 5, 4, 7}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1110
1111         { {0, {0}}, {0, {0}}, {9, {13, 12, 9, 8, 7, 5, 4, 11, 6}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1112
1113         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1114 };
1115
1116  /* ccpu132282-ADD-the table rgSchTddDlAscSetIdxKTbl is rearranged in 
1117   * decreasing order of Km, this is used to calculate the NCE used for 
1118   * calculating N1Pucch Resource for Harq*/
1119 PUBLIC RgSchTddDlAscSetIdxKTbl rgSchTddDlHqPucchResCalTbl = {
1120         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1121
1122         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1123
1124         { {0, {0}}, {0, {0}}, {4, {8, 7, 6, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {4, {8, 7, 6, 4}}, {0, {0}}, {0, {0}} },
1125
1126         { {0, {0}}, {0, {0}}, {3, {11, 7, 6}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1127
1128         { {0, {0}}, {0, {0}}, {4, {12, 11, 8, 7}}, {4, {7, 6, 5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1129
1130         { {0, {0}}, {0, {0}}, {9, {13, 12, 11, 9, 8, 7, 6, 5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1131
1132         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1133 };
1134
1135 /* Minimum number of Ack/Nack feeback information to be
1136    stored for each UL-DL configuration */
1137 PUBLIC RgSchTddANFdbkMapTbl rgSchTddANFdbkMapTbl = {4, 4, 2, 3, 2, 1, 5};
1138
1139 /* Uplink switch points and number of UL subframes Table */
1140 PUBLIC RgSchTddMaxUlSubfrmTbl rgSchTddMaxUlSubfrmTbl = {
1141      {2,3,3}, {2,2,2}, {2,1,1}, {1,3,0}, {1,2,0}, {1,1,0}, {2,3,2}
1142 };
1143
1144 /* Uplink switch points and number of DL subframes Table */
1145 PUBLIC RgSchTddMaxDlSubfrmTbl rgSchTddMaxDlSubfrmTbl = {
1146      {2,2,2}, {2,3,3}, {2,4,4}, {1,7,0}, {1,8,0}, {1,9,0}, {2,2,3}
1147 };
1148
1149 /* Number of UL subframes present before a particular subframe */
1150 PUBLIC RgSchTddNumUlSubfrmTbl rgSchTddNumUlSubfrmTbl = {
1151         {0, 0, 1, 2, 3, 3, 3, 4, 5, 6},
1152         {0, 0, 1, 2, 2, 2, 2, 3, 4, 4},
1153         {0, 0, 1, 1, 1, 1, 1, 2, 2, 2},
1154         {0, 0, 1, 2, 3, 3, 3, 3, 3, 3},
1155         {0, 0, 1, 2, 2, 2, 2, 2, 2, 2},
1156         {0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
1157         {0, 0, 1, 2, 3, 3, 3, 4, 5, 5}
1158 };
1159
1160 /* Number of DL subframes present till a particular subframe */
1161 PUBLIC RgSchTddNumDlSubfrmTbl rgSchTddNumDlSubfrmTbl = {
1162         {1, 2, 2, 2, 2, 3, 4, 4, 4, 4},
1163         {1, 2, 2, 2, 3, 4, 5, 5, 5, 6},
1164         {1, 2, 2, 3, 4, 5, 6, 6, 7, 8},
1165         {1, 2, 2, 2, 2, 3, 4, 5, 6, 7},
1166         {1, 2, 2, 2, 3, 4, 5, 6, 7, 8},
1167         {1, 2, 2, 3, 4, 5, 6, 7, 8, 9},
1168         {1, 2, 2, 2, 2, 3, 4, 4, 4, 5}
1169 };
1170
1171
1172 /* Nearest possible UL subframe Index from UL subframe
1173  * DL Index < UL Index */
1174 PUBLIC RgSchTddLowDlSubfrmIdxTbl rgSchTddLowDlSubfrmIdxTbl = {
1175         {0, 1, 1, 1, 1, 5, 6, 6, 6, 6},
1176         {0, 1, 1, 1, 4, 5, 6, 6, 6, 9},
1177         {0, 1, 1, 3, 4, 5, 6, 6, 8, 9},
1178         {0, 1, 1, 1, 1, 5, 6, 7, 8, 9},
1179         {0, 1, 1, 1, 4, 5, 6, 7, 8, 9},
1180         {0, 1, 1, 3, 4, 5, 6, 7, 8, 9},
1181         {0, 1, 1, 1, 1, 5, 6, 6, 6, 9}
1182 };
1183
1184 /* Nearest possible DL subframe Index from UL subframe
1185  * DL Index > UL Index
1186  * 10 represents Next SFN low DL Idx */
1187 PUBLIC RgSchTddHighDlSubfrmIdxTbl rgSchTddHighDlSubfrmIdxTbl = {
1188         {0, 1, 5, 5, 5, 5, 6, 10, 10, 10},
1189         {0, 1, 4, 4, 4, 5, 6,  9,  9,  9},
1190         {0, 1, 3, 3, 4, 5, 6,  8,  8,  9},
1191         {0, 1, 5, 5, 5, 5, 6,  7,  8,  9},
1192         {0, 1, 4, 4, 4, 5, 6,  7,  8,  9},
1193         {0, 1, 3, 3, 4, 5, 6,  7,  8,  9},
1194         {0, 1, 5, 5, 5, 5, 6,  9,  9,  9}
1195 };
1196
1197 /* RACH Message3 related information */
1198 PUBLIC RgSchTddMsg3SubfrmTbl rgSchTddMsg3SubfrmTbl = {
1199         {7,      6,  255,  255,  255,  7,   6,  255,  255,  255},
1200         {7,      6,  255,  255,    8,  7,   6,  255,  255,    8},
1201         {7,      6,  255,  9,      8,  7,   6,  255,    9,    8},
1202         {12,    11,  255,  255,  255,  7,   6,    6,    6,   13},
1203         {12,    11,  255,  255,    8,  7,   6,    6,   14,   13},
1204         {12,    11,  255,    9,    8,  7,   6,   15,   14,   13},
1205         {7,      6,  255,  255,  255,  7,   6,  255,  255,    8}
1206 };
1207
1208 /* ccpu00132341-DEL Removed rgSchTddRlsDlSubfrmTbl and used Kset table for 
1209  * releasing DL HARQs */
1210
1211 /* DwPTS Scheduling Changes Start */
1212 /* Provides the number of Cell Reference Signals in DwPTS
1213  * region per RB */
1214 PRIVATE U8  rgSchCmnDwptsCrs[2][3] = {/* [Spl Sf cfg][Ant Port] */
1215            {4, 8,  16}, /* Spl Sf cfg 1,2,3,6,7,8 */
1216            {6, 12, 20}, /* Spl Sf cfg 4 */
1217 };
1218
1219 PRIVATE S8  rgSchCmnSplSfDeltaItbs[9] = RG_SCH_DWPTS_ITBS_ADJ;
1220 /* DwPTS Scheduling Changes End */
1221 #endif
1222
1223
1224 PRIVATE U32 rgSchCmnBsrTbl[64] = {
1225    0, 10, 12, 14, 17, 19, 22, 26,
1226    31, 36, 42, 49, 57, 67, 78, 91,
1227    107, 125, 146, 171, 200, 234, 274, 321,
1228    376, 440, 515, 603, 706, 826, 967, 1132,
1229    1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
1230    4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
1231    16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
1232    58255, 68201, 79846, 93479, 109439, 128125, 150000, 220000
1233 };
1234
1235 PRIVATE U32 rgSchCmnExtBsrTbl[64] = {
1236    0, 10, 13, 16, 19, 23, 29, 35,
1237    43, 53, 65, 80, 98, 120, 147, 181,
1238    223, 274, 337, 414, 509, 625, 769, 945,
1239    1162, 1429, 1757, 2161, 2657, 3267, 4017, 4940,
1240    6074, 7469, 9185, 11294, 13888, 17077, 20999, 25822,
1241    31752, 39045, 48012, 59039, 72598, 89272, 109774, 134986,
1242    165989, 204111, 250990, 308634, 379519, 466683, 573866, 705666,
1243    867737, 1067031, 1312097, 1613447, 1984009, 2439678, 3000000, 3100000
1244 };
1245
1246
1247 PRIVATE U8 rgSchCmnUlRvIdxToIMcsTbl[4] = {32, 30, 31, 29};
1248
1249 PUBLIC U8 rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI];
1250
1251 PUBLIC RgSchTbSzTbl rgTbSzTbl = {
1252  {
1253    {16,    32,    56,    88,    120,   152,   176,   208,   224,   256,   288,   328,   344,   376,   392,   424,   456,   488,   504,   536,   568,   600,   616,   648,   680,   712,   744,   776,   776,   808,   840,   872,   904,   936,   968,   1000,  1032,  1032,  1064,  1096,  1128,  1160,  1192,  1224,  1256,  1256,  1288,  1320,  1352,  1384,  1416,  1416,  1480,  1480,  1544,  1544,  1608,  1608,  1608,  1672,  1672,  1736,  1736,  1800,  1800,  1800,  1864,  1864,  1928,  1928,  1992,  1992,  2024,  2088,  2088,  2088,  2152,  2152,  2216,  2216,  2280,  2280,  2280,  2344,  2344,  2408,  2408,  2472,  2472,  2536,  2536,  2536,  2600,  2600,  2664,  2664,  2728,  2728,  2728,  2792,  2792,  2856,  2856,  2856,  2984,  2984,  2984,  2984,  2984,  3112},
1254    {24,    56,    88,    144,   176,   208,   224,   256,   328,   344,   376,   424,   456,   488,   520,   568,   600,   632,   680,   712,   744,   776,   808,   872,   904,   936,   968,   1000,  1032,  1064,  1128,  1160,  1192,  1224,  1256,  1288,  1352,  1384,  1416,  1416,  1480,  1544,  1544,  1608,  1608,  1672,  1736,  1736,  1800,  1800,  1864,  1864,  1928,  1992,  1992,  2024,  2088,  2088,  2152,  2152,  2216,  2280,  2280,  2344,  2344,  2408,  2472,  2472,  2536,  2536,  2600,  2600,  2664,  2728,  2728,  2792,  2792,  2856,  2856,  2856,  2984,  2984,  2984,  3112,  3112,  3112,  3240,  3240,  3240,  3240,  3368,  3368,  3368,  3496,  3496,  3496,  3496,  3624,  3624,  3624,  3752,  3752,  3752,  3752,  3880,  3880,  3880,  4008,  4008,  4008},
1255    {32,    72,    144,   176,   208,   256,   296,   328,   376,   424,   472,   520,   568,   616,   648,   696,   744,   776,   840,   872,   936,   968,   1000,  1064,  1096,  1160,  1192,  1256,  1288,  1320,  1384,  1416,  1480,  1544,  1544,  1608,  1672,  1672,  1736,  1800,  1800,  1864,  1928,  1992,  2024,  2088,  2088,  2152,  2216,  2216,  2280,  2344,  2344,  2408,  2472,  2536,  2536,  2600,  2664,  2664,  2728,  2792,  2856,  2856,  2856,  2984,  2984,  3112,  3112,  3112,  3240,  3240,  3240,  3368,  3368,  3368,  3496,  3496,  3496,  3624,  3624,  3624,  3752,  3752,  3880,  3880,  3880,  4008,  4008,  4008,  4136,  4136,  4136,  4264,  4264,  4264,  4392,  4392,  4392,  4584,  4584,  4584,  4584,  4584,  4776,  4776,  4776,  4776,  4968,  4968},
1256    {40,    104,   176,   208,   256,   328,   392,   440,   504,   568,   616,   680,   744,   808,   872,   904,   968,   1032,  1096,  1160,  1224,  1256,  1320,  1384,  1416,  1480,  1544,  1608,  1672,  1736,  1800,  1864,  1928,  1992,  2024,  2088,  2152,  2216,  2280,  2344,  2408,  2472,  2536,  2536,  2600,  2664,  2728,  2792,  2856,  2856,  2984,  2984,  3112,  3112,  3240,  3240,  3368,  3368,  3496,  3496,  3624,  3624,  3624,  3752,  3752,  3880,  3880,  4008,  4008,  4136,  4136,  4264,  4264,  4392,  4392,  4392,  4584,  4584,  4584,  4776,  4776,  4776,  4776,  4968,  4968,  4968,  5160,  5160,  5160,  5352,  5352,  5352,  5352,  5544,  5544,  5544,  5736,  5736,  5736,  5736,  5992,  5992,  5992,  5992,  6200,  6200,  6200,  6200,  6456,  6456},
1257    {56,    120,   208,   256,   328,   408,   488,   552,   632,   696,   776,   840,   904,   1000,  1064,  1128,  1192,  1288,  1352,  1416,  1480,  1544,  1608,  1736,  1800,  1864,  1928,  1992,  2088,  2152,  2216,  2280,  2344,  2408,  2472,  2600,  2664,  2728,  2792,  2856,  2984,  2984,  3112,  3112,  3240,  3240,  3368,  3496,  3496,  3624,  3624,  3752,  3752,  3880,  4008,  4008,  4136,  4136,  4264,  4264,  4392,  4392,  4584,  4584,  4584,  4776,  4776,  4968,  4968,  4968,  5160,  5160,  5160,  5352,  5352,  5544,  5544,  5544,  5736,  5736,  5736,  5992,  5992,  5992,  5992,  6200,  6200,  6200,  6456,  6456,  6456,  6456,  6712,  6712,  6712,  6968,  6968,  6968,  6968,  7224,  7224,  7224,  7480,  7480,  7480,  7480,  7736,  7736,  7736,  7992},
1258    {72,    144,   224,   328,   424,   504,   600,   680,   776,   872,   968,   1032,  1128,  1224,  1320,  1384,  1480,  1544,  1672,  1736,  1864,  1928,  2024,  2088,  2216,  2280,  2344,  2472,  2536,  2664,  2728,  2792,  2856,  2984,  3112,  3112,  3240,  3368,  3496,  3496,  3624,  3752,  3752,  3880,  4008,  4008,  4136,  4264,  4392,  4392,  4584,  4584,  4776,  4776,  4776,  4968,  4968,  5160,  5160,  5352,  5352,  5544,  5544,  5736,  5736,  5736,  5992,  5992,  5992,  6200,  6200,  6200,  6456,  6456,  6712,  6712,  6712,  6968,  6968,  6968,  7224,  7224,  7224,  7480,  7480,  7480,  7736,  7736,  7736,  7992,  7992,  7992,  8248,  8248,  8248,  8504,  8504,  8760,  8760,  8760,  8760,  9144,  9144,  9144,  9144,  9528,  9528,  9528,  9528,  9528},
1259    {328,    176,   256,   392,   504,   600,   712,   808,   936,   1032,  1128,  1224,  1352,  1480,  1544,  1672,  1736,  1864,  1992,  2088,  2216,  2280,  2408,  2472,  2600,  2728,  2792,  2984,  2984,  3112,  3240,  3368,  3496,  3496,  3624,  3752,  3880,  4008,  4136,  4136,  4264,  4392,  4584,  4584,  4776,  4776,  4968,  4968,  5160,  5160,  5352,  5352,  5544,  5736,  5736,  5992,  5992,  5992,  6200,  6200,  6456,  6456,  6456,  6712,  6712,  6968,  6968,  6968,  7224,  7224,  7480,  7480,  7736,  7736,  7736,  7992,  7992,  8248,  8248,  8248,  8504,  8504,  8760,  8760,  8760,  9144,  9144,  9144,  9144,  9528,  9528,  9528,  9528,  9912,  9912,  9912,  10296, 10296, 10296, 10296, 10680, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448},
1260    {104,   224,   328,   472,   584,   712,   840,   968,   1096,  1224,  1320,  1480,  1608,  1672,  1800,  1928,  2088,  2216,  2344,  2472,  2536,  2664,  2792,  2984,  3112,  3240,  3368,  3368,  3496,  3624,  3752,  3880,  4008,  4136,  4264,  4392,  4584,  4584,  4776,  4968,  4968,  5160,  5352,  5352,  5544,  5736,  5736,  5992,  5992,  6200,  6200,  6456,  6456,  6712,  6712,  6712,  6968,  6968,  7224,  7224,  7480,  7480,  7736,  7736,  7992,  7992,  8248,  8248,  8504,  8504,  8760,  8760,  8760,  9144,  9144,  9144,  9528,  9528,  9528,  9912,  9912,  9912,  10296, 10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11448, 11832, 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 12960, 13536, 13536},
1261    {120,   256,   392,   536,   680,   808,   968,   1096,  1256,  1384,  1544,  1672,  1800,  1928,  2088,  2216,  2344,  2536,  2664,  2792,  2984,  3112,  3240,  3368,  3496,  3624,  3752,  3880,  4008,  4264,  4392,  4584,  4584,  4776,  4968,  4968,  5160,  5352,  5544,  5544,  5736,  5992,  5992,  6200,  6200,  6456,  6456,  6712,  6968,  6968,  7224,  7224,  7480,  7480,  7736,  7736,  7992,  7992,  8248,  8504,  8504,  8760,  8760,  9144,  9144,  9144,  9528,  9528,  9528,  9912,  9912,  9912,  10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15264},
1262    {136,   296,   456,   616,   776,   936,   1096,  1256,  1416,  1544,  1736,  1864,  2024,  2216,  2344,  2536,  2664,  2856,  2984,  3112,  3368,  3496,  3624,  3752,  4008,  4136,  4264,  4392,  4584,  4776,  4968,  5160,  5160,  5352,  5544,  5736,  5736,  5992,  6200,  6200,  6456,  6712,  6712,  6968,  6968,  7224,  7480,  7480,  7736,  7992,  7992,  8248,  8248,  8504,  8760,  8760,  9144,  9144,  9144,  9528,  9528,  9912,  9912,  10296, 10296, 10296, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11832, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16416, 16992, 16992, 16992, 16992, 17568},
1263    {144,   328,   504,   680,   872,   1032,  1224,  1384,  1544,  1736,  1928,  2088,  2280,  2472,  2664,  2792,  2984,  3112,  3368,  3496,  3752,  3880,  4008,  4264,  4392,  4584,  4776,  4968,  5160,  5352,  5544,  5736,  5736,  5992,  6200,  6200,  6456,  6712,  6712,  6968,  7224,  7480,  7480,  7736,  7992,  7992,  8248,  8504,  8504,  8760,  9144,  9144,  9144,  9528,  9528,  9912,  9912,  10296, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080},
1264    {176,   376,   584,   776,   1000,  1192,  1384,  1608,  1800,  2024,  2216,  2408,  2600,  2792,  2984,  3240,  3496,  3624,  3880,  4008,  4264,  4392,  4584,  4776,  4968,  5352,  5544,  5736,  5992,  5992,  6200,  6456,  6712,  6968,  6968,  7224,  7480,  7736,  7736,  7992,  8248,  8504,  8760,  8760,  9144,  9144,  9528,  9528,  9912,  9912,  10296, 10680, 10680, 11064, 11064, 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, 22152, 22152},
1265    {208,   440,   680,   904,   1128,  1352,  1608,  1800,  2024,  2280,  2472,  2728,  2984,  3240,  3368,  3624,  3880,  4136,  4392,  4584,  4776,  4968,  5352,  5544,  5736,  5992,  6200,  6456,  6712,  6712,  6968,  7224,  7480,  7736,  7992,  8248,  8504,  8760,  8760,  9144,  9528,  9528,  9912,  9912,  10296, 10680, 10680, 11064, 11064, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 23688, 24496, 24496, 24496, 24496, 25456},
1266    {224,   488,   744,   1000,  1256,  1544,  1800,  2024,  2280,  2536,  2856,  3112,  3368,  3624,  3880,  4136,  4392,  4584,  4968,  5160,  5352,  5736,  5992,  6200,  6456,  6712,  6968,  7224,  7480,  7736,  7992,  8248,  8504,  8760,  9144,  9144,  9528,  9912,  9912,  10296, 10680, 10680, 11064, 11448, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 26416, 26416, 26416, 26416, 27376, 27376, 27376, 27376, 28336, 28336},
1267    {256,   552,   840,   1128,  1416,  1736,  1992,  2280,  2600,  2856,  3112,  3496,  3752,  4008,  4264,  4584,  4968,  5160,  5544,  5736,  5992,  6200,  6456,  6968,  7224,  7480,  7736,  7992,  8248,  8504,  8760,  9144,  9528,  9912,  9912,  10296, 10680, 11064, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704},
1268    {280,   600,   904,   1224,  1544,  1800,  2152,  2472,  2728,  3112,  3368,  3624,  4008,  4264,  4584,  4968,  5160,  5544,  5736,  6200,  6456,  6712,  6968,  7224,  7736,  7992,  8248,  8504,  8760,  9144,  9528,  9912,  10296, 10296, 10680, 11064, 11448, 11832, 11832, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008},
1269    {328,   632,   968,   1288,  1608,  1928,  2280,  2600,  2984,  3240,  3624,  3880,  4264,  4584,  4968,  5160,  5544,  5992,  6200,  6456,  6712,  7224,  7480,  7736,  7992,  8504,  8760,  9144,  9528,  9912,  9912,  10296, 10680, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160, 35160, 35160, 35160},
1270    {336,   696,   1064,  1416,  1800,  2152,  2536,  2856,  3240,  3624,  4008,  4392,  4776,  5160,  5352,  5736,  6200,  6456,  6712,  7224,  7480,  7992,  8248,  8760,  9144,  9528,  9912,  10296, 10296, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 39232},
1271    {376,   776,   1160,  1544,  1992,  2344,  2792,  3112,  3624,  4008,  4392,  4776,  5160,  5544,  5992,  6200,  6712,  7224,  7480,  7992,  8248,  8760,  9144,  9528,  9912,  10296, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 14112, 14112, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816},
1272    {408,   840,   1288,  1736,  2152,  2600,  2984,  3496,  3880,  4264,  4776,  5160,  5544,  5992,  6456,  6968,  7224,  7736,  8248,  8504,  9144,  9528,  9912,  10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 15264, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19080, 19848, 20616, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888},
1273    {440,   904,   1384,  1864,  2344,  2792,  3240,  3752,  4136,  4584,  5160,  5544,  5992,  6456,  6968,  7480,  7992,  8248,  8760,  9144,  9912,  10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 20616, 21384, 22152, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 48936, 51024, 51024, 51024},
1274    {488,   1000,  1480,  1992,  2472,  2984,  3496,  4008,  4584,  4968,  5544,  5992,  6456,  6968,  7480,  7992,  8504,  9144,  9528,  9912,  10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 15840, 16416, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056},
1275    {520,   1064,  1608,  2152,  2664,  3240,  3752,  4264,  4776,  5352,  5992,  6456,  6968,  7480,  7992,  8504,  9144,  9528,  10296, 10680, 11448, 11832, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 19080, 19080, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256},
1276    {552,   1128,  1736,  2280,  2856,  3496,  4008,  4584,  5160,  5736,  6200,  6968,  7480,  7992,  8504,  9144,  9912,  10296, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22152, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776},
1277    {584,   1192,  1800,  2408,  2984,  3624,  4264,  4968,  5544,  5992,  6712,  7224,  7992,  8504,  9144,  9912,  10296, 11064, 11448, 12216, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22920, 22920, 23688, 24496, 25456, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592},
1278    {616,   1256,  1864,  2536,  3112,  3752,  4392,  5160,  5736,  6200,  6968,  7480,  8248,  8760,  9528,  10296, 10680, 11448, 12216, 12576, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 24496, 24496, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, 68808, 71112},
1279    {712,   1480,  2216,  2984,  3752,  4392,  5160,  5992,  6712,  7480,  8248,  8760,  9528,  10296, 11064, 11832, 12576, 13536, 14112, 14688, 15264, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 25456, 26416, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376}
1280  },
1281  {
1282    {32,    88,    152,   208,   256,   328,   376,   424,   488,   536,   600,   648,   712,   776,   808,   872,   936,   1000,  1032,  1096,  1160,  1224,  1256,  1320,  1384,  1416,  1480,  1544,  1608,  1672,  1736,  1800,  1800,  1864,  1928,  1992,  2088,  2088,  2152,  2216,  2280,  2344,  2408,  2472,  2536,  2536,  2600,  2664,  2728,  2792,  2856,  2856,  2984,  2984,  3112,  3112,  3240,  3240,  3240,  3368,  3368,  3496,  3496,  3624,  3624,  3624,  3752,  3752,  3880,  3880,  4008,  4008,  4008,  4136,  4136,  4136,  4264,  4264,  4392,  4392,  4584,  4584,  4584,  4776,  4776,  4776,  4776,  4968,  4968,  5160,  5160,  5160,  5160,  5160,  5352,  5352,  5544,  5544,  5544,  5544,  5544,  5736,  5736,  5736,  5992,  5992,  5992,  5992,  5992,  6200},
1283    {56,    144,   208,   256,   344,   424,   488,   568,   632,   712,   776,   872,   936,   1000,  1064,  1160,  1224,  1288,  1384,  1416,  1544,  1608,  1672,  1736,  1800,  1864,  1992,  2024,  2088,  2152,  2280,  2344,  2408,  2472,  2536,  2600,  2728,  2792,  2856,  2856,  2984,  3112,  3112,  3240,  3240,  3368,  3496,  3496,  3624,  3624,  3752,  3752,  3880,  4008,  4008,  4008,  4136,  4136,  4264,  4264,  4392,  4584,  4584,  4776,  4776,  4776,  4968,  4968,  5160,  5160,  5160,  5160,  5352,  5544,  5544,  5544,  5544,  5736,  5736,  5736,  5992,  5992,  5992,  6200,  6200,  6200,  6456,  6456,  6456,  6456,  6712,  6712,  6712,  6968,  6968,  6968,  6968,  7224,  7224,  7224,  7480,  7480,  7480,  7480,  7736,  7736,  7736,  7992,  7992,  7992},
1284    {72,    176,   256,   328,   424,   520,   616,   696,   776,   872,   968,   1064,  1160,  1256,  1320,  1416,  1544,  1608,  1672,  1800,  1864,  1992,  2088,  2152,  2216,  2344,  2408,  2536,  2600,  2664,  2792,  2856,  2984,  3112,  3112,  3240,  3368,  3368,  3496,  3624,  3624,  3752,  3880,  4008,  4008,  4136,  4264,  4264,  4392,  4584,  4584,  4584,  4776,  4776,  4968,  5160,  5160,  5160,  5352,  5352,  5544,  5544,  5736,  5736,  5736,  5992,  5992,  6200,  6200,  6200,  6456,  6456,  6456,  6712,  6712,  6712,  6968,  6968,  6968,  7224,  7224,  7224,  7480,  7480,  7736,  7736,  7736,  7992,  7992,  7992,  8248,  8248,  8248,  8504,  8504,  8504,  8760,  8760,  8760,  9144,  9144,  9144,  9144,  9144,  9528,  9528,  9528,  9528,  9912,  9912},
1285    {104,   208,   328,   440,   568,   680,   808,   904,   1032,  1160,  1256,  1384,  1480,  1608,  1736,  1864,  1992,  2088,  2216,  2344,  2472,  2536,  2664,  2792,  2856,  2984,  3112,  3240,  3368,  3496,  3624,  3752,  3880,  4008,  4136,  4264,  4392,  4392,  4584,  4776,  4776,  4968,  4968,  5160,  5352,  5352,  5544,  5544,  5736,  5736,  5992,  5992,  6200,  6200,  6456,  6456,  6712,  6712,  6968,  6968,  7224,  7224,  7224,  7480,  7480,  7736,  7736,  7992,  7992,  8248,  8248,  8504,  8504,  8760,  8760,  8760,  9144,  9144,  9144,  9528,  9528,  9528,  9528,  9912,  9912,  9912,  10296, 10296, 10296, 10680, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11448, 11832, 11832, 11832, 11832, 12576, 12576, 12576, 12576, 12960, 12960},
1286    {120,   256,   408,   552,   696,   840,   1000,  1128,  1288,  1416,  1544,  1736,  1864,  1992,  2152,  2280,  2408,  2600,  2728,  2856,  2984,  3112,  3240,  3496,  3624,  3752,  3880,  4008,  4136,  4264,  4392,  4584,  4776,  4968,  4968,  5160,  5352,  5544,  5544,  5736,  5992,  5992,  6200,  6200,  6456,  6456,  6712,  6968,  6968,  7224,  7224,  7480,  7480,  7736,  7992,  7992,  8248,  8248,  8504,  8504,  8760,  8760,  9144,  9144,  9144,  9528,  9528,  9912,  9912,  9912,  10296, 10296, 10296, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 11832, 11832, 12576, 12576, 12576, 12960, 12960, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840},
1287    {144,   328,   504,   680,   872,   1032,  1224,  1384,  1544,  1736,  1928,  2088,  2280,  2472,  2664,  2792,  2984,  3112,  3368,  3496,  3752,  3880,  4008,  4264,  4392,  4584,  4776,  4968,  5160,  5352,  5544,  5736,  5736,  5992,  6200,  6200,  6456,  6712,  6968,  6968,  7224,  7480,  7480,  7736,  7992,  7992,  8248,  8504,  8760,  8760,  9144,  9144,  9528,  9528,  9528,  9912,  9912,  10296, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11448, 11832, 11832,  11832,  12576,  12576,  12576,  12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992,  16992,  17568,  17568,  17568,  17568,  18336,  18336,  18336,  18336,  19080,  19080,  19080,  19080,  19080},
1288    {176,   392,   600,   808,   1032,  1224,  1480,  1672,  1864,  2088,  2280,  2472,  2728,  2984,  3112,  3368,  3496,  3752,  4008,  4136,  4392,  4584,  4776,  4968,  5160,  5352,  5736,  5992,  5992,  6200,  6456,  6712,  6968,  6968,  7224,  7480,  7736,  7992,  8248,  8248,  8504,  8760,  9144,  9144,  9528,  9528,  9912,  9912,  10296, 10296, 10680, 10680, 11064, 11448, 11448, 11832, 11832, 11832, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 14112, 14112, 14112,  14688,  14688,  14688,  14688,  15264, 15264, 15264, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848,  20616, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920},
1289    {224,   472,   712,   968,   1224,  1480,  1672,  1928,  2216,  2472,  2664,  2984,  3240,  3368,  3624,  3880,  4136,  4392,  4584,  4968,  5160,  5352,  5736,  5992,  6200,  6456,  6712,  6712,  6968,  7224,  7480,  7736,  7992,  8248,  8504,  8760,  9144,  9144,  9528,  9912,  9912,  10296, 10680, 10680, 11064, 11448, 11448, 11832, 11832, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 25456, 25456, 27376, 27376},
1290    {256,   536,   808,   1096,  1384,  1672,  1928,  2216,  2536,  2792,  3112,  3368,  3624,  3880,  4264,  4584,  4776,  4968,  5352,  5544,  5992,  6200,  6456,  6712,  6968,  7224,  7480,  7736,  7992,  8504,  8760,  9144,  9144,  9528,  9912,  9912,  10296, 10680, 11064, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576},
1291    {296,   616,   936,   1256,  1544,  1864,  2216,  2536,  2856,  3112,  3496,  3752,  4136,  4392,  4776,  5160,  5352,  5736,  5992,  6200,  6712,  6968,  7224,  7480,  7992,  8248,  8504,  8760,  9144,  9528,  9912,  10296, 10296, 10680, 11064, 11448, 11832, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160},
1292    {328,   680,   1032,  1384,  1736,  2088,  2472,  2792,  3112,  3496,  3880,  4264,  4584,  4968,  5352,  5736,  5992,  6200,  6712,  6968,  7480,  7736,  7992,  8504,  8760,  9144,  9528,  9912,  10296, 10680, 11064, 11448, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 16992, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 21384, 21384, 24264, 24264, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 37888},
1293    {376,   776,   1192,  1608,  2024,  2408,  2792,  3240,  3624,  4008,  4392,  4776,  5352,  5736,  5992,  6456,  6968,  7224,  7736,  7992,  8504,  8760,  9144,  9528,  9912,  10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816},
1294    {440,   904,   1352,  1800,  2280,  2728,  3240,  3624,  4136,  4584,  4968,  5544,  5992,  6456,  6712,  7224,  7736,  8248,  8760,  9144,  9528,  9912,  10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15264, 15840, 16416, 16992, 17568, 17568, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024},
1295    {488,   1000,  1544,  2024,  2536,  3112,  3624,  4136,  4584,  5160,  5736,  6200,  6712,  7224,  7736,  8248,  8760,  9144,  9912,  10296, 10680, 11448, 11832, 12216, 12960, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336},
1296    {552,   1128,  1736,  2280,  2856,  3496,  4008,  4584,  5160,  5736,  6200,  6968,  7480,  7992,  8504,  9144,  9912,  10296, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22152, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776},
1297    {600,   1224,  1800,  2472,  3112,  3624,  4264,  4968,  5544,  6200,  6712,  7224,  7992,  8504,  9144,  9912,  10296, 11064, 11832, 12216, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 23688, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808},
1298    {632,   1288,  1928,  2600,  3240,  3880,  4584,  5160,  5992,  6456,  7224,  7736,  8504,  9144,  9912,  10296, 11064, 11832, 12216, 12960, 13536, 14112, 14688, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 24496, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 68808, 71112, 71112, 71112, 71112},
1299    {696,   1416,  2152,  2856,  3624,  4392,  5160,  5736,  6456,  7224,  7992,  8760,  9528,  10296, 10680, 11448, 12216, 12960, 13536, 14688, 15264, 15840, 16416, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 26416, 26416, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 71112, 73712, 73712, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 78704, 78704},
1300    {776,   1544,  2344,  3112,  4008,  4776,  5544,  6200,  7224,  7992,  8760,  9528,  10296, 11064, 11832, 12576, 13536, 14112, 15264, 15840, 16416, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 26416, 27376, 27376, 28336, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936},
1301    {840,   1736,  2600,  3496,  4264,  5160,  5992,  6968,  7736,  8504,  9528,  10296, 11064, 12216, 12960, 13536, 14688, 15264, 16416, 16992, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 24496, 25456, 25456, 26416, 27376, 28336, 29296, 30576, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 36696, 37888, 39232, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800},
1302    {904,   1864,  2792,  3752,  4584,  5544,  6456,  7480,  8248,  9144,  10296, 11064, 12216, 12960, 14112, 14688, 15840, 16992, 17568, 18336, 19848, 20616, 21384, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 29296, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 36696, 37888, 39232, 40576, 40576, 42368, 42368, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 97896, 101840, 101840, 101840},
1303    {1000,  1992,  2984,  4008,  4968,  5992,  6968,  7992,  9144,  9912,  11064, 12216, 12960, 14112, 15264, 15840, 16992, 18336, 19080, 19848, 21384, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 30576, 31704, 31704, 32856, 34008, 35160, 36696, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 101840, 101840, 101840, 101840, 105528, 105528, 105528, 105528, 110136, 110136, 110136},
1304    {1064,  2152,  3240,  4264,  5352,  6456,  7480,  8504,  9528,  10680, 11832, 12960, 14112, 15264, 16416, 16992, 18336, 19080, 20616, 21384, 22920, 23688, 24496, 25456, 27376, 28336, 29296, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 101840, 101840, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816},
1305    {1128,  2280,  3496,  4584,  5736,  6968,  7992,  9144,  10296, 11448, 12576, 13536, 14688, 15840, 16992, 18336, 19848, 20616, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 45352, 45352, 46888, 48936, 48936, 51024, 51024, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 68808, 71112, 71112, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840,101840,101840,101840,105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496},
1306    {1192,  2408,  3624,  4968,  5992,  7224,  8504,  9912,  11064, 12216, 13536, 14688, 15840, 16992, 18336, 19848, 20616, 22152, 22920, 24496, 25456, 26416, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 42368, 42368, 43816, 45352, 46888, 46888, 48936, 51024, 51024, 52752, 52752, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 101840, 105528, 105528, 105528, 105528, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496, 128496, 128496, 128496, 133208, 133208, 133208, 133208},
1307    {1256,  2536,  3752,  5160,  6200,  7480,  8760,  10296, 11448, 12576, 14112, 15264, 16416, 17568, 19080, 20616, 21384, 22920, 24496, 25456, 26416, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 42368, 43816, 43816, 45352, 46888, 48936, 48936, 51024, 52752, 52752, 55056, 55056, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 71112, 71112, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040,115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496, 128496, 128496, 128496, 133208, 133208, 133208, 133208, 137792, 137792, 137792, 142248},
1308    {1480,  2984,  4392,  5992,  7480,  8760,  10296, 11832, 13536, 14688, 16416, 17568, 19080, 20616, 22152, 23688, 25456, 26416, 28336, 29296, 30576, 32856, 34008, 35160, 36696, 37888, 40576, 40576, 42368, 43816, 45352, 46888, 48936, 51024, 52752, 52752, 55056, 55056, 57336, 59256, 59256, 61664, 63776, 63776, 66592, 68808, 68808, 71112, 73712, 75376, 75376, 75376, 75376, 75376, 75376, 81176, 84760, 84760, 87936, 87936, 90816, 90816, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 128496, 128496, 128496, 133208, 133208, 133208, 137792, 137792, 137792, 142248, 142248, 142248, 146856, 146856,149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776}
1309  }
1310 };
1311 RgSchUlIMcsTbl rgUlIMcsTbl = {
1312    {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
1313    {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10},
1314    {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14},
1315    {4, 15}, {4, 16}, {4, 17}, {4, 18}, {4, 19},
1316    {6, 19}, {6, 20}, {6, 21}, {6, 22}, {6, 23},
1317    {6, 24}, {6, 25}, {6, 26}
1318 };
1319 RgSchUeCatTbl rgUeCatTbl = {
1320    /*Column1:Maximum number of bits of an UL-SCH 
1321              transport block transmitted within a TTI
1322              - maxUlBits
1323      Column2:Maximum number of bits of a DLSCH
1324              transport block received within a TTI 
1325              - maxDlBits
1326      Column3:Total number of soft channel bits 
1327              - maxSftChBits
1328      Column4:Support for 64QAM in UL 
1329              - ul64qamSup
1330      Column5:Maximum number of DL-SCH transport
1331              block bits received within a TTI
1332              - maxDlTbBits
1333      Column6:Maximum number of supported layers for 
1334              spatial multiplexing in DL 
1335              - maxTxLyrs*/
1336    {5160,  {10296,0},      250368,  FALSE, 10296,  1},
1337    {25456, {51024,0},      1237248, FALSE, 51024,  2},
1338    {51024, {75376,0},      1237248, FALSE, 102048, 2},
1339    {51024, {75376,0},      1827072, FALSE, 150752, 2},
1340    {75376, {149776,0},     3667200, TRUE,  299552, 4},
1341    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1342    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1343    {149776,{299856,0},     35982720,TRUE,  2998560, 8}
1344 };
1345
1346 /* [ccpu00138532]-ADD-The below table stores the min HARQ RTT time
1347    in Downlink for TDD and FDD. Indices 0 to 6 map to tdd UL DL config 0-6. 
1348    Index 7 map to FDD */    
1349 U8 rgSchCmnHarqRtt[8] = {4,7,10,9,12,15,6,8};
1350 /* Number of CFI Switchover Index is equals to 7 TDD Indexes + 1 FDD index */
1351 U8 rgSchCfiSwitchOvrWinLen[] = {7, 4, 2, 3, 2, 1, 6, 8};
1352
1353 /* EffTbl is calculated for single layer and two layers.
1354   * CqiToTbs is calculated for single layer and two layers */
1355 RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1356 RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1357 /* New variable to store UL effiency values for normal and extended CP*/
1358 RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1];
1359 RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1360 RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1361 RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
1362 RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1363 RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1364 RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1365 RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1366 /* Include CRS REs while calculating Efficiency */
1367 RgSchCmnTbSzEff *rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI];
1368 RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP];
1369 #ifdef LTE_TDD
1370 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3, 1};
1371 #else
1372 /* Added matrix 'rgRaPrmblToRaFrmTbl'for computation of RA sub-frames from RA preamble */
1373 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3};
1374 #endif
1375
1376 EXTERN  RgUlSchdInits        rgSchUlSchdInits;
1377 EXTERN  RgDlSchdInits        rgSchDlSchdInits;
1378 EXTERN  RgDlfsSchdInits      rgSchDlfsSchdInits;
1379 #ifdef EMTC_ENABLE
1380 EXTERN  RgEmtcUlSchdInits        rgSchEmtcUlSchdInits;
1381 EXTERN  RgEmtcDlSchdInits        rgSchEmtcDlSchdInits;
1382 #endif
1383
1384 /* RACHO : start */
1385 PRIVATE S16 rgSCHCmnUeIdleExdThrsld ARGS((
1386 RgSchCellCb     *cell,
1387 RgSchUeCb       *ue
1388 ));
1389 PUBLIC RgSchUeCb* rgSCHCmnGetHoUe ARGS((
1390 RgSchCellCb           *cell,
1391 U16                   rapId
1392 ));
1393 PRIVATE Void rgSCHCmnDelDedPreamble ARGS((
1394 RgSchCellCb           *cell,
1395 U8                    preambleId
1396 ));
1397 PUBLIC RgSchUeCb* rgSCHCmnGetPoUe ARGS((
1398 RgSchCellCb           *cell,
1399 U16                   rapId,
1400 CmLteTimingInfo       timingInfo
1401 ));
1402 PRIVATE Void rgSCHCmnDelRachInfo ARGS((
1403 RgSchCellCb  *cell,
1404 RgSchUeCb    *ue
1405 ));
1406 PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe ARGS((
1407 RgSchCellCb           *cell,
1408 RgSchUlSf             *sf,
1409 RgSchUeCb             *ue,
1410 U8                    maxRb
1411 ));
1412 PRIVATE Void rgSCHCmnHdlHoPo ARGS((
1413 RgSchCellCb           *cell,
1414 CmLListCp             *raRspLst,
1415 RgSchRaReqInfo        *raReq
1416 ));
1417 PRIVATE Void rgSCHCmnAllocPoHoGrnt ARGS((
1418 RgSchCellCb           *cell,
1419 CmLListCp             *raRspLst,
1420 RgSchUeCb             *ue,
1421 RgSchRaReqInfo        *raReq
1422 ));
1423 PRIVATE Void rgSCHCmnFillPdcchOdr2Sf ARGS((
1424 RgSchCellCb *cell,
1425 RgSchUeCb   *ue,
1426 RgSchPdcch  *pdcc,
1427 U8          rapId,
1428 U8          prachMskIdx
1429 ));
1430 PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ ARGS((
1431 RgSchCellCb                *cell,
1432 RgSchUeCb                  *ue
1433 ));
1434 PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ ARGS((
1435 RgSchCellCb                *cell,
1436 RgSchUeCb                  *ue
1437 ));
1438 PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx ARGS((
1439 RgSchCellCb  *cell
1440 ));
1441 PRIVATE Void rgSCHCmnUpdRachParam ARGS((
1442 RgSchCellCb  *cell
1443 ));
1444 PRIVATE S16 rgSCHCmnAllocPOParam ARGS((
1445 RgSchCellCb  *cell,
1446 RgSchDlSf    *dlSf,
1447 RgSchUeCb    *ue,
1448 RgSchPdcch   **pdcch,
1449 U8           *rapId,
1450 U8           *prachMskIdx
1451 ));
1452 PRIVATE Void rgSCHCmnGenPdcchOrder ARGS((
1453 RgSchCellCb  *cell,
1454 RgSchDlSf    *dlSf
1455 ));
1456 PRIVATE Void rgSCHCmnCfgRachDedPrm ARGS((
1457 RgSchCellCb   *cell
1458 ));
1459 /* RACHO : end */
1460
1461 PRIVATE Void rgSCHCmnHdlUlInactUes ARGS((
1462 RgSchCellCb  *cell
1463 ));
1464 PRIVATE Void rgSCHCmnHdlDlInactUes ARGS((
1465 RgSchCellCb  *cell
1466 ));
1467 PRIVATE Void rgSCHCmnUlInit ARGS((Void
1468 ));
1469 PRIVATE Void rgSCHCmnDlInit ARGS((Void
1470 ));
1471 PRIVATE Void rgSCHCmnInitDlRbAllocInfo ARGS((
1472 RgSchCmnDlRbAllocInfo  *allocInfo
1473 ));
1474 PRIVATE Void rgSCHCmnUpdUlCompEffBsr ARGS((
1475 RgSchUeCb *ue
1476 ));
1477 #if RG_UNUSED
1478 PRIVATE Void rgSCHCmnUlSetAllUnSched  ARGS((
1479 RgSchCmnUlRbAllocInfo *allocInfo
1480 ));
1481 PRIVATE Void rgSCHCmnUlUpdSf ARGS((
1482          RgSchCellCb           *cell,
1483          RgSchCmnUlRbAllocInfo *allocInfo,
1484          RgSchUlSf     *sf
1485          ));
1486 PRIVATE Void rgSCHCmnUlHndlAllocRetx ARGS((
1487          RgSchCellCb           *cell,
1488          RgSchCmnUlRbAllocInfo *allocInfo,
1489          RgSchUlSf     *sf,
1490          RgSchUlAlloc  *alloc
1491          ));
1492 #endif
1493 PRIVATE Void rgSCHCmnGrpPwrCntrlPucch ARGS((
1494 RgSchCellCb  *cell,
1495 RgSchDlSf    *dlSf
1496 ));
1497 PRIVATE Void rgSCHCmnGrpPwrCntrlPusch ARGS((
1498 RgSchCellCb  *cell,
1499 RgSchUlSf    *ulSf
1500 ));
1501 PRIVATE Void rgSCHCmnDelUeFrmRefreshQ ARGS((
1502 RgSchCellCb     *cell,
1503 RgSchUeCb       *ue
1504 ));
1505 PRIVATE S16 rgSCHCmnTmrExpiry ARGS((
1506 PTR cb,               /* Pointer to timer control block */
1507 S16 tmrEvnt           /* Timer Event */
1508 ));
1509 PRIVATE S16 rgSCHCmnTmrProc ARGS((
1510 RgSchCellCb *cell
1511 ));
1512 PRIVATE Void rgSCHCmnAddUeToRefreshQ ARGS((
1513 RgSchCellCb     *cell,
1514 RgSchUeCb       *ue,
1515 U32             wait
1516 ));
1517 PRIVATE Void rgSCHCmnDlCcchRetx ARGS((
1518 RgSchCellCb             *cell,
1519 RgSchCmnDlRbAllocInfo   *allocInfo
1520 ));
1521 PRIVATE Void rgSCHCmnUpdUeMimoInfo ARGS((
1522 RgrUeCfg     *ueCfg,
1523 RgSchCmnDlUe *ueDl,
1524 RgSchCellCb  *cell,
1525 RgSchCmnCell *cellSchd
1526 ));
1527 PRIVATE Void rgSCHCmnUpdUeUlCqiInfo ARGS((
1528 RgSchCellCb   *cell,
1529 RgSchUeCb     *ue,
1530 RgSchCmnUlUe  *ueUl,
1531 RgSchCmnUe    *ueSchCmn,
1532 RgSchCmnCell  *cellSchd,
1533 Bool          isEcp 
1534 ));
1535 #ifdef RGR_V1
1536 PRIVATE Void rgSCHCmnDlCcchSduRetx ARGS((
1537 RgSchCellCb             *cell,
1538 RgSchCmnDlRbAllocInfo   *allocInfo
1539 ));
1540 PRIVATE Void rgSCHCmnDlCcchSduTx ARGS((
1541 RgSchCellCb             *cell,
1542 RgSchCmnDlRbAllocInfo   *allocInfo
1543 ));
1544 PRIVATE S16 rgSCHCmnCcchSduAlloc ARGS((
1545 RgSchCellCb                *cell,
1546 RgSchUeCb                  *ueCb,
1547 RgSchCmnDlRbAllocInfo      *allocInfo
1548 ));
1549 PRIVATE S16 rgSCHCmnCcchSduDedAlloc ARGS((
1550 RgSchCellCb                *cell,
1551 RgSchUeCb                  *ueCb
1552 ));
1553 PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc ARGS((
1554 RgSchCellCb           *cell,
1555 RgSchUeCb             *ueCb,
1556 RgSchDlSf             *dlSf
1557 ));
1558 #endif
1559 PRIVATE Void rgSCHCmnInitVars ARGS((
1560          RgSchCellCb *cell
1561          ));
1562
1563 /*ccpu00117180 - DEL - Moved rgSCHCmnUpdVars to .x as its access is now PUBLIC */
1564 PRIVATE Void rgSCHCmnUlRbAllocForLst ARGS((
1565          RgSchCellCb           *cell,
1566          RgSchUlSf             *sf,
1567          U32                   count,
1568          CmLListCp             *reqLst,
1569          CmLListCp             *schdLst,
1570          CmLListCp             *nonSchdLst,
1571          Bool                  isNewTx
1572          ));
1573 PRIVATE S16 rgSCHCmnUlRbAllocForUe ARGS((
1574          RgSchCellCb           *cell,
1575          RgSchUlSf             *sf,
1576          RgSchUeCb             *ue,
1577          U8                    maxRb,
1578          RgSchUlHole           *hole
1579          ));
1580 PRIVATE Void rgSCHCmnMsg3GrntReq ARGS((
1581          RgSchCellCb     *cell,
1582          CmLteRnti       rnti,
1583          Bool            preamGrpA,
1584          RgSchUlHqProcCb *hqProc,
1585          RgSchUlAlloc    **ulAllocRef,
1586          U8              *hqProcIdRef
1587          ));
1588 PRIVATE Void rgSCHCmnUlNonadapRetx ARGS((
1589          RgSchCmnUlCell  *cellUl,
1590          RgSchUlAlloc    *alloc,
1591          U8               idx
1592          ));
1593
1594 PRIVATE Void rgSCHCmnDlCcchRarAlloc ARGS((
1595 RgSchCellCb             *cell
1596 ));
1597 PRIVATE Void rgSCHCmnDlCcchTx ARGS((
1598 RgSchCellCb             *cell,
1599 RgSchCmnDlRbAllocInfo   *allocInfo
1600 ));
1601 PRIVATE Void rgSCHCmnDlBcchPcch ARGS((
1602 RgSchCellCb             *cell,
1603 RgSchCmnDlRbAllocInfo   *allocInfo,
1604 RgInfSfAlloc            *subfrmAlloc
1605 ));
1606 PUBLIC Bool rgSCHCmnChkInWin ARGS((
1607 CmLteTimingInfo   frm,
1608 CmLteTimingInfo   start,
1609 CmLteTimingInfo   end
1610 ));
1611 PUBLIC Bool rgSCHCmnChkPastWin ARGS((
1612 CmLteTimingInfo   frm,
1613 CmLteTimingInfo   end
1614 ));
1615 PRIVATE Void rgSCHCmnClcAlloc ARGS((
1616 RgSchCellCb             *cell,
1617 RgSchDlSf               *sf,
1618 RgSchClcDlLcCb          *lch,
1619 U16                     rnti,
1620 RgSchCmnDlRbAllocInfo   *allocInfo
1621 ));
1622 #ifndef LTEMAC_SPS
1623 PRIVATE Void rgSCHCmnClcRbAlloc ARGS((
1624 RgSchCellCb             *cell,
1625 U32                     bo,
1626 U8                      cqi,
1627 U8                      *rb,
1628 U32                     *tbs,
1629 U8                      *mcs,
1630 RgSchDlSf               *sf 
1631 ));
1632 #endif
1633
1634 PRIVATE S16 rgSCHCmnMsg4Alloc ARGS((
1635 RgSchCellCb                *cell,
1636 RgSchRaCb                  *raCb,
1637 RgSchCmnDlRbAllocInfo      *allocInfo
1638 ));
1639 PRIVATE S16 rgSCHCmnMsg4DedAlloc ARGS((
1640 RgSchCellCb                *cell,
1641 RgSchRaCb                  *raCb
1642 ));
1643 PRIVATE Void rgSCHCmnDlRaRsp ARGS((
1644 RgSchCellCb                *cell,
1645 RgSchCmnDlRbAllocInfo      *allocInfo
1646 ));
1647 PRIVATE S16 rgSCHCmnRaRspAlloc ARGS((
1648 RgSchCellCb             *cell,
1649 RgSchDlSf               *subFrm,
1650 U16                     rntiIdx,
1651 U16                     rarnti,
1652 U8                      noRaRnti,
1653 RgSchCmnDlRbAllocInfo   *allocInfo
1654 ));
1655 PRIVATE Void rgSCHCmnUlUeDelAllocs ARGS((
1656 RgSchCellCb  *cell,
1657 RgSchUeCb   *ue
1658 ));
1659 PRIVATE Void rgSCHCmnDlSetUeAllocLmt ARGS((
1660 RgSchCellCb   *cell,
1661 RgSchCmnDlUe  *ueDl,
1662 Bool          isEmtcUe
1663 ));
1664 PRIVATE S16 rgSCHCmnDlRgrCellCfg ARGS((
1665 RgSchCellCb    *cell,
1666 RgrCellCfg     *cfg,
1667 RgSchErrInfo   *err
1668 ));
1669 PRIVATE Void rgSCHCmnUlAdapRetx ARGS((
1670 RgSchUlAlloc    *alloc,
1671 RgSchUlHqProcCb *proc
1672 ));
1673 PRIVATE Void rgSCHCmnUlUpdAllocRetx ARGS((
1674 RgSchCellCb    *cell,
1675 RgSchUlAlloc   *alloc
1676 ));
1677 PRIVATE Void rgSCHCmnUlSfReTxAllocs ARGS((
1678 RgSchCellCb *cell,
1679 RgSchUlSf   *sf
1680 ));
1681 /* Fix: syed Adaptive Msg3 Retx crash. */
1682 PRIVATE Void rgSCHCmnUlSfRlsRetxProcs ARGS((
1683 RgSchCellCb *cell,
1684 RgSchUlSf   *sf
1685 ));
1686
1687 #ifdef TFU_UPGRADE
1688 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg ARGS
1689 ((
1690 RgSchCellCb *cell,
1691 RgSchUeCb    *ue,
1692 RgrUeRecfg   *ueRecfg,
1693 U8 numTxPorts
1694 ));
1695 #else
1696 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg ARGS
1697 ((
1698 RgSchCellCb *cell,
1699 RgSchUeCb    *ue,
1700 RgrUeRecfg   *ueRecfg
1701 ));
1702 #endif
1703
1704
1705 /*
1706  * DL RB allocation specific functions
1707  */
1708
1709 PRIVATE Void rgSCHCmnDlRbAlloc ARGS((
1710 RgSchCellCb           *cell,
1711 RgSchCmnDlRbAllocInfo *allocInfo
1712 ));
1713 PRIVATE Void rgSCHCmnNonDlfsRbAlloc ARGS((
1714 RgSchCellCb           *cell,
1715 RgSchCmnDlRbAllocInfo *allocInfo
1716 ));
1717 PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc ARGS((
1718 RgSchCellCb           *cell,
1719 RgSchDlRbAlloc        *cmnAllocInfo));
1720
1721 #ifndef LTE_TDD
1722 PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj ARGS((
1723 RgSchCellCb           *cell,
1724 RgSchDlRbAlloc        *cmnAllocInfo,
1725 U8                    pbchSsRsSym,
1726 Bool                  isBcchPcch
1727 ));
1728 /* Added function to adjust TBSize*/
1729 PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj ARGS((
1730 RgSchDlRbAlloc        *allocInfo,
1731 U8                    numOvrlapgPbchRb,
1732 U8                    pbchSsRsSym,
1733 U8                    idx,
1734 U32                   bytesReq
1735 ));
1736
1737 /* Added function to find num of overlapping PBCH rb*/
1738 PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs ARGS((
1739 RgSchCellCb           *cell,
1740 RgSchDlSf             *dlSf,
1741 RgSchDlRbAlloc        *allocInfo,
1742 U8                    *numOvrlapgPbchRb
1743 ));
1744
1745 PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl ARGS((
1746 RgSchCellCb           *cell,
1747 RgSchDlSf             *dlSf,
1748 RgSchDlRbAlloc        *allocInfo
1749 ));
1750 #ifdef DEBUGP
1751 PRIVATE Void rgSCHCmnFindCodeRate ARGS((
1752 RgSchCellCb           *cell,
1753 RgSchDlSf             *dlSf,
1754 RgSchDlRbAlloc        *allocInfo,
1755 U8                    idx
1756 ));
1757 #endif
1758 #endif
1759 PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc ARGS((
1760 RgSchCellCb           *cell,
1761 RgSchCmnMsg4RbAlloc   *msg4AllocInfo,
1762 U8                    isRetx
1763 ));
1764 PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc ARGS((
1765 RgSchCellCb           *cell,
1766 RgSchRaCb             *raCb,
1767 RgSchDlSf             *dlSf
1768 ));
1769
1770 PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc ARGS((
1771 RgSchCellCb           *cell,
1772 RgSchUeCb             *ue,
1773 RgSchDlSf             *dlSf,
1774 U8                    *isDlBwAvail
1775 ));
1776 #ifndef LTEMAC_SPS
1777 PRIVATE U32 rgSCHCmnCalcRiv ARGS(( U8 bw,
1778          U8           rbStart,
1779          U8           numRb));
1780 #endif
1781
1782 #ifdef LTE_TDD
1783 PRIVATE Void rgSCHCmnUpdHqAndDai ARGS((
1784 RgSchDlHqProcCb   *hqP,
1785 RgSchDlSf         *subFrm,
1786 RgSchDlHqTbCb     *tbCb,
1787 U8                tbAllocIdx
1788 ));
1789 PRIVATE S16 rgSCHCmnUlCalcAvailBw ARGS((
1790 RgSchCellCb *cell,
1791 RgrCellCfg  *cellCfg,
1792 U8          cfi,
1793 U8          *rbStartRef,
1794 U8          *bwAvailRef
1795 ));
1796 PRIVATE S16 rgSCHCmnDlKdashUlAscInit ARGS((
1797 RgSchCellCb *cell
1798 ));
1799 PRIVATE S16 rgSCHCmnDlANFdbkInit ARGS((
1800 RgSchCellCb *cell
1801 ));
1802 PRIVATE S16 rgSCHCmnDlNpValInit ARGS((
1803 RgSchCellCb *cell
1804 ));
1805 PRIVATE S16 rgSCHCmnDlCreateRachPrmLst ARGS((
1806 RgSchCellCb *cell
1807 ));
1808 PRIVATE S16 rgSCHCmnDlCpyRachInfo ARGS((
1809 RgSchCellCb        *cell,
1810 RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES],
1811 U8                 raArrSz
1812 ));
1813 PRIVATE S16 rgSCHCmnDlRachInfoInit ARGS((
1814 RgSchCellCb *cell
1815 ));
1816 PRIVATE S16 rgSCHCmnDlPhichOffsetInit ARGS((
1817 RgSchCellCb *cell
1818 ));
1819 #endif
1820 #ifdef TFU_UPGRADE
1821 PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt ARGS
1822 ((
1823  RgSchCellCb          *cell,
1824  RgSchUeCb            *ue,
1825  U8                          wideCqi
1826  ));
1827  PRIVATE RgSchCmnRank rgSCHCmnComputeRank ARGS
1828 ((
1829  RgrTxMode    txMode,
1830  U32          *pmiBitMap,
1831  U8           numTxPorts
1832  ));
1833
1834  PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3 ARGS
1835 ((
1836  U32 *pmiBitMap
1837  ));
1838
1839   PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3 ARGS
1840 ((
1841  U32 *pmiBitMap
1842  ));
1843
1844   PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4 ARGS
1845 ((
1846  U32 *pmiBitMap
1847  ));
1848
1849   PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4 ARGS
1850 ((
1851  U32 *pmiBitMap
1852  ));
1853
1854  PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr ARGS
1855 ((
1856  RgSchCellCb        *cell,
1857  TfuSrsRpt        *srsRpt
1858  ));
1859 #endif
1860
1861 /* comcodsepa : start */
1862 \f
1863 /**
1864  * @brief This function computes efficiency and stores in a table.
1865  *
1866  * @details
1867  *
1868  *     Function: rgSCHCmnCompEff
1869  *     Purpose:  this function computes the efficiency as number of
1870  *               bytes per 1024 symbols. The CFI table is also filled
1871  *               with the same information such that comparison is valid
1872  *
1873  *     Invoked by: Scheduler
1874  *
1875  *  @param[in]  U8            noPdcchSym
1876  *  @param[in]  U8            cpType
1877  *  @param[in]  U8            txAntIdx
1878  *  @param[in]  RgSchCmnTbSzEff* effTbl
1879  *  @return  Void
1880  *
1881  **/
1882 #ifdef ANSI
1883 PRIVATE Void rgSCHCmnCompEff
1884 (
1885 U8                    noPdcchSym,
1886 U8                    cpType,
1887 U8                    txAntIdx,
1888 RgSchCmnTbSzEff       *effTbl
1889 )
1890 #else
1891 PRIVATE Void rgSCHCmnCompEff(noPdcchSym, cpType, txAntIdx, effTbl)
1892 U8                    noPdcchSym;
1893 U8                    cpType;
1894 U8                    txAntIdx;
1895 RgSchCmnTbSzEff       *effTbl;
1896 #endif
1897 {
1898    U8               noResPerRb;
1899    U8               noSymPerRb;
1900    U8               resOfCrs; /* Effective REs occupied by CRS */
1901    U8               i, j;
1902
1903    TRC2(rgSCHCmnCompEff);
1904
1905    switch (cpType)
1906    {
1907       case RG_SCH_CMN_NOR_CP:
1908          noSymPerRb = 14;
1909          break;
1910       case RG_SCH_CMN_EXT_CP:
1911          noSymPerRb = 12;
1912          break;
1913       default:
1914          /* Generate a log error. This case should never be executed */
1915          RETVOID;
1916    }
1917
1918    /* Depending on the Tx Antenna Index, deduct the
1919     * Resource elements for the CRS */
1920    switch (txAntIdx)
1921    {
1922       case 0:
1923          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
1924          break;
1925       case 1:
1926          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
1927          break;
1928       case 2:
1929          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
1930          break;
1931       default:
1932          /* Generate a log error. This case should never be executed */
1933          RETVOID;
1934    }
1935    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
1936    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1937    {
1938       (*effTbl)[i] = 0;
1939       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1940       {
1941          /* This line computes the coding efficiency per 1024 REs */
1942          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1943       }
1944       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1945    }
1946    RETVOID;
1947 }
1948 /**
1949  * @brief This function computes efficiency and stores in a table.
1950  *
1951  * @details
1952  *
1953  *     Function: rgSCHCmnCompUlEff
1954  *     Purpose:  this function computes the efficiency as number of
1955  *               bytes per 1024 symbols. The CFI table is also filled
1956  *               with the same information such that comparison is valid
1957  *
1958  *     Invoked by: Scheduler
1959  *
1960  *  @param[in]  U8            noUlRsSym
1961  *  @param[in]  U8            cpType
1962  *  @param[in]  U8            txAntIdx
1963  *  @param[in]  RgSchCmnTbSzEff* effTbl
1964  *  @return  Void
1965  *
1966  **/
1967 #ifdef ANSI
1968 PRIVATE Void rgSCHCmnCompUlEff
1969 (
1970 U8                    noUlRsSym,
1971 U8                    cpType,
1972 RgSchCmnTbSzEff       *effTbl
1973 )
1974 #else
1975 PRIVATE Void rgSCHCmnCompUlEff(noUlRsSym, cpType, effTbl)
1976 U8                    noUlRsSym;
1977 U8                    cpType;
1978 RgSchCmnTbSzEff       *effTbl;
1979 #endif
1980 {
1981    U8               noResPerRb;
1982    U8               noSymPerRb;
1983    U8               i, j;
1984
1985    TRC2(rgSCHCmnCompUlEff);
1986
1987    switch (cpType)
1988    {
1989       case RG_SCH_CMN_NOR_CP:
1990          noSymPerRb = 14;
1991          break;
1992       case RG_SCH_CMN_EXT_CP:
1993          noSymPerRb = 12;
1994          break;
1995       default:
1996          /* Generate a log error. This case should never be executed */
1997          RETVOID;
1998    }
1999
2000    noResPerRb = ((noSymPerRb - noUlRsSym) * RB_SCH_CMN_NUM_SCS_PER_RB);
2001    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
2002    {
2003       (*effTbl)[i] = 0;
2004       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
2005       {
2006          /* This line computes the coding efficiency per 1024 REs */
2007          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
2008       }
2009       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
2010    }
2011    RETVOID;
2012 }
2013
2014 /**
2015  * @brief This function computes efficiency for 2 layers and stores in a table.
2016  *
2017  * @details
2018  *
2019  *     Function: rgSCHCmn2LyrCompEff
2020  *     Purpose:  this function computes the efficiency as number of
2021  *               bytes per 1024 symbols. The CFI table is also filled
2022  *               with the same information such that comparison is valid
2023  *
2024  *     Invoked by: Scheduler
2025  *
2026  *  @param[in]  U8            noPdcchSym
2027  *  @param[in]  U8            cpType
2028  *  @param[in]  U8            txAntIdx
2029  *  @param[in]  RgSchCmnTbSzEff* effTbl2Lyr
2030  *  @return  Void
2031  *
2032  **/
2033 #ifdef ANSI
2034 PRIVATE Void rgSCHCmn2LyrCompEff
2035 (
2036 U8                    noPdcchSym,
2037 U8                    cpType,
2038 U8                    txAntIdx,
2039 RgSchCmnTbSzEff       *effTbl2Lyr
2040 )
2041 #else
2042 PRIVATE Void rgSCHCmn2LyrCompEff(noPdcchSym, cpType, txAntIdx, effTbl2Lyr)
2043 U8                    noPdcchSym;
2044 U8                    cpType;
2045 U8                    txAntIdx;
2046 RgSchCmnTbSzEff       *effTbl2Lyr;
2047 #endif
2048 {
2049    U8               noResPerRb;
2050    U8               noSymPerRb;
2051    U8               resOfCrs; /* Effective REs occupied by CRS */
2052    U8               i, j;
2053
2054    TRC2(rgSCHCmn2LyrCompEff);
2055
2056    switch (cpType)
2057    {
2058       case RG_SCH_CMN_NOR_CP:
2059          noSymPerRb = 14;
2060          break;
2061       case RG_SCH_CMN_EXT_CP:
2062          noSymPerRb = 12;
2063          break;
2064       default:
2065          /* Generate a log error. This case should never be executed */
2066          RETVOID;
2067    }
2068
2069    /* Depending on the Tx Antenna Index, deduct the
2070     * Resource elements for the CRS */
2071    switch (txAntIdx)
2072    {
2073       case 0:
2074          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
2075          break;
2076       case 1:
2077          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
2078          break;
2079       case 2:
2080          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
2081          break;
2082       default:
2083          /* Generate a log error. This case should never be executed */
2084          RETVOID;
2085    }
2086
2087    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
2088    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
2089    {
2090       (*effTbl2Lyr)[i] = 0;
2091       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
2092       {
2093          /* This line computes the coding efficiency per 1024 REs */
2094          (*effTbl2Lyr)[i] += (rgTbSzTbl[1][i][j] * 1024) / (noResPerRb * (j+1));
2095       }
2096       (*effTbl2Lyr)[i] /= RG_SCH_CMN_NUM_RBS;
2097    }
2098    RETVOID;
2099 }
2100
2101 \f
2102 /**
2103  * @brief This function initializes the rgSchCmnDciFrmtSizes table.
2104  *
2105  * @details
2106  *
2107  *     Function: rgSCHCmnGetDciFrmtSizes
2108  *     Purpose:  This function determines the sizes of all
2109  *               the available DCI Formats. The order of
2110  *               bits addition for each format is inaccordance
2111  *               with the specs.
2112  *     Invoked by: rgSCHCmnRgrCellCfg
2113  *
2114  *  @return  Void
2115  *
2116  **/
2117 #ifdef ANSI
2118 PRIVATE Void rgSCHCmnGetDciFrmtSizes
2119 (
2120 RgSchCellCb *cell
2121 )
2122 #else
2123 PRIVATE Void rgSCHCmnGetDciFrmtSizes(cell)
2124 RgSchCellCb *cell;
2125 #endif
2126 {
2127
2128    TRC2(rgSCHCmnGetDciFrmtSizes);
2129
2130    /* DCI Format 0 size determination */
2131    rgSchCmnDciFrmtSizes[0] = 1 +
2132                              1 +
2133                              rgSCHUtlLog32bitNbase2((cell->bwCfg.ulTotalBw * \
2134                              (cell->bwCfg.ulTotalBw + 1))/2) +
2135                              5 +
2136                              1 +
2137                              2 +
2138                              3 +
2139 #ifdef LTE_TDD
2140                              2 +
2141                              2 +
2142 #endif
2143                              1;
2144    /* DCI Format 1 size determination */
2145    rgSchCmnDciFrmtSizes[1] = 1 +
2146    RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2147                              5 +
2148 #ifndef LTE_TDD
2149                              3 +
2150 #else
2151                              4 + 2 + /* HqProc Id and DAI */
2152 #endif
2153                              1 +
2154                              2 +
2155                              2;
2156
2157    /* DCI Format 1A size determination */
2158    rgSchCmnDciFrmtSizes[2] = 1 + /* Flag for format0/format1a differentiation */
2159                1 + /* Localized/distributed VRB assignment flag */
2160                5 + /* For mcs */
2161 #ifndef LTE_TDD
2162                3 + /* Harq process Id */
2163 #else
2164                4 + /* Harq process Id */
2165                2 + /* UL Index or DAI */
2166 #endif
2167                1 + /* New Data Indicator */
2168                2 + /* For RV */
2169                2 + /* For tpc */
2170                1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2171                    (cell->bwCfg.dlTotalBw + 1))/2);
2172                /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
2173                   Since VRB is local */
2174
2175    /* DCI Format 1B size determination */
2176    rgSchCmnDciFrmtSizes[3] = 1 +
2177                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2178                              (cell->bwCfg.dlTotalBw + 1))/2) +
2179                              5 +
2180                              3 +
2181 #ifdef LTE_TDD
2182                              1 + /* HqP */
2183                              2 + /* Dai */
2184 #endif
2185                              1 +
2186                              2 +
2187                              2 +
2188                              ((cell->numTxAntPorts == 4)? 4:2) +
2189                              1;
2190
2191    /* DCI Format 1C size determination */
2192    /* Approximation: NDLVrbGap1 ~= Nprb for DL */
2193    rgSchCmnDciFrmtSizes[4] = (cell->bwCfg.dlTotalBw < 50)? 0:1 +
2194                              (cell->bwCfg.dlTotalBw < 50)?
2195                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/2 * \
2196                                 (cell->bwCfg.dlTotalBw/2 + 1))/2)) :
2197                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/4 * \
2198                                 (cell->bwCfg.dlTotalBw/4 + 1))/2)) +
2199                              5;
2200
2201    /* DCI Format 1D size determination */
2202    rgSchCmnDciFrmtSizes[5] = 1 +
2203                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2204                              (cell->bwCfg.dlTotalBw + 1))/2) +
2205                              5 +
2206                              3 +
2207 #ifdef LTE_TDD
2208                              1 + 2 +
2209 #endif
2210                              1 +
2211                              2 +
2212                              2 +
2213                              ((cell->numTxAntPorts == 4)? 4:2) +
2214                              1;
2215
2216    /* DCI Format 2 size determination */
2217    rgSchCmnDciFrmtSizes[6] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2218                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2219                              2 +
2220 #ifdef LTE_TDD
2221                              2 + 1 +
2222 #endif
2223                              3 +
2224                              1 +
2225                              (5 + 1 + 2)*2 +
2226                              ((cell->numTxAntPorts == 4)? 6:3);
2227
2228    /* DCI Format 2A size determination */
2229    rgSchCmnDciFrmtSizes[7] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2230                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2231                              2 +
2232 #ifdef LTE_TDD
2233                              2 + 1 +
2234 #endif
2235                              3 +
2236                              1 +
2237                              (5 + 1 + 2)*2 +
2238                              ((cell->numTxAntPorts == 4)? 2:0);
2239
2240    /* DCI Format 3 size determination */
2241    rgSchCmnDciFrmtSizes[8] = rgSchCmnDciFrmtSizes[0];
2242
2243    /* DCI Format 3A size determination */
2244    rgSchCmnDciFrmtSizes[9] = rgSchCmnDciFrmtSizes[0];
2245
2246    RETVOID;
2247 }
2248
2249
2250 /**
2251  * @brief This function initializes the cmnCell->dciAggrLvl table.
2252  *
2253  * @details
2254  *
2255  *     Function: rgSCHCmnGetCqiDciFrmt2AggrLvl
2256  *     Purpose:  This function determines the Aggregation level
2257  *               for each CQI level against each DCI format.
2258  *     Invoked by: rgSCHCmnRgrCellCfg
2259  *
2260  *  @return  Void
2261  *
2262  **/
2263 #ifdef ANSI
2264 PRIVATE Void rgSCHCmnGetCqiDciFrmt2AggrLvl
2265 (
2266 RgSchCellCb *cell
2267 )
2268 #else
2269 PRIVATE Void rgSCHCmnGetCqiDciFrmt2AggrLvl(cell)
2270 RgSchCellCb *cell;
2271 #endif
2272 {
2273    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2274    U8            i;
2275    U8            j;
2276
2277    TRC2(rgSCHCmnGetCqiDciFrmt2AggrLvl);
2278
2279    for (i = 0; i < RG_SCH_CMN_MAX_CQI; i++)
2280    {
2281       for (j = 0; j < 10; j++)
2282       {
2283          U32 pdcchBits; /* Actual number of phy bits needed for a given DCI Format
2284                * for a given CQI Level */
2285          pdcchBits = (rgSchCmnDciFrmtSizes[j] * 1024)/rgSchCmnCqiPdcchEff[i];
2286                         /* V5G_211 : 6.6 */
2287          if (pdcchBits < 192)
2288          {
2289              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL2;
2290              continue;
2291          }
2292          if (pdcchBits < 384)
2293          {
2294              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL4;
2295              continue;
2296          }
2297          if (pdcchBits < 768)
2298          {
2299              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL8;
2300              continue;
2301          }
2302          cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL16;
2303       }
2304    }
2305    RETVOID;
2306 }
2307 \f
2308 /**
2309  * @brief This function initializes all the data for the scheduler.
2310  *
2311  * @details
2312  *
2313  *     Function: rgSCHCmnDlInit
2314  *     Purpose:  This function initializes the following information:
2315  *               1. Efficiency table
2316  *               2. CQI to table index - It is one row for upto 3 RBs
2317  *                  and another row for greater than 3 RBs
2318  *                  currently extended prefix is compiled out.
2319  *     Invoked by: MAC intialization code..may be ActvInit
2320  *
2321  *  @return  Void
2322  *
2323  **/
2324 #ifdef ANSI
2325 PRIVATE Void rgSCHCmnDlInit
2326 (
2327 )
2328 #else
2329 PRIVATE Void rgSCHCmnDlInit()
2330 #endif
2331 {
2332    U8                   i;
2333    S16                  j;
2334    S16                  k;
2335    U8                   idx;
2336    RgSchCmnTbSzEff      *effTbl;
2337    RgSchCmnCqiToTbs     *tbsTbl;
2338
2339    TRC2(rgSCHCmnDlInit);
2340
2341    /* 0 corresponds to Single layer case, 1 corresponds to 2 layers case*/
2342    /* Init Efficiency table for normal cyclic prefix */
2343    /*Initialize Efficiency table for Layer Index 0 */
2344    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2345    /*Initialize Efficiency table for each of the CFI indices. The
2346     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2347    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[0];
2348    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[0];
2349    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[0];
2350    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[0];
2351    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2352    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[0];
2353    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[0];
2354    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[0];
2355    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[0];
2356    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2357    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[0];
2358    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[0];
2359    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[0];
2360    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[0];
2361
2362    /*Initialize CQI to TBS table for Layer Index 0 for Normal CP */
2363    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[0];
2364    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[0];
2365    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[0];
2366    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[0];
2367
2368    /*Intialize Efficency table for Layer Index 1 */
2369    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2370    /*Initialize Efficiency table for each of the CFI indices. The
2371     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2372    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[1];
2373    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[1];
2374    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[1];
2375    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[1];
2376    /*Initialize Efficiency table for Tx Antenna Port Index 1 */
2377    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[1];
2378    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[1];
2379    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[1];
2380    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[1];
2381    /*Initialize Efficiency table for Tx Antenna Port Index 2 */
2382    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[1];
2383    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[1];
2384    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[1];
2385    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[1];
2386
2387    /*Initialize CQI to TBS table for Layer Index 1 for Normal CP */
2388    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[1];
2389    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[1];
2390    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[1];
2391    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[1];
2392
2393    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2394    {
2395       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2396       {
2397          /* EfficiencyTbl calculation incase of 2 layers for normal CP  */
2398          rgSCHCmnCompEff((U8)(i + 1), RG_SCH_CMN_NOR_CP, idx,\
2399                rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]);
2400          rgSCHCmn2LyrCompEff((U8)(i + 1), RG_SCH_CMN_NOR_CP, idx, \
2401                rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]);
2402       }
2403    }
2404
2405    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2406    {
2407       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2408       {
2409          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i];
2410          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][i];
2411          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2412                (j >= 0) && (k > 0); --j)
2413          {
2414             /* ADD CQI to MCS mapping correction
2415             * single dimensional array is replaced by 2 dimensions for different CFI*/
2416             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2417             {
2418                (*tbsTbl)[k--] = (U8)j;
2419             }
2420          }
2421          for (; k > 0; --k)
2422          {
2423             (*tbsTbl)[k] = 0;
2424          }
2425          /* effTbl,tbsTbl calculation incase of 2 layers for normal CP */
2426          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i];
2427          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][i];
2428          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2429                (j >= 0) && (k > 0); --j)
2430          {
2431             /* ADD CQI to MCS mapping correction
2432             * single dimensional array is replaced by 2 dimensions for different CFI*/
2433             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2434             {
2435                (*tbsTbl)[k--] = (U8)j;
2436             }
2437          }
2438          for (; k > 0; --k)
2439          {
2440             (*tbsTbl)[k] = 0;
2441          }
2442       }
2443    }
2444
2445    /* Efficiency Table for Extended CP */
2446    /*Initialize Efficiency table for Layer Index 0 */
2447    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2448    /*Initialize Efficiency table for each of the CFI indices. The
2449     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2450    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[0];
2451    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[0];
2452    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[0];
2453    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[0];
2454    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2455    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[0];
2456    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[0];
2457    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[0];
2458    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[0];
2459    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2460    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[0];
2461    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[0];
2462    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[0];
2463    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[0];
2464
2465    /*Initialize CQI to TBS table for Layer Index 0 for Extended CP */
2466    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[0];
2467    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[0];
2468    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[0];
2469    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[0];
2470
2471    /*Initialize Efficiency table for Layer Index 1 */
2472    /*Initialize Efficiency table for each of the CFI indices. The
2473     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2474    /*Initialize Efficency table for Tx Antenna Port Index 0 */
2475    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[1];
2476    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[1];
2477    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[1];
2478    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[1];
2479    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2480    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[1];
2481    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[1];
2482    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[1];
2483    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[1];
2484    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2485    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[1];
2486    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[1];
2487    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[1];
2488    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[1];
2489
2490    /*Initialize CQI to TBS table for Layer Index 1 for Extended CP */
2491    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[1];
2492    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[1];
2493    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[1];
2494    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[1];
2495    /* Activate this code when extended cp is supported */
2496    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2497    {
2498       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2499       {
2500          /* EfficiencyTbl calculation incase of 2 layers for extendedl CP  */
2501          rgSCHCmnCompEff( (U8)(i + 1 ), (U8)RG_SCH_CMN_EXT_CP, idx,\
2502                rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]);
2503          rgSCHCmn2LyrCompEff((U8)(i + 1), (U8) RG_SCH_CMN_EXT_CP,idx, \
2504                rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]);
2505       }
2506    }
2507
2508    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2509    {
2510       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2511       {
2512          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i];
2513          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][i];
2514          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2515                (j >= 0) && (k > 0); --j)
2516          {
2517             /* ADD CQI to MCS mapping correction
2518             * single dimensional array is replaced by 2 dimensions for different CFI*/
2519             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2520             {
2521                (*tbsTbl)[k--] = (U8)j;
2522             }
2523          }
2524          for (; k > 0; --k)
2525          {
2526             (*tbsTbl)[k] = 0;
2527          }
2528          /* effTbl,tbsTbl calculation incase of 2 layers for extended CP */
2529          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i];
2530          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][i];
2531          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2532                (j >= 0) && (k > 0); --j)
2533          {
2534            /* ADD CQI to MCS mapping correction
2535             * single dimensional array is replaced by 2 dimensions for different CFI*/
2536             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2537             {
2538                (*tbsTbl)[k--] = (U8)j;
2539             }
2540          }
2541          for (; k > 0; --k)
2542          {
2543             (*tbsTbl)[k] = 0;
2544          }
2545       }
2546    }
2547    RETVOID;
2548 }
2549 \f
2550 /**
2551  * @brief This function initializes all the data for the scheduler.
2552  *
2553  * @details
2554  *
2555  *     Function: rgSCHCmnUlInit
2556  *     Purpose:  This function initializes the following information:
2557  *               1. Efficiency table
2558  *               2. CQI to table index - It is one row for upto 3 RBs
2559  *                  and another row for greater than 3 RBs
2560  *                  currently extended prefix is compiled out.
2561  *     Invoked by: MAC intialization code..may be ActvInit
2562  *
2563  *  @return  Void
2564  *
2565  **/
2566 #ifdef ANSI
2567 PRIVATE Void rgSCHCmnUlInit
2568 (
2569 )
2570 #else
2571 PRIVATE Void rgSCHCmnUlInit()
2572 #endif
2573 {
2574    U8              *mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_NOR_CP][0];
2575    RgSchCmnTbSzEff    *effTbl    = &rgSchCmnNorUlEff[0];
2576    CONSTANT RgSchCmnUlCqiInfo *cqiTbl = &rgSchCmnUlCqiTbl[0];
2577    S16              i;
2578    S16              j;
2579    TRC2(rgSCHCmnUlInit);
2580
2581    /* Initaializing new variable added for UL eff */
2582    rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP] = &rgSchCmnNorUlEff[0];
2583    /* Reason behind using 3 as the number of symbols to rule out for
2584     * efficiency table computation would be that we are using 2 symbols for
2585     * DMRS(1 in each slot) and 1 symbol for SRS*/
2586    rgSCHCmnCompUlEff(RGSCH_UL_SYM_DMRS_SRS,RG_SCH_CMN_NOR_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP]);
2587
2588    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2589          i >= 0 && j > 0; --i)
2590    {
2591       if ((*effTbl)[i] <= cqiTbl[j].eff)
2592       {
2593          mapTbl[j--] = (U8)i;
2594       }
2595    }
2596    for (; j > 0; --j)
2597    {
2598       mapTbl[j] = 0;
2599    }
2600    effTbl    = &rgSchCmnExtUlEff[0];
2601    mapTbl    = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_EXT_CP][0];
2602
2603    /* Initaializing new variable added for UL eff */
2604    rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP] = &rgSchCmnExtUlEff[0];
2605    /* Reason behind using 3 as the number of symbols to rule out for
2606     * efficiency table computation would be that we are using 2 symbols for
2607     * DMRS(1 in each slot) and 1 symbol for SRS*/
2608    rgSCHCmnCompUlEff(3,RG_SCH_CMN_EXT_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP]);
2609
2610    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2611          i >= 0 && j > 0; --i)
2612    {
2613       if ((*effTbl)[i] <= cqiTbl[j].eff)
2614       {
2615          mapTbl[j--] = (U8)i;
2616       }
2617    }
2618    for (; j > 0; --j)
2619    {
2620       mapTbl[j] = 0;
2621    }
2622    rgSCHPwrInit();
2623    RETVOID;
2624 }
2625
2626 \f
2627 /**
2628  * @brief This function initializes all the data for the scheduler.
2629  *
2630  * @details
2631  *
2632  *     Function: rgSCHCmnInit
2633  *     Purpose:  This function initializes the following information:
2634  *               1. Efficiency table
2635  *               2. CQI to table index - It is one row for upto 3 RBs
2636  *                  and another row for greater than 3 RBs
2637  *                  currently extended prefix is compiled out.
2638  *     Invoked by: MAC intialization code..may be ActvInit
2639  *
2640  *  @return  Void
2641  *
2642  **/
2643 #ifdef ANSI
2644 PUBLIC Void rgSCHCmnInit
2645 (
2646 )
2647 #else
2648 PUBLIC Void rgSCHCmnInit()
2649 #endif
2650 {
2651    U8   idx;
2652    TRC2(rgSCHCmnInit);
2653
2654    rgSCHCmnDlInit();
2655    rgSCHCmnUlInit();
2656 #ifdef EMTC_ENABLE
2657    rgSCHEmtcCmnDlInit();
2658    rgSCHEmtcCmnUlInit();
2659 #endif      
2660 #ifdef LTEMAC_SPS
2661    rgSCHCmnSpsInit();
2662 #endif
2663
2664    /* Init the function pointers */
2665    rgSchCmnApis.rgSCHRgrUeCfg         = rgSCHCmnRgrUeCfg;
2666    rgSchCmnApis.rgSCHRgrUeRecfg       = rgSCHCmnRgrUeRecfg;
2667    rgSchCmnApis.rgSCHFreeUe           = rgSCHCmnUeDel;
2668    rgSchCmnApis.rgSCHRgrCellCfg       = rgSCHCmnRgrCellCfg;
2669    rgSchCmnApis.rgSCHRgrCellRecfg     = rgSCHCmnRgrCellRecfg;
2670    rgSchCmnApis.rgSCHFreeCell         = rgSCHCmnCellDel;
2671    rgSchCmnApis.rgSCHRgrLchCfg        = rgSCHCmnRgrLchCfg;
2672    rgSchCmnApis.rgSCHRgrLcgCfg        = rgSCHCmnRgrLcgCfg;
2673    rgSchCmnApis.rgSCHRgrLchRecfg      = rgSCHCmnRgrLchRecfg;
2674    rgSchCmnApis.rgSCHRgrLcgRecfg      = rgSCHCmnRgrLcgRecfg;
2675    rgSchCmnApis.rgSCHFreeDlLc         = rgSCHCmnFreeDlLc;
2676    rgSchCmnApis.rgSCHFreeLcg          = rgSCHCmnLcgDel;
2677    rgSchCmnApis.rgSCHRgrLchDel        = rgSCHCmnRgrLchDel;
2678    rgSchCmnApis.rgSCHActvtUlUe        = rgSCHCmnActvtUlUe;
2679    rgSchCmnApis.rgSCHActvtDlUe        = rgSCHCmnActvtDlUe;
2680    rgSchCmnApis.rgSCHHdlUlTransInd    = rgSCHCmnHdlUlTransInd;
2681    rgSchCmnApis.rgSCHDlDedBoUpd       = rgSCHCmnDlDedBoUpd;
2682    rgSchCmnApis.rgSCHUlRecMsg3Alloc   = rgSCHCmnUlRecMsg3Alloc;
2683    rgSchCmnApis.rgSCHUlCqiInd         = rgSCHCmnUlCqiInd;
2684    rgSchCmnApis.rgSCHPucchDeltaPwrInd = rgSCHPwrPucchDeltaInd;
2685    rgSchCmnApis.rgSCHUlHqProcForUe    = rgSCHCmnUlHqProcForUe;
2686 #ifdef RG_UNUSED
2687    rgSchCmnApis.rgSCHUpdUlHqProc      = rgSCHCmnUpdUlHqProc;
2688 #endif
2689    rgSchCmnApis.rgSCHUpdBsrShort      = rgSCHCmnUpdBsrShort;
2690    rgSchCmnApis.rgSCHUpdBsrTrunc      = rgSCHCmnUpdBsrTrunc;
2691    rgSchCmnApis.rgSCHUpdBsrLong       = rgSCHCmnUpdBsrLong;
2692    rgSchCmnApis.rgSCHUpdPhr           = rgSCHCmnUpdPhr;
2693    rgSchCmnApis.rgSCHUpdExtPhr        = rgSCHCmnUpdExtPhr;
2694    rgSchCmnApis.rgSCHContResUlGrant   = rgSCHCmnContResUlGrant;
2695    rgSchCmnApis.rgSCHSrRcvd           = rgSCHCmnSrRcvd;
2696    rgSchCmnApis.rgSCHFirstRcptnReq    = rgSCHCmnFirstRcptnReq;
2697    rgSchCmnApis.rgSCHNextRcptnReq     = rgSCHCmnNextRcptnReq;
2698    rgSchCmnApis.rgSCHFirstHqFdbkAlloc = rgSCHCmnFirstHqFdbkAlloc;
2699    rgSchCmnApis.rgSCHNextHqFdbkAlloc  = rgSCHCmnNextHqFdbkAlloc;
2700    rgSchCmnApis.rgSCHDlProcAddToRetx  = rgSCHCmnDlProcAddToRetx;
2701    rgSchCmnApis.rgSCHDlCqiInd         = rgSCHCmnDlCqiInd;
2702 #ifdef EMTC_ENABLE
2703    rgSchCmnApis.rgSCHUlProcAddToRetx  = rgSCHCmnEmtcUlProcAddToRetx;
2704 #endif
2705 #ifdef TFU_UPGRADE
2706    rgSchCmnApis.rgSCHSrsInd           = rgSCHCmnSrsInd;
2707 #endif
2708    rgSchCmnApis.rgSCHDlTARpt          = rgSCHCmnDlTARpt;
2709    rgSchCmnApis.rgSCHDlRlsSubFrm      = rgSCHCmnDlRlsSubFrm;
2710    rgSchCmnApis.rgSCHUeReset          = rgSCHCmnUeReset;
2711 #ifdef LTEMAC_SPS
2712    rgSchCmnApis.rgSCHHdlCrntiCE         = rgSCHCmnHdlCrntiCE;
2713    rgSchCmnApis.rgSCHDlProcAck        = rgSCHCmnDlProcAck;
2714    rgSchCmnApis.rgSCHDlRelPdcchFbk    = rgSCHCmnDlRelPdcchFbk;
2715    rgSchCmnApis.rgSCHUlSpsRelInd      = rgSCHCmnUlSpsRelInd;
2716    rgSchCmnApis.rgSCHUlSpsActInd      = rgSCHCmnUlSpsActInd;
2717    rgSchCmnApis.rgSCHUlCrcFailInd     = rgSCHCmnUlCrcFailInd;
2718    rgSchCmnApis.rgSCHUlCrcInd     = rgSCHCmnUlCrcInd;
2719 #endif
2720    rgSchCmnApis.rgSCHDrxStrtInActvTmrInUl = rgSCHCmnDrxStrtInActvTmrInUl;
2721    rgSchCmnApis.rgSCHUpdUeDataIndLcg      = rgSCHCmnUpdUeDataIndLcg;
2722
2723    for (idx = 0; idx < RGSCH_NUM_SCHEDULERS; ++idx)
2724    {
2725       rgSchUlSchdInits[idx](&rgSchUlSchdTbl[idx]);
2726       rgSchDlSchdInits[idx](&rgSchDlSchdTbl[idx]);
2727    }
2728 #ifdef EMTC_ENABLE 
2729    for (idx = 0; idx < RGSCH_NUM_EMTC_SCHEDULERS; ++idx)
2730    {
2731       rgSchEmtcUlSchdInits[idx](&rgSchEmtcUlSchdTbl[idx]);
2732       rgSchEmtcDlSchdInits[idx](&rgSchEmtcDlSchdTbl[idx]);
2733    }
2734 #endif
2735 #if (defined (RG_PHASE2_SCHED) && defined(TFU_UPGRADE))
2736    for (idx = 0; idx < RGSCH_NUM_DLFS_SCHEDULERS; ++idx)
2737    {
2738       rgSchDlfsSchdInits[idx](&rgSchDlfsSchdTbl[idx]);
2739    }
2740 #endif
2741 #ifdef LTE_ADV
2742    rgSchCmnApis.rgSCHRgrSCellUeCfg         = rgSCHCmnRgrSCellUeCfg;
2743    rgSchCmnApis.rgSCHRgrSCellUeDel         = rgSCHCmnRgrSCellUeDel;
2744 #endif
2745    RETVOID;
2746 }
2747
2748 \f
2749 /**
2750  * @brief This function is a wrapper to call scheduler specific API.
2751  *
2752  * @details
2753  *
2754  *     Function: rgSCHCmnDlRlsSubFrm
2755  *     Purpose:  Releases scheduler Information from DL SubFrm.
2756  *
2757  *     Invoked by: DHM
2758  *
2759  *  @param[in]   RgSchCellCb     *cell
2760  *  @param[out]  CmLteTimingInfo frm
2761  *  @return  Void
2762  *
2763  **/
2764 #ifdef ANSI
2765 PUBLIC Void rgSCHCmnDlRlsSubFrm
2766 (
2767 RgSchCellCb        *cell,
2768 CmLteTimingInfo   frm
2769 )
2770 #else
2771 PUBLIC Void rgSCHCmnDlRlsSubFrm(cell, frm)
2772 RgSchCellCb        *cell;
2773 CmLteTimingInfo    frm;
2774 #endif
2775 {
2776    RgSchCmnCell        *cellSch = RG_SCH_CMN_GET_CELL(cell);
2777    RgSchDlSf           *sf;
2778
2779    TRC2(rgSCHCmnDlRlsSubFrm);
2780
2781    /* Get the pointer to the subframe */
2782    sf = rgSCHUtlSubFrmGet(cell, frm);
2783
2784    rgSCHUtlSubFrmPut(cell, sf);
2785    if (sf->dlfsSf)
2786    {
2787       /* Re-initialize DLFS specific information for the sub-frame */
2788       cellSch->apisDlfs->rgSCHDlfsReinitSf(cell, sf);
2789    }
2790    RETVOID;
2791 }
2792
2793
2794 \f
2795 /**
2796  * @brief This function is the starting function for DL allocation.
2797  *
2798  * @details
2799  *
2800  *     Function: rgSCHCmnDlCmnChAlloc
2801  *     Purpose:  Scheduling for downlink. It performs allocation in the order
2802  *               of priority wich BCCH/PCH first, CCCH, Random Access and TA.
2803  *
2804  *     Invoked by: Scheduler
2805  *
2806  *  @param[in]  RgSchCellCb*           cell
2807  *  @param[out] RgSchCmnDlRbAllocInfo* allocInfo
2808  *  @return  Void
2809  *
2810  **/
2811 #ifdef ANSI
2812 PRIVATE Void rgSCHCmnDlCcchRarAlloc
2813 (
2814 RgSchCellCb             *cell
2815 )
2816 #else
2817 PRIVATE Void rgSCHCmnDlCcchRarAlloc(cell)
2818 RgSchCellCb             *cell;
2819 #endif
2820 {
2821    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2822
2823    TRC2(rgSCHCmnDlCcchRarAlloc);
2824
2825    rgSCHCmnDlCcchRetx(cell, &cellSch->allocInfo);
2826    /* LTE_ADV_FLAG_REMOVED_START */
2827    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2828    {
2829       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2830       {
2831          /*eNodeB need to blank the subframe */
2832       }
2833       else
2834       {
2835          rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2836       }
2837    }
2838    else
2839    {
2840       rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2841    }
2842    /* LTE_ADV_FLAG_REMOVED_END */
2843
2844 #ifdef RGR_V1
2845
2846    /*Added these function calls for processing CCCH SDU arriving
2847     * after guard timer expiry.Functions differ from above two functions
2848     * in using ueCb instead of raCb.*/
2849    rgSCHCmnDlCcchSduRetx(cell, &cellSch->allocInfo);
2850    /* LTE_ADV_FLAG_REMOVED_START */
2851    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2852    {
2853       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2854       {
2855          /*eNodeB need to blank the subframe */
2856       }
2857       else
2858       {
2859          rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2860       }
2861    }
2862    else
2863    {
2864       rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2865    }
2866    /* LTE_ADV_FLAG_REMOVED_END */
2867 #endif
2868
2869 #ifdef LTE_TDD
2870    if(cellSch->ul.msg3SchdIdx != RGSCH_INVALID_INFO)
2871    {
2872       /* Do not schedule msg3 if there is a CFI change ongoing */
2873       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2874       {
2875          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2876       }
2877    }
2878 #else
2879    /* LTE_ADV_FLAG_REMOVED_START */
2880    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2881    {
2882       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2883       {
2884          /*eNodeB need to blank the subframe */
2885       }
2886       else
2887       {
2888          /* Do not schedule msg3 if there is a CFI change ongoing */
2889          if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2890          {
2891             rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2892          }
2893       }
2894    }
2895    else
2896    {
2897       /* Do not schedule msg3 if there is a CFI change ongoing */
2898       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2899       {
2900          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2901       }
2902    }
2903    /* LTE_ADV_FLAG_REMOVED_END */
2904 #endif
2905
2906    RETVOID;
2907 }
2908
2909 #ifdef RGR_V1
2910 /**
2911  * @brief Scheduling for CCCH SDU.
2912  *
2913  * @details
2914  *
2915  *     Function: rgSCHCmnCcchSduAlloc
2916  *     Purpose:  Scheduling for CCCH SDU
2917  *
2918  *     Invoked by: Scheduler
2919  *
2920  *  @param[in]  RgSchCellCb*          cell
2921  *  @param[in]  RgSchUeCb*            ueCb
2922  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2923  *  @return  S16
2924  *
2925  **/
2926 #ifdef ANSI
2927 PRIVATE S16 rgSCHCmnCcchSduAlloc
2928 (
2929 RgSchCellCb                *cell,
2930 RgSchUeCb                  *ueCb,
2931 RgSchCmnDlRbAllocInfo      *allocInfo
2932 )
2933 #else
2934 PRIVATE S16 rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)
2935 RgSchCellCb                *cell;
2936 RgSchUeCb                  *ueCb;
2937 RgSchCmnDlRbAllocInfo      *allocInfo;
2938 #endif
2939 {
2940    RgSchDlRbAlloc  *rbAllocInfo;
2941    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
2942    RgSchCmnDlUe       *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2943
2944    TRC2(rgSCHCmnCcchSduAlloc);
2945
2946    /* Return if subframe BW exhausted */
2947    if (allocInfo->ccchSduAlloc.ccchSduDlSf->bw <=
2948        allocInfo->ccchSduAlloc.ccchSduDlSf->bwAssigned)
2949    {
2950       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2951          "bw<=bwAssigned for UEID:%d",ueCb->ueId);
2952       RETVALUE(RFAILED);
2953    }
2954
2955    if (rgSCHDhmGetCcchSduHqProc(ueCb, cellSch->dl.time, &(ueDl->proc)) != ROK)
2956    {
2957       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2958          "rgSCHDhmGetCcchSduHqProc failed UEID:%d",ueCb->ueId);
2959       RETVALUE(RFAILED);
2960    }
2961
2962    rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
2963    rbAllocInfo->dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2964
2965    if (rgSCHCmnCcchSduDedAlloc(cell, ueCb) != ROK)
2966    {
2967       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
2968       rgSCHDhmRlsHqpTb(ueDl->proc, 0, FALSE);
2969       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2970          "rgSCHCmnCcchSduDedAlloc failed UEID:%d",ueCb->ueId);
2971       RETVALUE(RFAILED);
2972    }
2973    cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduTxLst, &ueDl->proc->reqLnk);
2974    ueDl->proc->reqLnk.node = (PTR)ueDl->proc;
2975    allocInfo->ccchSduAlloc.ccchSduDlSf->schdCcchUe++;
2976
2977    RETVALUE(ROK);
2978 }
2979 /**
2980  * @brief This function scheduler for downlink CCCH messages.
2981  *
2982  * @details
2983  *
2984  *     Function: rgSCHCmnDlCcchSduTx
2985  *     Purpose:  Scheduling for downlink CCCH
2986  *
2987  *     Invoked by: Scheduler
2988  *
2989  *  @param[in]  RgSchCellCb           *cell
2990  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2991  *  @return  Void
2992  *
2993  **/
2994 #ifdef ANSI
2995 PRIVATE Void rgSCHCmnDlCcchSduTx
2996 (
2997 RgSchCellCb             *cell,
2998 RgSchCmnDlRbAllocInfo   *allocInfo
2999 )
3000 #else
3001 PRIVATE Void rgSCHCmnDlCcchSduTx(cell, allocInfo)
3002 RgSchCellCb             *cell;
3003 RgSchCmnDlRbAllocInfo   *allocInfo;
3004 #endif
3005 {
3006    CmLList           *node;
3007    RgSchUeCb         *ueCb;
3008    RgSchCmnDlUe      *ueCmnDl;
3009    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3010
3011    RgSchDlSf         *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
3012    
3013    TRC2(rgSCHCmnDlCcchSduTx);
3014
3015    node = cell->ccchSduUeLst.first;
3016    while(node)
3017    {
3018       if(cellSch->dl.maxCcchPerDlSf &&
3019             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3020       {
3021          break;
3022       }
3023       else
3024       {
3025          ueCb = (RgSchUeCb *)(node->node);
3026          ueCmnDl  = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
3027          node = node->next;
3028          /* Fix : syed postpone scheduling for this
3029           * until msg4 is done */
3030          /* Fix : syed RLC can erroneously send CCCH SDU BO 
3031           * twice. Hence an extra guard to avoid if already 
3032           * scheduled for RETX */
3033          if ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
3034                (!ueCmnDl->proc))
3035          {
3036             if ((rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)) != ROK)
3037             {
3038                break;
3039             }
3040          }
3041          else
3042          {
3043             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"ERROR!! THIS SHOULD "
3044                      "NEVER HAPPEN for UEID:%d", ueCb->ueId);
3045             continue;
3046          }
3047       }
3048    }
3049    RETVOID;
3050 }
3051 #endif
3052 \f
3053 /**
3054  * @brief This function scheduler for downlink CCCH messages.
3055  *
3056  * @details
3057  *
3058  *     Function: rgSCHCmnDlCcchTx
3059  *     Purpose:  Scheduling for downlink CCCH
3060  *
3061  *     Invoked by: Scheduler
3062  *
3063  *  @param[in]  RgSchCellCb           *cell
3064  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3065  *  @return  Void
3066  *
3067  **/
3068 #ifdef ANSI
3069 PRIVATE Void rgSCHCmnDlCcchTx
3070 (
3071 RgSchCellCb             *cell,
3072 RgSchCmnDlRbAllocInfo   *allocInfo
3073 )
3074 #else
3075 PRIVATE Void rgSCHCmnDlCcchTx(cell, allocInfo)
3076 RgSchCellCb             *cell;
3077 RgSchCmnDlRbAllocInfo   *allocInfo;
3078 #endif
3079 {
3080    CmLList           *node;
3081    RgSchRaCb         *raCb;
3082    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3083    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3084    
3085    TRC2(rgSCHCmnDlCcchTx);
3086
3087    node = cell->raInfo.toBeSchdLst.first;
3088    while(node)
3089    {
3090       if(cellSch->dl.maxCcchPerDlSf &&
3091             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3092       {
3093          break;
3094       }
3095       else
3096       {
3097
3098          raCb = (RgSchRaCb *)(node->node);
3099          node = node->next;
3100          /* Address allocation for this UE for MSG 4 */
3101          /* Allocation for Msg4 */
3102          if ((rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)) != ROK)
3103          {
3104             break;
3105          }
3106       }
3107    }
3108    RETVOID;
3109 }
3110
3111 #ifdef RGR_V1
3112 /**
3113  * @brief This function scheduler for downlink CCCH messages.
3114  *
3115  * @details
3116  *
3117  *     Function: rgSCHCmnDlCcchSduRetx
3118  *     Purpose:  Scheduling for downlink CCCH
3119  *
3120  *     Invoked by: Scheduler
3121  *
3122  *  @param[in]  RgSchCellCb           *cell
3123  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3124  *  @return  Void
3125  *
3126  **/
3127 #ifdef ANSI
3128 PRIVATE Void rgSCHCmnDlCcchSduRetx
3129 (
3130 RgSchCellCb             *cell,
3131 RgSchCmnDlRbAllocInfo   *allocInfo
3132 )
3133 #else
3134 PRIVATE Void rgSCHCmnDlCcchSduRetx(cell, allocInfo)
3135 RgSchCellCb             *cell;
3136 RgSchCmnDlRbAllocInfo   *allocInfo;
3137 #endif
3138 {
3139    RgSchDlRbAlloc  *rbAllocInfo;
3140    CmLList           *node;
3141    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3142    RgSchUeCb         *ueCb;
3143    RgSchDlHqProcCb   *hqP;
3144    U8                retxBw = 0;
3145    RgSchCmnDlUe      *ueDl;
3146    RgSchDlSf         *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
3147    
3148    TRC2(rgSCHCmnDlCcchSduRetx);
3149
3150    node = cellSch->dl.ccchSduRetxLst.first;
3151    while(node)
3152    {
3153       if(cellSch->dl.maxCcchPerDlSf &&
3154             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3155       {
3156          break;
3157       }
3158       else
3159       {
3160
3161          hqP = (RgSchDlHqProcCb *)(node->node);
3162          node = node->next;
3163
3164          /* DwPts Scheduling Changes Start */      
3165 #ifdef LTE_TDD
3166          if (rgSCHCmnRetxAvoidTdd(allocInfo->ccchSduAlloc.ccchSduDlSf, 
3167                   cell, hqP) == TRUE)
3168          {
3169             continue;  
3170          }
3171 #endif
3172          /* DwPts Scheduling Changes End */     
3173
3174          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3175          {
3176             break;
3177          }
3178          ueCb = (RgSchUeCb*)(hqP->hqE->ue);
3179          ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
3180
3181          rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3182          /* Fill RB Alloc Info */
3183          rbAllocInfo->dlSf = dlSf;
3184          rbAllocInfo->tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3185          rbAllocInfo->rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3186          /* Fix : syed iMcs setting did not correspond to RETX */
3187          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3188                rbAllocInfo->tbInfo[0].imcs);
3189          rbAllocInfo->rnti = ueCb->ueId;
3190          rbAllocInfo->tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3191          /* Fix : syed Copying info in entirety without depending on stale TX information */
3192          rbAllocInfo->tbInfo[0].tbCb = &hqP->tbInfo[0];
3193          rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
3194          /* Fix : syed Assigning proc to scratchpad */ 
3195          ueDl->proc = hqP;
3196
3197          retxBw += rbAllocInfo->rbsReq;
3198
3199          cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduRetxLst, \
3200                &hqP->reqLnk);
3201          hqP->reqLnk.node = (PTR)hqP;
3202          dlSf->schdCcchUe++;
3203       }
3204    }
3205    dlSf->bwAssigned += retxBw;
3206    RETVOID;
3207 }
3208 #endif
3209 \f
3210 /**
3211  * @brief This function scheduler for downlink CCCH messages.
3212  *
3213  * @details
3214  *
3215  *     Function: rgSCHCmnDlCcchRetx
3216  *     Purpose:  Scheduling for downlink CCCH
3217  *
3218  *     Invoked by: Scheduler
3219  *
3220  *  @param[in]  RgSchCellCb           *cell
3221  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3222  *  @return  Void
3223  *
3224  **/
3225 #ifdef ANSI
3226 PRIVATE Void rgSCHCmnDlCcchRetx
3227 (
3228 RgSchCellCb             *cell,
3229 RgSchCmnDlRbAllocInfo   *allocInfo
3230 )
3231 #else
3232 PRIVATE Void rgSCHCmnDlCcchRetx(cell, allocInfo)
3233 RgSchCellCb             *cell;
3234 RgSchCmnDlRbAllocInfo   *allocInfo;
3235 #endif
3236 {
3237    CmLList           *node;
3238    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3239    RgSchRaCb         *raCb;
3240    RgSchDlHqProcCb   *hqP;
3241    U8                retxBw = 0;
3242    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3243         
3244    TRC2(rgSCHCmnDlCcchRetx);
3245
3246    node = cellSch->dl.msg4RetxLst.first;
3247    while(node)
3248    {
3249       if(cellSch->dl.maxCcchPerDlSf &&
3250             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3251       {
3252          break;
3253       }
3254       else
3255       {
3256          hqP = (RgSchDlHqProcCb *)(node->node);
3257
3258          node = node->next;
3259
3260          /* DwPts Scheduling Changes Start */     
3261 #ifdef LTE_TDD      
3262          if (rgSCHCmnRetxAvoidTdd(allocInfo->msg4Alloc.msg4DlSf, 
3263                   cell, hqP) == TRUE)
3264          {
3265             continue;  
3266          }
3267 #endif      
3268          /* DwPts Scheduling Changes End */      
3269
3270          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3271          {
3272             break;
3273          }
3274          raCb = (RgSchRaCb*)(hqP->hqE->raCb);
3275          /* Fill RB Alloc Info */
3276          raCb->rbAllocInfo.dlSf = dlSf;
3277          raCb->rbAllocInfo.tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3278          raCb->rbAllocInfo.rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3279          /* Fix : syed iMcs setting did not correspond to RETX */
3280          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3281                raCb->rbAllocInfo.tbInfo[0].imcs);
3282          raCb->rbAllocInfo.rnti = raCb->tmpCrnti;
3283          raCb->rbAllocInfo.tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3284          /* Fix; syed Copying info in entirety without depending on stale TX information */
3285          raCb->rbAllocInfo.tbInfo[0].tbCb = &hqP->tbInfo[0];
3286          raCb->rbAllocInfo.tbInfo[0].schdlngForTb = TRUE;
3287
3288          retxBw += raCb->rbAllocInfo.rbsReq;
3289
3290          cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4RetxLst, \
3291                &hqP->reqLnk);
3292          hqP->reqLnk.node = (PTR)hqP;
3293          dlSf->schdCcchUe++;
3294       }
3295    }
3296    dlSf->bwAssigned += retxBw;
3297    RETVOID;
3298 }
3299
3300 \f
3301 /**
3302  * @brief This function implements scheduler DL allocation for
3303  *        for broadcast (on PDSCH) and paging.
3304  *
3305  * @details
3306  *
3307  *     Function: rgSCHCmnDlBcchPcch
3308  *     Purpose:  This function implements scheduler for DL allocation
3309  *               for broadcast (on PDSCH) and paging.
3310  *
3311  *     Invoked by: Scheduler
3312  *
3313  *  @param[in]  RgSchCellCb*     cell
3314  *  @return  S16
3315  *      -# ROK
3316  *      -# RFAILED
3317  **/
3318 #ifdef ANSI
3319 PRIVATE Void rgSCHCmnDlBcchPcch
3320 (
3321 RgSchCellCb             *cell,
3322 RgSchCmnDlRbAllocInfo   *allocInfo,
3323 RgInfSfAlloc            *subfrmAlloc
3324 )
3325 #else
3326 PRIVATE Void rgSCHCmnDlBcchPcch(cell, allocInfo, subfrmAlloc)
3327 RgSchCellCb             *cell;
3328 RgSchCmnDlRbAllocInfo   *allocInfo;
3329 RgInfSfAlloc            *subfrmAlloc;
3330 #endif
3331 {
3332    CmLteTimingInfo   frm;
3333    RgSchDlSf         *sf;
3334    RgSchClcDlLcCb    *pcch;
3335    RgSchClcBoRpt     *bo;
3336 #ifndef RGR_SI_SCH
3337    Bool              valid;
3338    RgSchClcDlLcCb    *bcch, *bch;
3339 #endif/*RGR_SI_SCH*/
3340
3341
3342    TRC2(rgSCHCmnDlBcchPcch);
3343
3344    frm   = cell->crntTime;
3345 #ifdef LTEMAC_HDFDD
3346    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
3347       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
3348    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
3349 #else
3350    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
3351 #endif
3352
3353    /* Compute the subframe for which allocation is being made        */
3354    /* essentially, we need pointer to the dl frame for this subframe */
3355    sf = rgSCHUtlSubFrmGet(cell, frm);
3356
3357
3358 #ifndef RGR_SI_SCH
3359    bch = rgSCHDbmGetBcchOnBch(cell);
3360 #if (ERRCLASS & ERRCLS_DEBUG)
3361    if (bch == NULLP)
3362    {
3363       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on BCH is not configured");
3364       RETVOID;
3365    }
3366 #endif
3367    if (bch->boLst.first != NULLP)
3368    {
3369       bo = (RgSchClcBoRpt *)(bch->boLst.first->node);
3370       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3371       {
3372          sf->bch.tbSize = bo->bo;
3373          cmLListDelFrm(&bch->boLst, bch->boLst.first);
3374          /* ccpu00117052 - MOD - Passing double pointer
3375             for proper NULLP assignment*/
3376          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(*bo));
3377          rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, bch->lcId,TRUE);
3378       }
3379    }
3380    else
3381    {
3382       if ((frm.sfn % 4 == 0) && (frm.subframe == 0))
3383       {
3384       }
3385    }
3386
3387    allocInfo->bcchAlloc.schdFirst = FALSE;
3388    bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
3389 #if (ERRCLASS & ERRCLS_DEBUG)
3390    if (bcch == NULLP)
3391    {
3392       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured");
3393       RETVOID;
3394    }
3395 #endif
3396    if (bcch->boLst.first != NULLP)
3397    {
3398       bo = (RgSchClcBoRpt *)(bcch->boLst.first->node);
3399
3400       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3401       {
3402          allocInfo->bcchAlloc.schdFirst = TRUE;
3403          /* Time to perform allocation for this BCCH transmission */
3404          rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3405       }
3406    }
3407
3408    if(!allocInfo->bcchAlloc.schdFirst)
3409    {
3410       CmLList   *lnk;
3411       bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
3412 #if (ERRCLASS & ERRCLS_DEBUG)
3413       if (bcch == NULLP)
3414       {
3415          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured");
3416          RETVOID;
3417       }
3418 #endif
3419       lnk = bcch->boLst.first;
3420       while (lnk != NULLP)
3421       {
3422          bo = (RgSchClcBoRpt *)(lnk->node);
3423          lnk = lnk->next;
3424          valid = rgSCHCmnChkInWin(frm, bo->timeToTx, bo->maxTimeToTx);
3425
3426          if(valid)
3427          {
3428             bo->i = RGSCH_CALC_SF_DIFF(frm, bo->timeToTx);
3429             /* Time to perform allocation for this BCCH transmission */
3430             rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3431             break;
3432          }
3433          else
3434          {
3435             valid = rgSCHCmnChkPastWin(frm, bo->maxTimeToTx);
3436             if(valid)
3437             {
3438                cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
3439                /* ccpu00117052 - MOD - Passing double pointer
3440                   for proper NULLP assignment*/
3441                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo,
3442                      sizeof(RgSchClcBoRpt));
3443             }
3444          }
3445       }
3446    }
3447 #else
3448    rgSCHDlSiSched(cell, allocInfo, subfrmAlloc);
3449 #endif/*RGR_SI_SCH*/
3450
3451    pcch = rgSCHDbmGetPcch(cell);
3452 #ifdef ERRCLS_KW
3453    if (pcch == NULLP)
3454    {
3455       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"PCCH on DLSCH is not configured");
3456       RETVOID;
3457    }
3458 #endif
3459    if (pcch->boLst.first != NULLP)
3460    {
3461       bo = (RgSchClcBoRpt *)(pcch->boLst.first->node);
3462
3463       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3464       {
3465          /* Time to perform allocation for this PCCH transmission */
3466          rgSCHCmnClcAlloc(cell, sf, pcch, RGSCH_P_RNTI, allocInfo);
3467       }
3468    }
3469    RETVOID;
3470 }
3471
3472 /*
3473 *
3474 *       Fun:   rgSCHCmnChkInWin
3475 *
3476 *       Desc:  This function checks if frm occurs in window
3477 *
3478 *       Ret:   TRUE      - if in window
3479 *              FALSE     - otherwise
3480 *
3481 *       Notes: None
3482 *
3483 *       File:  rg_sch_cmn.c
3484 *
3485 */
3486 #ifdef ANSI
3487 PUBLIC Bool rgSCHCmnChkInWin
3488 (
3489 CmLteTimingInfo   frm,
3490 CmLteTimingInfo   start,
3491 CmLteTimingInfo   end
3492 )
3493 #else
3494 PUBLIC Bool rgSCHCmnChkInWin(frm, start, end)
3495 CmLteTimingInfo   frm;
3496 CmLteTimingInfo   start;
3497 CmLteTimingInfo   end;
3498 #endif
3499 {
3500    Bool    inWin = FALSE;
3501
3502    TRC2(rgSCHCmnChkInWin);
3503
3504    if (end.sfn > start.sfn)
3505    {
3506       if (frm.sfn > start.sfn
3507             || (frm.sfn == start.sfn && frm.subframe >= start.subframe))
3508       {
3509          if (frm.sfn < end.sfn
3510 #ifdef EMTC_ENABLE
3511                || (frm.sfn == end.sfn && frm.subframe <= end.subframe))
3512 #else
3513                || (frm.sfn == end.sfn && frm.subframe <= start.subframe))
3514 #endif
3515          {
3516             inWin = TRUE;
3517          }
3518       }
3519    }
3520    /* Testing for wrap around, sfn wraparound check should be enough */
3521    else if (end.sfn < start.sfn)
3522    {
3523       if (frm.sfn > start.sfn
3524             || (frm.sfn == start.sfn && frm.subframe >= start.subframe))
3525       {
3526          inWin = TRUE;
3527       }
3528       else
3529       {
3530          if (frm.sfn < end.sfn
3531                || (frm.sfn == end.sfn && frm.subframe <= end.subframe))
3532          {
3533             inWin = TRUE;
3534          }
3535       }
3536    }
3537    else  /* start.sfn == end.sfn */
3538    {
3539       if (frm.sfn == start.sfn
3540             && (frm.subframe >= start.subframe
3541                && frm.subframe <= end.subframe))
3542       {
3543          inWin = TRUE;
3544       }
3545    }
3546
3547    RETVALUE(inWin);
3548 } /* end of rgSCHCmnChkInWin*/
3549
3550 /*
3551 *
3552 *       Fun:   rgSCHCmnChkPastWin
3553 *
3554 *       Desc:  This function checks if frm has gone past window edge
3555 *
3556 *       Ret:   TRUE      - if past window edge
3557 *              FALSE     - otherwise
3558 *
3559 *       Notes: None
3560 *
3561 *       File:  rg_sch_cmn.c
3562 *
3563 */
3564 #ifdef ANSI
3565 PUBLIC Bool rgSCHCmnChkPastWin
3566 (
3567 CmLteTimingInfo   frm,
3568 CmLteTimingInfo   end
3569 )
3570 #else
3571 PUBLIC Bool rgSCHCmnChkPastWin(frm, end)
3572 CmLteTimingInfo   frm;
3573 CmLteTimingInfo   end;
3574 #endif
3575 {
3576    CmLteTimingInfo  refFrm = end;
3577    Bool             pastWin;
3578
3579    TRC2(rgSCHCmnChkPastWin);
3580
3581    RGSCH_INCR_FRAME(refFrm.sfn);
3582    RGSCH_INCR_SUB_FRAME(end, 1);
3583    pastWin = rgSCHCmnChkInWin(frm, end, refFrm);
3584
3585    RETVALUE(pastWin);
3586 } /* end of rgSCHCmnChkPastWin*/
3587 \f
3588 /**
3589  * @brief This function implements allocation of the resources for common
3590  * channels BCCH, PCCH.
3591  *
3592  * @details
3593  *
3594  *     Function: rgSCHCmnClcAlloc
3595  *     Purpose:  This function implements selection of number of RBs based
3596  *               the allowed grant for the service. It is also responsible
3597  *               for selection of MCS for the transmission.
3598  *
3599  *     Invoked by: Scheduler
3600  *
3601  *  @param[in]  RgSchCellCb                *cell,
3602  *  @param[in]  RgSchDlSf                  *sf,
3603  *  @param[in]  RgSchClcDlLcCb             *lch,
3604  *  @param[in]  U16                        rnti,
3605  *  @param[out] RgSchCmnDlRbAllocInfo      *allocInfo
3606  *  @return     Void
3607  *
3608  **/
3609 #ifdef ANSI
3610 PRIVATE Void rgSCHCmnClcAlloc
3611 (
3612 RgSchCellCb             *cell,
3613 RgSchDlSf               *sf,
3614 RgSchClcDlLcCb          *lch,
3615 U16                     rnti,
3616 RgSchCmnDlRbAllocInfo   *allocInfo
3617 )
3618 #else
3619 PRIVATE Void rgSCHCmnClcAlloc(cell, sf, lch, rnti, allocInfo)
3620 RgSchCellCb             *cell;
3621 RgSchDlSf               *sf;
3622 RgSchClcDlLcCb          *lch;
3623 U16                     rnti;
3624 RgSchCmnDlRbAllocInfo   *allocInfo;
3625 #endif
3626 {
3627    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3628    RgSchClcBoRpt        *bo;
3629    U32                  rb=0;
3630    U8                   mcs;
3631    U32                  tbs;
3632 #ifdef LTE_TDD   
3633    U8                   lostRe;
3634    U8                   cfi = cellDl->currCfi;  
3635 #endif
3636
3637    TRC2(rgSCHCmnClcAlloc);
3638
3639    bo = (RgSchClcBoRpt *)(lch->boLst.first->node);
3640
3641    mcs = bo->mcs;
3642    tbs = bo->bo;
3643    /* rgSCHCmnClcRbAllocForFxdTb(cell, bo->bo, cellDl->ccchCqi, &rb);*/
3644    if(cellDl->bitsPerRb==0)
3645    {
3646       while ((rgTbSzTbl[0][0][rb]) < (tbs*8))
3647       {
3648          rb++;
3649       }
3650       rb = rb+1;
3651    }
3652    else
3653    {
3654       rb = RGSCH_CEIL((tbs*8), cellDl->bitsPerRb);
3655    }
3656    /* DwPTS Scheduling Changes Start */   
3657 #ifdef LTE_TDD
3658    if(sf->sfType == RG_SCH_SPL_SF_DATA) 
3659    {
3660       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
3661
3662       /* Calculate the less RE's because of DwPTS */
3663       lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
3664
3665       /* Increase number of RBs in Spl SF to compensate for lost REs */
3666       rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
3667    }
3668 #endif
3669    /* DwPTS Scheduling Changes End */   
3670    /*ccpu00115595- end*/
3671    /* additional check to see if required RBs
3672     * exceeds the available */
3673    if (rb > sf->bw - sf->bwAssigned)
3674    {
3675       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"BW allocation "
3676                 "failed for CRNTI:%d",rnti);
3677       RETVOID;
3678    }
3679
3680    /* Update the subframe Allocated BW field */
3681    sf->bwAssigned = sf->bwAssigned + rb;
3682    /* Fill in the BCCH/PCCH transmission info to the RBAllocInfo struct */
3683    if (rnti == RGSCH_SI_RNTI)
3684    {
3685       allocInfo->bcchAlloc.rnti = rnti;
3686       allocInfo->bcchAlloc.dlSf = sf;
3687       allocInfo->bcchAlloc.tbInfo[0].bytesReq = tbs;
3688       allocInfo->bcchAlloc.rbsReq = rb;
3689       allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
3690       allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
3691       /* Nprb indication at PHY for common Ch */
3692       allocInfo->bcchAlloc.nPrb = bo->nPrb;
3693    }
3694    else
3695    {
3696       allocInfo->pcchAlloc.rnti = rnti;
3697       allocInfo->pcchAlloc.dlSf = sf;
3698       allocInfo->pcchAlloc.tbInfo[0].bytesReq = tbs;
3699       allocInfo->pcchAlloc.rbsReq = rb;
3700       allocInfo->pcchAlloc.tbInfo[0].imcs = mcs;
3701       allocInfo->pcchAlloc.tbInfo[0].noLyr = 1;
3702       allocInfo->pcchAlloc.nPrb = bo->nPrb;
3703    }
3704    RETVOID;
3705 }
3706
3707 \f
3708 /**
3709  * @brief This function implements PDCCH allocation for common channels.
3710  *
3711  * @details
3712  *
3713  *     Function: rgSCHCmnCmnPdcchAlloc
3714  *     Purpose:  This function implements allocation of PDCCH for a UE.
3715  *               1. This uses index 0 of PDCCH table for efficiency.
3716  *               2. Uses he candidate PDCCH count for the aggr level.
3717  *               3. Look for availability for each candidate and choose
3718  *                  the first one available.
3719  *
3720  *     Invoked by: Scheduler
3721  *
3722  *  @param[in]  RgSchCellCb           *cell
3723  *  @param[in]  RgSchDlSf             *sf
3724  *  @return     RgSchPdcch *
3725  *               -# NULLP when unsuccessful
3726  *
3727  **/
3728 #ifdef ANSI
3729 PUBLIC RgSchPdcch *rgSCHCmnCmnPdcchAlloc
3730 (
3731 RgSchCellCb                *cell,
3732 RgSchDlSf                  *subFrm
3733 )
3734 #else
3735 PUBLIC RgSchPdcch *rgSCHCmnCmnPdcchAlloc(cell, subFrm)
3736 RgSchCellCb                *cell;
3737 RgSchDlSf                  *subFrm;
3738 #endif
3739 {
3740    U8                   i;
3741    CmLteAggrLvl         aggrLvl;
3742    RgSchPdcchInfo       *pdcchInfo;
3743    RgSchPdcch           *pdcch;
3744    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
3745    U8                   numCce;  /*store num CCEs based on 
3746                                   aggregation level */
3747    TRC2(rgSCHCmnCmnPdcchAlloc);
3748
3749    aggrLvl   = cellSch->dl.cmnChAggrLvl;
3750
3751    pdcchInfo = &(subFrm->pdcchInfo);
3752
3753     /* Updating the no. of nCce in pdcchInfo, in case if CFI
3754     * was changed  */
3755 #ifdef LTE_TDD
3756    if(subFrm->nCce != pdcchInfo->nCce)
3757    {   
3758       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3759    }
3760 #else   
3761    if(cell->nCce != pdcchInfo->nCce)
3762    {
3763       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3764    }
3765 #endif  
3766
3767    switch (aggrLvl)
3768    {
3769       case CM_LTE_AGGR_LVL4:
3770         numCce = 4;
3771         break;
3772       case CM_LTE_AGGR_LVL8:
3773         numCce = 8;
3774         break;
3775                 case CM_LTE_AGGR_LVL16:
3776         numCce = 16;
3777         break;
3778       default:
3779         RETVALUE(NULLP);
3780    }
3781
3782    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3783    {
3784 #ifdef LTEMAC_SPS
3785       pdcch->isSpsRnti = FALSE;
3786 #endif
3787       /* Increment the CCE used counter in the current subframe */
3788       subFrm->cceCnt += numCce;
3789       pdcch->pdcchSearchSpace = RG_SCH_CMN_SEARCH_SPACE;
3790
3791       RETVALUE(pdcch);
3792    }
3793
3794    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3795    subFrm->isCceFailure = TRUE;
3796
3797    RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
3798             "PDCCH ERR: NO PDDCH AVAIL IN COMMON SEARCH SPACE aggr:%u", 
3799             aggrLvl);
3800    RETVALUE(NULLP);
3801 }
3802
3803 \f
3804 /**
3805  * @brief This function implements bandwidth allocation for common channels.
3806  *
3807  * @details
3808  *
3809  *     Function: rgSCHCmnClcRbAlloc
3810  *     Purpose:  This function implements bandwith allocation logic
3811  *               for common control channels.
3812  *
3813  *     Invoked by: Scheduler
3814  *
3815  *  @param[in]  RgSchCellCb*  cell
3816  *  @param[in]  U32           bo
3817  *  @param[in]  U8            cqi
3818  *  @param[in]  U8            *rb
3819  *  @param[in]  U32           *tbs
3820  *  @param[in]  U8            *mcs
3821  *  @param[in]  RgSchDlSf     *sf
3822  *  @return  Void
3823  *
3824  **/
3825 #ifdef LTEMAC_SPS
3826 #ifdef ANSI
3827 PUBLIC Void rgSCHCmnClcRbAlloc
3828 (
3829 RgSchCellCb             *cell,
3830 U32                     bo,
3831 U8                      cqi,
3832 U8                      *rb,
3833 U32                     *tbs,
3834 U8                      *mcs,
3835 U8                      *iTbs,
3836 Bool                    isSpsBo,
3837 RgSchDlSf               *sf 
3838 )
3839 #else
3840 PUBLIC Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, iTbs, isSpsBo)
3841 RgSchCellCb             *cell;
3842 U32                     bo;
3843 U8                      cqi;
3844 U8                      *rb;
3845 U32                     *tbs;
3846 U8                      *mcs;
3847 U8                      *iTbs;
3848 Bool                    isSpsBo;
3849 RgSchDlSf               *sf; 
3850 #endif
3851 #else
3852 #ifdef ANSI
3853 PRIVATE Void rgSCHCmnClcRbAlloc
3854 (
3855 RgSchCellCb             *cell,
3856 U32                     bo,
3857 U8                      cqi,
3858 U8                      *rb,
3859 U32                     *tbs,
3860 U8                      *mcs,
3861 RgSchDlSf               *sf 
3862 )
3863 #else
3864 PRIVATE Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, sf)
3865 RgSchCellCb             *cell;
3866 U32                     bo;
3867 U8                      cqi;
3868 U8                      *rb;
3869 U32                     *tbs;
3870 U8                      *mcs;
3871 RgSchDlSf               *sf; 
3872 #endif
3873 #endif /* LTEMAC_SPS */
3874 {
3875    U8                   iTbsVal;
3876    RgSchCmnTbSzEff      *effTbl;
3877    U32                  eff;
3878    U32                  noRes;
3879    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
3880    U8                   cfi = cellSch->dl.currCfi;
3881    U32                  tmpRb=0;
3882    TRC2(rgSCHCmnClcRbAlloc);
3883
3884    /* first get the CQI to MCS table and determine the number of RBs */
3885    effTbl = (RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]);
3886    iTbsVal = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[cqi];
3887    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3888
3889    /* Efficiency is number of bits per 1024 REs */
3890    eff  = (*effTbl)[iTbsVal];
3891
3892    /* Get the number of REs needed for this bo  */
3893    noRes = ((bo * 8 * 1024) / eff );
3894
3895    /* Get the number of RBs needed for this transmission */
3896    /* Number of RBs = No of REs / No of REs per RB       */
3897    tmpRb = RGSCH_CEIL(noRes, cellSch->dl.noResPerRb[cfi]);
3898    /* KWORK_FIX: added check to see if rb has crossed maxRb*/
3899    RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3900    if (tmpRb > cellSch->dl.maxDlBwPerUe)
3901    {
3902       tmpRb = cellSch->dl.maxDlBwPerUe;
3903    }
3904    while ((rgTbSzTbl[0][iTbsVal][tmpRb-1]/8) < bo && 
3905            (tmpRb < cellSch->dl.maxDlBwPerUe))
3906    {
3907       tmpRb++;
3908       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3909    }
3910    *tbs =  rgTbSzTbl[0][iTbsVal][tmpRb-1]/8;
3911    *rb = (U8)tmpRb;
3912    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3913
3914    RETVOID;
3915 }
3916
3917 \f
3918
3919 /**
3920  * @brief Scheduling for MSG4.
3921  *
3922  * @details
3923  *
3924  *     Function: rgSCHCmnMsg4Alloc
3925  *     Purpose:  Scheduling for MSG4
3926  *
3927  *     Invoked by: Scheduler
3928  *
3929  *  @param[in]  RgSchCellCb*          cell
3930  *  @param[in]  RgSchRaCb*            raCb
3931  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3932  *  @return  S16
3933  *
3934  **/
3935 #ifdef ANSI
3936 PRIVATE S16 rgSCHCmnMsg4Alloc
3937 (
3938 RgSchCellCb                *cell,
3939 RgSchRaCb                  *raCb,
3940 RgSchCmnDlRbAllocInfo      *allocInfo
3941 )
3942 #else
3943 PRIVATE S16 rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)
3944 RgSchCellCb                *cell;
3945 RgSchRaCb                  *raCb;
3946 RgSchCmnDlRbAllocInfo      *allocInfo;
3947 #endif
3948 {
3949    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
3950
3951    TRC2(rgSCHCmnMsg4Alloc);
3952
3953  /* SR_RACH_STATS : MSG4 TO BE TXED */
3954    rgNumMsg4ToBeTx++;
3955    /* Return if subframe BW exhausted */
3956    if (allocInfo->msg4Alloc.msg4DlSf->bw <=
3957        allocInfo->msg4Alloc.msg4DlSf->bwAssigned)
3958    {
3959       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId ,
3960          "bw<=bwAssigned");
3961       RETVALUE(RFAILED);
3962    }
3963
3964    if (rgSCHDhmGetMsg4HqProc(raCb, cellSch->dl.time) != ROK)
3965    {
3966       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
3967          "rgSCHDhmGetMsg4HqProc failed");
3968       RETVALUE(RFAILED);
3969    }
3970
3971    raCb->rbAllocInfo.dlSf = allocInfo->msg4Alloc.msg4DlSf;
3972
3973    if (rgSCHCmnMsg4DedAlloc(cell, raCb) != ROK)
3974    {
3975       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
3976       rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, FALSE);
3977       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
3978          "rgSCHCmnMsg4DedAlloc failed.");
3979       RETVALUE(RFAILED);
3980    }
3981    cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4TxLst, &raCb->dlHqE->msg4Proc->reqLnk);
3982    raCb->dlHqE->msg4Proc->reqLnk.node = (PTR)raCb->dlHqE->msg4Proc;
3983    allocInfo->msg4Alloc.msg4DlSf->schdCcchUe++;
3984
3985    RETVALUE(ROK);
3986 }
3987
3988 \f
3989 /**
3990  * @brief This function implements PDCCH allocation for an UE.
3991  *
3992  * @details
3993  *
3994  *     Function: PdcchAlloc
3995  *     Purpose:  This function implements allocation of PDCCH for an UE.
3996  *               1. Get the aggregation level for the CQI of the UE.
3997  *               2. Get the candidate PDCCH count for the aggr level.
3998  *               3. Look for availability for each candidate and choose
3999  *                  the first one available.
4000  *
4001  *     Invoked by: Scheduler
4002  *
4003  *  @param[in]  cell
4004  *  @param[in]  subFrm
4005  *  @param[in]  cqi
4006  *  @param[in]  dciFrmt
4007  *  @return  RgSchPdcch *
4008  *         -# NULLP when unsuccessful
4009  *
4010  **/
4011 #ifdef ANSI
4012 PUBLIC RgSchPdcch *rgSCHCmnPdcchAlloc
4013 (
4014 RgSchCellCb             *cell,
4015 RgSchUeCb               *ue,
4016 RgSchDlSf               *subFrm,
4017 U8                      cqi,
4018 TfuDciFormat            dciFrmt,
4019 Bool                    isDtx
4020 )
4021 #else
4022 PUBLIC RgSchPdcch *rgSCHCmnPdcchAlloc(cell, subFrm, cqi, dciFrmt, isDtx)
4023 RgSchCellCb             *cell;
4024 RgSchUeCb               *ue;
4025 RgSchDlSf               *subFrm;
4026 U8                      cqi;
4027 TfuDciFormat            dciFrmt;
4028 Bool                    isDtx;
4029 #endif
4030 {
4031    CmLteAggrLvl     aggrLvl;
4032    RgSchPdcchInfo   *pdcchInfo;
4033    RgSchPdcch       *pdcch;
4034    U8               numxREGs;
4035
4036    TRC2(rgSCHCmnPdcchAlloc);
4037
4038    /* 3.1 consider the selected DCI format size in determining the
4039     * aggregation level */
4040    //TODO_SID Need to update. Currently using 4 aggregation level
4041    aggrLvl   = CM_LTE_AGGR_LVL2;//cellSch->dciAggrLvl[cqi][dciFrmt];
4042
4043 #ifdef LTE_ADV
4044    if((dciFrmt == TFU_DCI_FORMAT_1A) &&
4045       ((ue) && (ue->allocCmnUlPdcch)) )
4046    {
4047       pdcch = rgSCHCmnCmnPdcchAlloc(cell, subFrm);
4048       /* Since CRNTI Scrambled */
4049       if(NULLP != pdcch)
4050       {
4051          pdcch->dciNumOfBits = ue->dciSize.cmnSize[dciFrmt];
4052         // prc_trace_format_string(PRC_TRACE_GROUP_PS, PRC_TRACE_INFO_LOW,"Forcing alloc in CMN search spc size %d fmt %d \n",
4053         // pdcch->dciNumOfBits, dciFrmt);
4054       }
4055       RETVALUE(pdcch);
4056    }
4057 #endif
4058
4059    /* Incrementing aggrLvl by 1 if it not AGGR_LVL8(MAX SIZE)
4060     * inorder to increse the redudancy bits for better decoding of UE */
4061    if (isDtx)
4062    {
4063       if (aggrLvl != CM_LTE_AGGR_LVL16)
4064       {
4065          switch(aggrLvl)
4066          {
4067             case CM_LTE_AGGR_LVL2:
4068                aggrLvl = CM_LTE_AGGR_LVL4;
4069                 break;
4070             case CM_LTE_AGGR_LVL4:
4071                aggrLvl = CM_LTE_AGGR_LVL8;
4072                break;
4073             case CM_LTE_AGGR_LVL8:
4074                aggrLvl = CM_LTE_AGGR_LVL16;
4075                break;
4076             default:
4077                break;
4078          }
4079          /* aggrLvl   += 1; */
4080       }
4081    }
4082
4083    pdcchInfo = &subFrm->pdcchInfo;
4084
4085    /* Updating the no. of nCce in pdcchInfo, in case if CFI
4086     * was changed  */
4087 #ifdef LTE_TDD
4088    if(subFrm->nCce != pdcchInfo->nCce)
4089    {   
4090       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
4091    }
4092 #else   
4093    if(cell->nCce != pdcchInfo->nCce)
4094    {
4095       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
4096    }
4097 #endif       
4098
4099    if (pdcchInfo->nCce < (1 << (aggrLvl - 1)))
4100    {
4101       /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
4102       subFrm->isCceFailure = TRUE;
4103       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
4104             "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", 
4105             aggrLvl);
4106
4107       RETVALUE(NULLP);
4108    }
4109
4110    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
4111    {
4112       /* SR_RACH_STATS : Reset isTBMsg4 */
4113       pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4= FALSE;         
4114       pdcch->dci.u.format0Info.isSrGrant = FALSE;
4115 #ifdef LTEMAC_SPS
4116       pdcch->isSpsRnti = FALSE;
4117 #endif
4118       /* Increment the CCE used counter in the current subframe */
4119       subFrm->cceCnt += aggrLvl;
4120       pdcch->pdcchSearchSpace = RG_SCH_UE_SPECIFIC_SEARCH_SPACE;
4121       if (ue != NULLP)
4122                 {
4123 #ifdef LTE_ADV
4124                  if (ue->cell != cell)
4125                  {
4126                     /* Secondary Cell */
4127                     //pdcch->dciNumOfBits = ue->dciSize.noUlCcSize[dciFrmt];
4128                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
4129                  }
4130                  else
4131 #endif
4132                  {
4133                     //pdcch->dciNumOfBits = ue->dciSize.dedSize[dciFrmt];
4134                     //TODO_SID Need to update dci size.
4135                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
4136                  }
4137                 }
4138       else
4139       {
4140          /* MSG4 */
4141          pdcch->dciNumOfBits = cell->dciSize.size[dciFrmt];
4142       }
4143       RETVALUE(pdcch);
4144    }
4145
4146    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
4147    subFrm->isCceFailure = TRUE;
4148
4149    RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
4150          "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)",
4151          aggrLvl);
4152    RETVALUE(NULLP);
4153 }
4154
4155 #ifdef RGR_V1
4156 /**
4157  * @brief This function implements BW allocation for CCCH SDU
4158  *
4159  * @details
4160  *
4161  *     Function: rgSCHCmnCcchSduDedAlloc
4162  *     Purpose:  Downlink bandwidth Allocation for CCCH SDU.
4163  *
4164  *     Invoked by: Scheduler
4165  *
4166  *  @param[in]  RgSchCellCb*     cell
4167  *  @param[out] RgSchUeCb        *ueCb
4168  *  @return S16
4169  *
4170  **/
4171 #ifdef ANSI
4172 PRIVATE S16 rgSCHCmnCcchSduDedAlloc
4173 (
4174 RgSchCellCb      *cell,
4175 RgSchUeCb        *ueCb
4176 )
4177 #else
4178 PRIVATE S16 rgSCHCmnCcchSduDedAlloc(cell, ueCb)
4179 RgSchCellCb      *cell;
4180 RgSchUeCb        *ueCb;
4181 #endif
4182 {
4183    RgSchDlHqEnt      *hqE = NULLP;
4184    U32                  effBo;
4185    RgSchDlRbAlloc       *rbAllocinfo = NULLP;
4186    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4187    U8                   iTbs;
4188    U8                   numRb;
4189 #ifdef LTE_TDD
4190    U8                   cfi     = cellDl->currCfi;
4191 #endif
4192
4193    TRC2(rgSCHCmnCcchSduDedAlloc);
4194
4195    rbAllocinfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
4196
4197    effBo  =   ueCb->dlCcchInfo.bo + RGSCH_CCCH_SDU_HDRSIZE;
4198
4199 #ifndef LTEMAC_SPS
4200    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
4201                       &rbAllocinfo->tbInfo[0].bytesReq,
4202                       &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
4203 #else /* LTEMAC_SPS */
4204    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
4205                       &rbAllocinfo->tbInfo[0].bytesReq,\
4206                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, 
4207                       rbAllocinfo->dlSf);
4208 #endif /* LTEMAC_SPS */
4209
4210    iTbs = 0;
4211    /* Cannot exceed the total number of RBs in the cell */
4212    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
4213                                    rbAllocinfo->dlSf->bwAssigned)))
4214    {
4215       /* Check if atleast one allocation was possible.
4216          This may be the case where the Bw is very less and
4217          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
4218       if (rbAllocinfo->dlSf->bwAssigned == 0)
4219       {
4220          numRb   = rbAllocinfo->dlSf->bw;
4221          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
4222          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
4223          {
4224             iTbs++;
4225          }
4226          rbAllocinfo->rbsReq = numRb;
4227          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
4228          /* DwPTS Scheduling Changes Start */
4229 #ifdef LTE_TDD
4230          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
4231          {
4232             rbAllocinfo->tbInfo[0].bytesReq =
4233                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1,cfi);
4234          }
4235 #endif
4236          /* DwPTS Scheduling Changes End */
4237          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
4238       }
4239       else
4240       {
4241          RETVALUE(RFAILED);
4242       }
4243    }
4244
4245    /* Update the subframe Allocated BW field */
4246    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4247                                    rbAllocinfo->rbsReq;
4248    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
4249    rbAllocinfo->tbInfo[0].tbCb = &hqE->ccchSduProc->tbInfo[0];
4250    rbAllocinfo->rnti = ueCb->ueId;
4251    rbAllocinfo->tbInfo[0].noLyr = 1;
4252
4253    RETVALUE(ROK);
4254 }
4255 #endif
4256 \f
4257 /**
4258  * @brief This function implements BW allocation for MSG4
4259  *
4260  * @details
4261  *
4262  *     Function: rgSCHCmnMsg4DedAlloc
4263  *     Purpose:  Downlink bandwidth Allocation for MSG4.
4264  *
4265  *     Invoked by: Scheduler
4266  *
4267  *  @param[in]  RgSchCellCb*     cell
4268  *  @param[out] RgSchRaCb        *raCb
4269  *  @return S16
4270  *
4271  **/
4272 #ifdef ANSI
4273 PRIVATE S16 rgSCHCmnMsg4DedAlloc
4274 (
4275 RgSchCellCb      *cell,
4276 RgSchRaCb        *raCb
4277 )
4278 #else
4279 PRIVATE S16 rgSCHCmnMsg4DedAlloc(cell, raCb)
4280 RgSchCellCb      *cell;
4281 RgSchRaCb        *raCb;
4282 #endif
4283 {
4284    U32                  effBo;
4285    RgSchDlRbAlloc       *rbAllocinfo = &raCb->rbAllocInfo;
4286    U8                   iTbs;
4287    U8                   numRb;
4288 #ifdef LTE_TDD
4289    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4290    U8                   cfi     = cellDl->currCfi;
4291 #endif
4292
4293    TRC2(rgSCHCmnMsg4DedAlloc);
4294
4295    effBo  = raCb->dlCcchInfo.bo + RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE;
4296
4297 #ifndef LTEMAC_SPS
4298    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
4299          &rbAllocinfo->tbInfo[0].bytesReq,\
4300          &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
4301 #else /* LTEMAC_SPS */
4302    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
4303                       &rbAllocinfo->tbInfo[0].bytesReq,\
4304                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE,
4305                       rbAllocinfo->dlSf);
4306 #endif /* LTEMAC_SPS */
4307
4308    iTbs = 0;
4309    /* Cannot exceed the total number of RBs in the cell */
4310    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
4311                rbAllocinfo->dlSf->bwAssigned)))
4312    {
4313       /* Check if atleast one allocation was possible.
4314          This may be the case where the Bw is very less and
4315          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
4316       if (rbAllocinfo->dlSf->bwAssigned == 0)
4317       {
4318          numRb   = rbAllocinfo->dlSf->bw;
4319          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
4320          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
4321          {
4322             iTbs++;
4323          }
4324          rbAllocinfo->rbsReq = numRb;
4325          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
4326          /* DwPTS Scheduling Changes Start */
4327 #ifdef LTE_TDD
4328          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
4329          {
4330             rbAllocinfo->tbInfo[0].bytesReq =
4331                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1, cfi);
4332          }
4333 #endif
4334          /* DwPTS Scheduling Changes End */
4335          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
4336       }
4337       else
4338       {
4339          RETVALUE(RFAILED);
4340       }
4341    }
4342
4343    /* Update the subframe Allocated BW field */
4344    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4345                                    rbAllocinfo->rbsReq;
4346    rbAllocinfo->rnti = raCb->tmpCrnti;
4347    rbAllocinfo->tbInfo[0].tbCb = &raCb->dlHqE->msg4Proc->tbInfo[0];
4348    rbAllocinfo->tbInfo[0].schdlngForTb = TRUE;
4349    rbAllocinfo->tbInfo[0].noLyr = 1;
4350
4351    RETVALUE(ROK);
4352 }
4353
4354 #ifdef LTE_TDD
4355 /**
4356  * @brief This function implements scheduling for RA Response.
4357  *
4358  * @details
4359  *
4360  *     Function: rgSCHCmnDlRaRsp
4361  *     Purpose:  Downlink scheduling for RA responses.
4362  *
4363  *     Invoked by: Scheduler
4364  *
4365  *  @param[in]  RgSchCellCb*     cell
4366  *  @return  Void
4367  *
4368  **/
4369 #ifdef ANSI
4370 PRIVATE Void rgSCHCmnDlRaRsp
4371 (
4372 RgSchCellCb                *cell,
4373 RgSchCmnDlRbAllocInfo      *allocInfo
4374 )
4375 #else
4376 PRIVATE Void rgSCHCmnDlRaRsp(cell, allocInfo)
4377 RgSchCellCb                *cell;
4378 RgSchCmnDlRbAllocInfo      *allocInfo;
4379 #endif
4380 {
4381    CmLteTimingInfo      frm;
4382    CmLteTimingInfo      schFrm;
4383    RgSchDlSf            *subFrm;
4384    U16                  rarnti;
4385    U8                   i;
4386    U8                   noRaRnti=0;
4387    U8                   raIdx;
4388    RgSchTddRachRspLst   *rachRsp;
4389    U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
4390    U8                   sfnIdx;
4391    U8                   subfrmIdx;
4392    U16                  rntiIdx=0;
4393    TRC2(rgSCHCmnDlRaRsp);
4394
4395    frm   = cell->crntTime;
4396    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4397
4398    /* Compute the subframe for which allocation is being made        */
4399    /* essentially, we need pointer to the dl frame for this subframe */
4400    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4401
4402    /* Get the RACH Response scheduling related information
4403     * for the subframe with RA index */
4404    raIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][frm.subframe]-1;
4405
4406    rachRsp = &cell->rachRspLst[raIdx];
4407
4408    for(sfnIdx = 0; sfnIdx < rachRsp->numRadiofrms; sfnIdx++)
4409    {
4410       /* For all scheduled RACH Responses in SFNs */
4411       schFrm = frm;
4412       RG_SCH_CMN_DECR_FRAME(schFrm.sfn, rachRsp->rachRsp[sfnIdx].sfnOffset);
4413       /* For all scheduled RACH Responses in subframes */
4414       for(subfrmIdx = 0;
4415             subfrmIdx < rachRsp->rachRsp[sfnIdx].numSubfrms; subfrmIdx++)
4416       {
4417          schFrm.subframe = rachRsp->rachRsp[sfnIdx].subframe[subfrmIdx];
4418          /* compute the last RA RNTI used in the previous subframe */
4419          raIdx = (((schFrm.sfn % cell->raInfo.maxRaSize) * \
4420                   RGSCH_NUM_SUB_FRAMES * RGSCH_MAX_RA_RNTI_PER_SUBFRM) \
4421                                     + schFrm.subframe);
4422
4423          /* For all RA RNTIs within a subframe */
4424
4425          for(i=0; (i < RGSCH_MAX_RA_RNTI_PER_SUBFRM) && \
4426                (noRaRnti < RGSCH_MAX_TDD_RA_RSP_ALLOC); i++)
4427          {
4428             rarnti = (schFrm.subframe + RGSCH_NUM_SUB_FRAMES*i + 1);
4429             rntiIdx = (raIdx + RGSCH_NUM_SUB_FRAMES*i);
4430
4431             if (cell->raInfo.raReqLst[rntiIdx].first != NULLP)
4432             {
4433                /* compute the next RA RNTI */
4434                if (rgSCHCmnRaRspAlloc(cell, subFrm, rntiIdx,
4435                         rarnti, noRaRnti, allocInfo) != ROK)
4436                {
4437                   /* The resources are exhausted */
4438                   break;
4439                }
4440                noRaRnti++;
4441             }
4442          }
4443          noRaRnti=0;
4444       }
4445    }
4446
4447    RETVOID;
4448 }
4449 #else
4450 /**
4451  * @brief This function implements scheduling for RA Response.
4452  *
4453  * @details
4454  *
4455  *     Function: rgSCHCmnDlRaRsp
4456  *     Purpose:  Downlink scheduling for RA responses.
4457  *
4458  *     Invoked by: Scheduler
4459  *
4460  *  @param[in]  RgSchCellCb*          cell
4461  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
4462  *  @return  Void
4463  *
4464  **/
4465 #ifdef ANSI
4466 PRIVATE Void rgSCHCmnDlRaRsp  //FDD
4467 (
4468 RgSchCellCb                *cell,
4469 RgSchCmnDlRbAllocInfo      *allocInfo
4470 )
4471 #else
4472 PRIVATE Void rgSCHCmnDlRaRsp(cell, allocInfo)
4473 RgSchCellCb                *cell;
4474 RgSchCmnDlRbAllocInfo      *allocInfo;
4475 #endif
4476 {
4477    CmLteTimingInfo      frm;
4478    CmLteTimingInfo      winStartFrm;
4479    RgSchDlSf            *subFrm;
4480    U8                   winStartIdx;
4481    U8                   winGap;
4482    U8                   rarnti;
4483    U8                   raIdx;
4484    RgSchCmnCell         *sched;
4485    U8                   i,noRaRnti=0;
4486    TRC2(rgSCHCmnDlRaRsp);
4487
4488    frm   = cell->crntTime;
4489    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4490
4491    /* Compute the subframe for which allocation is being made        */
4492    /* essentially, we need pointer to the dl frame for this subframe */
4493    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4494    sched   = RG_SCH_CMN_GET_CELL(cell);
4495
4496    /* ccpu00132523 - Window Start calculated by considering RAR window size, 
4497     * RAR Wait period, Subframes occuppied for respective preamble format*/
4498    winGap = (sched->dl.numRaSubFrms-1) + (cell->rachCfg.raWinSize-1) 
4499              +RGSCH_RARSP_WAIT_PERIOD;
4500
4501    /* Window starting occassion is retrieved using the gap and tried to 
4502     * fit to the size of raReqLst array*/ 
4503    RGSCHDECRFRMCRNTTIME(frm, winStartFrm, winGap);
4504
4505         //5G_TODO TIMING update. Need to check
4506    winStartIdx = (winStartFrm.sfn & 1) * RGSCH_MAX_RA_RNTI+ winStartFrm.subframe;
4507
4508    for(i = 0; ((i < cell->rachCfg.raWinSize) && (noRaRnti < RG_SCH_CMN_MAX_CMN_PDCCH)); i++)
4509    {
4510       raIdx = (winStartIdx + i) % RGSCH_RAREQ_ARRAY_SIZE;
4511
4512       if (cell->raInfo.raReqLst[raIdx].first != NULLP)
4513       {
4514          allocInfo->raRspAlloc[noRaRnti].biEstmt = \
4515                          (!i * RGSCH_ONE_BIHDR_SIZE);
4516          rarnti = raIdx % RGSCH_MAX_RA_RNTI+ 1;
4517          if (rgSCHCmnRaRspAlloc(cell, subFrm, raIdx,
4518                                  rarnti, noRaRnti, allocInfo) != ROK)
4519          {
4520             /* The resources are exhausted */
4521             break;
4522          }
4523          /* ccpu00132523- If all the RAP ids are not scheduled then need not 
4524           * proceed for next RA RNTIs*/
4525          if(allocInfo->raRspAlloc[noRaRnti].numRapids < cell->raInfo.raReqLst[raIdx].count)
4526          {
4527             break;
4528          }
4529          noRaRnti++; /* Max of RG_SCH_CMN_MAX_CMN_PDCCH RARNTIs
4530                         for response allocation */
4531       }
4532    }
4533    RETVOID;
4534 }
4535 #endif
4536
4537 \f
4538 /**
4539  * @brief This function allocates the resources for an RARNTI.
4540  *
4541  * @details
4542  *
4543  *     Function: rgSCHCmnRaRspAlloc
4544  *     Purpose:  Allocate resources to a RARNTI.
4545  *               0. Allocate PDCCH for sending the response.
4546  *               1. Locate the number of RA requests pending for the RARNTI.
4547  *               2. Compute the size of data to be built.
4548  *               3. Using common channel CQI, compute the number of RBs.
4549  *
4550  *     Invoked by: Scheduler
4551  *
4552  *  @param[in]  RgSchCellCb             *cell,
4553  *  @param[in]  RgSchDlSf               *subFrm,
4554  *  @param[in]  U16                     rarnti,
4555  *  @param[in]  U8                      noRaRnti
4556  *  @param[out] RgSchCmnDlRbAllocInfo   *allocInfo
4557  *  @return  S16
4558  *
4559  **/
4560 #ifdef ANSI
4561 PRIVATE S16 rgSCHCmnRaRspAlloc
4562 (
4563 RgSchCellCb             *cell,
4564 RgSchDlSf               *subFrm,
4565 U16                     raIndex,
4566 U16                     rarnti,
4567 U8                      noRaRnti,
4568 RgSchCmnDlRbAllocInfo   *allocInfo
4569 )
4570 #else
4571 PRIVATE S16 rgSCHCmnRaRspAlloc(cell,subFrm,raIndex,rarnti,noRaRnti,allocInfo)
4572 RgSchCellCb             *cell;
4573 RgSchDlSf               *subFrm;
4574 U16                     raIndex;
4575 U16                     rarnti;
4576 U8                      noRaRnti;
4577 RgSchCmnDlRbAllocInfo   *allocInfo;
4578 #endif
4579 {
4580    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4581    RgSchCmnUlCell       *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4582    U16                  noBytes;
4583    U32                  rb = 0;
4584    U32                  tbs;
4585    /*ccpu00116700,ccpu00116708- Corrected the wrong type for mcs*/
4586    U8                   mcs;
4587    CmLListCp            *reqLst;
4588    /* RACH handling related changes */
4589    Bool                 isAlloc = FALSE;
4590    static U8            schdNumRapid = 0;
4591    U8                   remNumRapid = 0;
4592    U8                   nPrb = 0;
4593    S32                  allwdTbSz = 0;
4594 #ifdef LTE_TDD   
4595    U16                  lostRe;  
4596    U8                   cfi = cellDl->currCfi;  
4597 #endif   
4598
4599    TRC2(rgSCHCmnRaRspAlloc);
4600 #ifndef RGR_V1
4601    UNUSED(cellUl);
4602 #endif
4603
4604    /* ccpu00132523: Resetting the schdRap Id count in every scheduling subframe*/
4605    if(noRaRnti == 0)
4606    {
4607       schdNumRapid = 0;
4608    }
4609
4610
4611    if (subFrm->bw == subFrm->bwAssigned)
4612    {
4613       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4614          "bw == bwAssigned RARNTI:%d",rarnti);
4615       RETVALUE(RFAILED);
4616    }
4617
4618    reqLst = &cell->raInfo.raReqLst[raIndex];
4619    if (reqLst->count == 0)
4620    {
4621       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4622          "reqLst Count=0 RARNTI:%d",rarnti);
4623       RETVALUE(RFAILED);
4624    }
4625    remNumRapid = reqLst->count;
4626
4627 #ifdef RGR_V1
4628    /* Limit number of rach rsps to maxMsg3PerUlsf */
4629    if ( schdNumRapid+remNumRapid > cellUl->maxMsg3PerUlSf )
4630    {
4631       remNumRapid = cellUl->maxMsg3PerUlSf-schdNumRapid;
4632    }
4633 #endif
4634  
4635    while (remNumRapid)
4636    {
4637       /* Try allocating for as many RAPIDs as possible */
4638       /* BI sub-header size to the tbSize requirement */
4639       noBytes  = RGSCH_GET_RAR_BYTES(remNumRapid) +\
4640                  allocInfo->raRspAlloc[noRaRnti].biEstmt;
4641       if ((allwdTbSz = rgSCHUtlGetAllwdCchTbSz(noBytes*8, &nPrb, &mcs)) == -1)
4642       {
4643          remNumRapid--;
4644          continue;
4645       }
4646
4647       /* rgSCHCmnClcRbAllocForFxdTb(cell, allwdTbSz/8, cellDl->ccchCqi, &rb);*/
4648       if(cellDl->bitsPerRb==0)
4649       {
4650          while ((rgTbSzTbl[0][0][rb]) <(U32) allwdTbSz)
4651          {
4652             rb++;
4653          }
4654          rb = rb+1;
4655       }
4656       else
4657       {
4658          rb = RGSCH_CEIL(allwdTbSz, cellDl->bitsPerRb);
4659       }
4660       /* DwPTS Scheduling Changes Start */      
4661 #ifdef LTE_TDD      
4662       if (subFrm->sfType == RG_SCH_SPL_SF_DATA)
4663       {
4664          RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
4665
4666          /* Calculate the less RE's because of DwPTS */
4667          lostRe = rb * (cellDl->noResPerRb[cfi] - 
4668                                   cellDl->numReDwPts[cfi]);
4669           
4670          /* Increase number of RBs in Spl SF to compensate for lost REs */
4671          rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]);
4672       }
4673 #endif      
4674       /* DwPTS Scheduling Changes End */
4675
4676       /*ccpu00115595- end*/
4677       if (rb > subFrm->bw - subFrm->bwAssigned)
4678       {
4679          remNumRapid--;
4680          continue;
4681       }
4682       /* Allocation succeeded for 'remNumRapid' */
4683       isAlloc = TRUE;
4684       tbs = allwdTbSz/8;
4685       printf("\n!!!RAR alloc noBytes:%u,allwdTbSz:%u,tbs:%u,rb:%u\n",
4686                                       noBytes,allwdTbSz,tbs,rb);
4687       break;
4688    }
4689    if (!isAlloc)
4690    {
4691       RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"BW alloc Failed");
4692       RETVALUE(RFAILED);
4693    }
4694
4695    subFrm->bwAssigned = subFrm->bwAssigned + rb;
4696
4697    /* Fill AllocInfo structure */
4698    allocInfo->raRspAlloc[noRaRnti].rnti = rarnti;
4699    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].bytesReq = tbs;
4700    allocInfo->raRspAlloc[noRaRnti].rbsReq = rb;
4701    allocInfo->raRspAlloc[noRaRnti].dlSf = subFrm;
4702    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].imcs = mcs;
4703    allocInfo->raRspAlloc[noRaRnti].raIndex = raIndex;
4704    /* RACH changes for multiple RAPID handling */
4705    allocInfo->raRspAlloc[noRaRnti].numRapids = remNumRapid;
4706    allocInfo->raRspAlloc[noRaRnti].nPrb = nPrb;
4707    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].noLyr = 1;
4708    allocInfo->raRspAlloc[noRaRnti].vrbgReq = RGSCH_CEIL(nPrb,MAX_5GTF_VRBG_SIZE); 
4709    schdNumRapid += remNumRapid; 
4710    RETVALUE(ROK);
4711 }
4712
4713 /***********************************************************
4714  *
4715  *     Func : rgSCHCmnUlAllocFillRbInfo
4716  *
4717  *     Desc : Fills the start RB and the number of RBs for
4718  *            uplink allocation.
4719  *
4720  *     Ret  : void
4721  *
4722  *     Notes:
4723  *
4724  *     File :
4725  *
4726  **********************************************************/
4727 #ifdef ANSI
4728 PUBLIC Void rgSCHCmnUlAllocFillRbInfo
4729 (
4730 RgSchCellCb   *cell,
4731 RgSchUlSf      *sf,
4732 RgSchUlAlloc  *alloc
4733 )
4734 #else
4735 PUBLIC Void rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc)
4736 RgSchCellCb    *cell;
4737 RgSchUlSf      *sf;
4738 RgSchUlAlloc   *alloc;
4739 #endif
4740 {
4741     RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4742     RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4743     U8             cfi = cellDl->currCfi;
4744
4745
4746    TRC2(rgSCHCmnUlAllocFillRbInfo);
4747    alloc->grnt.rbStart = (alloc->sbStart * cellUl->sbSize) + 
4748                                     cell->dynCfiCb.bwInfo[cfi].startRb;
4749
4750    /* Num RBs = numSbAllocated * sbSize - less RBs in the last SB */
4751    alloc->grnt.numRb = (alloc->numSb * cellUl->sbSize);
4752
4753    RETVOID;
4754 }
4755
4756 /**
4757  * @brief Grant request for Msg3.
4758  *
4759  * @details
4760  *
4761  *     Function : rgSCHCmnMsg3GrntReq
4762  *
4763  *     This is invoked by downlink scheduler to request allocation
4764  *     for msg3.
4765  *     Steps:
4766  *     - Attempt to allocate msg3 in the current msg3 subframe
4767  *       Allocation attempt based on whether preamble is from group A
4768  *       and the value of MESSAGE_SIZE_GROUP_A
4769  *     - Link allocation with passed RNTI and msg3 HARQ process
4770  *     - Set the HARQ process ID (*hqProcIdRef)
4771  *
4772  *  @param[in]  RgSchCellCb       *cell
4773  *  @param[in]  CmLteRnti         rnti
4774  *  @param[in]  Bool              preamGrpA
4775  *  @param[in]  RgSchUlHqProcCb   *hqProc
4776  *  @param[out] RgSchUlAlloc      **ulAllocRef
4777  *  @param[out] U8                *hqProcIdRef
4778  *  @return  Void
4779  **/
4780 #ifdef ANSI
4781 PRIVATE Void rgSCHCmnMsg3GrntReq
4782 (
4783 RgSchCellCb     *cell,
4784 CmLteRnti       rnti,
4785 Bool            preamGrpA,
4786 RgSchUlHqProcCb *hqProc,
4787 RgSchUlAlloc    **ulAllocRef,
4788 U8              *hqProcIdRef
4789 )
4790 #else
4791 PRIVATE Void rgSCHCmnMsg3GrntReq(cell, rnti, preamGrpA, hqProc,
4792                                  ulAllocRef, hqProcIdRef)
4793 RgSchCellCb     *cell;
4794 CmLteRnti       rnti;
4795 Bool            preamGrpA;
4796 RgSchUlHqProcCb *hqProc;
4797 RgSchUlAlloc    **ulAllocRef;
4798 U8              *hqProcIdRef;
4799 #endif
4800 {
4801    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4802    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
4803    RgSchUlHole     *hole;
4804    RgSchUlAlloc    *alloc;
4805    U8              iMcs;
4806    U8              numSb;
4807
4808    TRC2(rgSCHCmnMsg3GrntReq);
4809
4810    *ulAllocRef = NULLP;
4811
4812    /* Fix: ccpu00120610 Use remAllocs from subframe during msg3 allocation */
4813    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
4814    {
4815       RETVOID;
4816    }
4817    if (preamGrpA == FALSE)
4818    {
4819       numSb = cellUl->ra.prmblBNumSb;
4820       iMcs  = cellUl->ra.prmblBIMcs;
4821    }
4822    else
4823    {
4824       numSb = cellUl->ra.prmblANumSb;
4825       iMcs  = cellUl->ra.prmblAIMcs;
4826    }
4827
4828    if ((hole = rgSCHUtlUlHoleFirst(sf)) != NULLP)
4829    {
4830       if(*sf->allocCountRef == 0)
4831       {
4832          RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4833          /* Reinitialize the hole */
4834          if (sf->holeDb->count == 1 && (hole->start == 0)) /* Sanity check of holeDb */
4835          {
4836             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;
4837             /* Re-Initialize available subbands because of CFI change*/
4838             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
4839          }
4840          else
4841          {
4842             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4843                      "Error! holeDb sanity check failed RNTI:%d",rnti);
4844          } 
4845       }
4846       if (numSb <= hole->num)
4847       {
4848          U8 iTbs;
4849          alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
4850          rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
4851          alloc->grnt.iMcs     = iMcs;
4852          alloc->grnt.iMcsCrnt = iMcs;
4853          iTbs                 = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
4854          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); 
4855          /* To include the length and ModOrder in DataRecp Req.*/
4856          alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
4857          RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
4858          /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
4859          alloc->grnt.nDmrs    = 0;
4860          alloc->grnt.hop      = 0;
4861          alloc->grnt.delayBit = 0;
4862          alloc->grnt.isRtx    = FALSE;
4863          *ulAllocRef          = alloc;
4864          *hqProcIdRef         = (cellUl->msg3SchdHqProcIdx);
4865          hqProc->procId       = *hqProcIdRef;
4866          hqProc->ulSfIdx      = (cellUl->msg3SchdIdx);
4867          alloc->rnti          = rnti;
4868          alloc->ue            = NULLP;
4869          alloc->pdcch         = FALSE;
4870          alloc->forMsg3       = TRUE;
4871          alloc->hqProc        = hqProc;
4872          rgSCHUhmNewTx(hqProc, (U8)(cell->rachCfg.maxMsg3Tx - 1), alloc);
4873          //RLOG_ARG4(L_DEBUG,DBG_CELLID,cell->cellId,
4874          printf(
4875                "\nRNTI:%d MSG3 ALLOC proc(%p)procId(%d)schdIdx(%d)\n",
4876                alloc->rnti,
4877                ((PTR)alloc->hqProc),
4878                alloc->hqProc->procId,
4879                alloc->hqProc->ulSfIdx);
4880          RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
4881                "alloc(%p)maxMsg3Tx(%d)",
4882                ((PTR)alloc),
4883                cell->rachCfg.maxMsg3Tx);
4884       }
4885    }
4886
4887    RETVOID;
4888 }
4889
4890 \f
4891 /**
4892  * @brief This function determines the allocation limits and
4893  *        parameters that aid in DL scheduling.
4894  *
4895  * @details
4896  *
4897  *     Function: rgSCHCmnDlSetUeAllocLmt
4898  *     Purpose:  This function determines the Maximum RBs
4899  *               a UE is eligible to get based on softbuffer
4900  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4901  *               specific parameters like iTbs, eff and noLyrs
4902  *               are also set in this function. This function
4903  *               is called while UE configuration and UeDlCqiInd.
4904  *
4905  *     Invoked by: Scheduler
4906  *
4907  *  @param[in]  RgSchCellCb   *cellCb
4908  *  @param[in]  RgSchCmnDlUe  *ueDl
4909  *  @return  Void
4910  *
4911  **/
4912 #ifdef ANSI
4913 PRIVATE Void rgSCHCmnDlSetUeAllocLmt
4914 (
4915 RgSchCellCb   *cell,
4916 RgSchCmnDlUe  *ueDl,
4917 Bool          isEmtcUe
4918 )
4919 #else
4920 PRIVATE Void rgSCHCmnDlSetUeAllocLmt(cell, ueDl, isEmtcUe)
4921 RgSchCellCb   *cell;
4922 RgSchCmnDlUe  *ueDl;
4923 Bool          isEmtcUe;
4924 #endif
4925 {
4926    U8            modOrder;
4927    U32           maxRb;
4928    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4929    U8            cfi = cellSch->dl.currCfi;
4930
4931    TRC2(rgSCHCmnDlSetUeAllocLmt);
4932
4933 #ifdef EMTC_ENABLE
4934    if(TRUE == isEmtcUe)
4935    {
4936       /* ITbs for CW0 for 1 Layer Tx */
4937       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4938                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4939       /* ITbs for CW0 for 2 Layer Tx */
4940       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4941                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4942       /* Eff for CW0 for 1 Layer Tx */
4943       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4944                                             [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4945       /* Eff for CW0 for 2 Layer Tx */
4946       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4947                                             [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4948
4949       /* ITbs for CW1 for 1 Layer Tx */
4950       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4951                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4952       /* ITbs for CW1 for 2 Layer Tx */
4953       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4954                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4955       /* Eff for CW1 for 1 Layer Tx */
4956       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4957                                             [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4958       /* Eff for CW1 for 2 Layer Tx */
4959       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4960                                             [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4961    }
4962    else
4963 #endif 
4964    {
4965       /* ITbs for CW0 for 1 Layer Tx */
4966       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4967                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4968       /* ITbs for CW0 for 2 Layer Tx */
4969       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4970                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4971       /* Eff for CW0 for 1 Layer Tx */
4972       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4973                                         [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4974       /* Eff for CW0 for 2 Layer Tx */
4975       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4976                                         [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4977       
4978       /* ITbs for CW1 for 1 Layer Tx */
4979       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4980                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4981       /* ITbs for CW1 for 2 Layer Tx */
4982       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4983                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4984       /* Eff for CW1 for 1 Layer Tx */
4985       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4986                                         [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4987       /* Eff for CW1 for 2 Layer Tx */
4988       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4989                                         [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4990    }
4991
4992 //#ifdef DL_LA 
4993   // ueDl->laCb.cqiBasediTbs =  ueDl->mimoInfo.cwInfo[0].iTbs[0] * 100;
4994 //#endif
4995    /* Assigning noLyrs to each CW assuming optimal Spatial multiplexing
4996     * capability */
4997    (ueDl->mimoInfo.ri/2 == 0)? (ueDl->mimoInfo.cwInfo[0].noLyr = 1) : \
4998               (ueDl->mimoInfo.cwInfo[0].noLyr = ueDl->mimoInfo.ri/2);
4999    ueDl->mimoInfo.cwInfo[1].noLyr = ueDl->mimoInfo.ri - ueDl->mimoInfo.cwInfo[0].noLyr;
5000    /* rg002.101:ccpu00102106: correcting DL harq softbuffer limitation logic.
5001     * The maxTbSz is the maximum number of PHY bits a harq process can
5002     * hold. Hence we limit our allocation per harq process based on this.
5003     * Earlier implementation we misinterpreted the maxTbSz to be per UE
5004     * per TTI, but in fact it is per Harq per TTI. */
5005    /* rg002.101:ccpu00102106: cannot exceed the harq Tb Size
5006     * and harq Soft Bits limit.*/
5007
5008    /* Considering iTbs corresponding to 2 layer transmission for
5009     * codeword0(approximation) and the maxLayers supported by
5010     * this UE at this point of time. */
5011    RG_SCH_CMN_TBS_TO_MODODR(ueDl->mimoInfo.cwInfo[0].iTbs[1], modOrder);
5012
5013    /* Bits/modOrder gives #REs, #REs/noResPerRb gives #RBs */
5014    /* rg001.301 -MOD- [ccpu00119213] : avoiding wraparound */
5015    maxRb = ((ueDl->maxSbSz)/(cellSch->dl.noResPerRb[cfi] * modOrder *\
5016                    ueDl->mimoInfo.ri));
5017    if (cellSch->dl.isDlFreqSel)
5018    {
5019       /* Rounding off to left nearest multiple of RBG size */
5020       maxRb -= maxRb % cell->rbgSize;
5021    }
5022    ueDl->maxRb = RGSCH_MIN(maxRb, cellSch->dl.maxDlBwPerUe);
5023    if (cellSch->dl.isDlFreqSel)
5024    {
5025       /* Rounding off to right nearest multiple of RBG size */
5026       if (ueDl->maxRb % cell->rbgSize)
5027       {
5028          ueDl->maxRb += (cell->rbgSize - 
5029                          (ueDl->maxRb % cell->rbgSize));
5030       }
5031    }
5032
5033    /* Set the index of the cwInfo, which is better in terms of
5034     * efficiency. If RI<2, only 1 CW, hence btrCwIdx shall be 0 */
5035    if (ueDl->mimoInfo.ri < 2)
5036    {
5037       ueDl->mimoInfo.btrCwIdx = 0;
5038    }
5039    else
5040    {
5041       if (ueDl->mimoInfo.cwInfo[0].eff[ueDl->mimoInfo.cwInfo[0].noLyr-1] <\
5042           ueDl->mimoInfo.cwInfo[1].eff[ueDl->mimoInfo.cwInfo[1].noLyr-1])
5043       {
5044          ueDl->mimoInfo.btrCwIdx = 1;
5045       }
5046       else
5047       {
5048          ueDl->mimoInfo.btrCwIdx = 0;
5049       }
5050    }
5051
5052    RETVOID;
5053    }
5054
5055 #ifdef DL_LA
5056
5057 /**
5058  * @brief This function updates TX Scheme.
5059  *
5060  * @details
5061  *
5062  *     Function: rgSCHCheckAndSetTxScheme 
5063  *     Purpose:  This function determines the Maximum RBs
5064  *               a UE is eligible to get based on softbuffer
5065  *               limitation and cell->>>maxDlBwPerUe. The Codeword
5066  *               specific parameters like iTbs, eff and noLyrs
5067  *               are also set in this function. This function
5068  *               is called while UE configuration and UeDlCqiInd.
5069  *
5070  *     Invoked by: Scheduler
5071  *
5072  *  @param[in]  RgSchCellCb   *cell
5073  *  @param[in]  RgSchUeCb     *ue
5074  *  @return  Void
5075  *
5076  **/
5077 #ifdef ANSI
5078 PRIVATE Void rgSCHCheckAndSetTxScheme 
5079 (
5080 RgSchCellCb   *cell,
5081 RgSchUeCb     *ue
5082 )
5083 #else
5084 PRIVATE Void rgSCHCheckAndSetTxScheme(cell, ue)
5085 RgSchCellCb   *cell;
5086 RgSchUeCb     *ue;
5087 #endif
5088 {
5089    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
5090    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue ,cell);
5091    U8            cfi = cellSch->dl.currCfi;
5092    U8            maxiTbs;
5093    U8            cqiBasediTbs;
5094    U8            actualiTbs;
5095
5096    TRC2(rgSCHCheckAndSetTxScheme);
5097
5098    maxiTbs      = (*(RgSchCmnCqiToTbs*)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
5099                 [RG_SCH_CMN_MAX_CQI - 1];
5100    cqiBasediTbs = (ueDl->laCb[0].cqiBasediTbs)/100;
5101    actualiTbs   = ueDl->mimoInfo.cwInfo[0].iTbs[0];
5102
5103    if((actualiTbs < RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR) && (cqiBasediTbs >
5104      actualiTbs) && ((cqiBasediTbs - actualiTbs) > RG_SCH_TXSCHEME_CHNG_THRSHD)) 
5105    {
5106       RG_SCH_CMN_SET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
5107    }
5108    
5109    if(actualiTbs >= maxiTbs)
5110    {
5111       RG_SCH_CMN_UNSET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
5112    }
5113
5114    RETVOID;
5115 }
5116
5117 /**
5118  * @brief This function determines the allocation limits and
5119  *        parameters that aid in DL scheduling.
5120  *
5121  * @details
5122  *
5123  *     Function: rgSCHCmnDlSetUeAllocLmtLa
5124  *     Purpose:  This function determines the Maximum RBs
5125  *               a UE is eligible to get based on softbuffer
5126  *               limitation and cell->>>maxDlBwPerUe. The Codeword
5127  *               specific parameters like iTbs, eff and noLyrs
5128  *               are also set in this function. This function
5129  *               is called while UE configuration and UeDlCqiInd.
5130  *
5131  *     Invoked by: Scheduler
5132  *
5133  *  @param[in]  RgSchCellCb   *cell
5134  *  @param[in]  RgSchUeCb     *ue
5135  *  @return  Void
5136  *
5137  **/
5138 #ifdef ANSI
5139 PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa
5140 (
5141 RgSchCellCb   *cell,
5142 RgSchUeCb     *ue
5143 )
5144 #else
5145 PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa(cell, ue)
5146 RgSchCellCb   *cell;
5147 RgSchUeCb     *ue;
5148 #endif
5149 {
5150    U8            modOrder;
5151    U32           maxRb;
5152    U8            reportediTbs;
5153    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
5154    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
5155    U8            cfi = cellSch->dl.currCfi;
5156    U8            maxiTbs;
5157    U8            cwIdx = 0; 
5158
5159    TRC2(rgSCHCmnDlSetUeAllocLmtLa);
5160
5161    maxiTbs      = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1];
5162    if(ueDl->cqiFlag == TRUE)
5163    {
5164       for(cwIdx=0; cwIdx < RG_SCH_CMN_MAX_CW_PER_UE; cwIdx++)
5165       {
5166          S32 iTbsNew;
5167
5168          /* Calcluating the reported iTbs for code word 0 */
5169          reportediTbs = ue->ue5gtfCb.mcs; 
5170
5171          iTbsNew = (S32) reportediTbs;
5172
5173          if(!ueDl->laCb[cwIdx].notFirstCqi)
5174          {
5175             /* This is the first CQI report from UE */
5176             ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
5177             ueDl->laCb[cwIdx].notFirstCqi  =  TRUE;
5178          }
5179          else if ((RG_ITBS_DIFF(reportediTbs, ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0])) > 5)
5180          {
5181             /* Ignore this iTBS report and mark that last iTBS report was */
5182             /* ignored so that subsequently we reset the LA algorithm     */
5183             ueDl->laCb[cwIdx].lastiTbsIgnored = TRUE;
5184             ueDl->laCb[cwIdx].numLastiTbsIgnored++;
5185             if( ueDl->laCb[cwIdx].numLastiTbsIgnored > 10)
5186             {
5187                /* CQI reported by UE is not catching up. Reset the LA algorithm */
5188                ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
5189                ueDl->laCb[cwIdx].deltaiTbs = 0;
5190                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
5191                ueDl->laCb[cwIdx].numLastiTbsIgnored = 0;
5192             }
5193          }
5194          else
5195          {
5196             if (ueDl->laCb[cwIdx].lastiTbsIgnored != TRUE)
5197             {
5198                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
5199                      (80 * ueDl->laCb[cwIdx].cqiBasediTbs))/100;
5200             }
5201             else
5202             {
5203                /* Reset the LA as iTbs in use caught up with the value   */
5204                /* reported by UE.                                        */
5205                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
5206                      (80 * ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] * 100))/100;
5207                ueDl->laCb[cwIdx].deltaiTbs = 0;
5208                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
5209             }
5210          }
5211
5212          iTbsNew = (ueDl->laCb[cwIdx].cqiBasediTbs + ueDl->laCb[cwIdx].deltaiTbs)/100;
5213
5214          RG_SCH_CHK_ITBS_RANGE(iTbsNew, maxiTbs);       
5215
5216          ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] = RGSCH_MIN(iTbsNew, cell->thresholds.maxDlItbs);
5217          //ueDl->mimoInfo.cwInfo[cwIdx].iTbs[1] = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
5218 #ifdef RG_5GTF
5219          ue->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
5220          /*
5221          printf("reportediTbs[%d] cqiBasediTbs[%d] deltaiTbs[%d] iTbsNew[%d] mcs[%d] cwIdx[%d]\n", 
5222                  reportediTbs, ueDl->laCb[cwIdx].cqiBasediTbs, ueDl->laCb[cwIdx].deltaiTbs,
5223                  iTbsNew, ue->ue5gtfCb.mcs, cwIdx);
5224          */
5225 #endif
5226
5227          if((ue->mimoInfo.txMode != RGR_UE_TM_3) && (ue->mimoInfo.txMode != RGR_UE_TM_4))
5228          {
5229             break; 
5230          }
5231       }
5232       ueDl->cqiFlag = FALSE;
5233    } 
5234
5235
5236    RETVOID;
5237 }
5238 #endif
5239 /***********************************************************
5240  *
5241  *     Func : rgSCHCmnDlUeResetTemp
5242  *
5243  *     Desc : Reset whatever variables where temporarily used
5244  *            during UE scheduling.
5245  *
5246  *     Ret  : Void
5247  *
5248  *     Notes:
5249  *
5250  *     File :
5251  *
5252  **********************************************************/
5253 #ifdef ANSI
5254 PUBLIC Void rgSCHCmnDlHqPResetTemp 
5255 (
5256 RgSchDlHqProcCb         *hqP
5257 )
5258 #else
5259 PUBLIC Void rgSCHCmnDlHqPResetTemp(hqP)
5260 RgSchDlHqProcCb         *hqP;
5261 #endif
5262 {
5263
5264    TRC2(rgSCHCmnDlHqPResetTemp);
5265
5266    /* Fix: syed having a hqP added to Lists for RB assignment rather than
5267     * a UE, as adding UE was limiting handling some scenarios */ 
5268     hqP->reqLnk.node = (PTR)NULLP;
5269     hqP->schdLstLnk.node = (PTR)NULLP;
5270
5271    RETVOID;
5272 }  /* rgSCHCmnDlHqPResetTemp */
5273
5274 /***********************************************************
5275  *
5276  *     Func : rgSCHCmnDlUeResetTemp
5277  *
5278  *     Desc : Reset whatever variables where temporarily used
5279  *            during UE scheduling.
5280  *
5281  *     Ret  : Void
5282  *
5283  *     Notes:
5284  *
5285  *     File :
5286  *
5287  **********************************************************/
5288 #ifdef ANSI
5289 PUBLIC Void rgSCHCmnDlUeResetTemp
5290 (
5291 RgSchUeCb               *ue,
5292 RgSchDlHqProcCb         *hqP
5293 )
5294 #else
5295 PUBLIC Void rgSCHCmnDlUeResetTemp(ue, hqP)
5296 RgSchUeCb               *ue;
5297 RgSchDlHqProcCb         *hqP;
5298 #endif
5299 {
5300    RgSchDlRbAlloc  *allocInfo;
5301    RgSchCmnDlUe       *cmnUe = RG_SCH_CMN_GET_DL_UE(ue,hqP->hqE->cell);
5302 #ifdef LTE_ADV
5303    Void           *tmpCb;
5304 #endif
5305
5306    TRC2(rgSCHCmnDlUeResetTemp);
5307
5308    /* Fix : syed check for UE's existence was useless.
5309     * Instead we need to check that reset is done only for the 
5310     * information of a scheduled harq proc, which is cmnUe->proc.
5311     * Reset should not be done for non-scheduled hqP */
5312    if((cmnUe->proc == hqP) || (cmnUe->proc == NULLP))
5313    {
5314       cmnUe->proc = NULLP;
5315       allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, hqP->hqE->cell);
5316 #ifdef LTE_ADV
5317       tmpCb = allocInfo->laaCb;
5318 #endif
5319       cmMemset((U8 *)allocInfo, (U8)0, sizeof(RgSchDlRbAlloc));
5320       allocInfo->rnti = ue->ueId;
5321 #ifdef LTE_ADV
5322       allocInfo->laaCb = tmpCb;
5323 #endif
5324       /* Fix: syed moving this to a common function for both scheduled
5325        * and non-scheduled UEs */
5326       cmnUe->outStndAlloc = 0;
5327    }
5328    rgSCHCmnDlHqPResetTemp(hqP);
5329
5330    RETVOID;
5331 }  /* rgSCHCmnDlUeResetTemp */
5332
5333 /***********************************************************
5334  *
5335  *     Func : rgSCHCmnUlUeResetTemp
5336  *
5337  *     Desc : Reset whatever variables where temporarily used
5338  *            during UE scheduling.
5339  *
5340  *     Ret  : Void
5341  *
5342  *     Notes:
5343  *
5344  *     File :
5345  *
5346  **********************************************************/
5347 #ifdef ANSI
5348 PUBLIC Void rgSCHCmnUlUeResetTemp
5349 (
5350 RgSchCellCb             *cell,
5351 RgSchUeCb               *ue
5352 )
5353 #else
5354 PUBLIC Void rgSCHCmnUlUeResetTemp(cell, ue)
5355 RgSchCellCb             *cell;
5356 RgSchUeCb               *ue;
5357 #endif
5358 {
5359    RgSchCmnUlUe       *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue,cell);
5360
5361    TRC2(rgSCHCmnUlUeResetTemp);
5362
5363    cmMemset((U8 *)&cmnUlUe->alloc, (U8)0, sizeof(cmnUlUe->alloc));
5364
5365    RETVOID;
5366 }  /* rgSCHCmnUlUeResetTemp */
5367
5368
5369 \f
5370 /**
5371  * @brief This function fills the PDCCH information from dlProc.
5372  *
5373  * @details
5374  *
5375  *     Function: rgSCHCmnFillPdcch
5376  *     Purpose:  This function fills in the PDCCH information
5377  *               obtained from the RgSchDlRbAlloc
5378  *               during common channel scheduling(P, SI, RA - RNTI's).
5379  *
5380  *     Invoked by: Downlink Scheduler
5381  *
5382  *  @param[out] RgSchPdcch*       pdcch
5383  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5384  *  @return  Void
5385  *
5386  **/
5387 #ifdef ANSI
5388 PUBLIC Void rgSCHCmnFillPdcch
5389 (
5390 RgSchCellCb                *cell,
5391 RgSchPdcch                 *pdcch,
5392 RgSchDlRbAlloc             *rbAllocInfo
5393 )
5394 #else
5395 PUBLIC Void rgSCHCmnFillPdcch(cell, pdcch, rbAllocInfo)
5396 RgSchCellCb                *cell;
5397 RgSchPdcch                 *pdcch;
5398 RgSchDlRbAlloc             *rbAllocInfo;
5399 #endif
5400 {
5401
5402    TRC2(rgSCHCmnFillPdcch);
5403
5404    /* common channel pdcch filling,
5405     * only 1A and Local is supported */
5406    pdcch->rnti                       = rbAllocInfo->rnti;
5407    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
5408    switch(rbAllocInfo->dciFormat)
5409    {
5410 #ifdef RG_5GTF  /* ANOOP: ToDo: DCI format B1/B2 filling */
5411       case TFU_DCI_FORMAT_B1:
5412          {
5413             /* ToDo: Anoop */
5414             pdcch->dci.u.formatB1Info.formatType = 0;
5415             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].cmnGrnt.xPDSCHRange;
5416             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].cmnGrnt.rbAssign;
5417             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = 0;
5418             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5419             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = 0;
5420             //pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].ndi;
5421             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].cmnGrnt.rv;
5422             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5423             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5424             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5425             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5426             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5427             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5428             //TODO_SID: Need to update
5429             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5430             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5431             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5432             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5433             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5434             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5435             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].cmnGrnt.SCID;
5436             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5437             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5438             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5439
5440             break; /* case TFU_DCI_FORMAT_B1: */
5441          }
5442
5443       case TFU_DCI_FORMAT_B2:
5444          {
5445             //printf(" RG_5GTF:: Pdcch filling with DCI format B2\n");
5446             /* ToDo: Anoop */
5447             break; /* case TFU_DCI_FORMAT_B2: */
5448          }
5449 #endif
5450       case TFU_DCI_FORMAT_1A:
5451          pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
5452
5453          /*Nprb indication at PHY for common Ch
5454           *setting least significant bit of tpc field to 1 if
5455           nPrb=3 and 0 otherwise. */
5456          if (rbAllocInfo->nPrb == 3)
5457          {
5458             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 1;
5459          }
5460          else
5461          {
5462             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 0;
5463          }
5464          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
5465          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
5466          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
5467                                                                    rbAllocInfo->tbInfo[0].imcs;
5468          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = 0;
5469          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = 0;
5470          /* Add RIV CALC */
5471          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
5472             TFU_ALLOC_TYPE_RIV;
5473          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
5474             rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5475                   rbAllocInfo->allocInfo.raType2.rbStart,
5476                   rbAllocInfo->allocInfo.raType2.numRb);
5477
5478 #ifdef LTE_TDD
5479          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = \
5480                                                                            FALSE;
5481 #ifdef TFU_TDD
5482          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5483          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
5484 #endif
5485 #endif
5486          break; /* case TFU_DCI_FORMAT_1A: */
5487       case TFU_DCI_FORMAT_1:
5488          pdcch->dci.u.format1Info.tpcCmd = 0;
5489          /* Avoiding this check,as we dont support Type1 RA */
5490 #ifdef RG_UNUSED
5491          if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
5492          {
5493 #endif
5494             pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5495             pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5496                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5497                 & 0xff);
5498             pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5499                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5500                 & 0x00ff);
5501             pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5502                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5503                 & 0x0000ff);
5504             pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5505                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5506 #ifdef RG_UNUSED
5507          }
5508 #endif
5509          pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5510          pdcch->dci.u.format1Info.allocInfo.ndi = 0;
5511          pdcch->dci.u.format1Info.allocInfo.mcs = rbAllocInfo->tbInfo[0].imcs;
5512          pdcch->dci.u.format1Info.allocInfo.rv = 0;
5513 #ifdef TFU_TDD
5514          pdcch->dci.u.format1Info.dai = 1;
5515 #endif
5516          break;
5517       default:
5518          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Allocator's icorrect "
5519             "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5520          break;
5521    }
5522    RETVOID;
5523 }
5524
5525 #ifdef LTE_TDD
5526 /**
5527  * @brief This function finds whether the subframe is special subframe or not.
5528  *
5529  * @details
5530  *
5531  *     Function: rgSCHCmnIsSplSubfrm
5532  *     Purpose:  This function finds the subframe index of the special subframe
5533  *               and finds whether the current DL index matches it or not.
5534  *
5535  *     Invoked by: Scheduler
5536  *
5537  *  @param[in] U8                   splfrmCnt
5538  *  @param[in] U8                   curSubfrmIdx
5539  *  @param[in] U8                   periodicity
5540  *  @param[in] RgSchTddSubfrmInfo   *subfrmInfo
5541  *  @return  Bool
5542  *
5543  **/
5544 #ifdef ANSI
5545 PRIVATE Bool rgSCHCmnIsSplSubfrm
5546 (
5547 U8                   splfrmCnt,
5548 U8                   curSubfrmIdx,
5549 U8                   periodicity,
5550 RgSchTddSubfrmInfo   *subfrmInfo
5551 )
5552 #else
5553 PRIVATE Bool rgSCHCmnIsSplSubfrm(splfrmCnt, curSubfrmIdx, periodicity, subfrmInfo)
5554 U8                   splfrmCnt;
5555 U8                   curSubfrmIdx;
5556 U8                   periodicity;
5557 RgSchTddSubfrmInfo   *subfrmInfo;
5558 #endif
5559 {
5560    U8 dlSfCnt = 0;
5561    U8 splfrmIdx  = 0;
5562
5563    TRC2(rgSCHCmnIsSplSubfrm);
5564
5565    if(splfrmCnt > 0)
5566    {
5567       if(periodicity == RG_SCH_CMN_5_MS_PRD)
5568       {
5569          if(splfrmCnt%2)
5570          {
5571             dlSfCnt = ((splfrmCnt-1)/2) *\
5572                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5573             dlSfCnt = dlSfCnt + subfrmInfo->numFrmHf1;
5574          }
5575          else
5576          {
5577             dlSfCnt = (splfrmCnt/2) * \
5578                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5579          }
5580       }
5581       else
5582       {
5583          dlSfCnt = splfrmCnt * subfrmInfo->numFrmHf1;
5584       }
5585       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1 +\
5586                   (periodicity*splfrmCnt - dlSfCnt);
5587    }
5588    else
5589    {
5590       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1;
5591    }
5592
5593    if(splfrmIdx == curSubfrmIdx)
5594    {
5595       RETVALUE(TRUE);
5596    }
5597
5598    RETVALUE(FALSE);
5599 }
5600
5601 /**
5602  * @brief This function updates DAI or UL index.
5603  *
5604  * @details
5605  *
5606  *     Function: rgSCHCmnUpdHqAndDai
5607  *     Purpose:  Updates the DAI based on UL-DL Configuration
5608  *               index and UE. It also updates the HARQ feedback
5609  *               time and 'm' index.
5610  *
5611  *     Invoked by: TOM
5612  *
5613  *  @param[in]  RgDlHqProcCb  *hqP
5614  *  @param[in]  RgSchDlSf     *subFrm
5615  *  @param[in]  RgSchDlHqTbCb *tbCb
5616  *  @param[in]  U8            tbAllocIdx
5617  *  @return  Void
5618  *
5619  **/
5620 #ifdef ANSI
5621 PRIVATE Void rgSCHCmnUpdHqAndDai
5622 (
5623 RgSchDlHqProcCb   *hqP,
5624 RgSchDlSf         *subFrm,
5625 RgSchDlHqTbCb     *tbCb,
5626 U8                tbAllocIdx
5627 )
5628 #else
5629 PRIVATE Void rgSCHCmnUpdHqAndDai(hqP, subFrm, tbCb,tbAllocIdx)
5630 RgSchDlHqProcCb   *hqP;
5631 RgSchDlSf         *subFrm;
5632 RgSchDlHqTbCb     *tbCb;
5633 U8                tbAllocIdx;
5634 #endif
5635 {
5636    RgSchUeCb      *ue = hqP->hqE->ue;
5637    
5638    TRC2(rgSCHCmnUpdHqAndDai);
5639
5640    if(subFrm != NULLP)
5641    {
5642       /* set the time at which UE shall send the feedback
5643        * for this process */
5644       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5645             subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5646       tbCb->fdbkTime.subframe = subFrm->dlFdbkInfo.subframe;
5647       tbCb->m = subFrm->dlFdbkInfo.m;
5648    }
5649    else
5650    {
5651       /* set the time at which UE shall send the feedback
5652        * for this process */
5653       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5654             hqP->subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5655       tbCb->fdbkTime.subframe = hqP->subFrm->dlFdbkInfo.subframe;
5656       tbCb->m = hqP->subFrm->dlFdbkInfo.m;
5657    }
5658
5659    /* ccpu00132340-MOD- DAI need to be updated for first TB only*/
5660    if(ue && !tbAllocIdx)
5661    {
5662       Bool   havePdcch = (tbCb->hqP->pdcch ? TRUE : FALSE);
5663       U8     dlDai;
5664       
5665       dlDai = rgSCHCmnUpdDai(ue, &tbCb->fdbkTime, tbCb->m, havePdcch,tbCb->hqP,
5666             &tbCb->dai);
5667       if(havePdcch)
5668       {/* Non SPS occasions */
5669          tbCb->hqP->pdcch->dlDai = dlDai;
5670          /* hqP->ulDai is used for N1 resource filling
5671           * when SPS occaions present in a bundle */
5672          tbCb->hqP->ulDai = tbCb->dai;
5673          tbCb->hqP->dlDai = dlDai;
5674       }
5675    }
5676
5677    /* Updatijng pucchFdbkIdx for both PUCCH or PUSCH
5678       fdbk reception */
5679    tbCb->pucchFdbkIdx = tbCb->hqP->ulDai;
5680
5681    RETVOID;
5682 }
5683
5684
5685 /**
5686  * @brief This function updates DAI or UL index.
5687  *
5688  * @details
5689  *
5690  *     Function: rgSCHCmnUpdDai
5691  *     Purpose:  Updates the DAI in the ack-nack info, a valid
5692  *               ue should be passed
5693  *
5694  *     Invoked by: TOM
5695  *
5696  *  @param[in]  RgDlHqProcCb  *hqP
5697  *  @param[in]  RgSchDlSf     *subFrm
5698  *  @param[in]  RgSchDlHqTbCb *tbCb
5699  *  @return  U8 dlDai 
5700  *
5701  **/
5702 #ifdef ANSI
5703 PUBLIC U8 rgSCHCmnUpdDai
5704 (
5705 RgSchUeCb         *ue,
5706 CmLteTimingInfo   *fdbkTime,
5707 U8                 m,
5708 Bool               havePdcch,
5709 RgSchDlHqProcCb   *hqP,
5710 U8                *ulDai
5711 )
5712 #else
5713 PUBLIC U8 rgSCHCmnUpdDai(ue, fdbkTime, m, havePdcch,tbCb,servCellId,hqP,ulDai)
5714 RgSchUeCb         *ue;
5715 CmLteTimingInfo   *fdbkTime;
5716 U8                 m;
5717 Bool               havePdcch;
5718 RgSchDlHqProcCb   *hqP;
5719 U8                *ulDai;
5720 #endif
5721 {
5722    RgSchTddANInfo *anInfo;
5723    U8             servCellIdx;
5724    U8             ackNackFdbkArrSize;
5725   
5726
5727    TRC2(rgSCHCmnUpdDai);
5728
5729    if(hqP != NULLP)
5730    {/* Non SPS */
5731 #ifdef LTE_ADV
5732       servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5733             hqP->hqE->cell->cellId,
5734             ue);
5735 #else
5736      servCellIdx = RGSCH_PCELL_INDEX;
5737 #endif
5738       ackNackFdbkArrSize = hqP->hqE->cell->ackNackFdbkArrSize;
5739    }else
5740    {/* SPS on primary cell */
5741       servCellIdx = RGSCH_PCELL_INDEX;
5742       ackNackFdbkArrSize = ue->cell->ackNackFdbkArrSize;
5743    }
5744
5745
5746    anInfo = rgSCHUtlGetUeANFdbkInfo(ue, fdbkTime,servCellIdx);
5747
5748    /* If no ACK/NACK feedback already present, create a new one */
5749    if(NULLP == anInfo)
5750    {
5751       anInfo = &ue->cellInfo[servCellIdx]->anInfo[ue->cellInfo[servCellIdx]->nextFreeANIdx];
5752       anInfo->sfn = fdbkTime->sfn;
5753       anInfo->subframe = fdbkTime->subframe;
5754       anInfo->latestMIdx = m;
5755       /* Fixing DAI value - ccpu00109162 */
5756       /* Handle TDD case as in MIMO definition of the function */
5757       anInfo->ulDai = 1;
5758       if (havePdcch)
5759       {
5760          anInfo->dlDai = 1;
5761       }
5762       anInfo->isSpsOccasion = FALSE;
5763       /* set the free Index to store  Ack/Nack Information*/
5764       ue->cellInfo[servCellIdx]->nextFreeANIdx = (ue->cellInfo[servCellIdx]->nextFreeANIdx + 1) %
5765          ackNackFdbkArrSize;
5766
5767    }
5768    else
5769    {
5770       anInfo->latestMIdx = m;
5771       /* Fixing DAI value - ccpu00109162 */
5772       /* Handle TDD case as in MIMO definition of the function */
5773       anInfo->ulDai = anInfo->ulDai + 1;
5774       if (havePdcch)
5775       {
5776          anInfo->dlDai = anInfo->dlDai + 1;
5777       }
5778    }
5779 #ifdef LTE_ADV
5780    /* ignoring the Scell check,
5781     * for primary cell this field is unused*/
5782    if(hqP != NULLP)
5783    {/* SPS*/
5784       anInfo->n1ResTpcIdx = hqP->tpc;
5785    }
5786
5787    if(ulDai)
5788    {/* As this not required for release pdcch */
5789       *ulDai = anInfo->ulDai;
5790    }
5791 #endif
5792    RETVALUE(anInfo->dlDai);
5793
5794 }
5795 #endif /* ifdef LTE_TDD */
5796
5797 PUBLIC U32 rgHqRvRetxCnt[4][2];
5798 PUBLIC U32 rgUlrate_grant;
5799
5800 /**
5801  * @brief This function fills the HqP TB with rbAllocInfo.
5802  *
5803  * @details
5804  *
5805  *     Function: rgSCHCmnFillHqPTb
5806  *     Purpose:  This function fills in the HqP TB with rbAllocInfo.
5807  *
5808  *     Invoked by: rgSCHCmnFillHqPTb
5809  *
5810  *  @param[in]  RgSchCellCb*      cell
5811  *  @param[in]  RgSchDlRbAlloc    *rbAllocInfo,
5812  *  @param[in]  U8                tbAllocIdx
5813  *  @param[in]  RgSchPdcch        *pdcch
5814  *  @return  Void
5815  *
5816  **/
5817 #ifdef LTEMAC_SPS
5818 #ifdef ANSI
5819 PUBLIC Void rgSCHCmnFillHqPTb
5820 (
5821 RgSchCellCb                *cell,
5822 RgSchDlRbAlloc             *rbAllocInfo,
5823 U8                         tbAllocIdx,
5824 RgSchPdcch                 *pdcch
5825 )
5826 #else
5827 PUBLIC Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch)
5828 RgSchCellCb                *cell;
5829 RgSchDlRbAlloc             *rbAllocInfo;
5830 U8                         tbAllocIdx;
5831 RgSchPdcch                 *pdcch;
5832 #endif
5833 #else
5834 #ifdef ANSI
5835 PRIVATE Void rgSCHCmnFillHqPTb
5836 (
5837 RgSchCellCb                *cell,
5838 RgSchDlRbAlloc             *rbAllocInfo,
5839 U8                         tbAllocIdx,
5840 RgSchPdcch                 *pdcch
5841 )
5842 #else
5843 PRIVATE Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch)
5844 RgSchCellCb                *cell;
5845 RgSchDlRbAlloc             *rbAllocInfo;
5846 U8                         tbAllocIdx;
5847 RgSchPdcch                 *pdcch;
5848 #endif
5849 #endif /* LTEMAC_SPS */
5850 {
5851    RgSchCmnDlCell     *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5852    RgSchDlTbAllocInfo *tbAllocInfo = &rbAllocInfo->tbInfo[tbAllocIdx];
5853    RgSchDlHqTbCb      *tbInfo = tbAllocInfo->tbCb;
5854    RgSchDlHqProcCb    *hqP = tbInfo->hqP;
5855
5856    TRC2(rgSCHCmnFillHqPTb);
5857
5858    /*ccpu00120365-ADD-if tb is disabled, set mcs=0,rv=1.
5859     * Relevant for DCI format 2 & 2A as per 36.213-7.1.7.2
5860     */
5861    if ( tbAllocInfo->isDisabled)
5862    {
5863
5864       tbInfo->dlGrnt.iMcs = 0;
5865       tbInfo->dlGrnt.rv   = 1;
5866    }
5867    /* Fill for TB retransmission */
5868    else if (tbInfo->txCntr > 0)
5869    {
5870
5871       tbInfo->timingInfo = cmnCellDl->time;
5872       /* Fix */
5873       if ((tbInfo->isAckNackDtx == TFU_HQFDB_DTX)) 
5874       {
5875          tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;         
5876          rgHqRvRetxCnt[tbInfo->dlGrnt.rv][tbInfo->tbIdx]++;
5877       }
5878       else
5879       {
5880          tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[++(tbInfo->ccchSchdInfo.rvIdx) & 0x03];
5881       }
5882
5883       /* fill the scheduler information of hqProc */
5884       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5885       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx,hqP->tbInfo,tbInfo->tbIdx );
5886       rgSCHDhmHqTbRetx(hqP->hqE, tbInfo->timingInfo, hqP, tbInfo->tbIdx);
5887    }
5888    /* Fill for TB transmission */
5889    else
5890    {
5891       /* Fill the HqProc */
5892       tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;
5893       tbInfo->tbSz = tbAllocInfo->bytesAlloc;
5894       tbInfo->timingInfo = cmnCellDl->time;
5895
5896       tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[0];
5897       /* fill the scheduler information of hqProc */
5898       tbInfo->ccchSchdInfo.rvIdx = 0;
5899       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5900       /* DwPts Scheduling Changes Start */
5901       /* DwPts Scheduling Changes End */ 
5902       cell->measurements.dlBytesCnt += tbAllocInfo->bytesAlloc;
5903    }
5904
5905    /*ccpu00120365:-ADD-only add to subFrm list if tb is not disabled */
5906    if ( tbAllocInfo->isDisabled == FALSE )
5907    {
5908       /* Set the number of transmitting SM layers for this TB */
5909       tbInfo->numLyrs = tbAllocInfo->noLyr;
5910       /* Set the TB state as WAITING to indicate TB has been
5911        * considered for transmission */
5912       tbInfo->state  = HQ_TB_WAITING;
5913       hqP->subFrm = rbAllocInfo->dlSf;
5914       tbInfo->hqP->pdcch  = pdcch;
5915       //tbInfo->dlGrnt.numRb = rbAllocInfo->rbsAlloc;
5916       rgSCHUtlDlHqPTbAddToTx(hqP->subFrm, hqP, tbInfo->tbIdx);
5917    }
5918    RETVOID;
5919 }
5920
5921 /**
5922  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5923  *
5924  * @details
5925  *
5926  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5927  *     Purpose:  This function fills in the PDCCH information
5928  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5929  *               for dedicated service scheduling. It also
5930  *               obtains TPC to be filled in from the power module.
5931  *               Assign the PDCCH to HQProc.
5932  *
5933  *     Invoked by: Downlink Scheduler
5934  *
5935  *  @param[in]  RgSchCellCb*      cell
5936  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5937  *  @param[in]  RgDlHqProc*       hqP
5938  *  @param[out]  RgSchPdcch        *pdcch
5939  *  @param[in]   U8               tpc
5940  *  @return  Void
5941  *
5942  **/
5943 #ifdef ANSI
5944 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmtB1B2
5945 (
5946 RgSchCellCb                *cell,
5947 RgSchDlRbAlloc             *rbAllocInfo,
5948 RgSchDlHqProcCb            *hqP,
5949 RgSchPdcch                 *pdcch,
5950 U8                         tpc
5951 )
5952 #else
5953 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, pdcch, tpc)
5954 RgSchCellCb                *cell;
5955 RgSchDlRbAlloc             *rbAllocInfo;
5956 RgSchDlHqProcCb            *hqP;
5957 RgSchPdcch                 *pdcch;
5958 U8                         tpc;
5959 #endif
5960 {
5961
5962    TRC2(rgSCHCmnFillHqPPdcchDciFrmtB1B2)
5963
5964    rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);   
5965    //Currently hardcoding values here.
5966    //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
5967    switch(rbAllocInfo->dciFormat)
5968    {
5969       case TFU_DCI_FORMAT_B1:
5970          {
5971             pdcch->dci.u.formatB1Info.formatType = 0;
5972             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5973             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5974             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5975             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5976             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5977             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5978             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5979             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5980             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5981             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5982             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5983             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5984             //TODO_SID: Need to update
5985             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5986             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5987             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5988             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5989             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5990             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5991             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5992             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5993             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5994             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5995             break;
5996          }
5997       case TFU_DCI_FORMAT_B2:
5998          {
5999             pdcch->dci.u.formatB2Info.formatType = 1;
6000             pdcch->dci.u.formatB2Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
6001             pdcch->dci.u.formatB2Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
6002             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
6003             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
6004             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6005             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6006             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
6007             pdcch->dci.u.formatB2Info.CSI_BSI_BRI_Req = 0;
6008             pdcch->dci.u.formatB2Info.CSIRS_BRRS_TxTiming = 0;
6009             pdcch->dci.u.formatB2Info.CSIRS_BRRS_SymbIdx = 0;
6010             pdcch->dci.u.formatB2Info.CSIRS_BRRS_ProcInd = 0;
6011             pdcch->dci.u.formatB2Info.xPUCCH_TxTiming = 0;
6012             //TODO_SID: Need to update
6013             pdcch->dci.u.formatB2Info.freqResIdx_xPUCCH = 0;
6014             pdcch->dci.u.formatB2Info.beamSwitch  = 0;
6015             pdcch->dci.u.formatB2Info.SRS_Config = 0;
6016             pdcch->dci.u.formatB2Info.SRS_Symbol = 0;
6017             //TODO_SID: Need to check.Currently setting 4(2 layer, ports(8,9) w/o OCC).
6018             pdcch->dci.u.formatB2Info.AntPorts_numLayers = 4;
6019             pdcch->dci.u.formatB2Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
6020             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
6021             pdcch->dci.u.formatB2Info.tpcCmd = 1; //tpc;
6022             pdcch->dci.u.formatB2Info.DL_PCRS = 0;
6023             break;
6024          }
6025          default:
6026             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId," 5GTF_ERROR Allocator's icorrect "
6027                "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
6028             break;
6029    }
6030    
6031    RETVOID;
6032 }
6033
6034 extern U32 totPcellSCell;
6035 extern U32 addedForScell;
6036 extern U32 addedForScell1;
6037 extern U32 addedForScell2;
6038 /**
6039  * @brief This function fills the PDCCH information from dlProc.
6040  *
6041  * @details
6042  *
6043  *     Function: rgSCHCmnFillHqPPdcch
6044  *     Purpose:  This function fills in the PDCCH information
6045  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6046  *               for dedicated service scheduling. It also
6047  *               obtains TPC to be filled in from the power module.
6048  *               Assign the PDCCH to HQProc.
6049  *
6050  *     Invoked by: Downlink Scheduler
6051  *
6052  *  @param[in]  RgSchCellCb*      cell
6053  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6054  *  @param[in]  RgDlHqProc*       hqP
6055  *  @return  Void
6056  *
6057  **/
6058 #ifdef ANSI
6059 PUBLIC Void rgSCHCmnFillHqPPdcch
6060 (
6061 RgSchCellCb                *cell,
6062 RgSchDlRbAlloc             *rbAllocInfo,
6063 RgSchDlHqProcCb            *hqP
6064 )
6065 #else
6066 PUBLIC Void rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP)
6067 RgSchCellCb                *cell;
6068 RgSchDlRbAlloc             *rbAllocInfo;
6069 RgSchDlHqProcCb            *hqP;
6070 #endif
6071 {
6072    RgSchCmnDlCell     *cmnCell = RG_SCH_CMN_GET_DL_CELL(cell);
6073    RgSchPdcch         *pdcch = rbAllocInfo->pdcch;
6074    U8                 tpc = 1;
6075
6076    TRC2(rgSCHCmnFillHqPPdcch);
6077
6078    if (hqP->hqE->ue)
6079    {
6080 #ifdef LTE_ADV
6081       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6082       {
6083          tpc = hqP->tpc;
6084       }
6085       else
6086 #endif
6087       {
6088          tpc = rgSCHPwrPucchTpcForUe(cell, hqP->hqE->ue);
6089       }
6090       /* Fix: syed moving this to a common function for both scheduled
6091        * and non-scheduled UEs */
6092
6093       pdcch->ue = hqP->hqE->ue;
6094       if (hqP->hqE->ue->csgMmbrSta == FALSE)
6095       {
6096          cmnCell->ncsgPrbCnt += rbAllocInfo->rbsAlloc;
6097       }
6098       cmnCell->totPrbCnt += rbAllocInfo->rbsAlloc;
6099 #ifdef TENB_STATS
6100       {
6101          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlPrbUsg += 
6102             rbAllocInfo->rbsAlloc;
6103          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw0iTbs += 
6104             rbAllocInfo->tbInfo[0].iTbs;
6105          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw0iTbs ++; 
6106          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
6107             (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6108
6109 #ifdef LTE_ADV
6110       totPcellSCell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6111       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6112       {
6113          addedForScell +=  (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6114          addedForScell1 += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6115 /*
6116          printf (" Hqp %d cell %d addedForScell %lu addedForScell1 %lu sfn:sf %d:%d \n",
6117          hqP->procId,
6118          hqP->hqE->cell->cellId,
6119          addedForScell,
6120          addedForScell1,
6121          cell->crntTime.sfn,
6122          cell->crntTime.subframe);
6123          */
6124       }
6125 #endif
6126          hqP->hqE->cell->tenbStats->sch.dlPrbUsage[0] += 
6127             rbAllocInfo->rbsAlloc;
6128          hqP->hqE->cell->tenbStats->sch.dlSumCw0iTbs += 
6129             rbAllocInfo->tbInfo[0].iTbs;
6130          hqP->hqE->cell->tenbStats->sch.dlNumCw0iTbs ++; 
6131          hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
6132             (rbAllocInfo->tbInfo[0].bytesAlloc << 3); 
6133          if (rbAllocInfo->tbInfo[1].schdlngForTb)
6134          {
6135             hqP->hqE->cell->tenbStats->sch.dlSumCw1iTbs += 
6136                rbAllocInfo->tbInfo[1].iTbs;
6137             hqP->hqE->cell->tenbStats->sch.dlNumCw1iTbs ++; 
6138             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw1iTbs += 
6139                rbAllocInfo->tbInfo[1].iTbs;
6140             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw1iTbs ++; 
6141             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
6142                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6143
6144
6145 #ifdef LTE_ADV
6146             if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6147             {
6148                addedForScell +=  (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6149                addedForScell2 += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6150 /*
6151          printf (" Hqp %d cell %d addedForScell %lu addedForScell2 %lu \n",
6152          hqP->procId,
6153          hqP->hqE->cell->cellId,
6154          addedForScell,
6155          addedForScell2);
6156          */
6157             }
6158             totPcellSCell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6159 #endif
6160
6161
6162             hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
6163                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6164          }
6165          /*
6166          printf ("add DL TPT is %lu  sfn:sf %d:%d \n", hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt ,
6167          cell->crntTime.sfn,
6168          cell->crntTime.subframe);
6169          */
6170       }
6171 #endif
6172    }
6173
6174    pdcch->rnti                       = rbAllocInfo->rnti;
6175    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
6176    /* Update subframe and pdcch info in HqTb control block */
6177    switch(rbAllocInfo->dciFormat)
6178    {
6179 #ifdef RG_5GTF  
6180       case TFU_DCI_FORMAT_B1:
6181       case TFU_DCI_FORMAT_B2:
6182            {
6183         // printf(" RG_5GTF:: Pdcch filling with DCI format B1/B2\n");
6184               rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, \
6185                     pdcch, tpc);
6186               break;
6187            }
6188 #endif
6189       default:
6190          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6191             "Allocator's incorrect dciForamt Fill for RNTI:%d",rbAllocInfo->rnti);
6192          break;
6193    }
6194    RETVOID;
6195 }
6196
6197 /**
6198  * @brief This function fills the PDCCH DCI format 1 information from dlProc.
6199  *
6200  * @details
6201  *
6202  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1
6203  *     Purpose:  This function fills in the PDCCH information
6204  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6205  *               for dedicated service scheduling. It also
6206  *               obtains TPC to be filled in from the power module.
6207  *               Assign the PDCCH to HQProc.
6208  *
6209  *     Invoked by: Downlink Scheduler
6210  *
6211  *  @param[in]  RgSchCellCb*      cell
6212  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6213  *  @param[in]  RgDlHqProc*       hqP
6214  *  @param[out]  RgSchPdcch        *pdcch
6215  *  @param[in]   U8               tpc
6216  *  @return  Void
6217  *
6218  **/
6219 #ifdef ANSI
6220 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1
6221 (
6222 RgSchCellCb                *cell,
6223 RgSchDlRbAlloc             *rbAllocInfo,
6224 RgSchDlHqProcCb            *hqP,
6225 RgSchPdcch                 *pdcch,
6226 U8                         tpc
6227 )
6228 #else
6229 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1(cell, rbAllocInfo, hqP, pdcch, tpc)
6230 RgSchCellCb                *cell;
6231 RgSchDlRbAlloc             *rbAllocInfo;
6232 RgSchDlHqProcCb            *hqP;
6233 RgSchPdcch                 *pdcch;
6234 U8                         tpc;
6235 #endif
6236 {
6237
6238 #ifdef LTE_TDD
6239    RgSchTddANInfo     *anInfo;
6240 #endif
6241
6242 #ifdef LTEMAC_SPS
6243 /* For activation or reactivation,
6244  * Harq ProcId should be 0 */
6245    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6246 #endif
6247
6248     TRC2(rgSCHCmnFillHqPPdcchDciFrmt1)
6249
6250     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6251     pdcch->dci.u.format1Info.tpcCmd = tpc;
6252      /* Avoiding this check,as we dont support Type1 RA */
6253 #ifdef RG_UNUSED
6254     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6255     {
6256 #endif
6257        pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
6258        pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
6259          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6260                & 0xff);
6261        pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
6262          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6263                & 0x00ff);
6264        pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
6265            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6266                & 0x0000ff);
6267        pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
6268            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6269 #ifdef RG_UNUSED
6270     }
6271 #endif
6272 #ifdef LTEMAC_SPS
6273     if ((!(hqP->tbInfo[0].txCntr)) &&
6274        (cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6275          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6276          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)))
6277        )
6278     {
6279        pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
6280     }
6281     else
6282     {
6283       pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
6284     }
6285 #else
6286     pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
6287 #endif
6288
6289     pdcch->dci.u.format1Info.allocInfo.ndi = 
6290                         rbAllocInfo->tbInfo[0].tbCb->ndi;
6291     pdcch->dci.u.format1Info.allocInfo.mcs = 
6292                         rbAllocInfo->tbInfo[0].imcs;
6293     pdcch->dci.u.format1Info.allocInfo.rv = 
6294                         rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6295 #ifdef LTE_TDD
6296        if(hqP->hqE->ue != NULLP)
6297        {
6298 #ifdef LTE_ADV
6299            U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6300                                         hqP->hqE->cell->cellId,
6301                                         hqP->hqE->ue);
6302
6303            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6304                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6305 #else
6306            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6307                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6308 #endif
6309 #ifdef TFU_TDD
6310           if(anInfo)
6311           {
6312              pdcch->dci.u.format1Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6313           }
6314           else
6315           {
6316                /* Fixing DAI value - ccpu00109162 */
6317              pdcch->dci.u.format1Info.dai = RG_SCH_MAX_DAI_IDX;
6318           }
6319 #endif
6320        }
6321        else
6322        {
6323             /* always 0 for RACH */
6324            pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
6325 #ifdef TFU_TDD
6326             /* Fixing DAI value - ccpu00109162 */
6327            pdcch->dci.u.format1Info.dai = 1;
6328 #endif
6329        }
6330 #endif
6331  
6332
6333        RETVOID;
6334 }
6335 /**
6336  * @brief This function fills the PDCCH DCI format 1A information from dlProc.
6337  *
6338  * @details
6339  *
6340  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1A
6341  *     Purpose:  This function fills in the PDCCH information
6342  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6343  *               for dedicated service scheduling. It also
6344  *               obtains TPC to be filled in from the power module.
6345  *               Assign the PDCCH to HQProc.
6346  *
6347  *     Invoked by: Downlink Scheduler
6348  *
6349  *  @param[in]  RgSchCellCb*      cell
6350  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6351  *  @param[in]  RgDlHqProc*       hqP
6352  *  @param[out]  RgSchPdcch        *pdcch
6353  *  @param[in]   U8               tpc
6354  *  @return  Void
6355  *
6356  **/
6357 #ifdef ANSI
6358 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A
6359 (
6360 RgSchCellCb                *cell,
6361 RgSchDlRbAlloc             *rbAllocInfo,
6362 RgSchDlHqProcCb            *hqP,
6363 RgSchPdcch                 *pdcch,
6364 U8                         tpc
6365 )
6366 #else
6367 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A(cell, rbAllocInfo, hqP, pdcch, tpc)
6368 RgSchCellCb                *cell;
6369 RgSchDlRbAlloc             *rbAllocInfo;
6370 RgSchDlHqProcCb            *hqP;
6371 RgSchPdcch                 *pdcch;
6372 U8                         tpc;
6373 #endif
6374 {
6375
6376 #ifdef LTE_TDD
6377    RgSchTddANInfo     *anInfo;
6378 #endif
6379
6380 #ifdef LTEMAC_SPS
6381    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6382 #endif
6383
6384     TRC2(rgSCHCmnFillHqPPdcchDciFrmt1A)
6385
6386     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6387     pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
6388     pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = tpc;
6389     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
6390       rbAllocInfo->tbInfo[0].imcs;
6391     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = TRUE;
6392 #ifdef LTEMAC_SPS
6393     if ((!(hqP->tbInfo[0].txCntr)) &&
6394        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6395          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6396          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6397        ))
6398     {
6399        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = 0;
6400     }
6401     else
6402     {
6403       pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val
6404                                                 = hqP->procId;
6405     }
6406 #else
6407     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val =
6408                                               hqP->procId;
6409 #endif
6410     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = \
6411        rbAllocInfo->tbInfo[0].tbCb->ndi;
6412     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = \
6413        rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6414          /* As of now, we do not support Distributed allocations */
6415     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
6416     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
6417     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
6418             TFU_ALLOC_TYPE_RIV;
6419     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
6420     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
6421                   rbAllocInfo->allocInfo.raType2.rbStart,
6422                   rbAllocInfo->allocInfo.raType2.numRb);
6423 #ifdef LTE_TDD
6424     if(hqP->hqE->ue != NULLP)
6425     {
6426 #ifdef LTE_ADV
6427        U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6428                                         hqP->hqE->cell->cellId,
6429                                         hqP->hqE->ue);
6430        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6431                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6432 #else
6433        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6434                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6435 #endif
6436 #ifdef TFU_TDD
6437        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
6438        if(anInfo)
6439        {
6440           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 
6441                               RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6442        }
6443        else
6444        {
6445           /* Fixing DAI value - ccpu00109162 */
6446           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = RG_SCH_MAX_DAI_IDX;
6447           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6448                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6449                     rbAllocInfo->rnti);
6450        }
6451 #endif
6452     }
6453     else
6454     {
6455             /* always 0 for RACH */
6456        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres
6457                                                                      = FALSE;
6458 #ifdef TFU_TDD
6459        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
6460             /* Fixing DAI value - ccpu00109162 */
6461        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
6462 #endif
6463     }
6464 #endif
6465  
6466     RETVOID;
6467 }
6468 /**
6469  * @brief This function fills the PDCCH DCI format 1B information from dlProc.
6470  *
6471  * @details
6472  *
6473  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1B
6474  *     Purpose:  This function fills in the PDCCH information
6475  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6476  *               for dedicated service scheduling. It also
6477  *               obtains TPC to be filled in from the power module.
6478  *               Assign the PDCCH to HQProc.
6479  *
6480  *     Invoked by: Downlink Scheduler
6481  *
6482  *  @param[in]  RgSchCellCb*      cell
6483  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6484  *  @param[in]  RgDlHqProc*       hqP
6485  *  @param[out]  RgSchPdcch        *pdcch
6486  *  @param[in]   U8               tpc
6487  *  @return  Void
6488  *
6489  **/
6490 #ifdef ANSI
6491 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B
6492 (
6493 RgSchCellCb                *cell,
6494 RgSchDlRbAlloc             *rbAllocInfo,
6495 RgSchDlHqProcCb            *hqP,
6496 RgSchPdcch                 *pdcch,
6497 U8                         tpc
6498 )
6499 #else
6500 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B(cell, rbAllocInfo, hqP, pdcch, tpc)
6501 RgSchCellCb                *cell;
6502 RgSchDlRbAlloc             *rbAllocInfo;
6503 RgSchDlHqProcCb            *hqP;
6504 RgSchPdcch                 *pdcch;
6505 U8                         tpc;
6506 #endif
6507 {
6508
6509 #ifdef LTE_TDD
6510    RgSchTddANInfo     *anInfo;
6511 #endif
6512
6513 #ifdef LTEMAC_SPS
6514    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6515 #endif
6516
6517     TRC2(rgSCHCmnFillHqPPdcchDciFrmt1B)
6518
6519     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6520     pdcch->dci.u.format1bInfo.tpcCmd  = tpc;
6521     pdcch->dci.u.format1bInfo.allocInfo.mcs     = \
6522            rbAllocInfo->tbInfo[0].imcs;
6523 #ifdef LTEMAC_SPS
6524     if ((!(hqP->tbInfo[0].txCntr)) &&
6525        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6526          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6527          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6528        ))
6529     {
6530        pdcch->dci.u.format1bInfo.allocInfo.harqProcId = 0;
6531     }
6532     else
6533     {
6534       pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
6535     }
6536 #else
6537     pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
6538 #endif
6539     pdcch->dci.u.format1bInfo.allocInfo.ndi     = \
6540           rbAllocInfo->tbInfo[0].tbCb->ndi;
6541     pdcch->dci.u.format1bInfo.allocInfo.rv      = \
6542            rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6543          /* As of now, we do not support Distributed allocations */
6544     pdcch->dci.u.format1bInfo.allocInfo.isLocal = TRUE;
6545     pdcch->dci.u.format1bInfo.allocInfo.nGap2.pres = NOTPRSNT;
6546     pdcch->dci.u.format1bInfo.allocInfo.alloc.type =
6547             TFU_ALLOC_TYPE_RIV;
6548     pdcch->dci.u.format1bInfo.allocInfo.alloc.u.riv =
6549     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
6550                   rbAllocInfo->allocInfo.raType2.rbStart,
6551                   rbAllocInfo->allocInfo.raType2.numRb);
6552          /* Fill precoding Info */
6553     pdcch->dci.u.format1bInfo.allocInfo.pmiCfm = \
6554                rbAllocInfo->mimoAllocInfo.precIdxInfo >> 4;
6555     pdcch->dci.u.format1bInfo.allocInfo.tPmi   = \
6556                rbAllocInfo->mimoAllocInfo.precIdxInfo & 0x0F;
6557 #ifdef LTE_TDD
6558     if(hqP->hqE->ue != NULLP)
6559     {
6560 #ifdef LTE_ADV
6561        U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6562                                         hqP->hqE->cell->cellId,
6563                                         hqP->hqE->ue);
6564        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6565              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6566 #else
6567        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6568              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6569 #endif
6570 #ifdef TFU_TDD
6571        if(anInfo)
6572        {
6573           pdcch->dci.u.format1bInfo.dai = 
6574                          RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6575        }
6576        else
6577        {
6578           pdcch->dci.u.format1bInfo.dai = RG_SCH_MAX_DAI_IDX;
6579           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6580                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6581                    rbAllocInfo->rnti);
6582        }
6583 #endif
6584     }
6585 #endif
6586        
6587     RETVOID;
6588
6589 }
6590 /**
6591  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
6592  *
6593  * @details
6594  *
6595  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
6596  *     Purpose:  This function fills in the PDCCH information
6597  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6598  *               for dedicated service scheduling. It also
6599  *               obtains TPC to be filled in from the power module.
6600  *               Assign the PDCCH to HQProc.
6601  *
6602  *     Invoked by: Downlink Scheduler
6603  *
6604  *  @param[in]  RgSchCellCb*      cell
6605  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6606  *  @param[in]  RgDlHqProc*       hqP
6607  *  @param[out]  RgSchPdcch        *pdcch
6608  *  @param[in]   U8               tpc
6609  *  @return  Void
6610  *
6611  **/
6612 #ifdef ANSI
6613 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2
6614 (
6615 RgSchCellCb                *cell,
6616 RgSchDlRbAlloc             *rbAllocInfo,
6617 RgSchDlHqProcCb            *hqP,
6618 RgSchPdcch                 *pdcch,
6619 U8                         tpc
6620 )
6621 #else
6622 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2(cell, rbAllocInfo, hqP, pdcch, tpc)
6623 RgSchCellCb                *cell;
6624 RgSchDlRbAlloc             *rbAllocInfo;
6625 RgSchDlHqProcCb            *hqP;
6626 RgSchPdcch                 *pdcch;
6627 U8                         tpc;
6628 #endif
6629 {
6630
6631 #ifdef LTE_TDD
6632    RgSchTddANInfo     *anInfo;
6633 #endif
6634
6635 #ifdef LTEMAC_SPS
6636 /* ccpu00119023-ADD-For activation or reactivation,
6637  * Harq ProcId should be 0 */
6638    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6639 #endif
6640
6641     TRC2(rgSCHCmnFillHqPPdcchDciFrmt2)
6642
6643     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6644     /*ccpu00120365:-ADD-call also if tb is disabled */
6645     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6646         rbAllocInfo->tbInfo[1].isDisabled)
6647     {
6648         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6649     }
6650     pdcch->dci.u.format2Info.tpcCmd = tpc;
6651          /* Avoiding this check,as we dont support Type1 RA */
6652 #ifdef RG_UNUSED
6653     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6654     {
6655 #endif
6656         pdcch->dci.u.format2Info.allocInfo.isAllocType0 = TRUE;
6657         pdcch->dci.u.format2Info.allocInfo.resAllocMap[0] =
6658           ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6659                & 0xff);
6660         pdcch->dci.u.format2Info.allocInfo.resAllocMap[1] =
6661            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6662                & 0x00ff);
6663         pdcch->dci.u.format2Info.allocInfo.resAllocMap[2] =
6664                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6665                 & 0x0000ff);
6666         pdcch->dci.u.format2Info.allocInfo.resAllocMap[3] =
6667                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6668 #ifdef RG_UNUSED
6669     }
6670 #endif
6671 #ifdef LTEMAC_SPS
6672     if ((!(hqP->tbInfo[0].txCntr)) &&
6673        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6674          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6675          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6676        ))
6677     {
6678        pdcch->dci.u.format2Info.allocInfo.harqProcId = 0;
6679     }
6680     else
6681     {
6682       pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6683     }
6684 #else
6685      pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6686 #endif
6687          /* Initialize the TB info for both the TBs */
6688      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].mcs = 0;
6689      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].rv  = 1;
6690      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].mcs = 0;
6691      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].rv  = 1;
6692          /* Fill tbInfo for scheduled TBs */
6693      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6694         tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6695      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6696         tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6697      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6698             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6699           /* If we reach this function. It is safely assumed that
6700            *  rbAllocInfo->tbInfo[0] always has non default valid values.
6701            *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6702      if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6703      {
6704             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6705                 tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6706             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6707                 tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6708             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6709                 tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6710      }
6711      pdcch->dci.u.format2Info.allocInfo.transSwap =
6712              rbAllocInfo->mimoAllocInfo.swpFlg;
6713      pdcch->dci.u.format2Info.allocInfo.precoding =
6714              rbAllocInfo->mimoAllocInfo.precIdxInfo;
6715 #ifdef LTE_TDD
6716      if(hqP->hqE->ue != NULLP)
6717      {
6718
6719 #ifdef LTE_ADV
6720         U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6721                                         hqP->hqE->cell->cellId,
6722                                         hqP->hqE->ue);
6723         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6724                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6725 #else
6726         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6727                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6728 #endif
6729 #ifdef TFU_TDD
6730         if(anInfo)
6731         {
6732            pdcch->dci.u.format2Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6733         }
6734         else
6735         {
6736            pdcch->dci.u.format2Info.dai = RG_SCH_MAX_DAI_IDX;
6737            RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6738                     "PDCCH is been scheduled without updating anInfo RNTI:%d",
6739                     rbAllocInfo->rnti);
6740         }
6741 #endif
6742      }
6743 #endif
6744
6745      RETVOID;
6746 }
6747 /**
6748  * @brief This function fills the PDCCH DCI format 2A information from dlProc.
6749  *
6750  * @details
6751  *
6752  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2A
6753  *     Purpose:  This function fills in the PDCCH information
6754  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6755  *               for dedicated service scheduling. It also
6756  *               obtains TPC to be filled in from the power module.
6757  *               Assign the PDCCH to HQProc.
6758  *
6759  *     Invoked by: Downlink Scheduler
6760  *
6761  *  @param[in]  RgSchCellCb*      cell
6762  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6763  *  @param[in]  RgDlHqProc*       hqP
6764  *  @param[out]  RgSchPdcch        *pdcch
6765  *  @param[in]   U8               tpc
6766  *  @return  Void
6767  *
6768  **/
6769 #ifdef ANSI
6770 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A
6771 (
6772 RgSchCellCb                *cell,
6773 RgSchDlRbAlloc             *rbAllocInfo,
6774 RgSchDlHqProcCb            *hqP,
6775 RgSchPdcch                 *pdcch,
6776 U8                         tpc
6777 )
6778 #else
6779 PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A(cell, rbAllocInfo, hqP, pdcch, tpc)
6780 RgSchCellCb                *cell;
6781 RgSchDlRbAlloc             *rbAllocInfo;
6782 RgSchDlHqProcCb            *hqP;
6783 RgSchPdcch                 *pdcch;
6784 U8                         tpc;
6785 #endif
6786 {
6787 #ifdef LTE_TDD
6788    RgSchTddANInfo     *anInfo;
6789 #endif
6790
6791 #ifdef LTEMAC_SPS
6792    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6793 #endif
6794
6795     TRC2(rgSCHCmnFillHqPPdcchDciFrmt2A)
6796
6797     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6798     /*ccpu00120365:-ADD-call also if tb is disabled */
6799     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6800           rbAllocInfo->tbInfo[1].isDisabled)
6801     {
6802
6803         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6804     }
6805
6806     pdcch->dci.u.format2AInfo.tpcCmd = tpc;
6807          /* Avoiding this check,as we dont support Type1 RA */
6808 #ifdef RG_UNUSED
6809     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6810     {
6811 #endif
6812         pdcch->dci.u.format2AInfo.allocInfo.isAllocType0 = TRUE;
6813         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[0] =
6814               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6815                & 0xff);
6816         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[1] =
6817               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6818                & 0x00ff);
6819         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[2] =
6820                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6821                 & 0x0000ff);
6822         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[3] =
6823                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6824 #ifdef RG_UNUSED
6825     }
6826 #endif
6827 #ifdef LTEMAC_SPS
6828     if ((!(hqP->tbInfo[0].txCntr)) &&
6829        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6830          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6831          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6832        ))
6833     {
6834        pdcch->dci.u.format2AInfo.allocInfo.harqProcId = 0;
6835     }
6836     else
6837     {
6838       pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6839     }
6840 #else
6841     pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6842 #endif
6843          /* Initialize the TB info for both the TBs */
6844     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].mcs = 0;
6845     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].rv  = 1;
6846     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].mcs = 0;
6847     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].rv  = 1;
6848          /* Fill tbInfo for scheduled TBs */
6849     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6850             tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6851     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6852             tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6853     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6854             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6855          /* If we reach this function. It is safely assumed that
6856           *  rbAllocInfo->tbInfo[0] always has non default valid values.
6857           *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6858
6859     if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6860     {
6861             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6862                tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6863             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6864                tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6865             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6866                tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6867
6868     }
6869     pdcch->dci.u.format2AInfo.allocInfo.transSwap =
6870             rbAllocInfo->mimoAllocInfo.swpFlg;
6871     pdcch->dci.u.format2AInfo.allocInfo.precoding =
6872             rbAllocInfo->mimoAllocInfo.precIdxInfo;
6873 #ifdef LTE_TDD
6874     if(hqP->hqE->ue != NULLP)
6875     {
6876 #ifdef LTE_ADV
6877        U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6878                                         hqP->hqE->cell->cellId,
6879                                         hqP->hqE->ue);
6880        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6881                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6882 #else
6883        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6884                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6885 #endif
6886 #ifdef TFU_TDD
6887        if(anInfo)
6888        {
6889           pdcch->dci.u.format2AInfo.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6890        }
6891        else
6892        {
6893           pdcch->dci.u.format2AInfo.dai = RG_SCH_MAX_DAI_IDX;
6894           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6895                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6896                    rbAllocInfo->rnti);
6897        }
6898 #endif
6899      }
6900 #endif
6901
6902
6903     RETVOID;
6904 }
6905
6906 /**
6907  * @brief init of Sch vars.
6908  *
6909  * @details
6910  *
6911  *     Function: rgSCHCmnInitVars
6912        Purpose:  Initialization of various UL subframe indices
6913  *
6914  *  @param[in]  RgSchCellCb *cell
6915  *  @return  Void
6916  *
6917  **/
6918 #ifdef ANSI
6919 PRIVATE Void rgSCHCmnInitVars
6920 (
6921 RgSchCellCb *cell
6922 )
6923 #else
6924 PRIVATE Void rgSCHCmnInitVars(cell)
6925 RgSchCellCb *cell;
6926 #endif
6927 {
6928    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6929
6930    TRC2(rgSCHCmnInitVars);
6931
6932    cellUl->idx         = RGSCH_INVALID_INFO;
6933    cellUl->schdIdx     = RGSCH_INVALID_INFO;
6934    cellUl->schdHqProcIdx = RGSCH_INVALID_INFO;
6935    cellUl->msg3SchdIdx = RGSCH_INVALID_INFO;
6936 #ifdef EMTC_ENBLE
6937    cellUl->emtcMsg3SchdIdx = RGSCH_INVALID_INFO;
6938 #endif
6939    cellUl->msg3SchdHqProcIdx = RGSCH_INVALID_INFO;
6940    cellUl->rcpReqIdx   = RGSCH_INVALID_INFO;
6941    cellUl->hqFdbkIdx[0] = RGSCH_INVALID_INFO;
6942    cellUl->hqFdbkIdx[1] = RGSCH_INVALID_INFO;
6943    cellUl->reTxIdx[0]   = RGSCH_INVALID_INFO;
6944    cellUl->reTxIdx[1]   = RGSCH_INVALID_INFO;
6945   /* Stack Crash problem for TRACE5 Changes. Added the return below */
6946   RETVOID;
6947
6948 }
6949
6950 #ifndef LTE_TDD
6951 /**
6952  * @brief Updation of Sch vars per TTI.
6953  *
6954  * @details
6955  *
6956  *     Function: rgSCHCmnUpdVars
6957  *     Purpose:  Updation of Sch vars per TTI.
6958  *
6959  *  @param[in]  RgSchCellCb *cell
6960  *  @return  Void
6961  *
6962  **/
6963 #ifdef ANSI
6964 PUBLIC Void rgSCHCmnUpdVars
6965 (
6966 RgSchCellCb *cell
6967 )
6968 #else
6969 PUBLIC Void rgSCHCmnUpdVars(cell)
6970 RgSchCellCb *cell;
6971 #endif
6972 {
6973    CmLteTimingInfo   timeInfo;
6974    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6975    U16 idx;
6976
6977    TRC2(rgSCHCmnUpdVars);
6978
6979    idx = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe);
6980    cellUl->idx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6981 #ifdef UL_ADPT_DBG     
6982    printf("idx %d cellUl->idx  %d RGSCH_NUM_SUB_FRAMES_5G %d  time(%d %d) \n",idx,cellUl->idx ,RGSCH_NUM_SUB_FRAMES_5G,cell->crntTime.sfn,cell->crntTime.subframe);
6983 #endif    
6984    /* Need to scheduler for after SCHED_DELTA */
6985    /* UL allocation has been advanced by 1 subframe
6986     * so that we do not wrap around and send feedback
6987     * before the data is even received by the PHY */
6988    /* Introduced timing delta for UL control */
6989    idx = (cellUl->idx + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA);
6990    cellUl->schdIdx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6991
6992    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6993             TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)
6994    cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6995
6996    /* ccpu00127193 filling schdTime for logging and enhancement purpose*/
6997    cellUl->schdTime = timeInfo;
6998
6999    /* msg3 scheduling two subframes after general scheduling */
7000    idx = (cellUl->idx + RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA);
7001    cellUl->msg3SchdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
7002
7003    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
7004             RG_SCH_CMN_DL_DELTA+ RGSCH_RARSP_MSG3_DELTA)
7005    cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
7006
7007    idx = (cellUl->idx + TFU_RECPREQ_DLDELTA);
7008
7009    cellUl->rcpReqIdx   = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
7010
7011    /* Downlink harq feedback is sometime after data reception / harq failure */
7012    /* Since feedback happens prior to scheduling being called, we add 1 to   */
7013    /* take care of getting the correct subframe for feedback                 */
7014    idx = (cellUl->idx - TFU_CRCIND_ULDELTA + RG_SCH_CMN_UL_NUM_SF);
7015 #ifdef UL_ADPT_DBG     
7016    printf("Finally setting cellUl->hqFdbkIdx[0] = %d TFU_CRCIND_ULDELTA %d RG_SCH_CMN_UL_NUM_SF %d\n",idx,TFU_CRCIND_ULDELTA,RG_SCH_CMN_UL_NUM_SF);
7017 #endif
7018    cellUl->hqFdbkIdx[0]   = (idx % (RG_SCH_CMN_UL_NUM_SF));
7019
7020    idx = ((cellUl->schdIdx) % (RG_SCH_CMN_UL_NUM_SF));
7021
7022    cellUl->reTxIdx[0] = (U8) idx;
7023 #ifdef UL_ADPT_DBG     
7024    printf("cellUl->hqFdbkIdx[0] %d cellUl->reTxIdx[0] %d \n",cellUl->hqFdbkIdx[0], cellUl->reTxIdx[0] );
7025 #endif
7026    /* RACHO: update cmn sched specific RACH variables,
7027     * mainly the prachMaskIndex */
7028    rgSCHCmnUpdRachParam(cell);
7029
7030    RETVOID;
7031 }
7032 #endif
7033
7034 #ifdef LTE_TDD
7035
7036 /**
7037  * @brief To get uplink subframe index associated with current PHICH
7038  *        transmission.
7039  *
7040  * @details
7041  *
7042  *     Function: rgSCHCmnGetPhichUlSfIdx
7043  *     Purpose:  Gets uplink subframe index associated with current PHICH
7044  *               transmission based on SFN and subframe no
7045  *
7046  *  @param[in]  CmLteTimingInfo  *timeInfo
7047  *  @param[in]  RgSchCellCb              *cell
7048  *  @return U8
7049  *
7050  **/
7051 #ifdef ANSI
7052 PUBLIC U8  rgSCHCmnGetPhichUlSfIdx
7053 (
7054 CmLteTimingInfo *timeInfo,
7055 RgSchCellCb *cell
7056 )
7057 #else
7058 PUBLIC U8  rgSCHCmnGetPhichUlSfIdx(timeInfo, cell)
7059 CmLteTimingInfo *timeInfo;
7060 RgSchCellCb        *cell;
7061 #endif
7062 {
7063    RgSchCmnUlCell       *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
7064    RgSchDlSf            *dlsf;
7065    U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
7066    U8                   idx;
7067    U16                  numUlSf;
7068    U16                  sfn;
7069    U8                   subframe;
7070
7071    TRC2(rgSCHCmnGetPhichUlSfIdx);
7072
7073    dlsf = rgSCHUtlSubFrmGet(cell, *timeInfo);
7074
7075    if(dlsf->phichOffInfo.sfnOffset == RGSCH_INVALID_INFO)
7076    {
7077       RETVALUE(RGSCH_INVALID_INFO);
7078    }
7079    subframe = dlsf->phichOffInfo.subframe;
7080
7081    sfn = (RGSCH_MAX_SFN + timeInfo->sfn -
7082                    dlsf->phichOffInfo.sfnOffset) % RGSCH_MAX_SFN;
7083
7084    /* ccpu00130980: numUlSf(U16) parameter added to avoid integer
7085     * wrap case such that idx will be proper*/
7086    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7087    numUlSf = ((numUlSf * sfn) + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subframe]) - 1;
7088    idx = numUlSf % (cellUl->numUlSubfrms);
7089
7090    RETVALUE(idx);
7091 }
7092
7093 /**
7094  * @brief To get uplink subframe index.
7095  *
7096  * @details
7097  *
7098  *
7099  *     Function: rgSCHCmnGetUlSfIdx
7100  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
7101  *
7102  *  @param[in]  CmLteTimingInfo  *timeInfo
7103  *  @param[in]  U8               ulDlCfgIdx
7104  *  @return U8
7105  *
7106  **/
7107 #ifdef ANSI
7108 PUBLIC U8  rgSCHCmnGetUlSfIdx
7109 (
7110 CmLteTimingInfo *timeInfo,
7111 RgSchCellCb *cell
7112 )
7113 #else
7114 PUBLIC U8  rgSCHCmnGetUlSfIdx(timeInfo, cell)
7115 CmLteTimingInfo *timeInfo;
7116 RgSchCellCb *cell;
7117 #endif
7118 {
7119    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
7120    U8                ulDlCfgIdx = cell->ulDlCfgIdx;
7121    U8                idx = 0;
7122    U16               numUlSf;
7123
7124    TRC2(rgSCHCmnGetUlSfIdx);
7125
7126    /* ccpu00130980: numUlSf(U16) parameter added to avoid integer
7127     * wrap case such that idx will be proper*/
7128    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7129    numUlSf = ((numUlSf * timeInfo->sfn) + \
7130          rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe]) - 1;
7131    idx = numUlSf % (cellUl->numUlSubfrms);
7132
7133    RETVALUE(idx);
7134 }
7135
7136 #endif
7137
7138 /**
7139  * @brief To get uplink hq index.
7140  *
7141  * @details
7142  *
7143  *
7144  *     Function: rgSCHCmnGetUlHqProcIdx
7145  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
7146  *
7147  *  @param[in]  CmLteTimingInfo  *timeInfo
7148  *  @param[in]  U8               ulDlCfgIdx
7149  *  @return U8
7150  *
7151  **/
7152 #ifdef ANSI
7153 PUBLIC U8  rgSCHCmnGetUlHqProcIdx
7154 (
7155 CmLteTimingInfo *timeInfo,
7156 RgSchCellCb *cell
7157 )
7158 #else
7159 PUBLIC U8  rgSCHCmnGetUlHqProcIdx(timeInfo, cell)
7160 CmLteTimingInfo *timeInfo;
7161 RgSchCellCb *cell;
7162 #endif
7163 {
7164    U8            procId;
7165    U32           numUlSf;
7166   
7167 #ifndef LTE_TDD
7168    numUlSf  = (timeInfo->sfn * RGSCH_NUM_SUB_FRAMES_5G + timeInfo->subframe);
7169    procId   = numUlSf % RGSCH_NUM_UL_HQ_PROC;
7170 #else
7171    U8            ulDlCfgIdx = cell->ulDlCfgIdx;
7172    /*ccpu00130639 - MOD - To get correct UL HARQ Proc IDs for all UL/DL Configs*/
7173    U8            numUlSfInSfn;
7174    S8            sfnCycle = cell->tddHqSfnCycle;
7175    U8            numUlHarq = rgSchTddUlNumHarqProcTbl[ulDlCfgIdx]
7176
7177    /* TRACE 5 Changes */
7178    TRC2(rgSCHCmnGetUlHqProcIdx);
7179
7180    /* Calculate the number of UL SF in one SFN */
7181    numUlSfInSfn = RGSCH_NUM_SUB_FRAMES -
7182                rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7183
7184    /* Check for the SFN wrap around case */
7185    if(cell->crntTime.sfn == 1023 && timeInfo->sfn == 0)
7186    {
7187       sfnCycle++;
7188    }
7189    else if(cell->crntTime.sfn == 0 && timeInfo->sfn == 1023)
7190    {
7191       /* sfnCycle decremented by 1 */
7192       sfnCycle = (sfnCycle + numUlHarq-1) % numUlHarq;
7193    }
7194    /* Calculate the total number of UL sf */
7195    /*  -1 is done since uplink sf are counted from 0 */
7196    numUlSf = numUlSfInSfn *  (timeInfo->sfn + (sfnCycle*1024)) +
7197                   rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe] - 1;
7198
7199    procId = numUlSf % numUlHarq;   
7200 #endif
7201    RETVALUE(procId);
7202 }
7203
7204
7205 /* UL_ALLOC_CHANGES */
7206 /***********************************************************
7207  *
7208  *     Func : rgSCHCmnUlFreeAlloc
7209  *
7210  *     Desc : Free an allocation - invokes UHM and releases
7211  *            alloc for the scheduler
7212  *            Doest need subframe as argument
7213  *
7214  *     Ret  :
7215  *
7216  *     Notes:
7217  *
7218  *     File :
7219  *
7220  **********************************************************/
7221 #ifdef ANSI
7222 PUBLIC Void rgSCHCmnUlFreeAlloc
7223 (
7224 RgSchCellCb     *cell,
7225 RgSchUlAlloc    *alloc
7226 )
7227 #else
7228 PUBLIC Void rgSCHCmnUlFreeAlloc(cell, alloc)
7229 RgSchCellCb     *cell;
7230 RgSchUlAlloc    *alloc;
7231 #endif
7232 {
7233    RgSchUlHqProcCb *hqProc;
7234    TRC2(rgSCHCmnUlFreeAllocation);
7235
7236    if (alloc->forMsg3)
7237    {
7238       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
7239       if ((alloc->hqProc->remTx == 0) &&
7240           (alloc->hqProc->rcvdCrcInd == FALSE) &&
7241           (alloc->raCb))
7242       {
7243          RgSchRaCb      *raCb = alloc->raCb;
7244          rgSCHUhmFreeProc(alloc->hqProc, cell);
7245          rgSCHUtlUlAllocRelease(alloc);
7246          rgSCHRamDelRaCb(cell, raCb, TRUE);
7247          RETVOID;
7248       }
7249    }
7250    
7251    hqProc = alloc->hqProc;
7252    rgSCHUtlUlAllocRelease(alloc);
7253    rgSCHUhmFreeProc(hqProc, cell);
7254    RETVOID;
7255 }
7256
7257
7258 /***********************************************************
7259  *
7260  *     Func : rgSCHCmnUlFreeAllocation
7261  *
7262  *     Desc : Free an allocation - invokes UHM and releases
7263  *            alloc for the scheduler
7264  *
7265  *     Ret  :
7266  *
7267  *     Notes:
7268  *
7269  *     File :
7270  *
7271  **********************************************************/
7272 #ifdef ANSI
7273 PUBLIC Void rgSCHCmnUlFreeAllocation
7274 (
7275 RgSchCellCb     *cell,
7276 RgSchUlSf       *sf,
7277 RgSchUlAlloc    *alloc
7278 )
7279 #else
7280 PUBLIC Void rgSCHCmnUlFreeAllocation(cell, sf, alloc)
7281 RgSchCellCb     *cell;
7282 RgSchUlSf       *sf;
7283 RgSchUlAlloc    *alloc;
7284 #endif
7285 {
7286    RgSchUlHqProcCb *hqProc;
7287
7288    TRC2(rgSCHCmnUlFreeAllocation);
7289
7290    if (alloc->forMsg3)
7291    {
7292       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
7293       if ((alloc->hqProc->remTx == 0) &&
7294           (alloc->hqProc->rcvdCrcInd == FALSE) &&
7295           (alloc->raCb))
7296       {
7297          RgSchRaCb      *raCb = alloc->raCb;
7298          rgSCHUhmFreeProc(alloc->hqProc, cell);
7299          rgSCHUtlUlAllocRls(sf, alloc);
7300          rgSCHRamDelRaCb(cell, raCb, TRUE);
7301          RETVOID;
7302       }
7303    }
7304    
7305    hqProc = alloc->hqProc;
7306    rgSCHUhmFreeProc(hqProc, cell);
7307 #ifdef LTE_L2_MEAS
7308    /* re-setting the PRB count while freeing the allocations */
7309    sf->totPrb = 0;
7310 #endif
7311    rgSCHUtlUlAllocRls(sf, alloc);
7312
7313    RETVOID;
7314 }
7315
7316 /**
7317  * @brief This function implements PDCCH allocation for an UE
7318  *        in the currently running subframe.
7319  *
7320  * @details
7321  *
7322  *     Function: rgSCHCmnPdcchAllocCrntSf
7323  *     Purpose:  This function determines current DL subframe
7324  *               and UE DL CQI to call the actual pdcch allocator
7325  *               function.
7326  *               Note that this function is called only
7327  *               when PDCCH request needs to be made during
7328  *               uplink scheduling.
7329  *
7330  *     Invoked by: Scheduler
7331  *
7332  *  @param[in]  RgSchCellCb  *cell
7333  *  @param[in]  RgSchUeCb    *ue
7334  *  @return  RgSchPdcch *
7335  *         -# NULLP when unsuccessful
7336  **/
7337 #ifdef ANSI
7338 PUBLIC RgSchPdcch *rgSCHCmnPdcchAllocCrntSf
7339 (
7340 RgSchCellCb                *cell,
7341 RgSchUeCb                  *ue
7342 )
7343 #else
7344 PUBLIC RgSchPdcch *rgSCHCmnPdcchAllocCrntSf(cell, ue)
7345 RgSchCellCb                *cell;
7346 RgSchUeCb                  *ue;
7347 #endif
7348 {
7349    CmLteTimingInfo      frm = cell->crntTime;
7350    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7351    RgSchDlSf            *sf;
7352    RgSchPdcch           *pdcch = NULLP;
7353
7354    TRC2(rgSCHCmnPdcchAllocCrntSf);
7355    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
7356    sf = rgSCHUtlSubFrmGet(cell, frm);
7357
7358 #ifdef LTE_ADV
7359    if (ue->allocCmnUlPdcch)
7360    {
7361       pdcch = rgSCHCmnCmnPdcchAlloc(cell, sf);
7362       /* Since CRNTI Scrambled */
7363       if(NULLP != pdcch)
7364       {
7365          pdcch->dciNumOfBits = ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
7366       }
7367    }
7368    else
7369 #endif
7370    {
7371       //pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, y, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_0, FALSE);
7372                 pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_A1, FALSE);
7373    }
7374    RETVALUE(pdcch);
7375 }
7376
7377 /***********************************************************
7378  *
7379  *     Func : rgSCHCmnUlAllocFillNdmrs
7380  *
7381  *     Desc : Determines and fills N_dmrs for a UE uplink
7382  *            allocation.
7383  *
7384  *     Ret  :
7385  *
7386  *     Notes: N_dmrs determination is straightforward, so
7387  *            it is configured per subband
7388  *
7389  *     File :
7390  *
7391  **********************************************************/
7392 #ifdef ANSI
7393 PUBLIC Void rgSCHCmnUlAllocFillNdmrs
7394 (
7395 RgSchCmnUlCell *cellUl,
7396 RgSchUlAlloc   *alloc
7397 )
7398 #else
7399 PUBLIC Void rgSCHCmnUlAllocFillNdmrs(cellUl, alloc)
7400 RgSchCmnUlCell *cellUl;
7401 RgSchUlAlloc   *alloc;
7402 #endif
7403 {
7404    TRC2(rgSCHCmnUlAllocFillNdmrs);
7405    alloc->grnt.nDmrs = cellUl->dmrsArr[alloc->sbStart];
7406    RETVOID;
7407 }
7408
7409 /***********************************************************
7410  *
7411  *     Func : rgSCHCmnUlAllocLnkHqProc
7412  *
7413  *     Desc : Links a new allocation for an UE with the
7414  *            appropriate HARQ process of the UE.
7415  *
7416  *     Ret  :
7417  *
7418  *     Notes:
7419  *
7420  *     File :
7421  *
7422  **********************************************************/
7423 #ifdef ANSI
7424 PUBLIC Void rgSCHCmnUlAllocLnkHqProc
7425 (
7426 RgSchUeCb       *ue,
7427 RgSchUlAlloc    *alloc,
7428 RgSchUlHqProcCb *proc,
7429 Bool            isRetx
7430 )
7431 #else
7432 PUBLIC Void rgSCHCmnUlAllocLnkHqProc(ue, alloc, proc, isRetx)
7433 RgSchUeCb       *ue;
7434 RgSchUlAlloc    *alloc;
7435 RgSchUlHqProcCb *proc;
7436 Bool            isRetx;
7437 #endif
7438 {
7439    TRC2(rgSCHCmnUlAllocLnkHqProc);
7440
7441    if(TRUE == isRetx)
7442    {
7443       rgSCHCmnUlAdapRetx(alloc, proc);
7444    }
7445    else
7446    {
7447 #ifdef LTE_L2_MEAS /* L2_COUNTERS */
7448       alloc->ue = ue;
7449 #endif
7450       rgSCHUhmNewTx(proc, (((RgUeUlHqCb*)proc->hqEnt)->maxHqRetx), alloc);
7451    }
7452    RETVOID;
7453 }
7454
7455 /**
7456  * @brief This function releases a PDCCH in the subframe that is
7457  *        currently being allocated for.
7458  *
7459  * @details
7460  *
7461  *     Function: rgSCHCmnPdcchRlsCrntSf
7462  *     Purpose:  This function determines current DL subframe
7463  *               which is considered for PDCCH allocation,
7464  *               and then calls the actual function that
7465  *               releases a PDCCH in a specific subframe.
7466  *               Note that this function is called only
7467  *               when PDCCH release needs to be made during
7468  *               uplink scheduling.
7469  *
7470  *     Invoked by: Scheduler
7471  *
7472  *  @param[in]  RgSchCellCb  *cell
7473  *  @param[in]  RgSchPdcch   *pdcch
7474  *  @return  Void
7475  **/
7476 #ifdef ANSI
7477 PUBLIC Void rgSCHCmnPdcchRlsCrntSf
7478 (
7479 RgSchCellCb                *cell,
7480 RgSchPdcch                 *pdcch
7481 )
7482 #else
7483 PUBLIC Void rgSCHCmnPdcchRlsCrntSf(cell, pdcch)
7484 RgSchCellCb                *cell;
7485 RgSchPdcch                 *pdcch;
7486 #endif
7487 {
7488    CmLteTimingInfo      frm = cell->crntTime;
7489    RgSchDlSf               *sf;
7490
7491    TRC2(rgSCHCmnPdcchRlsCrntSf);
7492
7493    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
7494    sf = rgSCHUtlSubFrmGet(cell, frm);
7495    rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, pdcch);
7496    RETVOID;
7497 }
7498 /***********************************************************
7499  *
7500  *     Func : rgSCHCmnUlFillPdcchWithAlloc
7501  *
7502  *     Desc : Fills a PDCCH with format 0 information.
7503  *
7504  *     Ret  :
7505  *
7506  *     Notes:
7507  *
7508  *     File :
7509  *
7510  **********************************************************/
7511 #ifdef ANSI
7512 PUBLIC Void rgSCHCmnUlFillPdcchWithAlloc
7513 (
7514 RgSchPdcch      *pdcch,
7515 RgSchUlAlloc    *alloc,
7516 RgSchUeCb       *ue
7517 )
7518 #else
7519 PUBLIC Void rgSCHCmnUlFillPdcchWithAlloc(pdcch, alloc, ue)
7520 RgSchPdcch      *pdcch;
7521 RgSchUlAlloc    *alloc;
7522 RgSchUeCb       *ue;
7523 #endif
7524 {
7525
7526    TRC2(rgSCHCmnUlFillPdcchWithAlloc);
7527
7528    pdcch->ue = ue;
7529    pdcch->rnti = alloc->rnti;
7530    //pdcch->dci.dciFormat = TFU_DCI_FORMAT_A2;
7531    pdcch->dci.dciFormat = alloc->grnt.dciFrmt;
7532
7533    //Currently hardcoding values here.
7534    //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
7535    switch(pdcch->dci.dciFormat)
7536    {
7537       case TFU_DCI_FORMAT_A1:
7538                 {
7539                         pdcch->dci.u.formatA1Info.formatType = 0;
7540          pdcch->dci.u.formatA1Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
7541          pdcch->dci.u.formatA1Info.xPUSCH_TxTiming = 0;
7542          pdcch->dci.u.formatA1Info.RBAssign = alloc->grnt.rbAssign;
7543          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
7544          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
7545          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
7546          pdcch->dci.u.formatA1Info.CSI_BSI_BRI_Req = 0;
7547          pdcch->dci.u.formatA1Info.CSIRS_BRRS_TxTiming = 0;
7548          pdcch->dci.u.formatA1Info.CSIRS_BRRS_SymbIdx = 0;
7549          pdcch->dci.u.formatA1Info.CSIRS_BRRS_ProcInd = 0;
7550          pdcch->dci.u.formatA1Info.numBSI_Reports = 0;
7551          pdcch->dci.u.formatA1Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
7552          pdcch->dci.u.formatA1Info.beamSwitch  = 0;
7553          pdcch->dci.u.formatA1Info.SRS_Config = 0;
7554          pdcch->dci.u.formatA1Info.SRS_Symbol = 0;
7555          pdcch->dci.u.formatA1Info.REMapIdx_DMRS_PCRS_numLayers = 0;
7556          pdcch->dci.u.formatA1Info.SCID = alloc->grnt.SCID;
7557          pdcch->dci.u.formatA1Info.PMI = alloc->grnt.PMI;
7558          pdcch->dci.u.formatA1Info.UL_PCRS = 0;
7559          pdcch->dci.u.formatA1Info.tpcCmd = alloc->grnt.tpc;
7560                         break;
7561       }
7562                 case TFU_DCI_FORMAT_A2:
7563                 {
7564                         pdcch->dci.u.formatA2Info.formatType = 1;
7565          pdcch->dci.u.formatA2Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
7566          pdcch->dci.u.formatA2Info.xPUSCH_TxTiming = 0;
7567          pdcch->dci.u.formatA2Info.RBAssign = alloc->grnt.rbAssign;
7568          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
7569          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
7570          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
7571          pdcch->dci.u.formatA2Info.CSI_BSI_BRI_Req = 0;
7572          pdcch->dci.u.formatA2Info.CSIRS_BRRS_TxTiming = 0;
7573          pdcch->dci.u.formatA2Info.CSIRS_BRRS_SymbIdx = 0;
7574          pdcch->dci.u.formatA2Info.CSIRS_BRRS_ProcInd = 0;
7575          pdcch->dci.u.formatA2Info.numBSI_Reports = 0;
7576          pdcch->dci.u.formatA2Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
7577          pdcch->dci.u.formatA2Info.beamSwitch  = 0;
7578          pdcch->dci.u.formatA2Info.SRS_Config = 0;
7579          pdcch->dci.u.formatA2Info.SRS_Symbol = 0;
7580          pdcch->dci.u.formatA2Info.REMapIdx_DMRS_PCRS_numLayers = 0;
7581          pdcch->dci.u.formatA2Info.SCID = alloc->grnt.SCID;
7582          pdcch->dci.u.formatA2Info.PMI = alloc->grnt.PMI;
7583          pdcch->dci.u.formatA2Info.UL_PCRS = 0;
7584          pdcch->dci.u.formatA2Info.tpcCmd = alloc->grnt.tpc;
7585                         break;
7586                 }
7587       default:
7588          RLOG1(L_ERROR," 5GTF_ERROR UL Allocator's icorrect "
7589                "dciForamt Fill RNTI:%d",alloc->rnti);
7590          break;
7591    }    
7592    
7593
7594    RETVOID;
7595 }
7596
7597 /***********************************************************
7598  *
7599  *     Func : rgSCHCmnUlAllocFillTpc
7600  *
7601  *     Desc : Determines and fills TPC for an UE allocation.
7602  *
7603  *     Ret  :
7604  *
7605  *     Notes:
7606  *
7607  *     File :
7608  *
7609  **********************************************************/
7610 #ifdef ANSI
7611 PUBLIC Void rgSCHCmnUlAllocFillTpc
7612 (
7613 RgSchCellCb  *cell,
7614 RgSchUeCb    *ue,
7615 RgSchUlAlloc *alloc
7616 )
7617 #else
7618 PUBLIC Void rgSCHCmnUlAllocFillTpc(cell, ue, alloc)
7619 RgSchCellCb  *cell;
7620 RgSchUeCb    *ue;
7621 RgSchUlAlloc *alloc;
7622 #endif
7623 {
7624    TRC2(rgSCHCmnUlAllocFillTpc);
7625    alloc->grnt.tpc = rgSCHPwrPuschTpcForUe(cell, ue);
7626    RETVOID;
7627 }
7628
7629
7630 /***********************************************************
7631  *
7632  *     Func : rgSCHCmnAddUeToRefreshQ
7633  *
7634  *     Desc : Adds a UE to refresh queue, so that the UE is
7635  *            periodically triggered to refresh it's GBR and
7636  *            AMBR values.
7637  *
7638  *     Ret  :
7639  *
7640  *     Notes:
7641  *
7642  *     File :
7643  *
7644  **********************************************************/
7645 #ifdef ANSI
7646 PRIVATE Void rgSCHCmnAddUeToRefreshQ
7647 (
7648 RgSchCellCb     *cell,
7649 RgSchUeCb       *ue,
7650 U32             wait
7651 )
7652 #else
7653 PRIVATE Void rgSCHCmnAddUeToRefreshQ(cell, ue, wait)
7654 RgSchCellCb     *cell;
7655 RgSchUeCb       *ue;
7656 U32             wait;
7657 #endif
7658 {
7659    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
7660    CmTmrArg       arg;
7661    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
7662
7663    TRC2(rgSCHCmnAddUeToRefreshQ);
7664    UNUSED(cell);
7665
7666    cmMemset((U8 *)&arg, 0, sizeof(arg));
7667    arg.tqCp   = &sched->tmrTqCp;
7668    arg.tq     = sched->tmrTq;
7669    arg.timers = &ueSchd->tmr;
7670    arg.cb     = (PTR)ue;
7671    arg.tNum   = 0;
7672    arg.max    = 1;
7673    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
7674    arg.wait   = wait;
7675    cmPlcCbTq(&arg);
7676    RETVOID;
7677 }
7678
7679 /**
7680  * @brief Perform UE reset procedure.
7681  *
7682  * @details
7683  *
7684  *     Function : rgSCHCmnUlUeReset
7685  *
7686  *     This functions performs BSR resetting and
7687  *     triggers UL specific scheduler
7688  *     to Perform UE reset procedure.
7689  *
7690  *  @param[in]  RgSchCellCb  *cell
7691  *  @param[in]  RgSchUeCb    *ue
7692  *  @return  Void
7693  **/
7694 #ifdef ANSI
7695 PRIVATE Void rgSCHCmnUlUeReset
7696 (
7697 RgSchCellCb  *cell,
7698 RgSchUeCb    *ue
7699 )
7700 #else
7701 PRIVATE Void rgSCHCmnUlUeReset(cell, ue)
7702 RgSchCellCb  *cell;
7703 RgSchUeCb    *ue;
7704 #endif
7705 {
7706    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7707    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
7708    U8                   lcgCnt=0;
7709    RgSchCmnLcg          *lcgCmn;
7710    CmLList              *node;
7711    RgSchCmnAllocRecord  *allRcd;
7712    TRC2(rgSCHCmnUlUeReset);
7713
7714    ue->ul.minReqBytes = 0;
7715    ue->ul.totalBsr = 0;
7716    ue->ul.effBsr = 0;
7717    ue->ul.nonGbrLcgBs = 0;
7718    ue->ul.effAmbr = ue->ul.cfgdAmbr;
7719
7720    node = ueUl->ulAllocLst.first;
7721    while (node)
7722    {
7723       allRcd = (RgSchCmnAllocRecord *)node->node;
7724       allRcd->alloc = 0;
7725       node = node->next;
7726    }
7727    for(lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++)
7728    {
7729       lcgCmn = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[lcgCnt]);
7730       lcgCmn->bs = 0;
7731       lcgCmn->reportedBs = 0;
7732       lcgCmn->effGbr = lcgCmn->cfgdGbr;
7733       lcgCmn->effDeltaMbr = lcgCmn->deltaMbr;
7734    }
7735    rgSCHCmnUlUeDelAllocs(cell, ue);
7736
7737    ue->isSrGrant = FALSE;
7738
7739    cellSchd->apisUl->rgSCHUlUeReset(cell, ue);
7740
7741    /* Stack Crash problem for TRACE5 changes. Added the return below */
7742    RETVOID;
7743
7744 }
7745
7746 /**
7747  * @brief RESET UL CQI and DL CQI&RI to conservative values
7748     * for a reestablishing UE.
7749  *
7750  * @details
7751  *
7752  *     Function : rgSCHCmnResetRiCqi 
7753  *     
7754  *     RESET UL CQI and DL CQI&RI to conservative values
7755  *     for a reestablishing UE
7756  *
7757  *  @param[in]  RgSchCellCb  *cell
7758  *  @param[in]  RgSchUeCb    *ue
7759  *  @return  Void
7760  **/
7761 #ifdef ANSI
7762 PRIVATE Void rgSCHCmnResetRiCqi 
7763 (
7764 RgSchCellCb  *cell,
7765 RgSchUeCb    *ue
7766 )
7767 #else
7768 PRIVATE Void rgSCHCmnResetRiCqi(cell, ue)
7769 RgSchCellCb  *cell;
7770 RgSchUeCb    *ue;
7771 #endif
7772 {
7773    RgSchCmnCell  *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7774    RgSchCmnUe    *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
7775    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7776    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
7777
7778    TRC2(rgSCHCmnResetRiCqi);
7779
7780    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, 
7781          cell->isCpUlExtend);
7782
7783    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
7784    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
7785    ueDl->mimoInfo.ri = 1;
7786    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
7787           (ue->mimoInfo.txMode == RGR_UE_TM_6))
7788    {
7789       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
7790    }
7791    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
7792    {
7793       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
7794    }
7795 #ifdef EMTC_ENABLE   
7796    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
7797 #else
7798    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
7799 #endif      
7800
7801 #ifdef TFU_UPGRADE
7802    /* Request for an early Aper CQI in case of reest */
7803    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
7804    if(acqiCb && acqiCb->aCqiCfg.pres)
7805    {
7806       acqiCb->aCqiTrigWt = 0;
7807    }
7808 #endif   
7809
7810    RETVOID;
7811 }
7812
7813 /**
7814  * @brief Perform UE reset procedure.
7815  *
7816  * @details
7817  *
7818  *     Function : rgSCHCmnDlUeReset
7819  *
7820  *     This functions performs BO resetting and
7821  *     triggers DL specific scheduler
7822  *     to Perform UE reset procedure.
7823  *
7824  *  @param[in]  RgSchCellCb  *cell
7825  *  @param[in]  RgSchUeCb    *ue
7826  *  @return  Void
7827  **/
7828 #ifdef ANSI
7829 PRIVATE Void rgSCHCmnDlUeReset
7830 (
7831 RgSchCellCb  *cell,
7832 RgSchUeCb    *ue
7833 )
7834 #else
7835 PRIVATE Void rgSCHCmnDlUeReset(cell, ue)
7836 RgSchCellCb  *cell;
7837 RgSchUeCb    *ue;
7838 #endif
7839 {
7840    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7841    RgSchCmnDlCell       *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
7842    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7843
7844    TRC2(rgSCHCmnDlUeReset);
7845
7846    if (ueDl->rachInfo.poLnk.node != NULLP)
7847    {
7848       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
7849    }
7850
7851    /* Fix: syed Remove from TA List if this UE is there.
7852     * If TA Timer is running. Stop it */
7853    if (ue->dlTaLnk.node)
7854    {
7855       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
7856       ue->dlTaLnk.node = (PTR)NULLP;
7857    }
7858    else if (ue->taTmr.tmrEvnt != TMR_NONE)
7859    {
7860       rgSCHTmrStopTmr(cell, ue->taTmr.tmrEvnt, ue);
7861    }
7862
7863    cellSchd->apisDl->rgSCHDlUeReset(cell, ue);
7864 #ifdef LTE_ADV
7865    if (ue->numSCells)
7866    {
7867       rgSCHSCellDlUeReset(cell,ue);
7868    }
7869 #endif
7870 }
7871
7872 /**
7873  * @brief Perform UE reset procedure.
7874  *
7875  * @details
7876  *
7877  *     Function : rgSCHCmnUeReset
7878  *
7879  *     This functions triggers specific scheduler
7880  *     to Perform UE reset procedure.
7881  *
7882  *  @param[in]  RgSchCellCb  *cell
7883  *  @param[in]  RgSchUeCb    *ue
7884  *  @return  S16
7885  *      -# ROK
7886  *      -# RFAILED
7887  **/
7888 #ifdef ANSI
7889 PUBLIC Void rgSCHCmnUeReset
7890 (
7891 RgSchCellCb  *cell,
7892 RgSchUeCb    *ue
7893 )
7894 #else
7895 PUBLIC Void rgSCHCmnUeReset(cell, ue)
7896 RgSchCellCb  *cell;
7897 RgSchUeCb    *ue;
7898 #endif
7899 {
7900    U8 idx;
7901    Pst               pst;
7902    RgInfResetHqEnt   hqEntRstInfo;
7903
7904    TRC2(rgSCHCmnUeReset);
7905    /* RACHO: remove UE from pdcch, handover and rapId assoc Qs */
7906    rgSCHCmnDelRachInfo(cell, ue);
7907
7908    rgSCHPwrUeReset(cell, ue);
7909
7910    rgSCHCmnUlUeReset(cell, ue);
7911    rgSCHCmnDlUeReset(cell, ue);
7912    
7913 #ifdef LTE_ADV
7914    /* Making allocCmnUlPdcch TRUE to allocate DCI0/1A from Common search space.
7915       As because multiple cells are added hence 2 bits CqiReq is there 
7916       This flag will be set to FALSE once we will get Scell READY */
7917    ue->allocCmnUlPdcch = TRUE;
7918 #endif
7919
7920    /* Fix : syed RESET UL CQI and DL CQI&RI to conservative values
7921     * for a reestablishing UE */
7922    /*Reset Cqi Config for all the configured cells*/
7923    for (idx = 0;idx < CM_LTE_MAX_CELLS; idx++)
7924    {
7925       if (ue->cellInfo[idx] != NULLP) 
7926       {   
7927          rgSCHCmnResetRiCqi(ue->cellInfo[idx]->cell, ue);
7928       }
7929    }
7930    /*After Reset Trigger APCQI for Pcell*/
7931    RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7932    if(pCellInfo->acqiCb.aCqiCfg.pres)
7933    {
7934       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
7935    }
7936
7937 /* sending HqEnt reset to MAC */
7938    hqEntRstInfo.cellId = cell->cellId;
7939    hqEntRstInfo.crnti  = ue->ueId;
7940
7941    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
7942    RgSchMacRstHqEnt(&pst,&hqEntRstInfo);
7943
7944    RETVOID;
7945 }
7946
7947 /**
7948  * @brief UE out of MeasGap or AckNackReptn.
7949  *
7950  * @details
7951  *
7952  *     Function : rgSCHCmnActvtUlUe
7953  *
7954  *     This functions triggers specific scheduler
7955  *     to start considering it for scheduling.
7956  *
7957  *  @param[in]  RgSchCellCb  *cell
7958  *  @param[in]  RgSchUeCb    *ue
7959  *  @return  S16
7960  *      -# ROK
7961  *      -# RFAILED
7962  **/
7963 #ifdef ANSI
7964 PUBLIC Void rgSCHCmnActvtUlUe
7965 (
7966 RgSchCellCb  *cell,
7967 RgSchUeCb    *ue
7968 )
7969 #else
7970 PUBLIC Void rgSCHCmnActvtUlUe(cell, ue)
7971 RgSchCellCb  *cell;
7972 RgSchUeCb    *ue;
7973 #endif
7974 {
7975    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7976    TRC2(rgSCHCmnActvtUlUe);
7977
7978    /* : take care of this in UL retransmission */
7979    cellSchd->apisUl->rgSCHUlActvtUe(cell, ue);
7980    RETVOID;
7981 }
7982
7983 /**
7984  * @brief UE out of MeasGap or AckNackReptn.
7985  *
7986  * @details
7987  *
7988  *     Function : rgSCHCmnActvtDlUe
7989  *
7990  *     This functions triggers specific scheduler
7991  *     to start considering it for scheduling.
7992  *
7993  *  @param[in]  RgSchCellCb  *cell
7994  *  @param[in]  RgSchUeCb    *ue
7995  *  @return  S16
7996  *      -# ROK
7997  *      -# RFAILED
7998  **/
7999 #ifdef ANSI
8000 PUBLIC Void rgSCHCmnActvtDlUe
8001 (
8002 RgSchCellCb  *cell,
8003 RgSchUeCb    *ue
8004 )
8005 #else
8006 PUBLIC Void rgSCHCmnActvtDlUe(cell, ue)
8007 RgSchCellCb  *cell;
8008 RgSchUeCb    *ue;
8009 #endif
8010 {
8011    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8012    TRC2(rgSCHCmnActvtDlUe);
8013
8014    cellSchd->apisDl->rgSCHDlActvtUe(cell, ue);
8015    RETVOID;
8016 }
8017
8018 /**
8019  * @brief This API is invoked to indicate scheduler of a CRC indication.
8020  *
8021  * @details
8022  *
8023  *     Function : rgSCHCmnHdlUlTransInd
8024  *      This API is invoked to indicate scheduler of a CRC indication.
8025  *
8026  *  @param[in]  RgSchCellCb     *cell
8027  *  @param[in]  RgSchUeCb       *ue
8028  *  @param[in]  CmLteTimingInfo timingInfo
8029  *
8030  *  @return Void
8031  **/
8032 #ifdef ANSI
8033 PUBLIC Void rgSCHCmnHdlUlTransInd
8034 (
8035 RgSchCellCb     *cell,
8036 RgSchUeCb       *ue,
8037 CmLteTimingInfo timingInfo
8038 )
8039 #else
8040 PUBLIC Void rgSCHCmnHdlUlTransInd(cell, ue, timingInfo)
8041 RgSchCellCb     *cell;
8042 RgSchUeCb       *ue;
8043 CmLteTimingInfo timingInfo;
8044 #endif
8045 {
8046    TRC2(rgSCHCmnHdlUlTransInd);
8047
8048    /* Update the latest UL dat/sig transmission time */
8049    RGSCHCPYTIMEINFO(timingInfo, ue->ul.ulTransTime);
8050    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
8051    {
8052       /* Some UL Transmission from this UE.
8053        * Activate this UE if it was inactive */
8054       RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
8055       RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
8056    }
8057    RETVOID;
8058 }
8059
8060 #ifdef TFU_UPGRADE
8061
8062 /**
8063  * @brief Compute the minimum Rank based on Codebook subset
8064  *        restriction configuration for 4 Tx Ports and Tx Mode 4.
8065  *
8066  * @details
8067  *
8068  *     Function : rgSCHCmnComp4TxMode4
8069  *
8070  *     Depending on BitMap set at CBSR during Configuration
8071  *      - return the least possible Rank
8072  *
8073  *
8074  *  @param[in]  U32 *pmiBitMap
8075  *  @return  RgSchCmnRank
8076  **/
8077 #ifdef ANSI
8078 PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4
8079 (
8080  U32    *pmiBitMap
8081  )
8082 #else
8083 PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4(pmiBitMap)
8084    U32  *pmiBitMap;
8085 #endif
8086 {
8087    U32 bitMap0, bitMap1;
8088    TRC2(rgSCHCmnComp4TxMode4);
8089    bitMap0 = pmiBitMap[0];
8090    bitMap1 = pmiBitMap[1];
8091    if((bitMap1) & 0xFFFF)
8092    {
8093       RETVALUE (RG_SCH_CMN_RANK_1);
8094    }
8095    else if((bitMap1>>16) & 0xFFFF)
8096    {
8097       RETVALUE (RG_SCH_CMN_RANK_2);
8098    }
8099    else if((bitMap0) & 0xFFFF)
8100    {
8101       RETVALUE (RG_SCH_CMN_RANK_3);
8102    }
8103    else if((bitMap0>>16) & 0xFFFF)
8104    {
8105       RETVALUE (RG_SCH_CMN_RANK_4);
8106    }
8107    else
8108    {
8109       RETVALUE (RG_SCH_CMN_RANK_1);
8110    }
8111 }
8112
8113
8114 /**
8115  * @brief Compute the minimum Rank based on Codebook subset
8116  *        restriction configuration for 2 Tx Ports and Tx Mode 4.
8117  *
8118  * @details
8119  *
8120  *     Function : rgSCHCmnComp2TxMode4
8121  *
8122  *     Depending on BitMap set at CBSR during Configuration
8123  *      - return the least possible Rank
8124  *
8125  *
8126  *  @param[in]  U32 *pmiBitMap
8127  *  @return  RgSchCmnRank
8128  **/
8129 #ifdef ANSI
8130 PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4
8131 (
8132  U32    *pmiBitMap
8133  )
8134 #else
8135 PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4(pmiBitMap)
8136    U32  *pmiBitMap;
8137 #endif
8138 {
8139    U32 bitMap0;
8140    TRC2(rgSCHCmnComp2TxMode4);
8141    bitMap0 = pmiBitMap[0];
8142    if((bitMap0>>26)& 0x0F)
8143    {
8144       RETVALUE (RG_SCH_CMN_RANK_1);
8145    }
8146    else if((bitMap0>>30) & 3)
8147    {
8148       RETVALUE (RG_SCH_CMN_RANK_2);
8149    }
8150    else
8151    {
8152       RETVALUE (RG_SCH_CMN_RANK_1);
8153    }
8154 }
8155
8156 /**
8157  * @brief Compute the minimum Rank based on Codebook subset
8158  *        restriction configuration for 4 Tx Ports and Tx Mode 3.
8159  *
8160  * @details
8161  *
8162  *     Function : rgSCHCmnComp4TxMode3
8163  *
8164  *     Depending on BitMap set at CBSR during Configuration
8165  *      - return the least possible Rank
8166  *
8167  *
8168  *  @param[in]  U32 *pmiBitMap
8169  *  @return  RgSchCmnRank
8170  **/
8171 #ifdef ANSI
8172 PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3
8173 (
8174  U32    *pmiBitMap
8175  )
8176 #else
8177 PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3(pmiBitMap)
8178    U32  *pmiBitMap;
8179 #endif
8180 {
8181    U32 bitMap0;
8182    TRC2(rgSCHCmnComp4TxMode3);
8183    bitMap0 = pmiBitMap[0];
8184    if((bitMap0>>28)& 1)
8185    {
8186       RETVALUE (RG_SCH_CMN_RANK_1);
8187    }
8188    else if((bitMap0>>29) &1)
8189    {
8190       RETVALUE (RG_SCH_CMN_RANK_2);
8191    }
8192    else if((bitMap0>>30) &1)
8193    {
8194       RETVALUE (RG_SCH_CMN_RANK_3);
8195    }
8196    else if((bitMap0>>31) &1)
8197    {
8198       RETVALUE (RG_SCH_CMN_RANK_4);
8199    }
8200    else
8201    {
8202       RETVALUE (RG_SCH_CMN_RANK_1);
8203    }
8204 }
8205
8206 /**
8207  * @brief Compute the minimum Rank based on Codebook subset
8208  *        restriction configuration for 2 Tx Ports and Tx Mode 3.
8209  *
8210  * @details
8211  *
8212  *     Function : rgSCHCmnComp2TxMode3
8213  *
8214  *     Depending on BitMap set at CBSR during Configuration
8215  *      - return the least possible Rank
8216  *
8217  *
8218  *  @param[in]  U32 *pmiBitMap
8219  *  @return  RgSchCmnRank
8220  **/
8221 #ifdef ANSI
8222 PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3
8223 (
8224  U32 *pmiBitMap
8225  )
8226 #else
8227 PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3(pmiBitMap)
8228    U32 *pmiBitMap;
8229 #endif
8230 {
8231    U32 bitMap0;
8232    TRC2(rgSCHCmnComp2TxMode3);
8233    bitMap0 = pmiBitMap[0];
8234    if((bitMap0>>30)& 1)
8235    {
8236       RETVALUE (RG_SCH_CMN_RANK_1);
8237    }
8238    else if((bitMap0>>31) &1)
8239    {
8240       RETVALUE (RG_SCH_CMN_RANK_2);
8241    }
8242    else
8243    {
8244       RETVALUE (RG_SCH_CMN_RANK_1);
8245    }
8246 }
8247
8248 /**
8249  * @brief Compute the minimum Rank based on Codebook subset
8250  *        restriction configuration.
8251  *
8252  * @details
8253  *
8254  *     Function : rgSCHCmnComputeRank
8255  *
8256  *     Depending on Num Tx Ports and Transmission mode
8257  *      - return the least possible Rank
8258  *
8259  *
8260  *  @param[in]  RgrTxMode txMode
8261  *  @param[in]  U32 *pmiBitMap
8262  *  @param[in]  U8 numTxPorts
8263  *  @return  RgSchCmnRank
8264  **/
8265 #ifdef ANSI
8266 PRIVATE RgSchCmnRank rgSCHCmnComputeRank
8267 (
8268  RgrTxMode    txMode,
8269  U32          *pmiBitMap,
8270  U8           numTxPorts
8271  )
8272 #else
8273 PRIVATE RgSchCmnRank rgSCHCmnComputeRank(txMode, pmiBitMap, numTxPorts)
8274    RgrTxMode    txMode;
8275    U32          *pmiBitMap;
8276    U8           numTxPorts;
8277 #endif
8278 {
8279    TRC2(rgSCHCmnComputeRank);
8280
8281    if (numTxPorts ==2 && txMode == RGR_UE_TM_3)
8282    {
8283       RETVALUE (rgSCHCmnComp2TxMode3(pmiBitMap));
8284    }
8285    else if (numTxPorts ==4 && txMode == RGR_UE_TM_3)
8286    {
8287       RETVALUE (rgSCHCmnComp4TxMode3(pmiBitMap));
8288    }
8289    else if (numTxPorts ==2 && txMode == RGR_UE_TM_4)
8290    {
8291       RETVALUE (rgSCHCmnComp2TxMode4(pmiBitMap));
8292    }
8293    else if (numTxPorts ==4 && txMode == RGR_UE_TM_4)
8294    {
8295       RETVALUE (rgSCHCmnComp4TxMode4(pmiBitMap));
8296    }
8297    else
8298    {
8299       RETVALUE (RG_SCH_CMN_RANK_1);
8300    }
8301 }
8302
8303 #endif
8304
8305 /**
8306  * @brief Harq Entity Deinitialization for CMN SCH.
8307  *
8308  * @details
8309  *
8310  *     Function : rgSCHCmnDlDeInitHqEnt 
8311  *
8312  *     Harq Entity Deinitialization for CMN SCH 
8313  *
8314  *  @param[in]  RgSchCellCb  *cell
8315  *  @param[in]  RgSchDlHqEnt *hqE 
8316  *  @return  VOID
8317  **/
8318 /*KWORK_FIX:Changed function return type to void */
8319 #ifdef ANSI
8320 PUBLIC Void rgSCHCmnDlDeInitHqEnt 
8321 (
8322 RgSchCellCb  *cell,
8323 RgSchDlHqEnt *hqE
8324 )
8325 #else
8326 PUBLIC Void rgSCHCmnDlDeInitHqEnt(cell, hqE)
8327 RgSchCellCb  *cell;
8328 RgSchDlHqEnt *hqE;
8329 #endif
8330 {
8331    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8332    RgSchDlHqProcCb      *hqP;
8333    U8                   cnt;
8334    S16                  ret;
8335
8336    TRC2(rgSCHCmnDlDeInitHqEnt);
8337
8338    ret = cellSchd->apisDl->rgSCHDlUeHqEntDeInit(cell, hqE);
8339    /* Free only If the Harq proc are created*/
8340    if(RFAILED == ret)
8341    {
8342    }
8343
8344    for(cnt = 0; cnt < hqE->numHqPrcs; cnt++)
8345    {
8346       hqP = &hqE->procs[cnt];
8347       if ((RG_SCH_CMN_GET_DL_HQP(hqP)))
8348       {
8349          rgSCHUtlFreeSBuf(cell->instIdx,
8350               (Data**)(&(hqP->sch)), (sizeof(RgSchCmnDlHqProc)));
8351       }
8352    }
8353 #ifdef LTE_ADV
8354    rgSCHLaaDeInitDlHqProcCb (cell, hqE);
8355 #endif
8356
8357    RETVOID;
8358 }
8359
8360 /**
8361  * @brief Harq Entity initialization for CMN SCH.
8362  *
8363  * @details
8364  *
8365  *     Function : rgSCHCmnDlInitHqEnt 
8366  *
8367  *     Harq Entity initialization for CMN SCH 
8368  *
8369  *  @param[in]  RgSchCellCb  *cell
8370  *  @param[in]  RgSchUeCb    *ue
8371  *  @return  S16
8372  *      -# ROK
8373  *      -# RFAILED
8374  **/
8375 #ifdef ANSI
8376 PUBLIC S16 rgSCHCmnDlInitHqEnt 
8377 (
8378 RgSchCellCb  *cell,
8379 RgSchDlHqEnt  *hqEnt
8380 )
8381 #else
8382 PUBLIC S16 rgSCHCmnDlInitHqEnt(cell, hqEnt)
8383 RgSchCellCb  *cell;
8384 RgSchDlHqEnt  *hqEnt;
8385 #endif
8386
8387 {
8388    RgSchDlHqProcCb      *hqP;
8389    U8                   cnt;
8390
8391    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8392    TRC2(rgSCHCmnDlInitHqEnt);
8393
8394    for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
8395    {
8396       hqP = &hqEnt->procs[cnt];
8397       if (rgSCHUtlAllocSBuf(cell->instIdx,
8398                (Data**)&(hqP->sch), (sizeof(RgSchCmnDlHqProc))) != ROK)
8399       {
8400          RETVALUE(RFAILED);
8401       }
8402    }
8403 #ifdef EMTC_ENABLE
8404    if((cell->emtcEnable) &&(hqEnt->ue->isEmtcUe))
8405    {
8406       if(ROK != cellSchd->apisEmtcDl->rgSCHDlUeHqEntInit(cell, hqEnt))
8407       {
8408          RETVALUE(RFAILED);
8409       }
8410
8411    }
8412    else
8413 #endif
8414    {
8415       if(ROK != cellSchd->apisDl->rgSCHDlUeHqEntInit(cell, hqEnt))
8416       {
8417          RETVALUE(RFAILED);
8418       }
8419    }
8420
8421    RETVALUE(ROK);
8422 }  /* rgSCHCmnDlInitHqEnt */
8423
8424 /**
8425  * @brief This function computes distribution of refresh period
8426  *
8427  * @details
8428  *
8429  *     Function: rgSCHCmnGetRefreshDist 
8430  *     Purpose: This function computes distribution of refresh period
8431  *              This is required to align set of UEs refresh
8432  *              around the different consecutive subframe.
8433  *               
8434  *     Invoked by: rgSCHCmnGetRefreshPerDist
8435  *
8436  *  @param[in]  RgSchCellCb        *cell
8437  *  @param[in]  RgSchUeCb          *ue
8438  *  @return  Void
8439  *
8440  **/
8441 #ifdef ANSI
8442 PRIVATE U8 rgSCHCmnGetRefreshDist 
8443 (
8444 RgSchCellCb        *cell,
8445 RgSchUeCb          *ue
8446 )
8447 #else
8448 PRIVATE U8 rgSCHCmnGetRefreshDist(cell, ue)
8449 RgSchCellCb        *cell;
8450 RgSchUeCb          *ue;
8451 #endif
8452 {
8453    U8   refOffst;
8454 #ifdef DEBUGP
8455    Inst inst = cell->instIdx;
8456 #endif
8457    TRC2(rgSCHCmnGetRefreshDist);
8458
8459    for(refOffst = 0; refOffst < RGSCH_MAX_REFRESH_OFFSET; refOffst++)
8460    {
8461       if(cell->refreshUeCnt[refOffst] < RGSCH_MAX_REFRESH_GRPSZ)
8462       {
8463          cell->refreshUeCnt[refOffst]++;
8464          ue->refreshOffset = refOffst;
8465          /* printf("UE[%d] refresh offset[%d]. Cell refresh ue count[%d].\n", ue->ueId, refOffst,  cell->refreshUeCnt[refOffst]); */
8466          RETVALUE(refOffst);
8467       }
8468    }
8469   
8470    RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Allocation of refresh distribution failed\n"));
8471    /* We should not enter here  normally, but incase of failure, allocating from  last offset*/
8472    cell->refreshUeCnt[refOffst-1]++;
8473    ue->refreshOffset = refOffst-1;
8474
8475    RETVALUE(refOffst-1);
8476 }
8477 /**
8478  * @brief This function computes initial Refresh Wait Period.
8479  *
8480  * @details
8481  *
8482  *     Function: rgSCHCmnGetRefreshPer 
8483  *     Purpose: This function computes initial Refresh Wait Period.
8484  *              This is required to align multiple UEs refresh
8485  *              around the same time.
8486  *               
8487  *     Invoked by: rgSCHCmnGetRefreshPer 
8488  *
8489  *  @param[in]  RgSchCellCb        *cell
8490  *  @param[in]  RgSchUeCb          *ue
8491  *  @param[in]  U32                *waitPer 
8492  *  @return  Void
8493  *
8494  **/
8495 #ifdef ANSI
8496 PRIVATE Void rgSCHCmnGetRefreshPer 
8497 (
8498 RgSchCellCb        *cell,
8499 RgSchUeCb          *ue,
8500 U32                *waitPer
8501 )
8502 #else
8503 PRIVATE Void rgSCHCmnGetRefreshPer(cell, ue, waitPer)
8504 RgSchCellCb        *cell;
8505 RgSchUeCb          *ue;
8506 U32                *waitPer;
8507 #endif
8508 {
8509    U32       refreshPer;           
8510    U32       crntSubFrm;
8511
8512    TRC2(rgSCHCmnGetRefreshPer);     
8513
8514    refreshPer = RG_SCH_CMN_REFRESH_TIME * RG_SCH_CMN_REFRESH_TIMERES;
8515    crntSubFrm = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe;
8516    /* Fix: syed align multiple UEs to refresh at same time */
8517    *waitPer = refreshPer - (crntSubFrm % refreshPer);
8518    *waitPer = RGSCH_CEIL(*waitPer, RG_SCH_CMN_REFRESH_TIMERES);
8519    *waitPer = *waitPer + rgSCHCmnGetRefreshDist(cell, ue);
8520
8521    RETVOID;
8522 }
8523
8524
8525 #ifdef LTE_ADV
8526 /**
8527  * @brief UE initialisation for scheduler.
8528  *
8529  * @details
8530  *
8531  *     Function : rgSCHCmnRgrSCellUeCfg
8532  *
8533  *     This functions intialises UE specific scheduler 
8534  *     information for SCELL
8535  *     0. Perform basic validations
8536  *     1. Allocate common sched UE cntrl blk
8537  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
8538  *     3. Perform UL cfg
8539  *     4. Perform DLFS cfg
8540  *
8541  *  @param[in]  RgSchCellCb  *cell
8542  *  @param[in]  RgSchUeCb    *ue
8543  *  @param[out] RgSchErrInfo *err
8544  *  @return  S16
8545  *      -# ROK
8546  *      -# RFAILED
8547  **/
8548 #ifdef ANSI
8549 PUBLIC S16 rgSCHCmnRgrSCellUeCfg
8550 (
8551 RgSchCellCb  *sCell,
8552 RgSchUeCb    *ue,
8553 RgrUeSecCellCfg  *sCellInfoCfg,
8554 RgSchErrInfo *err
8555 )
8556 #else
8557 PUBLIC S16 rgSCHCmnRgrSCellUeCfg(sCell, ue, sCellInfoCfg, err)
8558 RgSchCellCb  *sCell;
8559 RgSchUeCb    *ue;
8560 RgrUeSecCellCfg  *sCellInfoCfg;
8561 RgSchErrInfo *err;
8562 #endif
8563 {
8564    U8 i;
8565    S16                  ret;
8566    U8                   cnt;
8567    RgSchCmnAllocRecord  *allRcd;
8568    RgSchDlRbAlloc       *allocInfo;
8569    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
8570    RgSchCmnUlUe         *ueUl;
8571    RgSchCmnUlUe         *ueUlPcell;
8572    RgSchCmnUe           *pCellUeSchCmn;
8573    RgSchCmnUe           *ueSchCmn;
8574    RgSchCmnDlUe         *ueDl;
8575    RgSchCmnDlUe         *pCellUeDl;
8576 #ifdef DEBUGP
8577    Inst                 inst = ue->cell->instIdx;
8578 #endif
8579    U32 idx = (U8)((sCell->cellId - rgSchCb[sCell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
8580    TRC2(rgSCHCmnRgrSCellUeCfg);
8581
8582    pCellUeSchCmn = RG_SCH_CMN_GET_UE(ue,ue->cell);
8583    pCellUeDl = &pCellUeSchCmn->dl;
8584
8585    /* 1. Allocate Common sched control block */
8586    if((rgSCHUtlAllocSBuf(sCell->instIdx,
8587                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
8588    {
8589       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Memory allocation FAILED\n"));
8590       err->errCause = RGSCHERR_SCH_CFG;
8591       RETVALUE(RFAILED);
8592    }
8593    ueSchCmn = RG_SCH_CMN_GET_UE(ue,sCell);
8594
8595    /*2.  Perform UEs downlink configuration */
8596    ueDl = &ueSchCmn->dl;
8597
8598    /*CA TODO*/
8599    ueDl->mimoInfo = pCellUeDl->mimoInfo;
8600
8601    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
8602          (ue->mimoInfo.txMode == RGR_UE_TM_6))
8603    {
8604       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_NO_PMI);
8605    }
8606    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
8607    {
8608       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_RI_1);
8609    }
8610    RGSCH_ARRAY_BOUND_CHECK(sCell->instIdx, rgUeCatTbl, pCellUeSchCmn->cmn.ueCat);
8611    ueDl->maxTbBits = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlTbBits;
8612    /*CA dev-Start*/
8613    U8 ri = 0;
8614    ri = RGSCH_MIN(ri, sCell->numTxAntPorts);
8615    if(((CM_LTE_UE_CAT_6 == pCellUeSchCmn->cmn.ueCat )
8616             ||(CM_LTE_UE_CAT_7 == pCellUeSchCmn->cmn.ueCat)) 
8617          && (4 == ri))
8618    {
8619       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[1];
8620    }
8621    else
8622    {
8623       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[0];
8624    }
8625    /*CA dev-End*/
8626    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
8627 #ifdef LTE_TDD
8628    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
8629          rgSchTddDlNumHarqProcTbl[sCell->ulDlCfgIdx]);
8630 #else
8631    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
8632          RGSCH_NUM_DL_HQ_PROC);
8633 #endif
8634 #ifdef EMTC_ENABLE   
8635    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, ue->isEmtcUe);
8636 #else
8637    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, FALSE);
8638 #endif      
8639
8640    /* DL ambr */
8641    /* ambrCfgd config moved to ueCb.dl, as it's not needed for per cell wise*/
8642
8643    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, sCell);
8644    allocInfo->rnti = ue->ueId;
8645
8646    /* Initializing the lastCfi value to current cfi value */
8647    ueDl->lastCfi = cellSchd->dl.currCfi;
8648
8649    if ((cellSchd->apisDl->rgSCHRgrSCellDlUeCfg(sCell, ue, err)) != ROK)
8650    {
8651       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Spec Sched DL UE CFG FAILED\n"));
8652       RETVALUE(RFAILED);
8653    }
8654
8655    /* TODO: enhance for DLFS RB Allocation for SCELLs in future dev */
8656
8657    /* DLFS UE Config */
8658    if (cellSchd->dl.isDlFreqSel)
8659    {
8660       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeCfg(sCell, ue, sCellInfoCfg, err)) != ROK)
8661       {
8662          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS UE config FAILED\n"));
8663          RETVALUE(RFAILED);
8664       }
8665    }
8666
8667    /* TODO: Do UL SCELL CFG during UL CA dev */
8668    {
8669       ueUl = RG_SCH_CMN_GET_UL_UE(ue, sCell);
8670
8671       /* TODO_ULCA: SRS for SCELL needs to be handled in the below function call */
8672       rgSCHCmnUpdUeUlCqiInfo(sCell, ue, ueUl, ueSchCmn, cellSchd,
8673             sCell->isCpUlExtend);
8674
8675       ret = rgSCHUhmHqEntInit(sCell, ue);
8676       if (ret != ROK)
8677       {
8678          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL UHM HARQ Ent Init "
8679                "Failed for CRNTI:%d", ue->ueId);
8680          RETVALUE(RFAILED);
8681       }
8682
8683       ueUlPcell = RG_SCH_CMN_GET_UL_UE(ue, ue->cell);
8684       /* Initialize uplink HARQ related information for UE */
8685       ueUl->hqEnt.maxHqRetx = ueUlPcell->hqEnt.maxHqRetx;
8686       cmLListInit(&ueUl->hqEnt.free);
8687       cmLListInit(&ueUl->hqEnt.inUse);
8688       for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
8689       {
8690          ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
8691          ueUl->hqEnt.hqProcCb[i].procId = i;
8692          ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
8693          ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
8694 #ifdef LTEMAC_SPS
8695          /* ccpu00139513- Initializing SPS flags*/
8696          ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
8697          ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
8698 #endif
8699          cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
8700          ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
8701       }
8702
8703       /* Allocate UL BSR allocation tracking List */
8704       cmLListInit(&ueUl->ulAllocLst);
8705
8706       for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
8707       {
8708          if((rgSCHUtlAllocSBuf(sCell->instIdx,
8709                      (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
8710          {
8711             RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL Memory allocation FAILED"
8712                   "for CRNTI:%d",ue->ueId);
8713             err->errCause = RGSCHERR_SCH_CFG;
8714             RETVALUE(RFAILED);
8715          }
8716          allRcd->allocTime = sCell->crntTime;
8717          cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
8718          allRcd->lnk.node = (PTR)allRcd;
8719       }
8720
8721       /* After initialising UL part, do power related init */
8722       ret = rgSCHPwrUeSCellCfg(sCell, ue, sCellInfoCfg);
8723       if (ret != ROK)
8724       {
8725          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Could not do "
8726                "power config for UE CRNTI:%d",ue->ueId);
8727          RETVALUE(RFAILED);
8728       }
8729
8730 #ifdef EMTC_ENABLE   
8731       if(TRUE == ue->isEmtcUe)
8732       {
8733          if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
8734          {
8735             RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED"
8736                   "for CRNTI:%d",ue->ueId);
8737             RETVALUE(RFAILED);
8738          }
8739       }
8740       else
8741 #endif
8742       {
8743       if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
8744       {
8745          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED"
8746                "for CRNTI:%d",ue->ueId);
8747          RETVALUE(RFAILED);
8748       }
8749       }
8750    
8751       ue->ul.isUlCaEnabled = TRUE;
8752    }
8753
8754    RETVALUE(ROK);
8755 }  /* rgSCHCmnRgrSCellUeCfg */
8756
8757
8758 /**
8759  * @brief UE initialisation for scheduler.
8760  *
8761  * @details
8762  *
8763  *     Function : rgSCHCmnRgrSCellUeDel 
8764  *
8765  *     This functions Delete UE specific scheduler 
8766  *     information for SCELL
8767  *
8768  *  @param[in]  RgSchCellCb  *cell
8769  *  @param[in]  RgSchUeCb    *ue
8770  *  @return  S16
8771  *      -# ROK
8772  *      -# RFAILED
8773  **/
8774 #ifdef ANSI
8775 PUBLIC S16 rgSCHCmnRgrSCellUeDel
8776 (
8777 RgSchUeCellInfo *sCellInfo,
8778 RgSchUeCb    *ue
8779 )
8780 #else
8781 PUBLIC S16 rgSCHCmnRgrSCellUeDel(sCellInfo, ue)
8782 RgSchUeCellInfo *sCellInfo;
8783 RgSchUeCb    *ue;
8784 #endif
8785 {
8786    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
8787    Inst                 inst = ue->cell->instIdx;
8788
8789    TRC2(rgSCHCmnRgrSCellUeDel);
8790
8791    cellSchd->apisDl->rgSCHRgrSCellDlUeDel(sCellInfo, ue);
8792
8793    /* UL CA */
8794    rgSCHCmnUlUeDelAllocs(sCellInfo->cell, ue);
8795
8796 #ifdef EMTC_ENABLE   
8797    if(TRUE == ue->isEmtcUe)
8798    {
8799       cellSchd->apisEmtcUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
8800    }
8801    else
8802 #endif
8803    {
8804    cellSchd->apisUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
8805    }
8806
8807    /* DLFS UE Config */
8808    if (cellSchd->dl.isDlFreqSel)
8809    {
8810       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeDel(sCellInfo->cell, ue)) != ROK)
8811       {
8812          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS Scell del FAILED\n"));
8813          RETVALUE(RFAILED);
8814       }
8815    }
8816
8817    rgSCHUtlFreeSBuf(sCellInfo->cell->instIdx,
8818          (Data**)(&(sCellInfo->sch)), (sizeof(RgSchCmnUe)));
8819
8820
8821    RETVALUE(ROK);
8822 }  /* rgSCHCmnRgrSCellUeDel */
8823  
8824 #endif
8825
8826 #ifdef RG_5GTF
8827 /**
8828  * @brief Handles 5gtf configuration for a UE
8829  *
8830  * @details
8831  *
8832  *     Function : rgSCHCmn5gtfUeCfg
8833  *
8834  *     Processing Steps:
8835  *
8836  *      - Return ROK
8837  *
8838  *  @param[in]  RgSchCellCb  *cell
8839  *  @param[in]  RgSchUeCb    *ue
8840  *  @param[in]  RgrUeCfg     *cfg
8841  *  @return  S16
8842  *      -# ROK
8843  *      -# RFAILED
8844  **/
8845 #ifdef ANSI
8846 PUBLIC S16 rgSCHCmn5gtfUeCfg
8847 (
8848 RgSchCellCb *cell,
8849 RgSchUeCb   *ue,
8850 RgrUeCfg    *cfg
8851 )
8852 #else
8853 PUBLIC S16 rgSCHCmn5gtfUeCfg(cell, ue, cfg)
8854 RgSchCellCb *cell;
8855 RgSchUeCb   *ue;
8856 RgrUeCfg    *cfg;
8857 #endif
8858 {
8859    TRC2(rgSCHCmnRgrUeCfg);
8860
8861    RgSchUeGrp *ue5gtfGrp;
8862    ue->ue5gtfCb.grpId = cfg->ue5gtfCfg.grpId;
8863    ue->ue5gtfCb.BeamId = cfg->ue5gtfCfg.BeamId;
8864    ue->ue5gtfCb.numCC = cfg->ue5gtfCfg.numCC;   
8865    ue->ue5gtfCb.mcs = cfg->ue5gtfCfg.mcs;
8866    ue->ue5gtfCb.maxPrb = cfg->ue5gtfCfg.maxPrb;
8867
8868    ue->ue5gtfCb.cqiRiPer = 100;
8869    /* 5gtf TODO: CQIs to start from (10,0)*/
8870    ue->ue5gtfCb.nxtCqiRiOccn.sfn = 10;
8871    ue->ue5gtfCb.nxtCqiRiOccn.subframe = 0;
8872    ue->ue5gtfCb.rank = 1;
8873
8874    printf("\nschd cfg at mac,%u,%u,%u,%u,%u\n",ue->ue5gtfCb.grpId,ue->ue5gtfCb.BeamId,ue->ue5gtfCb.numCC,
8875          ue->ue5gtfCb.mcs,ue->ue5gtfCb.maxPrb); 
8876
8877    ue5gtfGrp = &(cell->cell5gtfCb.ueGrp5gConf[ue->ue5gtfCb.BeamId]);
8878
8879    /* TODO_5GTF: Currently handling 1 group only. Need to update when multi group 
8880       scheduling comes into picture */
8881    if(ue5gtfGrp->beamBitMask & (1 << ue->ue5gtfCb.BeamId))
8882    {
8883       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8884             "5GTF_ERROR Invalid beam id CRNTI:%d",cfg->crnti);
8885       RETVALUE(RFAILED);
8886    }
8887    ue5gtfGrp->beamBitMask |= (1 << ue->ue5gtfCb.BeamId);
8888
8889    RETVALUE(ROK);
8890 }
8891 #endif
8892
8893 /**
8894  * @brief UE initialisation for scheduler.
8895  *
8896  * @details
8897  *
8898  *     Function : rgSCHCmnRgrUeCfg
8899  *
8900  *     This functions intialises UE specific scheduler
8901  *     information
8902  *     0. Perform basic validations
8903  *     1. Allocate common sched UE cntrl blk
8904  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
8905  *     3. Perform UL cfg
8906  *     4. Perform DLFS cfg
8907  *
8908  *  @param[in]  RgSchCellCb  *cell
8909  *  @param[in]  RgSchUeCb    *ue
8910  *  @param[int] RgrUeCfg     *ueCfg
8911  *  @param[out] RgSchErrInfo *err
8912  *  @return  S16
8913  *      -# ROK
8914  *      -# RFAILED
8915  **/
8916 #ifdef ANSI
8917 PUBLIC S16 rgSCHCmnRgrUeCfg
8918 (
8919 RgSchCellCb  *cell,
8920 RgSchUeCb    *ue,
8921 RgrUeCfg     *ueCfg,
8922 RgSchErrInfo *err
8923 )
8924 #else
8925 PUBLIC S16 rgSCHCmnRgrUeCfg(cell, ue, ueCfg, err)
8926 RgSchCellCb  *cell;
8927 RgSchUeCb    *ue;
8928 RgrUeCfg     *ueCfg;
8929 RgSchErrInfo *err;
8930 #endif
8931 {
8932    RgSchDlRbAlloc  *allocInfo;
8933    S16                  ret;
8934    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8935    RgSchCmnUe           *ueSchCmn;
8936    RgSchCmnUlUe         *ueUl;
8937    RgSchCmnDlUe         *ueDl;
8938    U8                   cnt;
8939    RgSchCmnAllocRecord  *allRcd;
8940    U32                  waitPer;
8941    U32                  idx = (U8)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
8942    RgSchUeCellInfo      *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
8943    TRC2(rgSCHCmnRgrUeCfg);
8944
8945
8946    /* 1. Allocate Common sched control block */
8947    if((rgSCHUtlAllocSBuf(cell->instIdx,
8948                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
8949    {
8950       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8951             "Memory allocation FAILED for CRNTI:%d",ueCfg->crnti);
8952       err->errCause = RGSCHERR_SCH_CFG;
8953       RETVALUE(RFAILED);
8954    }
8955    ueSchCmn   = RG_SCH_CMN_GET_UE(ue,cell);
8956    ue->dl.ueDlCqiCfg = ueCfg->ueDlCqiCfg;
8957    pCellInfo->acqiCb.aCqiCfg = ueCfg->ueDlCqiCfg.aprdCqiCfg;
8958    if(ueCfg->ueCatEnum > 0 )
8959    {
8960      /*KWORK_FIX removed NULL chk for ueSchCmn*/
8961       ueSchCmn->cmn.ueCat = ueCfg->ueCatEnum - 1; 
8962    }
8963    else
8964    {
8965       ueSchCmn->cmn.ueCat = 0; /* Assuming enum values correctly set */
8966    }
8967    cmInitTimers(&ueSchCmn->cmn.tmr, 1);
8968
8969    /*2.  Perform UEs downlink configuration */
8970    ueDl = &ueSchCmn->dl;
8971    /* RACHO : store the rapId assigned for HandOver UE.
8972     * Append UE to handover list of cmnCell */
8973    if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
8974    {
8975       rgSCHCmnDelDedPreamble(cell, ueCfg->dedPreambleId.val);
8976       ueDl->rachInfo.hoRapId = ueCfg->dedPreambleId.val;
8977       cmLListAdd2Tail(&cellSchd->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
8978       ueDl->rachInfo.hoLnk.node = (PTR)ue;
8979    }
8980
8981    rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd);
8982
8983    if (ueCfg->txMode.pres == TRUE)
8984    {
8985       if ((ueCfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8986             (ueCfg->txMode.txModeEnum == RGR_UE_TM_6))
8987       {
8988          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8989       }
8990       if (ueCfg->txMode.txModeEnum == RGR_UE_TM_3)
8991       {
8992          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8993       }
8994    }
8995    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
8996    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
8997    /*CA dev-Start*/
8998    U8 ri = 0;
8999    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
9000    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
9001             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
9002                   && (4 == ri))
9003    {
9004       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
9005    }
9006    else
9007    {
9008       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
9009    }
9010    /*CA dev-End*/
9011    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
9012 #ifdef LTE_TDD
9013    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
9014          rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]);
9015 #else
9016    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
9017          RGSCH_NUM_DL_HQ_PROC);
9018 #endif
9019 #ifdef EMTC_ENABLE   
9020    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
9021 #else
9022    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
9023 #endif 
9024      /* if none of the DL and UL AMBR are configured then fail the configuration
9025     */     
9026    if((ueCfg->ueQosCfg.dlAmbr == 0) && (ueCfg->ueQosCfg.ueBr == 0))
9027    {
9028       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"UL Ambr and DL Ambr are"
9029          "configured as 0 for CRNTI:%d",ueCfg->crnti);
9030       err->errCause = RGSCHERR_SCH_CFG;
9031       RETVALUE(RFAILED);
9032    }
9033    /* DL ambr */
9034    ue->dl.ambrCfgd = (ueCfg->ueQosCfg.dlAmbr * RG_SCH_CMN_REFRESH_TIME)/100;
9035
9036    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
9037    allocInfo->rnti = ue->ueId;
9038
9039    /* Initializing the lastCfi value to current cfi value */
9040    ueDl->lastCfi = cellSchd->dl.currCfi;
9041 #ifdef EMTC_ENABLE
9042    if(cell->emtcEnable && ue->isEmtcUe)
9043    {
9044       if ((cellSchd->apisEmtcDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
9045       {
9046          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9047                "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
9048          RETVALUE(RFAILED);
9049       }
9050
9051    }
9052    else
9053 #endif
9054    {
9055       if ((cellSchd->apisDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
9056       {
9057          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9058                "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
9059          RETVALUE(RFAILED);
9060       }
9061    }
9062
9063
9064
9065    /* 3. Initialize ul part */
9066    ueUl     = &ueSchCmn->ul;
9067
9068    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd,
9069             cell->isCpUlExtend);
9070
9071    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
9072                                RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
9073
9074    ue->ul.cfgdAmbr = (ueCfg->ueQosCfg.ueBr * RG_SCH_CMN_REFRESH_TIME)/100;
9075    ue->ul.effAmbr = ue->ul.cfgdAmbr;
9076    RGSCHCPYTIMEINFO(cell->crntTime, ue->ul.ulTransTime);
9077
9078    /* Allocate UL BSR allocation tracking List */
9079    cmLListInit(&ueUl->ulAllocLst);
9080
9081    for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
9082    {
9083       if((rgSCHUtlAllocSBuf(cell->instIdx,
9084                   (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
9085       {
9086          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED"
9087                    "for CRNTI:%d",ueCfg->crnti);
9088          err->errCause = RGSCHERR_SCH_CFG;
9089          RETVALUE(RFAILED);
9090       }
9091       allRcd->allocTime = cell->crntTime;
9092       cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
9093       allRcd->lnk.node = (PTR)allRcd;
9094    }
9095    /* Allocate common sch cntrl blocks for LCGs */
9096    for (cnt=0; cnt<RGSCH_MAX_LCG_PER_UE; cnt++)
9097    {
9098       ret = rgSCHUtlAllocSBuf(cell->instIdx,
9099             (Data**)&(ue->ul.lcgArr[cnt].sch), (sizeof(RgSchCmnLcg)));
9100       if (ret != ROK)
9101       {
9102          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9103             "SCH struct alloc failed for CRNTI:%d",ueCfg->crnti);
9104          err->errCause = RGSCHERR_SCH_CFG;
9105          RETVALUE(ret);
9106       }
9107    }
9108    /* After initialising UL part, do power related init */
9109    ret = rgSCHPwrUeCfg(cell, ue, ueCfg);
9110    if (ret != ROK)
9111    {
9112       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do "
9113          "power config for UE CRNTI:%d",ueCfg->crnti);
9114       RETVALUE(RFAILED);
9115    }
9116 #ifdef LTEMAC_SPS
9117    ret = rgSCHCmnSpsUeCfg(cell, ue, ueCfg, err);
9118    if (ret != ROK)
9119    {
9120       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do "
9121          "SPS config for CRNTI:%d",ueCfg->crnti);
9122       RETVALUE(RFAILED);
9123    }
9124 #endif /* LTEMAC_SPS */
9125
9126 #ifdef EMTC_ENABLE   
9127    if(TRUE == ue->isEmtcUe)
9128    {
9129       if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
9130       {
9131          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED"
9132                   "for CRNTI:%d",ueCfg->crnti);
9133          RETVALUE(RFAILED);
9134       }
9135    }
9136    else
9137 #endif
9138    {
9139    if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
9140    {
9141       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED"
9142                "for CRNTI:%d",ueCfg->crnti);
9143       RETVALUE(RFAILED);
9144    }
9145    }
9146
9147    /* DLFS UE Config */
9148    if (cellSchd->dl.isDlFreqSel)
9149    {
9150       if ((cellSchd->apisDlfs->rgSCHDlfsUeCfg(cell, ue, ueCfg, err)) != ROK)
9151       {
9152          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "DLFS UE config FAILED"
9153                    "for CRNTI:%d",ueCfg->crnti);
9154          RETVALUE(RFAILED);
9155       }
9156    }
9157
9158    /* Fix: syed align multiple UEs to refresh at same time */
9159    rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
9160    /* Start UE Qos Refresh Timer */
9161    rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
9162 #ifdef RG_5GTF
9163    rgSCHCmn5gtfUeCfg(cell, ue, ueCfg);
9164 #endif
9165
9166    RETVALUE(ROK);
9167 }  /* rgSCHCmnRgrUeCfg */
9168
9169 /**
9170  * @brief UE TX mode reconfiguration handler.
9171  *
9172  * @details
9173  *
9174  *     Function : rgSCHCmnDlHdlTxModeRecfg
9175  *
9176  *     This functions updates UE specific scheduler
9177  *     information upon UE reconfiguration.
9178  *
9179  *  @param[in]  RgSchUeCb    *ue
9180  *  @param[in] RgrUeRecfg   *ueRecfg
9181  *  @return  Void
9182  **/
9183 #ifdef TFU_UPGRADE
9184 #ifdef ANSI
9185 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg
9186 (
9187 RgSchCellCb *cell,
9188 RgSchUeCb    *ue,
9189 RgrUeRecfg   *ueRecfg,
9190 U8 numTxPorts
9191 )
9192 #else
9193 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, numTxPorts)
9194 RgSchCellCb *cell;
9195 RgSchUeCb    *ue;
9196 RgrUeRecfg   *ueRecfg;
9197 U8 numTxPorts;
9198 #endif
9199 #else
9200 #ifdef ANSI
9201 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg
9202 (
9203 RgSchCellCb *cell,
9204 RgSchUeCb    *ue,
9205 RgrUeRecfg   *ueRecfg
9206 )
9207 #else
9208 PRIVATE Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg)
9209 RgSchCellCb *cell;
9210 RgSchUeCb    *ue;
9211 RgrUeRecfg   *ueRecfg;
9212 #endif
9213 #endif
9214 {
9215    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
9216    TRC2(rgSCHCmnDlHdlTxModeRecfg);
9217
9218    if (ueRecfg->txMode.pres != PRSNT_NODEF)
9219    {
9220       RETVOID;
9221    }
9222    /* ccpu00140894- Starting Timer for TxMode Transition Completion*/
9223    ue->txModeTransCmplt =FALSE;
9224    rgSCHTmrStartTmr (ue->cell, ue, RG_SCH_TMR_TXMODE_TRNSTN, RG_SCH_TXMODE_TRANS_TIMER);
9225    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_CMPLT)
9226    {
9227       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell,
9228                                 RG_SCH_CMN_TD_TXMODE_RECFG);
9229      /* MS_WORKAROUND for ccpu00123186 MIMO Fix Start: need to set FORCE TD bitmap based on TX mode */
9230      ueDl->mimoInfo.ri = 1;
9231      if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
9232           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
9233       {
9234          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
9235       }
9236       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
9237       {
9238          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
9239       }
9240       /* MIMO Fix End: need to set FORCE TD bitmap based on TX mode */
9241       RETVOID;
9242    }
9243    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_START)
9244    {
9245       /* start afresh forceTD masking */
9246       RG_SCH_CMN_INIT_FORCE_TD(ue, cell, 0);
9247       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_TXMODE_RECFG);
9248       /* Intialize MIMO related parameters of UE */
9249
9250 #ifdef TFU_UPGRADE
9251       if(ueRecfg->txMode.pres)
9252       {
9253          if((ueRecfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
9254                (ueRecfg->txMode.txModeEnum ==RGR_UE_TM_4))
9255          {
9256             if(ueRecfg->ueCodeBookRstRecfg.pres)
9257             {
9258                ueDl->mimoInfo.ri =
9259                   rgSCHCmnComputeRank(ueRecfg->txMode.txModeEnum,
9260                     ueRecfg->ueCodeBookRstRecfg.pmiBitMap, numTxPorts);
9261             }
9262             else
9263             {
9264                ueDl->mimoInfo.ri = 1;
9265             }
9266          }
9267          else
9268          {
9269             ueDl->mimoInfo.ri = 1;
9270          }
9271       }
9272       else
9273       {
9274          ueDl->mimoInfo.ri = 1;
9275       }
9276 #else
9277       ueDl->mimoInfo.ri = 1;
9278 #endif /* TFU_UPGRADE */
9279       if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
9280           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
9281       {
9282          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
9283       }
9284       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
9285       {
9286          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
9287       }
9288       RETVOID;
9289    }
9290 }
9291 /***********************************************************
9292  *
9293  *     Func : rgSCHCmnUpdUeMimoInfo
9294  *
9295  *     Desc : Updates UL and DL Ue Information
9296  *
9297  *     Ret  :
9298  *
9299  *     Notes:
9300  *
9301  *     File :
9302  *
9303  **********************************************************/
9304 #ifdef ANSI
9305 PRIVATE Void rgSCHCmnUpdUeMimoInfo
9306 (
9307 RgrUeCfg     *ueCfg,
9308 RgSchCmnDlUe *ueDl,
9309 RgSchCellCb  *cell,
9310 RgSchCmnCell *cellSchd
9311 )
9312 #else
9313 PRIVATE Void rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd)
9314 RgrUeCfg     *ueCfg;
9315 RgSchCmnDlUe *ueDl;
9316 RgSchCellCb  *cell;
9317 RgSchCmnCell *cellSchd;
9318 #endif
9319 {
9320    TRC2(rgSCHCmnUpdUeMimoInfo)
9321 #ifdef TFU_UPGRADE
9322    if(ueCfg->txMode.pres)
9323    {
9324       if((ueCfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
9325             (ueCfg->txMode.txModeEnum ==RGR_UE_TM_4))
9326       {
9327          if(ueCfg->ueCodeBookRstCfg.pres)
9328          {
9329             ueDl->mimoInfo.ri =
9330                rgSCHCmnComputeRank(ueCfg->txMode.txModeEnum,
9331                  ueCfg->ueCodeBookRstCfg.pmiBitMap, cell->numTxAntPorts);
9332          }
9333          else
9334          {
9335             ueDl->mimoInfo.ri = 1;
9336          }
9337       }
9338       else
9339       {
9340          ueDl->mimoInfo.ri = 1;
9341       }
9342    }
9343    else
9344    {
9345       ueDl->mimoInfo.ri = 1;
9346    }
9347
9348 #else
9349    ueDl->mimoInfo.ri = 1;
9350 #endif /*TFU_UPGRADE */
9351    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
9352    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
9353
9354    RETVOID;
9355 }
9356 /***********************************************************
9357  *
9358  *     Func : rgSCHCmnUpdUeUlCqiInfo
9359  *
9360  *     Desc : Updates UL and DL Ue Information
9361  *
9362  *     Ret  :
9363  *
9364  *     Notes:
9365  *
9366  *     File :
9367  *
9368  **********************************************************/
9369 #ifdef ANSI
9370 PRIVATE Void rgSCHCmnUpdUeUlCqiInfo
9371 (
9372 RgSchCellCb   *cell,
9373 RgSchUeCb     *ue,
9374 RgSchCmnUlUe  *ueUl,
9375 RgSchCmnUe    *ueSchCmn,
9376 RgSchCmnCell  *cellSchd,
9377 Bool          isEcp
9378 )
9379 #else
9380 PRIVATE Void rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, isEcp)
9381 RgSchCellCb  *cell;
9382 RgSchUeCb    *ue;
9383 RgSchCmnUlUe *ueUl;
9384 RgSchCmnUe   *ueSchCmn;
9385 RgSchCmnCell *cellSchd;
9386 Bool          isEcp;
9387 #endif
9388 {
9389
9390    TRC2(rgSCHCmnUpdUeUlCqiInfo)
9391
9392 #ifdef TFU_UPGRADE
9393    if(ue->srsCb.srsCfg.type  ==  RGR_SCH_SRS_SETUP)
9394    {
9395      if(ue->ul.ulTxAntSel.pres)
9396      {
9397        ueUl->crntUlCqi[ue->srsCb.selectedAnt] = cellSchd->ul.dfltUlCqi;
9398        ueUl->validUlCqi = ueUl->crntUlCqi[ue->srsCb.selectedAnt];
9399      }
9400      else
9401      {
9402        ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
9403        ueUl->validUlCqi =  ueUl->crntUlCqi[0];
9404      }
9405       ue->validTxAnt = ue->srsCb.selectedAnt;
9406    }
9407    else
9408    {
9409       ueUl->validUlCqi = cellSchd->ul.dfltUlCqi;
9410       ue->validTxAnt = 0;
9411    }
9412 #ifdef UL_LA
9413    ueUl->ulLaCb.cqiBasediTbs = rgSchCmnUlCqiToTbsTbl[isEcp]
9414                                                 [ueUl->validUlCqi] * 100;   
9415    ueUl->ulLaCb.deltaiTbs = 0;
9416 #endif
9417
9418 #else
9419    ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
9420 #endif /*TFU_UPGRADE */
9421    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
9422    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
9423    {
9424       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
9425    }
9426    else
9427    {
9428       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
9429    }
9430
9431    RETVOID;
9432 }
9433 /***********************************************************
9434  *
9435  *     Func : rgSCHCmnUpdUeCatCfg
9436  *
9437  *     Desc : Updates UL and DL Ue Information
9438  *
9439  *     Ret  :
9440  *
9441  *     Notes:
9442  *
9443  *     File :
9444  *
9445  **********************************************************/
9446 #ifdef ANSI
9447 PRIVATE Void rgSCHCmnUpdUeCatCfg
9448 (
9449 RgSchUeCb    *ue,
9450 RgSchCellCb  *cell
9451 )
9452 #else
9453 PRIVATE Void rgSCHCmnUpdUeCatCfg(ue, cell)
9454 RgSchUeCb    *ue;
9455 RgSchCellCb  *cell;
9456 #endif
9457 {
9458    RgSchDlHqEnt *hqE = NULLP;
9459    RgSchCmnUlUe *ueUl     = RG_SCH_CMN_GET_UL_UE(ue,cell);
9460    RgSchCmnDlUe *ueDl     = RG_SCH_CMN_GET_DL_UE(ue,cell);
9461    RgSchCmnUe   *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
9462    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
9463
9464    TRC2(rgSCHCmnUpdUeCatCfg)
9465
9466    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
9467    
9468    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
9469    /*CA dev-Start*/
9470    U8 ri = 0;
9471    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
9472    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
9473             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
9474          && (RG_SCH_MAX_TX_LYRS_4 == ri))
9475    {
9476       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
9477    }
9478    else
9479    {
9480       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
9481    }
9482    /*CA dev-End*/
9483    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
9484                            hqE->numHqPrcs);
9485    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
9486    {
9487       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
9488    }
9489    else
9490    {
9491       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
9492    }
9493    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
9494                    RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
9495    RETVOID;
9496 }
9497
9498 /**
9499  * @brief UE reconfiguration for scheduler.
9500  *
9501  * @details
9502  *
9503  *     Function : rgSChCmnRgrUeRecfg
9504  *
9505  *     This functions updates UE specific scheduler
9506  *     information upon UE reconfiguration.
9507  *
9508  *  @param[in]  RgSchCellCb  *cell
9509  *  @param[in]  RgSchUeCb    *ue
9510  *  @param[int] RgrUeRecfg   *ueRecfg
9511  *  @param[out] RgSchErrInfo *err
9512  *  @return  S16
9513  *      -# ROK
9514  *      -# RFAILED
9515  **/
9516 #ifdef ANSI
9517 PUBLIC S16 rgSCHCmnRgrUeRecfg
9518 (
9519 RgSchCellCb  *cell,
9520 RgSchUeCb    *ue,
9521 RgrUeRecfg   *ueRecfg,
9522 RgSchErrInfo *err
9523 )
9524 #else
9525 PUBLIC S16 rgSCHCmnRgrUeRecfg(cell, ue, ueRecfg, err)
9526 RgSchCellCb  *cell;
9527 RgSchUeCb    *ue;
9528 RgrUeRecfg   *ueRecfg;
9529 RgSchErrInfo *err;
9530 #endif
9531 {
9532    RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
9533    U32          waitPer;
9534
9535    TRC2(rgSCHCmnRgrUeRecfg);
9536    /* Basic validations */
9537    if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
9538    {
9539 #ifdef TFU_UPGRADE
9540       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, cell->numTxAntPorts);
9541 #else
9542       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg);
9543 #endif /* TFU_UPGRADE */
9544    }
9545    if(ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG)
9546    {
9547       ue->csgMmbrSta = ueRecfg->csgMmbrSta;
9548    }
9549    /* Changes for UE Category reconfiguration feature */
9550    if(ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
9551    {
9552        rgSCHCmnUpdUeCatCfg(ue, cell);
9553    }
9554    if (ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG)
9555    {
9556       RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
9557       pCellInfo->acqiCb.aCqiCfg = ueRecfg->aprdDlCqiRecfg;
9558    }
9559 #ifndef TFU_UPGRADE
9560    if (ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG)
9561    {
9562       if ((ueRecfg->prdDlCqiRecfg.pres == TRUE)
9563             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD10)
9564             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD20))
9565       {
9566          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unsupported periodic CQI "
9567             "reporting mode %d for old CRNIT:%d", 
9568             (int)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->oldCrnti);
9569          err->errCause = RGSCHERR_SCH_CFG;
9570          RETVALUE(RFAILED);
9571       }
9572      ue->dl.ueDlCqiCfg.prdCqiCfg = ueRecfg->prdDlCqiRecfg;
9573    }
9574 #endif
9575
9576    if (ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG)
9577    {
9578       if (rgSCHPwrUeRecfg(cell, ue, ueRecfg) != ROK)
9579       {
9580          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9581                "Power Reconfiguration Failed for OLD CRNTI:%d",ueRecfg->oldCrnti);
9582          RETVALUE(RFAILED);
9583       }
9584    }
9585
9586    if (ueRecfg->ueRecfgTypes & RGR_UE_QOS_RECFG)
9587    {
9588       /* Uplink Sched related Initialization */
9589       if ((ueRecfg->ueQosRecfg.dlAmbr == 0) && (ueRecfg->ueQosRecfg.ueBr == 0))
9590       {
9591          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Ul Ambr and DL Ambr "
9592             "configured as 0 for OLD CRNTI:%d",ueRecfg->oldCrnti);
9593          err->errCause = RGSCHERR_SCH_CFG;
9594          RETVALUE(RFAILED);
9595       }
9596       ue->ul.cfgdAmbr = (ueRecfg->ueQosRecfg.ueBr * \
9597       RG_SCH_CMN_REFRESH_TIME)/100;
9598       /* Downlink Sched related Initialization */
9599       ue->dl.ambrCfgd = (ueRecfg->ueQosRecfg.dlAmbr * \
9600       RG_SCH_CMN_REFRESH_TIME)/100;
9601       /* Fix: syed Update the effAmbr and effUeBR fields w.r.t the
9602        * new QOS configuration */
9603       rgSCHCmnDelUeFrmRefreshQ(cell, ue);
9604       /* Fix: syed align multiple UEs to refresh at same time */
9605       rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
9606       rgSCHCmnApplyUeRefresh(cell, ue);
9607       rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
9608    }
9609 #ifdef EMTC_ENABLE   
9610    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
9611    {
9612       if ((cellSchCmn->apisEmtcUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9613       {
9614          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9615                "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9616          RETVALUE(RFAILED);
9617       }
9618       if ((cellSchCmn->apisEmtcDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9619       {
9620          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9621                "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9622          RETVALUE(RFAILED);
9623       }
9624    }
9625    else
9626 #endif
9627    {
9628       if ((cellSchCmn->apisUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9629       {
9630          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9631             "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9632          RETVALUE(RFAILED);
9633       }
9634       if ((cellSchCmn->apisDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9635       {
9636          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9637             "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9638          RETVALUE(RFAILED);
9639       }
9640    }
9641    /* DLFS UE Config */
9642    if (cellSchCmn->dl.isDlFreqSel)
9643    {
9644       if ((cellSchCmn->apisDlfs->rgSCHDlfsUeRecfg(cell, ue, \
9645          ueRecfg, err)) != ROK)
9646       {
9647          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9648                "DLFS UE re-config FAILED for CRNTI:%d",ue->ueId);
9649          RETVALUE(RFAILED);
9650       }
9651    }
9652
9653 #ifdef LTEMAC_SPS
9654    /* Invoke re-configuration on SPS module */
9655    if (rgSCHCmnSpsUeRecfg(cell, ue, ueRecfg, err) != ROK)
9656    {
9657       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9658               "DL SPS ReCFG FAILED for UE CRNTI:%d", ue->ueId);
9659       RETVALUE(RFAILED);
9660    }
9661 #endif
9662
9663    RETVALUE(ROK);
9664 }  /* rgSCHCmnRgrUeRecfg*/
9665
9666 /***********************************************************
9667  *
9668  *     Func : rgSCHCmnUlUeDelAllocs
9669  *
9670  *     Desc : Deletion of all UE allocations.
9671  *
9672  *     Ret  :
9673  *
9674  *     Notes:
9675  *
9676  *     File :
9677  *
9678  **********************************************************/
9679 #ifdef ANSI
9680 PRIVATE Void rgSCHCmnUlUeDelAllocs
9681 (
9682 RgSchCellCb  *cell,
9683 RgSchUeCb   *ue
9684 )
9685 #else
9686 PRIVATE Void rgSCHCmnUlUeDelAllocs(cell, ue)
9687 RgSchCellCb  *cell;
9688 RgSchUeCb   *ue;
9689 #endif
9690 {
9691    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
9692    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
9693    U8 i;
9694 #ifdef LTEMAC_SPS
9695    RgSchCmnUlUeSpsInfo   *ulSpsUe   = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
9696 #endif
9697    TRC2(rgSCHCmnUlUeDelAllocs);
9698
9699    for (i = 0; i < ueUl->hqEnt.numHqPrcs; ++i)
9700    {
9701       RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, i);
9702
9703 #ifdef ERRCLS_KW
9704       /* proc can't be NULL here */
9705       if (proc)
9706 #endif
9707       {
9708          /* R8 Upgrade */
9709          proc->ndi = 0;
9710          if (proc->alloc)
9711          {
9712             /* Added Insure Fixes Of reading Dangling memory.NULLed crntAlloc */
9713 #ifdef LTEMAC_SPS
9714             if(proc->alloc == ulSpsUe->ulSpsSchdInfo.crntAlloc)
9715             {
9716                ulSpsUe->ulSpsSchdInfo.crntAlloc = NULLP;
9717                ulSpsUe->ulSpsSchdInfo.crntAllocSf = NULLP;
9718             }
9719 #endif
9720 #ifdef EMTC_ENABLE
9721             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
9722                   proc->alloc,ue->isEmtcUe);
9723 #else
9724             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
9725                   proc->alloc);
9726 #endif
9727             /* PHY probably needn't be intimated since
9728              * whatever intimation it needs happens at the last minute
9729              */
9730          }
9731          /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
9732           * from adaptive retx List. */
9733          if (proc->reTxLnk.node)
9734          {
9735             {
9736                //TODO_SID: Need to take care
9737                cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); 
9738                proc->reTxLnk.node = (PTR)NULLP;
9739             }
9740          }
9741       }
9742    }
9743    RETVOID;
9744 }
9745
9746 /***********************************************************
9747  *
9748  *     Func : rgSCHCmnDelUeFrmRefreshQ
9749  *
9750  *     Desc : Adds a UE to refresh queue, so that the UE is
9751  *            periodically triggered to refresh it's GBR and
9752  *            AMBR values.
9753  *
9754  *     Ret  :
9755  *
9756  *     Notes:
9757  *
9758  *     File :
9759  *
9760  **********************************************************/
9761 #ifdef ANSI
9762 PRIVATE Void rgSCHCmnDelUeFrmRefreshQ
9763 (
9764 RgSchCellCb     *cell,
9765 RgSchUeCb       *ue
9766 )
9767 #else
9768 PRIVATE Void rgSCHCmnDelUeFrmRefreshQ(cell, ue)
9769 RgSchCellCb     *cell;
9770 RgSchUeCb       *ue;
9771 #endif
9772 {
9773    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
9774    CmTmrArg       arg;
9775    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
9776
9777    TRC2(rgSCHCmnDelUeFrmRefreshQ);
9778
9779 #ifdef RGL_SPECIFIC_CHANGES
9780    if(ue->refreshOffset < RGSCH_MAX_REFRESH_GRPSZ)
9781    {
9782       if(cell->refreshUeCnt[ue->refreshOffset])
9783       {
9784          cell->refreshUeCnt[ue->refreshOffset]--;
9785       }
9786    }
9787 #endif
9788
9789
9790    cmMemset((U8 *)&arg, 0, sizeof(arg));
9791    arg.tqCp   = &sched->tmrTqCp;
9792    arg.tq     = sched->tmrTq;
9793    arg.timers = &ueSchd->tmr;
9794    arg.cb     = (PTR)ue;
9795    arg.tNum   = 0;
9796    arg.max    = 1;
9797    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
9798
9799    cmRmvCbTq(&arg);
9800    RETVOID;
9801 }
9802
9803 /***********************************************************
9804  *
9805  *     Func : rgSCHCmnUeCcchSduDel
9806  *
9807  *     Desc : Clear CCCH SDU scheduling context.
9808  *
9809  *     Ret  :
9810  *
9811  *     Notes:
9812  *
9813  *     File :
9814  *
9815  **********************************************************/
9816 #ifdef ANSI
9817 PRIVATE Void rgSCHCmnUeCcchSduDel
9818 (
9819 RgSchCellCb  *cell,
9820 RgSchUeCb    *ueCb
9821 )
9822 #else
9823 PRIVATE Void rgSCHCmnUeCcchSduDel(cell, ueCb)
9824 RgSchCellCb  *cell;
9825 RgSchUeCb    *ueCb;
9826 #endif
9827 {
9828    RgSchDlHqEnt      *hqE = NULLP;
9829    RgSchDlHqProcCb   *ccchSduHqP = NULLP;
9830    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
9831
9832    TRC2(rgSCHCmnUeCcchSduDel);
9833
9834    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
9835    if (hqE == NULLP)
9836    {
9837       RETVOID;
9838    }
9839    ccchSduHqP = hqE->ccchSduProc;
9840    if(ueCb->ccchSduLnk.node != NULLP)
9841    {
9842       /* Remove the ccchSduProc if it is in the Tx list */
9843       cmLListDelFrm(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
9844       ueCb->ccchSduLnk.node = NULLP;   
9845    }
9846    else if(ccchSduHqP != NULLP)
9847    {
9848       /* Fix for crash due to stale pdcch. Release ccch pdcch*/
9849       if(ccchSduHqP->pdcch)
9850       {
9851          cmLListDelFrm(&ccchSduHqP->subFrm->pdcchInfo.pdcchs,
9852                &ccchSduHqP->pdcch->lnk);
9853          cmLListAdd2Tail(&cell->pdcchLst, &ccchSduHqP->pdcch->lnk);
9854          ccchSduHqP->pdcch = NULLP;
9855       }
9856       if(ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node != NULLP)
9857       {
9858          /* Remove the ccchSduProc if it is in the retx list */
9859          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
9860           &ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk);
9861          /* ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node = NULLP; */
9862          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
9863       }
9864       else if ((ccchSduHqP->subFrm != NULLP) &&
9865        (ccchSduHqP->hqPSfLnk.node != NULLP))
9866       {
9867          rgSCHUtlDlHqPTbRmvFrmTx(ccchSduHqP->subFrm, 
9868                ccchSduHqP, 0, FALSE);
9869          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
9870       }
9871    }   
9872    RETVOID;
9873 }
9874
9875
9876
9877
9878 /**
9879  * @brief UE deletion for scheduler.
9880  *
9881  * @details
9882  *
9883  *     Function : rgSCHCmnUeDel
9884  *
9885  *     This functions deletes all scheduler information
9886  *     pertaining to an UE.
9887  *
9888  *  @param[in]  RgSchCellCb  *cell
9889  *  @param[in]  RgSchUeCb    *ue
9890  *  @return  Void
9891  **/
9892 #ifdef ANSI
9893 PUBLIC Void rgSCHCmnUeDel
9894 (
9895 RgSchCellCb  *cell,
9896 RgSchUeCb    *ue
9897 )
9898 #else
9899 PUBLIC Void rgSCHCmnUeDel(cell, ue)
9900 RgSchCellCb  *cell;
9901 RgSchUeCb    *ue;
9902 #endif
9903 {
9904    RgSchDlHqEnt         *hqE = NULLP;
9905    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
9906    CmLList              *node;
9907    RgSchCmnAllocRecord  *allRcd;
9908    U8                    cnt;
9909    RgSchCmnCell         *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
9910    U32                   idx = 0;
9911    TRC2(rgSCHCmnUeDel);
9912
9913    if (RG_SCH_CMN_GET_UE(ue,cell) == NULLP)
9914    {
9915       /* Common scheduler config has not happened yet */
9916       RETVOID;
9917    }
9918    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
9919    if(hqE)
9920    {
9921       /* UE Free can be triggered before MSG4 done when dlHqE is not updated */
9922 #ifdef EMTC_ENABLE
9923       if(ue->isEmtcUe)
9924       {
9925          rgSCHEmtcCmnUeCcchSduDel(cell, ue);
9926       }
9927       else
9928 #endif
9929      {    
9930          rgSCHCmnUeCcchSduDel(cell, ue);
9931      }
9932    }
9933    rgSCHCmnDelUeFrmRefreshQ(cell, ue);
9934
9935    rgSCHCmnUlUeDelAllocs(cell, ue);
9936
9937    rgSCHCmnDelRachInfo(cell, ue);
9938
9939 #ifdef EMTC_ENABLE   
9940    if(TRUE == ue->isEmtcUe)
9941    {
9942       cellSchCmn->apisEmtcUl->rgSCHFreeUlUe(cell, ue);
9943    }
9944    else
9945 #endif
9946    {
9947    cellSchCmn->apisUl->rgSCHFreeUlUe(cell, ue);
9948    }
9949 #ifdef LTE_ADV
9950    if (ue->numSCells)
9951    {
9952       for(idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
9953       {
9954          if(ue->cellInfo[idx] != NULLP) 
9955          {
9956             rgSCHSCellDelUeSCell(cell,ue,idx);
9957          }
9958       }
9959
9960    }
9961 #endif
9962 #ifdef EMTC_ENABLE
9963    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
9964    {
9965       cellSchCmn->apisEmtcDl->rgSCHFreeDlUe(cell, ue);
9966    }
9967    else
9968 #endif
9969    {
9970       cellSchCmn->apisDl->rgSCHFreeDlUe(cell, ue);
9971    }
9972    rgSCHPwrUeDel(cell, ue);
9973
9974 #ifdef LTEMAC_SPS
9975    rgSCHCmnSpsUeDel(cell, ue);
9976 #endif /* LTEMAC_SPS*/
9977
9978    /* CA Dev Start*/
9979    rgSchCmnDlSfHqDel(ue, cell);
9980    /* CA Dev End*/
9981    /* DLFS UE delete */
9982    if (cellSchCmn->dl.isDlFreqSel)
9983    {
9984       cellSchCmn->apisDlfs->rgSCHDlfsUeDel(cell, ue);
9985    }
9986    node = ueUl->ulAllocLst.first;
9987
9988 /* ccpu00117052 - MOD - Passing double pointer in all the places of
9989    rgSCHUtlFreeSBuf function call for proper NULLP assignment*/
9990    while(node)
9991    {
9992       allRcd = (RgSchCmnAllocRecord *)node->node;
9993       node = node->next;
9994       cmLListDelFrm(&ueUl->ulAllocLst, &allRcd->lnk);
9995       rgSCHUtlFreeSBuf(cell->instIdx,
9996          (Data**)(&allRcd), (sizeof(RgSchCmnAllocRecord)));
9997    }
9998
9999    for(cnt = 0; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
10000    {
10001       if (ue->ul.lcgArr[cnt].sch != NULLP)
10002       {
10003          rgSCHUtlFreeSBuf(cell->instIdx,
10004             (Data**)(&(ue->ul.lcgArr[cnt].sch)), (sizeof(RgSchCmnLcg)));
10005       }
10006    }
10007
10008    /* Fix : syed Moved hqEnt deinit to rgSCHCmnDlDeInitHqEnt */
10009    idx = (U8)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId) & (CM_LTE_MAX_CELLS - 1));
10010    rgSCHUtlFreeSBuf(cell->instIdx,
10011          (Data**)(&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch))), (sizeof(RgSchCmnUe)));
10012    RETVOID;
10013 }  /* rgSCHCmnUeDel */
10014
10015 \f
10016 /**
10017  * @brief This function handles the common code rate configurations
10018  *        done as part of RgrCellCfg/RgrCellRecfg.
10019  *
10020  * @details
10021  *
10022  *     Function: rgSCHCmnDlCnsdrCmnRt
10023  *     Purpose:  This function handles the common code rate configurations
10024  *        done as part of RgrCellCfg/RgrCellRecfg.
10025  *
10026  *     Invoked by: Scheduler
10027  *
10028  *  @param[in]  RgSchCellCb                *cell
10029  *  @param[in]  RgrDlCmnCodeRateCfg     *dlCmnCodeRate
10030  *  @return     S16
10031  *
10032  **/
10033 #ifdef ANSI
10034 PRIVATE S16 rgSCHCmnDlCnsdrCmnRt
10035 (
10036 RgSchCellCb             *cell,
10037 RgrDlCmnCodeRateCfg     *dlCmnCodeRate
10038 )
10039 #else
10040 PRIVATE S16 rgSCHCmnDlCnsdrCmnRt(cell, dlCmnCodeRate)
10041 RgSchCellCb             *cell;
10042 RgrDlCmnCodeRateCfg     *dlCmnCodeRate;
10043 #endif
10044 {
10045    RgSchCmnCell         *cellDl = RG_SCH_CMN_GET_CELL(cell);
10046    U32                  bitsPerRb;
10047    U32                  bitsPer2Rb;
10048    U32                  bitsPer3Rb;
10049    U8                   i, rbNum;
10050    U32                  pdcchBits;
10051
10052    TRC2(rgSCHCmnDlCnsdrCmnRt);
10053
10054    /* code rate is bits per 1024 phy bits, since modl'n scheme is 2. it is
10055     * bits per 1024/2 REs */
10056    if (dlCmnCodeRate->bcchPchRaCodeRate != 0)
10057    {
10058       bitsPerRb = ((dlCmnCodeRate->bcchPchRaCodeRate * 2) *
10059             cellDl->dl.noResPerRb[3])/1024;
10060    }
10061    else
10062    {
10063       bitsPerRb = ((RG_SCH_CMN_DEF_BCCHPCCH_CODERATE * 2) *
10064             cellDl->dl.noResPerRb[3])/1024;
10065    }
10066    /* Store bitsPerRb in cellDl->dl to use later to determine
10067     * Number of RBs for UEs with SI-RNTI, P-RNTI and RA-RNTI */
10068    cellDl->dl.bitsPerRb = bitsPerRb;
10069    /* ccpu00115595 end*/
10070    /* calculate the ITbs for 2 RBs. Initialize ITbs to MAX value */
10071    i = 0;
10072    rbNum = 2;
10073    bitsPer2Rb = bitsPerRb * rbNum;
10074    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer2Rb))
10075       i++;
10076
10077    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs2Rbs = 0) :
10078       (cellDl->dl.cmnChITbs.iTbs2Rbs = i-1);
10079
10080    /* calculate the ITbs for 3 RBs. Initialize ITbs to MAX value */
10081    i = 0;
10082    rbNum = 3;
10083    bitsPer3Rb = bitsPerRb * rbNum;
10084    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer3Rb))
10085          i++;
10086
10087    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs3Rbs = 0) :
10088       (cellDl->dl.cmnChITbs.iTbs3Rbs = i-1);
10089
10090
10091    pdcchBits = 1 + /* Flag for format0/format1a differentiation */
10092       1 + /* Localized/distributed VRB assignment flag */
10093       5 + /* For mcs */
10094 #ifndef LTE_TDD
10095       3 + /* Harq process Id */
10096 #else
10097       4 + /* Harq process Id */
10098       2 + /* UL Index or DAI */
10099 #endif
10100       1 + /* New Data Indicator */
10101       2 + /* For RV */
10102       2 + /* For tpc */
10103       1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
10104                (cell->bwCfg.dlTotalBw + 1))/2);
10105    /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
10106       Since VRB is local */
10107    /* For TDD consider DAI */
10108
10109    /* Convert the pdcchBits to actual pdcchBits required for transmission */
10110    if (dlCmnCodeRate->pdcchCodeRate != 0)
10111    {
10112       pdcchBits = (pdcchBits * 1024)/dlCmnCodeRate->pdcchCodeRate;
10113       if (pdcchBits <= 288) /* 288 : Num of pdcch bits for aggrLvl=4 */
10114       {
10115          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
10116       }
10117       else                  /* 576 : Num of pdcch bits for aggrLvl=8 */
10118       {
10119          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL8;
10120       }
10121    }
10122    else
10123    {
10124       cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
10125    }
10126    if (dlCmnCodeRate->ccchCqi == 0)
10127    {
10128       RETVALUE(RFAILED);
10129    }
10130    else
10131    {
10132       cellDl->dl.ccchCqi = dlCmnCodeRate->ccchCqi;
10133    }
10134    RETVALUE(ROK);
10135 }
10136
10137 #ifdef LTE_TDD
10138 /**
10139  * @brief This function handles the configuration of cell for the first
10140  *        time by the scheduler.
10141  *
10142  * @details
10143  *
10144  *     Function: rgSCHCmnDlRgrCellCfg
10145  *     Purpose:  Configuration received is stored into the data structures
10146  *               Also, update the scheduler with the number of frames of
10147  *               RACH preamble transmission.
10148  *
10149  *     Invoked by: BO and Scheduler
10150  *
10151  *  @param[in]  RgSchCellCb*     cell
10152  *  @param[in]  RgrCellCfg*      cfg
10153  *  @return     S16
10154  *
10155  **/
10156 #ifdef ANSI
10157 PRIVATE S16 rgSCHCmnDlRgrCellCfg
10158 (
10159 RgSchCellCb    *cell,
10160 RgrCellCfg     *cfg,
10161 RgSchErrInfo   *err
10162 )
10163 #else
10164 PRIVATE S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err)
10165 RgSchCellCb    *cell;
10166 RgrCellCfg     *cfg;
10167 RgSchErrInfo   *err;
10168 #endif
10169 {
10170    RgSchCmnCell         *cellSch;
10171    U8                   cp;
10172    U8                   sfCount;
10173    U8                   numPdcchSym;
10174    U8                   noSymPerSlot;
10175    U8                   maxDlSubfrms = cell->numDlSubfrms;
10176    U8                   splSubfrmIdx = cfg->spclSfCfgIdx;
10177    U8                   swPtCnt = 0;
10178    Bool                 isSplfrm;
10179    RgSchTddSubfrmInfo   subfrmInfo = rgSchTddMaxUlSubfrmTbl[cell->ulDlCfgIdx];
10180    S16                  ret;
10181    U8                   splSfIdx;
10182    U8                   antPortIdx;
10183    U8                   numCrs;
10184    U8                   cfi;  
10185    U8                   cfiIdx;
10186    RgSchDlSf            *sf;
10187    U8                   splSfCfi;
10188    U8                   mPhich;
10189
10190    TRC2(rgSCHCmnDlRgrCellCfg);
10191    
10192
10193    cellSch = RG_SCH_CMN_GET_CELL(cell);
10194    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->\
10195                                                   rachCfg.preambleFormat];
10196    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
10197    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
10198    
10199    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
10200                        3 TTI (MAX L1+L2 processing delay at the UE) */
10201    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
10202                                  rgSchCmnHarqRtt[cell->ulDlCfgIdx] + 3; 
10203    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10204    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10205    if (cfg->maxUePerDlSf == 0)
10206    {
10207       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10208    }
10209    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
10210    {
10211       RETVALUE(RFAILED);
10212    }
10213
10214
10215    if (cell->bwCfg.dlTotalBw <= 10)
10216    {
10217       cfiIdx = 1;
10218       numPdcchSym = 2;
10219    }
10220    else
10221    {
10222       cfiIdx = 0;
10223       numPdcchSym = 1;
10224    }
10225    /* DwPTS Scheduling Changes Start */
10226    cellSch->dl.splSfCfg  = splSubfrmIdx;
10227  
10228    if (cfg->isCpDlExtend == TRUE)
10229    {
10230       if((0 == splSubfrmIdx) || (4 == splSubfrmIdx) ||
10231          (7 == splSubfrmIdx) || (8 == splSubfrmIdx)
10232         )
10233       {
10234          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
10235       }
10236       else
10237       {
10238          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
10239       }
10240    }
10241    else
10242    {
10243       /* Refer to 36.213 Section 7.1.7 */
10244       if((0 == splSubfrmIdx) || (5 == splSubfrmIdx))
10245       {
10246          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
10247       }
10248       else
10249       {
10250          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
10251       }
10252    }
10253    /* DwPTS Scheduling Changes End */  
10254
10255    splSfCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
10256    RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
10257    
10258    for (sfCount = 0; sfCount < maxDlSubfrms; sfCount++)
10259    {
10260       sf = cell->subFrms[sfCount];
10261       /* Sfcount matches the first special subframe occurs at Index 0
10262             * or subsequent special subframes */
10263       if(subfrmInfo.switchPoints == 1)
10264       {
10265          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
10266                                  RG_SCH_CMN_10_MS_PRD, &subfrmInfo);
10267       }
10268       else
10269       {
10270          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
10271                                  RG_SCH_CMN_5_MS_PRD, &subfrmInfo);
10272       }
10273       if(isSplfrm == TRUE)
10274       {
10275          swPtCnt++;
10276          /* DwPTS Scheduling Changes Start */        
10277          if (cell->splSubfrmCfg.isDlDataAllowed == TRUE)
10278          {
10279             sf->sfType = RG_SCH_SPL_SF_DATA;
10280          }
10281          else
10282          {
10283             sf->sfType = RG_SCH_SPL_SF_NO_DATA;
10284          }
10285          /* DwPTS Scheduling Changes End */
10286       }
10287       else
10288       {
10289          /* DwPTS Scheduling Changes Start */
10290          if (sf->sfNum != 0)
10291          {
10292             sf->sfType = RG_SCH_DL_SF;
10293          }
10294          else
10295          {
10296             sf->sfType = RG_SCH_DL_SF_0;
10297          }
10298          /* DwPTS Scheduling Changes End */
10299       }
10300       
10301       /* Calculate the number of CCEs per subframe in the cell */
10302       mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][sf->sfNum];
10303       if(cell->dynCfiCb.isDynCfiEnb == TRUE)
10304       {   
10305          /* In case if Dynamic CFI feature is enabled, default CFI 
10306           * value 1 is used  */
10307          sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][1];
10308       }
10309       else
10310       {
10311          if (sf->sfType == RG_SCH_SPL_SF_DATA)
10312          {
10313             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
10314          }
10315          else
10316          {
10317             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi)];
10318          }
10319       }   
10320    }
10321
10322    /* Intialize the RACH response scheduling related infromation */
10323    if(rgSCHCmnDlRachInfoInit(cell) != ROK)
10324    {
10325      RETVALUE(RFAILED);
10326    }
10327
10328    /* Allocate PRACH preamble list */
10329    rgSCHCmnDlCreateRachPrmLst(cell);
10330
10331    /* Initialize PHICH offset information */
10332    rgSCHCmnDlPhichOffsetInit(cell);
10333
10334    /* Update the size of HARQ ACK/NACK feedback table */
10335    /* The array size is increased by 2 to have enough free indices, where other
10336     * indices are busy waiting for HARQ feedback */
10337    cell->ackNackFdbkArrSize = rgSchTddANFdbkMapTbl[cell->ulDlCfgIdx] + 2; 
10338
10339    /* Initialize expected HARQ ACK/NACK feedback time */
10340    rgSCHCmnDlANFdbkInit(cell);
10341
10342    /* Initialize UL association set index */
10343    if(cell->ulDlCfgIdx != 0)
10344    {
10345       rgSCHCmnDlKdashUlAscInit(cell);
10346    }
10347
10348    if (cfg->isCpDlExtend == TRUE)
10349    {
10350       cp = RG_SCH_CMN_EXT_CP;
10351       noSymPerSlot = 6;
10352       cell->splSubfrmCfg.dwPts =
10353           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlDwPts;
10354    
10355       if ( cell->splSubfrmCfg.dwPts == 0 )
10356       {
10357          cell->isDwPtsCnted = FALSE;
10358       }
10359       else
10360       {
10361          cell->isDwPtsCnted = TRUE;
10362       }
10363
10364       if(cfg->isCpUlExtend == TRUE)
10365       {
10366          cell->splSubfrmCfg.upPts =
10367             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlExtUpPts;
10368       }
10369       else
10370       {
10371          cell->splSubfrmCfg.upPts =
10372             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlNorUpPts;
10373       }
10374    }
10375    else
10376    {
10377       cp = RG_SCH_CMN_NOR_CP;
10378       noSymPerSlot = 7;
10379       cell->splSubfrmCfg.dwPts =
10380           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlDwPts;
10381       cell->isDwPtsCnted = TRUE;
10382
10383       if(cfg->isCpUlExtend == TRUE)
10384       {
10385          cell->splSubfrmCfg.upPts =
10386             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlExtUpPts;
10387       }
10388       else
10389       {
10390          cell->splSubfrmCfg.upPts =
10391             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlNorUpPts;
10392       }
10393    }
10394
10395    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
10396    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++,cfiIdx++)
10397    {   
10398       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
10399       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
10400                                                  [cell->numTxAntPorts]][cfiIdx];
10401       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
10402       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
10403                                                  [cell->numTxAntPorts]][cfiIdx];
10404    }
10405
10406    /* Initializing the values of CFI parameters */
10407    if(cell->dynCfiCb.isDynCfiEnb)
10408    {   
10409       /* If DCFI is enabled, current CFI value will start from 1 */
10410       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
10411    }
10412    else
10413    {
10414       /* If DCFI is disabled, current CFI value is set as default max allowed CFI value */
10415       cellSch->dl.currCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
10416       cellSch->dl.newCfi = cellSch->dl.currCfi;
10417    }   
10418
10419    /* Include CRS REs while calculating Efficiency
10420     * The number of Resource Elements occupied by CRS depends on Number of
10421     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
10422     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
10423     * details of the same. Please note that PDCCH overlap symbols would not
10424     * considered in CRS REs deduction */
10425    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
10426    {
10427       cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
10428             - numPdcchSym) *RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
10429    }
10430
10431    /* DwPTS Scheduling Changes Start */
10432    antPortIdx = (cell->numTxAntPorts == 1)? 0: 
10433       ((cell->numTxAntPorts == 2)? 1: 2);     
10434
10435    if (cp == RG_SCH_CMN_NOR_CP)
10436    {
10437       splSfIdx = (splSubfrmIdx == 4)? 1: 0;   
10438    }
10439    else
10440    {
10441       splSfIdx = (splSubfrmIdx == 3)? 1: 0;
10442    }
10443
10444    numCrs = rgSchCmnDwptsCrs[splSfIdx][antPortIdx];
10445
10446    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI-1; cfi++)
10447    { 
10448       /* If CFI is 2 and Ant Port is 4, don't consider the sym 1 CRS REs */  
10449       if (antPortIdx == 2 && cfi == 2)
10450       {
10451          numCrs -= 4;      
10452       }
10453       cellSch->dl.numReDwPts[cfi]  =  ((cell->splSubfrmCfg.dwPts - cfi)*
10454                                   RB_SCH_CMN_NUM_SCS_PER_RB) - numCrs;
10455    }
10456    /* DwPTS Scheduling Changes End */
10457
10458    if (cfg->maxDlBwPerUe == 0)
10459    {
10460       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
10461    }
10462    else
10463    {
10464       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
10465    }
10466    if (cfg->maxDlRetxBw == 0)
10467    {
10468       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
10469    }
10470    else
10471    {
10472       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
10473    }
10474    /* Fix: MUE_PERTTI_DL*/
10475    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10476    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10477    if (cfg->maxUePerDlSf == 0)
10478    {
10479       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10480    }
10481    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
10482    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
10483    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
10484    {
10485       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
10486                       "Invalid configuration !: "
10487                       "maxCcchPerDlSf %u > maxUePerDlSf %u",
10488                    cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
10489
10490       RETVALUE(RFAILED);
10491    }
10492    else if (!cfg->maxCcchPerDlSf)
10493    {
10494       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
10495        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
10496        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
10497        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
10498        * FLE crash in PHY as PHY has limit of 16 max*/
10499       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
10500    }
10501    else
10502    {
10503       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
10504    }
10505    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
10506    {
10507       RETVALUE(RFAILED);
10508    }
10509
10510    /*ccpu00118273 - ADD - start */
10511    cmLListInit(&cellSch->dl.msg4RetxLst);
10512 #ifdef RGR_V1
10513    cmLListInit(&cellSch->dl.ccchSduRetxLst);
10514 #endif
10515
10516 #ifdef RG_PHASE2_SCHED
10517    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
10518    {
10519       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
10520    }
10521    if (cfg->dlfsCfg.isDlFreqSel)
10522    {
10523       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
10524       if (ret != ROK)
10525       {
10526          RETVALUE(RFAILED);
10527       }
10528    }
10529    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
10530 #endif
10531
10532    /* Power related configuration */
10533    ret = rgSCHPwrCellCfg(cell, cfg);
10534    if (ret != ROK)
10535    {
10536       RETVALUE(RFAILED);
10537    }
10538
10539    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
10540    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
10541    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
10542    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
10543    cellSch->dl.msg4pAVal        = cfg->msg4pAVal;
10544    RETVALUE(ROK);
10545 }
10546 #else /* LTE_TDD */
10547 /**
10548  * @brief This function handles the configuration of cell for the first
10549  *        time by the scheduler.
10550  *
10551  * @details
10552  *
10553  *     Function: rgSCHCmnDlRgrCellCfg
10554  *     Purpose:  Configuration received is stored into the data structures
10555  *               Also, update the scheduler with the number of frames of
10556  *               RACH preamble transmission.
10557  *
10558  *     Invoked by: BO and Scheduler
10559  *
10560  *  @param[in]  RgSchCellCb*   cell
10561  *  @param[in]  RgrCellCfg*    cfg
10562  *  @param[in]  RgSchErrInfo*  err
10563  *  @return     S16
10564  *
10565  **/
10566 #ifdef ANSI
10567 PRIVATE S16 rgSCHCmnDlRgrCellCfg
10568 (
10569 RgSchCellCb             *cell,
10570 RgrCellCfg              *cfg,
10571 RgSchErrInfo            *err
10572 )
10573 #else
10574 PRIVATE S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err)
10575 RgSchCellCb             *cell;
10576 RgrCellCfg              *cfg;
10577 RgSchErrInfo            *err;
10578 #endif
10579 {
10580    S16                 ret;
10581    RgSchCmnCell        *cellSch;
10582    U8                   cp;
10583    U8                   numPdcchSym;
10584    U8                   noSymPerSlot;
10585    U8                   cfi;  
10586    U8                   cfiIdx;
10587
10588    TRC2(rgSCHCmnDlRgrCellCfg);
10589
10590    cellSch = RG_SCH_CMN_GET_CELL(cell);
10591
10592    /* Initialize the parameters with the ones received in the */
10593    /* configuration.                                          */
10594
10595    /* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA
10596     * sub-frames from preamble format */
10597    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat];
10598
10599    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
10600    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
10601    
10602    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
10603                        3 TTI (MAX L1+L2 processing delay at the UE) */
10604    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
10605                                  rgSchCmnHarqRtt[7] + 3; 
10606
10607    if (cell->bwCfg.dlTotalBw <= 10)
10608    {
10609       cfiIdx = 1;
10610       numPdcchSym = 2;
10611    }
10612    else
10613    {
10614       cfiIdx = 0;
10615       numPdcchSym = 1;
10616    }
10617
10618    if (cell->isCpDlExtend == TRUE)
10619    {
10620       cp = RG_SCH_CMN_EXT_CP;
10621       noSymPerSlot = 6;
10622    }
10623    else
10624    {
10625       cp = RG_SCH_CMN_NOR_CP;
10626       noSymPerSlot = 7;
10627    }
10628
10629    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
10630    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, cfiIdx++)
10631    {   
10632       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
10633 #ifdef EMTC_ENABLE      
10634       cellSch->dl.emtcCqiToTbsTbl[0][cfi]   = rgSchEmtcCmnCqiToTbs[0][cp][cfiIdx];
10635 #endif      
10636       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
10637                                                  [cell->numTxAntPorts]][cfiIdx];
10638       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
10639 #ifdef EMTC_ENABLE      
10640       cellSch->dl.emtcCqiToTbsTbl[1][cfi]   = rgSchEmtcCmnCqiToTbs[1][cp][cfiIdx];
10641 #endif      
10642       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
10643                                                  [cell->numTxAntPorts]][cfiIdx];
10644    }
10645
10646    /* Initializing the values of CFI parameters */
10647    if(cell->dynCfiCb.isDynCfiEnb)
10648    {   
10649       /* If DCFI is enabled, current CFI value will start from 1 */
10650       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
10651    }
10652    else
10653    {
10654       /* If DCFI is disabled, current CFI value is set as default CFI value */
10655       cellSch->dl.currCfi = cellSch->cfiCfg.cfi;
10656       cellSch->dl.newCfi = cellSch->dl.currCfi;
10657    }   
10658
10659    /* Include CRS REs while calculating Efficiency
10660     * The number of Resource Elements occupied by CRS depends on Number of
10661     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
10662     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
10663     * details of the same. Please note that PDCCH overlap symbols would not
10664     * considered in CRS REs deduction */
10665    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
10666    {
10667        cellSch->dl.noResPerRb[cfi]    = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
10668             - numPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
10669    }           
10670
10671    if (cfg->maxDlBwPerUe == 0)
10672    {
10673       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
10674    }
10675    else
10676    {
10677       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
10678    }
10679    if (cfg->maxDlRetxBw == 0)
10680    {
10681       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
10682    }
10683    else
10684    {
10685       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
10686    }
10687    
10688    /* Fix: MUE_PERTTI_DL*/
10689    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10690    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10691    if (cfg->maxUePerDlSf == 0)
10692    {
10693       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10694    }
10695    /* Fix: MUE_PERTTI_DL syed validating Cell Configuration */
10696    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
10697    {
10698       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
10699             "FAILED MaxUePerDlSf(%u) < MaxDlUeNewTxPerTti(%u)",
10700             cellSch->dl.maxUePerDlSf,
10701             cellSch->dl.maxUeNewTxPerTti);
10702       RETVALUE(RFAILED);
10703    }
10704    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
10705    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
10706    {
10707       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid configuration !: "
10708             "maxCcchPerDlSf %u > maxUePerDlSf %u",
10709             cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
10710
10711       RETVALUE(RFAILED);
10712    }
10713    else if (!cfg->maxCcchPerDlSf)
10714    {
10715       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
10716        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
10717        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
10718        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
10719        * FLE crash in PHY as PHY has limit of 16 max*/
10720       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
10721    }
10722    else
10723    {
10724       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
10725    }
10726
10727
10728    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
10729    {
10730       RETVALUE(RFAILED);
10731    }
10732    cmLListInit(&cellSch->dl.msg4RetxLst);
10733 #ifdef RGR_V1
10734    cmLListInit(&cellSch->dl.ccchSduRetxLst);
10735 #endif
10736
10737 #ifdef RG_PHASE2_SCHED
10738    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
10739    {
10740       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
10741    }
10742    if (cfg->dlfsCfg.isDlFreqSel)
10743    {
10744       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
10745       if (ret != ROK)
10746       {
10747          RETVALUE(RFAILED);
10748       }
10749    }
10750    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
10751 #endif
10752
10753    /* Power related configuration */
10754    ret = rgSCHPwrCellCfg(cell, cfg);
10755    if (ret != ROK)
10756    {
10757       RETVALUE(RFAILED);
10758    }
10759
10760    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
10761    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
10762    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
10763    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
10764    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
10765    RETVALUE(ROK);
10766 }
10767 #endif /* LTE_TDD */
10768
10769 /***********************************************************
10770  *
10771  *     Func : rgSCHCmnUlCalcReqRbCeil
10772  *
10773  *     Desc : Calculate RB required to satisfy 'bytes' for
10774  *            a given CQI.
10775  *            Returns number of RBs such that requirement
10776  *            is necessarily satisfied (does a 'ceiling'
10777  *            computation).
10778  *
10779  *     Ret  : Required RBs (U8)
10780  *
10781  *     Notes:
10782  *
10783  *     File :
10784  *
10785  **********************************************************/
10786 #ifdef ANSI
10787 PUBLIC U8 rgSCHCmnUlCalcReqRbCeil
10788 (
10789 U32            bytes,
10790 U8             cqi,
10791 RgSchCmnUlCell *cellUl
10792 )
10793 #else
10794 PUBLIC U8 rgSCHCmnUlCalcReqRbCeil(bytes, cqi, cellUl)
10795 U32            bytes;
10796 U8             cqi;
10797 RgSchCmnUlCell *cellUl;
10798 #endif
10799 {
10800    U32 numRe = RGSCH_CEIL((bytes * 8) * 1024, rgSchCmnUlCqiTbl[cqi].eff);
10801    TRC2(rgSCHCmnUlCalcReqRbCeil);
10802    RETVALUE((U8)RGSCH_CEIL(numRe, RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl)));
10803 }
10804
10805 /***********************************************************
10806  *
10807  *     Func : rgSCHCmnPrecompMsg3Vars
10808  *
10809  *     Desc : Precomputes the following for msg3 allocation:
10810  *            1. numSb and Imcs for msg size A
10811  *            2. numSb and Imcs otherwise
10812  *
10813  *     Ret  :
10814  *
10815  *     Notes: The corresponding vars in cellUl struct is filled
10816  *            up
10817  *
10818  *     File :
10819  *
10820  **********************************************************/
10821 #ifdef ANSI
10822 PRIVATE S16 rgSCHCmnPrecompMsg3Vars
10823 (
10824 RgSchCmnUlCell *cellUl,
10825 U8           ccchCqi,
10826 U16          msgSzA,
10827 U8           sbSize,
10828 Bool         isEcp
10829 )
10830 #else
10831 PRIVATE S16 rgSCHCmnPrecompMsg3Vars(cellUl, ccchCqi, msgSzA, sbSize, isEcp)
10832 RgSchCmnUlCell *cellUl;
10833 U8           ccchCqi;
10834 U16          msgSzA;
10835 U8           sbSize;
10836 Bool         isEcp;
10837 #endif
10838 {
10839    U8 numSb;
10840    U8 ccchTbs;
10841    U8 ccchMcs;
10842    U8   numRb = 0;
10843    U8   iTbs = 0;
10844    U16  msg3GrntSz = 0;
10845
10846    TRC2(rgSCHCmnPrecompMsg3Vars);
10847
10848    if (ccchCqi > cellUl->max16qamCqi)
10849    {
10850       ccchCqi = cellUl->max16qamCqi;
10851    }
10852 /* #ifndef RG_SCH_CMN_EXP_CP_SUP For ECP Pick the index 1 */
10853    /* Fix */
10854    ccchTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi];
10855    ccchMcs = rgSCHCmnUlGetIMcsFrmITbs(ccchTbs, CM_LTE_UE_CAT_1);
10856    
10857    /* MCS should fit in 4 bits in RAR */
10858    if (ccchMcs >= 15)
10859    {
10860       ccchMcs = 15;
10861    }
10862    
10863    /* Limit the ccchMcs to 15 as it
10864     * can be inferred from 36.213, section 6.2 that msg3 imcs
10865     * field is 4 bits.
10866     * Since, UE doesn't exist right now, we use CAT_1 for ue
10867     * category*/
10868    while((ccchMcs = (rgSCHCmnUlGetIMcsFrmITbs(
10869                       rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi],CM_LTE_UE_CAT_1))
10870                     ) >
10871                  RG_SCH_CMN_MAX_MSG3_IMCS)
10872    {
10873       ccchCqi--;
10874    }
10875    
10876    iTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi];
10877    
10878    if (msgSzA < RGSCH_MIN_MSG3_GRNT_SZ)
10879    {
10880       RETVALUE(RFAILED);
10881    }
10882    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(msgSzA, ccchCqi, cellUl), sbSize);
10883    
10884    numRb   = numSb * sbSize;
10885    msg3GrntSz = 8 * msgSzA;
10886
10887    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
10888    {
10889       ++numSb;
10890       numRb   = numSb * sbSize;
10891    }
10892    while (rgSchCmnMult235Tbl[numSb].match != numSb)
10893    {
10894       ++numSb;
10895    }
10896    /* Reversed(Corrected) the assignment for preamble-GrpA
10897     * Refer- TG36.321- section- 5.1.2*/
10898    cellUl->ra.prmblBNumSb = numSb;
10899    cellUl->ra.prmblBIMcs  = ccchMcs;
10900    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(RGSCH_MIN_MSG3_GRNT_SZ, \
10901                       ccchCqi, cellUl),
10902          sbSize);
10903
10904    numRb   = numSb * sbSize;
10905    msg3GrntSz = 8 * RGSCH_MIN_MSG3_GRNT_SZ;
10906    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
10907    {
10908       ++numSb;
10909       numRb   = numSb * sbSize;
10910    }
10911    while (rgSchCmnMult235Tbl[numSb].match != numSb)
10912    {
10913       ++numSb;
10914    }
10915    /* Reversed(Corrected) the assignment for preamble-GrpA
10916     * Refer- TG36.321- section- 5.1.2*/
10917    cellUl->ra.prmblANumSb = numSb;
10918    cellUl->ra.prmblAIMcs  = ccchMcs;
10919    RETVALUE(ROK);
10920 }
10921
10922 PUBLIC U32 gPrntPucchDet=0;
10923
10924 #ifdef LTE_TDD
10925 /***********************************************************
10926  *
10927  *     Func : rgSCHCmnUlCalcAvailBw
10928  *
10929  *     Desc : Calculates bandwidth available for PUSCH scheduling.
10930  *
10931  *     Ret  : S16 (ROK/RFAILED)
10932  *
10933  *     Notes:
10934  *
10935  *     File :
10936  *
10937  **********************************************************/
10938 #ifdef ANSI
10939 PRIVATE S16 rgSCHCmnUlCalcAvailBw
10940 (
10941 RgSchCellCb    *cell,
10942 RgrCellCfg     *cellCfg,
10943 U8              cfi,
10944 U8             *rbStartRef,
10945 U8             *bwAvailRef
10946 )
10947 #else
10948 PRIVATE S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef)
10949 RgSchCellCb   *cell;
10950 RgrCellCfg    *cellCfg;
10951 U8             cfi;  
10952 U8            *rbStartRef;
10953 U8            *bwAvailRef;
10954 #endif
10955 {
10956    U8  c        = 3;
10957    U8  ulBw     = cell->bwCfg.ulTotalBw;
10958    U8  n2Rb     = cell->pucchCfg.resourceSize;
10959    U8  pucchDeltaShft = cell->pucchCfg.deltaShift;
10960    U16 n1Pucch  = cell->pucchCfg.n1PucchAn;
10961    U8  n1Cs     = cell->pucchCfg.cyclicShift;
10962
10963    U8  n1PerRb;
10964    U8  totalCce;
10965    U16 n1Max;
10966    U8  n1Rb;
10967    U32 mixedRb;
10968    U8  exclRb; /* RBs to exclude */
10969    U8  n1RbPart;
10970    U8  puschRbStart;
10971    /* To avoid PUCCH and PUSCH collision issue */
10972    U8  P;
10973    U8  n1PlusOne;
10974    U8  mi;
10975    /* Maximum value of M as per Table 10.1-1 */
10976    U8  M[RGSCH_MAX_TDD_UL_DL_CFG] = {1, 2, 4, 3, 4, 9, 1};
10977
10978    TRC2(rgSCHCmnUlCalcAvailBw);
10979
10980    if (cell->isCpUlExtend)
10981    {
10982       c = 2;
10983    }
10984
10985    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
10986
10987    /* Considering the max no. of CCEs for PUSCH BW calculation 
10988     * based on min mi value */
10989    if (cell->ulDlCfgIdx == 0 || cell->ulDlCfgIdx == 6)
10990    {
10991       mi = 1;
10992    }
10993    else
10994    { 
10995       mi = 0;
10996    }
10997    
10998    totalCce = cell->dynCfiCb.cfi2NCceTbl[mi][cfi];
10999
11000    P        = rgSCHCmnGetPValFrmCCE(cell, totalCce-1);
11001    n1PlusOne = cell->rgSchTddNpValTbl[P + 1];
11002    n1Max    = (M[cell->ulDlCfgIdx] - 1)*n1PlusOne + (totalCce-1) + n1Pucch;
11003
11004    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
11005     * TS 36.211  */
11006    n1RbPart = (c*n1Cs)/pucchDeltaShft;
11007    n1Rb = (n1Max - n1RbPart)/ n1PerRb;
11008    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
11009
11010    /* get the total Number of RB's to be excluded for PUSCH */
11011    /* ccpu00137339 */
11012    if(n1Pucch < n1RbPart)
11013    {
11014       exclRb = n2Rb;
11015    }
11016    else
11017    {
11018       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
11019    }
11020    puschRbStart = exclRb/2 + 1; 
11021
11022    /* Num of PUCCH RBs = puschRbStart*2 */
11023    if (puschRbStart * 2 >= ulBw)
11024    {
11025       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH");
11026       RETVALUE(RFAILED);
11027    }
11028
11029    *rbStartRef = puschRbStart;
11030    *bwAvailRef = ulBw -  puschRbStart * 2;
11031  
11032    if(cell->pucchCfg.maxPucchRb !=0 && 
11033          (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
11034    {
11035       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
11036    }
11037     
11038    RETVALUE(ROK);
11039 }
11040 #else
11041
11042 /***********************************************************
11043  *
11044  *     Func : rgSCHCmnUlCalcAvailBw
11045  *
11046  *     Desc : Calculates bandwidth available for PUSCH scheduling.
11047  *
11048  *     Ret  : S16 (ROK/RFAILED)
11049  *
11050  *     Notes:
11051  *
11052  *     File :
11053  *
11054  **********************************************************/
11055 #ifdef ANSI
11056 PRIVATE S16 rgSCHCmnUlCalcAvailBw
11057 (
11058 RgSchCellCb    *cell,
11059 RgrCellCfg     *cellCfg,
11060 U8              cfi,
11061 U8             *rbStartRef,
11062 U8             *bwAvailRef
11063 )
11064 #else
11065 PRIVATE S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef)
11066 RgSchCellCb   *cell;
11067 RgrCellCfg    *cellCfg;
11068 U8             cfi;
11069 U8            *rbStartRef;
11070 U8            *bwAvailRef;
11071 #endif
11072 {
11073    U8  c        = 3;
11074    U8  ulBw     = cell->bwCfg.ulTotalBw;
11075    U8  n2Rb     = cell->pucchCfg.resourceSize;
11076    U8  pucchDeltaShft = cell->pucchCfg.deltaShift;
11077    U16 n1Pucch  = cell->pucchCfg.n1PucchAn;
11078    U8  n1Cs     = cell->pucchCfg.cyclicShift;
11079    U8  n1PerRb;
11080    U8  totalCce;
11081    U16 n1Max;
11082    U8  n1Rb;
11083    U32 mixedRb;
11084    U8  exclRb; /* RBs to exclude */
11085    U8  n1RbPart;
11086    U8  puschRbStart;
11087 #ifdef LTE_ADV
11088    U16 numOfN3PucchRb;
11089    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);  
11090 #endif
11091    
11092    TRC2(rgSCHCmnUlCalcAvailBw);
11093
11094    if (cell->isCpUlExtend)
11095    {
11096       c = 2;
11097    }
11098
11099    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
11100
11101    totalCce = cell->dynCfiCb.cfi2NCceTbl[0][cfi];
11102
11103    n1Max    = n1Pucch + totalCce-1;
11104
11105    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
11106     * TS 36.211  */
11107    n1RbPart = (c*n1Cs)/pucchDeltaShft;
11108    n1Rb = (U8)((n1Max - n1RbPart) / n1PerRb);
11109    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
11110
11111    /* get the total Number of RB's to be excluded for PUSCH */
11112    /* ccpu00137339 */
11113    if(n1Pucch < n1RbPart)
11114    {
11115       exclRb = n2Rb;
11116    }
11117    else
11118    {
11119       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
11120    }
11121    /*Support for PUCCH Format 3*/
11122 #ifdef LTE_ADV
11123    if (cell->isPucchFormat3Sptd)
11124    {
11125       numOfN3PucchRb = RGSCH_CEIL(cellSch->dl.maxUePerDlSf,5); 
11126       exclRb = exclRb + numOfN3PucchRb;
11127    }
11128 #endif
11129    puschRbStart = exclRb/2 + 1;
11130
11131    if(gPrntPucchDet)
11132    {
11133 #ifndef ALIGN_64BIT
11134            printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%ld:%d:%d:%d:%d:%d]\n",
11135         cell->crntTime.sfn, cell->crntTime.subframe, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
11136 #else
11137            printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%d:%d:%d:%d:%d:%d]\n",
11138         cell->crntTime.sfn, cell->crntTime.subframe, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
11139 #endif
11140    }
11141
11142    if (puschRbStart*2 >= ulBw)
11143    {
11144       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH");
11145       RETVALUE(RFAILED);
11146    }
11147
11148    *rbStartRef = puschRbStart;
11149    *bwAvailRef = ulBw - puschRbStart * 2;
11150
11151    if(cell->pucchCfg.maxPucchRb !=0 && 
11152       (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
11153    {
11154       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
11155    }
11156    
11157    RETVALUE(ROK);
11158 }
11159 #endif
11160
11161
11162
11163 /***********************************************************
11164  *
11165  *     Func : rgSCHCmnUlCellInit
11166  *
11167  *     Desc : Uplink scheduler initialisation for cell.
11168  *
11169  *     Ret  : S16
11170  *
11171  *     Notes:
11172  *
11173  *     File :
11174  *
11175  **********************************************************/
11176 #ifdef ANSI
11177 PRIVATE S16 rgSCHCmnUlCellInit
11178 (
11179  RgSchCellCb  *cell,
11180  RgrCellCfg   *cellCfg
11181  )
11182 #else
11183 PRIVATE S16 rgSCHCmnUlCellInit(cell, cellCfg)
11184    RgSchCellCb *cell;
11185    RgrCellCfg  *cellCfg;
11186 #endif
11187 {
11188    S16            ret;
11189    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
11190    U8             maxUePerUlSf = cellCfg->maxUePerUlSf;
11191 #ifdef RGR_V1
11192    /* Added configuration for maximum number of MSG3s */
11193    U8             maxMsg3PerUlSf = cellCfg->maxMsg3PerUlSf;
11194 #endif
11195    U8             maxUlBwPerUe = cellCfg->maxUlBwPerUe;
11196    U8             sbSize       = cellCfg->puschSubBand.size;
11197    U8             i;
11198    U8             rbStart;
11199    U8             bwAvail;
11200    U8             cfi;  
11201    U8             maxSbPerUe;
11202    U8             numSb;
11203 #ifdef LTE_TDD
11204    U16            ulDlCfgIdx = cell->ulDlCfgIdx;
11205    /* [ccpu00127294]-MOD-Change the max Ul subfrms size in TDD */
11206    U8             maxSubfrms = 2 * rgSchTddNumUlSf[ulDlCfgIdx]; 
11207    U8             ulToDlMap[12] = {0}; /* maximum 6 Subframes in UL  * 2 */
11208    U8             maxUlsubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
11209                                            [RGSCH_NUM_SUB_FRAMES-1];
11210    U16             subfrm;
11211    S8             dlIdx;
11212 #else
11213    U8             maxSubfrms = RG_SCH_CMN_UL_NUM_SF;
11214 #endif
11215 #ifdef LTE_L2_MEAS
11216    U8             idx;
11217 #endif
11218    U8  iTbs;
11219 #if (defined(LTE_L2_MEAS) )
11220    Inst           inst         = cell->instIdx;
11221 #endif /* #if (defined(LTE_L2_MEAS) || defined(DEBUGP) */
11222    RgSchCmnCell      *cellSch =  (RgSchCmnCell *)(cell->sc.sch);
11223    
11224    TRC2(rgSCHCmnUlCellInit);
11225
11226    cellUl->maxUeNewTxPerTti = cellCfg->maxUlUeNewTxPerTti;
11227    if (maxUePerUlSf == 0)
11228    {
11229       maxUePerUlSf = RG_SCH_CMN_MAX_UE_PER_UL_SF;
11230    }
11231 #ifdef RGR_V1
11232    if (maxMsg3PerUlSf == 0)
11233    {
11234       maxMsg3PerUlSf = RG_SCH_CMN_MAX_MSG3_PER_UL_SF;
11235    }
11236    /*  fixed the problem while sending raRsp 
11237     * if maxMsg3PerUlSf is greater than 
11238     * RGSCH_MAX_RNTI_PER_RARNTI 
11239     * */
11240    if(maxMsg3PerUlSf > RGSCH_MAX_RNTI_PER_RARNTI)
11241    {
11242       maxMsg3PerUlSf = RGSCH_MAX_RNTI_PER_RARNTI; 
11243    } 
11244
11245    if(maxMsg3PerUlSf > maxUePerUlSf)
11246    {
11247       maxMsg3PerUlSf =  maxUePerUlSf;   
11248    }
11249    
11250    /*cellUl->maxAllocPerUlSf = maxUePerUlSf + maxMsg3PerUlSf;*/
11251    /*Max MSG3 should be a subset of Max UEs*/
11252    cellUl->maxAllocPerUlSf = maxUePerUlSf;
11253    cellUl->maxMsg3PerUlSf = maxMsg3PerUlSf;
11254 #else
11255    cellUl->maxAllocPerUlSf = maxUePerUlSf;
11256 #endif
11257    /* Fix: MUE_PERTTI_UL syed validating Cell Configuration */
11258    if (cellUl->maxAllocPerUlSf < cellUl->maxUeNewTxPerTti)
11259    {
11260       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
11261             "FAILED: MaxUePerUlSf(%u) < MaxUlUeNewTxPerTti(%u)",
11262             cellUl->maxAllocPerUlSf,
11263             cellUl->maxUeNewTxPerTti);
11264       RETVALUE(RFAILED);
11265    }
11266
11267 #ifdef LTE_L2_MEAS
11268 #ifdef LTE_TDD
11269    for(idx = 0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
11270 #else
11271    for(idx = 0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
11272 #endif
11273    {
11274
11275       ret = rgSCHUtlAllocSBuf(inst,  (Data **)&(cell->sfAllocArr[idx].
11276               ulUeInfo.ulAllocInfo), (cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)));
11277       if (ret != ROK)
11278       {
11279             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation failed ");
11280             RETVALUE(ret);
11281       }
11282    }
11283 #endif
11284    if (maxUlBwPerUe == 0)
11285    {
11286       /* ccpu00139362- Setting to configured UL BW instead of MAX BW(100)*/
11287       maxUlBwPerUe = cell->bwCfg.ulTotalBw;
11288    }
11289    cellUl->maxUlBwPerUe = maxUlBwPerUe;
11290
11291    /* FOR RG_SCH_CMN_EXT_CP_SUP */
11292    if (!cellCfg->isCpUlExtend)
11293    {
11294       cellUl->ulNumRePerRb = 12 * (14 - RGSCH_UL_SYM_DMRS_SRS);
11295    }
11296    else
11297    {
11298       cellUl->ulNumRePerRb = 12 * (12 - RGSCH_UL_SYM_DMRS_SRS);
11299    }
11300
11301    if (sbSize != rgSchCmnMult235Tbl[sbSize].match)
11302    {
11303       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid subband size %d", sbSize);
11304       RETVALUE(RFAILED);
11305    }
11306         //Setting the subband size to 4 which is size of VRBG in 5GTF
11307 #ifdef RG_5GTF
11308         sbSize = MAX_5GTF_VRBG_SIZE;
11309 #endif
11310         
11311    maxSbPerUe = maxUlBwPerUe / sbSize;
11312    if (maxSbPerUe == 0)
11313    {
11314       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnUlCellInit(): "
11315          "maxUlBwPerUe/sbSize is zero");
11316       RETVALUE(RFAILED);
11317    }
11318    cellUl->maxSbPerUe = rgSchCmnMult235Tbl[maxSbPerUe].prvMatch;
11319
11320    /* CQI related updations */
11321    if ((!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->ulCmnCodeRate.ccchCqi))
11322          || (!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->trgUlCqi.trgCqi)))
11323    {
11324       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnUlCellInit(): "
11325          "Invalid cqi");
11326       RETVALUE(RFAILED);
11327    }
11328    cellUl->dfltUlCqi = cellCfg->ulCmnCodeRate.ccchCqi;
11329
11330    /* Changed the logic to determine maxUlCqi.
11331     * For a 16qam UE, maxUlCqi is the CQI Index at which
11332     * efficiency is as close as possible to RG_SCH_MAX_CODE_RATE_16QAM
11333     * Refer to 36.213-8.6.1 */
11334     for (i = RG_SCH_CMN_UL_NUM_CQI - 1;i > 0; --i)
11335    {
11336       RLOG_ARG2(L_INFO,DBG_CELLID,cell->cellId,
11337             "CQI %u:iTbs %u",
11338             i, 
11339             rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]);
11340 #ifdef MAC_SCH_STATS
11341       /* ccpu00128489 ADD Update mcs in hqFailStats here instead of at CRC 
11342        * since CQI to MCS mapping does not change. The only exception is for 
11343        * ITBS = 19 where the MCS can be 20 or 21 based on the UE cat. We 
11344        * choose 20, instead of 21, ie UE_CAT_3 */
11345       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
11346       RG_SCH_CMN_UL_TBS_TO_MCS(iTbs, hqFailStats.ulCqiStat[i - 1].mcs);
11347 #endif
11348    }
11349    for (i = RG_SCH_CMN_UL_NUM_CQI - 1; i != 0; --i)
11350    {
11351       /* Fix for ccpu00123912*/
11352       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
11353       if (iTbs <= RGSCH_UL_16QAM_MAX_ITBS) /* corresponds to 16QAM */
11354       {
11355          RLOG_ARG1(L_INFO,DBG_CELLID,cell->cellId,
11356                          "16 QAM CQI %u", i);
11357          cellUl->max16qamCqi = i;
11358          break;
11359       }
11360    }
11361
11362 #ifdef EMTC_ENABLE
11363    /* Precompute useful values for RA msg3 */
11364    ret = rgSCHCmnPrecompEmtcMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
11365          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
11366    if (ret != ROK)
11367    {
11368       RETVALUE(ret);
11369    }
11370 #endif   
11371
11372    /* Precompute useful values for RA msg3 */
11373    ret = rgSCHCmnPrecompMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
11374          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
11375    if (ret != ROK)
11376    {
11377       RETVALUE(ret);
11378    }
11379
11380    cellUl->sbSize  = sbSize;
11381    
11382 #ifdef LTE_TDD  
11383    cellUl->numUlSubfrms = maxSubfrms;
11384
11385    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->ulSfArr,
11386             cellUl->numUlSubfrms * sizeof(RgSchUlSf));
11387
11388    if (ret != ROK)
11389    {
11390       cellUl->numUlSubfrms = 0;
11391       RETVALUE(ret);
11392    }
11393
11394    /* store the DL subframe corresponding to the PUSCH offset
11395     * in their respective UL subframe */
11396    for(i=0; i < RGSCH_NUM_SUB_FRAMES; i++)
11397    {
11398       if(rgSchTddPuschTxKTbl[ulDlCfgIdx][i] != 0)
11399       {
11400          subfrm = (i + rgSchTddPuschTxKTbl[ulDlCfgIdx][i]) % \
11401                                  RGSCH_NUM_SUB_FRAMES;
11402          subfrm = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subfrm]-1;
11403          dlIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][i]-1;
11404          RGSCH_ARRAY_BOUND_CHECK( cell->instIdx, ulToDlMap, subfrm);
11405          ulToDlMap[subfrm] = dlIdx;
11406       }
11407    }
11408    /* Copy the information in the remaining UL subframes based
11409     * on number of HARQ processes */
11410    for(i=maxUlsubfrms; i < maxSubfrms; i++)
11411    {
11412       subfrm = i-maxUlsubfrms;
11413       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, i);
11414       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, subfrm)
11415       ulToDlMap[i] = ulToDlMap[subfrm];
11416    }
11417 #endif
11418
11419    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++)
11420    {
11421 #ifdef LTE_TDD        
11422       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
11423 #else
11424       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
11425 #endif
11426       if (ret != ROK)
11427       {
11428          RETVALUE(ret);
11429       }
11430
11431       if (cfi == 1)
11432       {
11433          cell->ulAvailBw = bwAvail;
11434       }
11435
11436       numSb = bwAvail/sbSize; 
11437
11438       cell->dynCfiCb.bwInfo[cfi].startRb  = rbStart;
11439       cell->dynCfiCb.bwInfo[cfi].numSb    = numSb;
11440    }
11441
11442    if(0 == cell->dynCfiCb.maxCfi)
11443    {
11444       RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, 
11445                "Incorrect Default CFI(%u), maxCfi(%u), maxPucchRb(%d)",
11446                cellSch->cfiCfg.cfi, cell->dynCfiCb.maxCfi, 
11447                cell->pucchCfg.maxPucchRb);
11448             
11449       RETVALUE(RFAILED);
11450    }
11451
11452    /* DMRS values */
11453    cellUl->dmrsArrSize = cell->dynCfiCb.bwInfo[1].numSb;
11454    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->dmrsArr,
11455          cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11456    if (ret != ROK)
11457    {
11458       RETVALUE(ret);
11459    }
11460    for (i = 0; i < cellUl->dmrsArrSize; ++i)
11461    {
11462       cellUl->dmrsArr[i] = cellCfg->puschSubBand.dmrs[i];
11463    }
11464  
11465    /* Init subframes */
11466    for (i = 0; i < maxSubfrms; ++i)
11467    {
11468       ret = rgSCHUtlUlSfInit(cell, &cellUl->ulSfArr[i], i,
11469                              cellUl->maxAllocPerUlSf);
11470       if (ret != ROK)
11471       {
11472          for (; i != 0; --i)
11473          {
11474             rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[i-1]);
11475          }
11476          /* ccpu00117052 - MOD - Passing double pointer
11477             for proper NULLP assignment*/
11478          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(cellUl->dmrsArr)),
11479                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11480 #ifdef LTE_TDD
11481          /* ccpu00117052 - MOD - Passing double pointer
11482             for proper NULLP assignment*/
11483          rgSCHUtlFreeSBuf(cell->instIdx,
11484             (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
11485 #endif
11486          RETVALUE(ret);
11487       }
11488    }
11489    RG_SCH_RESET_HCSG_UL_PRB_CNTR(cellUl);
11490    RETVALUE(ROK);
11491 }
11492
11493 /**
11494  * @brief Scheduler processing on cell configuration.
11495  *
11496  * @details
11497  *
11498  *     Function : rgSCHCmnRgrCellCfg
11499  *
11500  *     This function does requisite initialisation
11501  *     and setup for scheduler1 when a cell is
11502  *     configured.
11503  *
11504  *  @param[in]  RgSchCellCb   *cell
11505  *  @param[in]  RgrCellCfg    *cellCfg
11506  *  @param[out] RgSchErrInfo  *err
11507  *  @return  S16
11508  *      -# ROK
11509  *      -# RFAILED
11510  **/
11511 #ifdef ANSI
11512 PUBLIC S16 rgSCHCmnRgrCellCfg
11513 (
11514 RgSchCellCb   *cell,
11515 RgrCellCfg    *cellCfg,
11516 RgSchErrInfo  *err
11517 )
11518 #else
11519 PUBLIC S16 rgSCHCmnRgrCellCfg(cell, cellCfg, err)
11520 RgSchCellCb   *cell;
11521 RgrCellCfg    *cellCfg;
11522 RgSchErrInfo  *err;
11523 #endif
11524 {
11525    S16       ret;
11526    RgSchCmnCell *cellSch;
11527    TRC2(rgSCHCmnRgrCellCfg);
11528
11529    /* As part of RGR cell configuration, validate the CRGCellCfg
11530     * There is no trigger for crgCellCfg from SC1 */
11531    /* Removed failure check for Extended CP */
11532
11533    if (((ret = rgSCHUtlAllocSBuf(cell->instIdx,
11534       (Data**)&(cell->sc.sch), (sizeof(RgSchCmnCell)))) != ROK))
11535    {
11536       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,  
11537          "Memory allocation FAILED");
11538       err->errCause = RGSCHERR_SCH_CFG;
11539       RETVALUE(ret);
11540    }
11541    cellSch = (RgSchCmnCell *)(cell->sc.sch);
11542    cellSch->cfiCfg = cellCfg->cfiCfg;
11543    cellSch->trgUlCqi.trgCqi = cellCfg->trgUlCqi.trgCqi;
11544    /* Initialize the scheduler refresh timer queues */
11545    cellSch->tmrTqCp.nxtEnt = 0;
11546    cellSch->tmrTqCp.tmrLen = RG_SCH_CMN_NUM_REFRESH_Q;
11547
11548    /* RACHO Intialize the RACH ded Preamble Information */
11549    rgSCHCmnCfgRachDedPrm(cell);
11550 #ifdef LTE_TDD
11551    /* Initialize 'Np' value for each 'p' used for
11552     * HARQ ACK/NACK reception */
11553    rgSCHCmnDlNpValInit(cell);
11554 #endif
11555
11556    /* Initialize 'Np' value for each 'p' used for
11557     * HARQ ACK/NACK reception */
11558 #ifdef LTE_TDD
11559    rgSCHCmnDlNpValInit(cell);
11560 #endif
11561
11562    /* Now perform uplink related initializations  */
11563    ret = rgSCHCmnUlCellInit(cell, cellCfg);
11564    if (ret != ROK)
11565    {
11566       /* There is no downlink deinit to be performed */
11567       err->errCause = RGSCHERR_SCH_CFG;
11568       RETVALUE(ret);
11569    }
11570    ret = rgSCHCmnDlRgrCellCfg(cell, cellCfg, err);
11571    if (ret != ROK)
11572    {
11573       err->errCause = RGSCHERR_SCH_CFG;
11574       RETVALUE(ret);
11575    }
11576    /* DL scheduler has no initializations to make */
11577    /* As of now DL scheduler always returns ROK   */
11578
11579    rgSCHCmnGetDciFrmtSizes(cell);
11580    rgSCHCmnGetCqiDciFrmt2AggrLvl(cell);
11581 #ifdef EMTC_ENABLE 
11582    rgSCHCmnGetEmtcDciFrmtSizes(cell);
11583    rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl(cell);
11584 #endif /* EMTC_ENABLE  */
11585
11586 #ifdef EMTC_ENABLE   
11587    if(TRUE == cellCfg->emtcEnable)
11588    {
11589       cellSch->apisEmtcUl = &rgSchEmtcUlSchdTbl[0];
11590       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
11591       if (ret != ROK)
11592       {
11593          RETVALUE(ret);
11594       }
11595    }
11596 #endif
11597    cellSch->apisUl = &rgSchUlSchdTbl[RG_SCH_CMN_GET_UL_SCHED_TYPE(cell)];
11598    ret = cellSch->apisUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
11599    if (ret != ROK)
11600    {
11601       RETVALUE(ret);
11602    }
11603 #ifdef EMTC_ENABLE   
11604    if(TRUE == cellCfg->emtcEnable)
11605    {
11606       cellSch->apisEmtcDl = &rgSchEmtcDlSchdTbl[0];
11607       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
11608       if (ret != ROK)
11609       {
11610          RETVALUE(ret);
11611       }
11612    }
11613 #endif
11614    cellSch->apisDl = &rgSchDlSchdTbl[RG_SCH_CMN_GET_DL_SCHED_TYPE(cell)];
11615 #ifdef LTEMAC_SPS
11616    /* Perform SPS specific initialization for the cell */
11617    ret = rgSCHCmnSpsCellCfg(cell, cellCfg, err);
11618    if (ret != ROK)
11619    {
11620       RETVALUE(ret);
11621    }
11622 #endif
11623    ret = cellSch->apisDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
11624    if (ret != ROK)
11625    {
11626       RETVALUE(ret);
11627    }
11628    rgSCHCmnInitVars(cell);
11629
11630    RETVALUE(ROK);
11631 }  /* rgSCHCmnRgrCellCfg*/
11632
11633 \f
11634 /**
11635  * @brief This function handles the reconfiguration of cell.
11636  *
11637  * @details
11638  *
11639  *     Function: rgSCHCmnRgrCellRecfg
11640  *     Purpose:  Update the reconfiguration parameters.
11641  *
11642  *     Invoked by: Scheduler
11643  *
11644  *  @param[in]  RgSchCellCb*  cell
11645  *  @return  Void
11646  *
11647  **/
11648 #ifdef ANSI
11649 PUBLIC S16 rgSCHCmnRgrCellRecfg
11650 (
11651 RgSchCellCb             *cell,
11652 RgrCellRecfg            *recfg,
11653 RgSchErrInfo            *err
11654 )
11655 #else
11656 PUBLIC S16 rgSCHCmnRgrCellRecfg(cell, recfg, err)
11657 RgSchCellCb             *cell;
11658 RgrCellRecfg            *recfg;
11659 RgSchErrInfo            *err;
11660 #endif
11661 {
11662    S16                  ret;
11663    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
11664    RgSchCmnUlCell       *cellUl  = RG_SCH_CMN_GET_UL_CELL(cell);
11665
11666    TRC2(rgSCHCmnRgrCellRecfg);
11667
11668    if (recfg->recfgTypes & RGR_CELL_UL_CMNRATE_RECFG)
11669    {
11670       U8   oldCqi = cellUl->dfltUlCqi;
11671       if (!RG_SCH_CMN_UL_IS_CQI_VALID(recfg->ulCmnCodeRate.ccchCqi))
11672       {
11673          err->errCause = RGSCHERR_SCH_CFG;
11674          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnRgrCellRecfg(): "
11675             "Invalid cqi");
11676          RETVALUE(RFAILED);
11677       }
11678       cellUl->dfltUlCqi = recfg->ulCmnCodeRate.ccchCqi;
11679       ret = rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
11680             cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
11681       if (ret != ROK)
11682       {
11683          cellUl->dfltUlCqi = oldCqi;
11684          rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
11685                cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
11686          RETVALUE(ret);
11687       }
11688    }
11689
11690    if (recfg->recfgTypes & RGR_CELL_DL_CMNRATE_RECFG)
11691    {
11692       if (rgSCHCmnDlCnsdrCmnRt(cell, &recfg->dlCmnCodeRate) != ROK)
11693       {
11694          err->errCause = RGSCHERR_SCH_CFG;
11695          RETVALUE(RFAILED);
11696       }
11697    }
11698  
11699 #ifdef EMTC_ENABLE  
11700    if(TRUE == cell->emtcEnable) 
11701    {
11702       /* Invoke UL sched for cell Recfg */
11703       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
11704       if (ret != ROK)
11705       {
11706          RETVALUE(RFAILED);
11707       }
11708
11709       /* Invoke DL sched for cell Recfg */
11710       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
11711       if (ret != ROK)
11712       {
11713          RETVALUE(RFAILED);
11714       }
11715    }
11716    else
11717 #endif
11718    {
11719    /* Invoke UL sched for cell Recfg */
11720    ret = cellSch->apisUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
11721    if (ret != ROK)
11722    {
11723       RETVALUE(RFAILED);
11724    }
11725
11726    /* Invoke DL sched for cell Recfg */
11727    ret = cellSch->apisDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
11728    if (ret != ROK)
11729    {
11730       RETVALUE(RFAILED);
11731    }
11732    }
11733
11734    if (recfg->recfgTypes & RGR_CELL_DLFS_RECFG)
11735    {
11736       ret = cellSch->apisDlfs->rgSCHDlfsCellRecfg(cell, recfg, err);
11737       if (ret != ROK)
11738       {
11739          RETVALUE(RFAILED);
11740       }
11741       cellSch->dl.isDlFreqSel = recfg->dlfsRecfg.isDlFreqSel;
11742    }
11743
11744    if (recfg->recfgTypes & RGR_CELL_PWR_RECFG)
11745    {
11746       ret = rgSCHPwrCellRecfg(cell, recfg);
11747       if (ret != ROK)
11748       {
11749          RETVALUE(RFAILED);
11750       }
11751    }
11752
11753    RETVALUE(ROK);
11754 }
11755
11756 /***********************************************************
11757  *
11758  *     Func : rgSCHCmnUlCellDeinit
11759  *
11760  *     Desc : Uplink scheduler de-initialisation for cell.
11761  *
11762  *     Ret  : S16
11763  *
11764  *     Notes:
11765  *
11766  *     File :
11767  *
11768  **********************************************************/
11769 #ifdef ANSI
11770 PRIVATE Void rgSCHCmnUlCellDeinit
11771 (
11772 RgSchCellCb *cell
11773 )
11774 #else
11775 PRIVATE Void rgSCHCmnUlCellDeinit(cell)
11776 RgSchCellCb *cell;
11777 #endif
11778 {
11779    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11780    U8               ulSfIdx;
11781 #ifdef LTE_TDD
11782    U8        maxSubfrms = cellUl->numUlSubfrms;
11783 #endif
11784 #ifdef LTE_L2_MEAS
11785    CmLList       *lnk = NULLP;
11786    RgSchL2MeasCb *measCb;
11787 #endif
11788    TRC2(rgSCHCmnUlCellDeinit);
11789 #ifdef LTE_L2_MEAS
11790 #ifdef LTE_TDD
11791    for(ulSfIdx = 0; ulSfIdx < RGSCH_SF_ALLOC_SIZE; ulSfIdx++)
11792 #else
11793    for(ulSfIdx = 0; ulSfIdx < RGSCH_NUM_SUB_FRAMES; ulSfIdx++)
11794 #endif
11795    {
11796       if(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo != NULLP)
11797       {
11798          /* ccpu00117052 - MOD - Passing double pointer
11799             for proper NULLP assignment*/
11800          rgSCHUtlFreeSBuf(cell->instIdx,
11801          (Data **)(&(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo)),
11802          cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc));
11803
11804          /* ccpu00117052 - DEL - removed explicit NULLP assignment
11805             as it is done in above utility function */
11806       }
11807    }
11808    /* Free the memory allocated to measCb */
11809    lnk = cell->l2mList.first;
11810    while(lnk != NULLP)
11811    {
11812       measCb = (RgSchL2MeasCb *)lnk->node;
11813       cmLListDelFrm(&cell->l2mList, lnk);
11814       lnk = lnk->next;
11815    /* ccpu00117052 - MOD - Passing double pointer
11816    for proper NULLP assignment*/
11817       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\
11818                           sizeof(RgSchL2MeasCb));
11819    }
11820 #endif
11821    if (cellUl->dmrsArr != NULLP)
11822    {
11823       /* ccpu00117052 - MOD - Passing double pointer
11824       for proper NULLP assignment*/
11825       rgSCHUtlFreeSBuf(cell->instIdx,(Data **)(&(cellUl->dmrsArr)),
11826                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11827    }
11828    /* De-init subframes */
11829 #ifdef LTE_TDD
11830    for (ulSfIdx = 0; ulSfIdx < maxSubfrms; ++ulSfIdx)
11831 #else
11832    for (ulSfIdx = 0; ulSfIdx < RG_SCH_CMN_UL_NUM_SF; ++ulSfIdx)
11833 #endif
11834    {
11835       rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[ulSfIdx]);
11836    }
11837
11838 #ifdef LTE_TDD
11839    if (cellUl->ulSfArr != NULLP)
11840    {
11841       /* ccpu00117052 - MOD - Passing double pointer
11842       for proper NULLP assignment*/
11843       rgSCHUtlFreeSBuf(cell->instIdx,
11844          (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
11845    }
11846 #endif
11847
11848    RETVOID;
11849 }
11850
11851 /**
11852  * @brief Scheduler processing for cell delete.
11853  *
11854  * @details
11855  *
11856  *     Function : rgSCHCmnCellDel
11857  *
11858  *     This functions de-initialises and frees memory
11859  *     taken up by scheduler1 for the entire cell.
11860  *
11861  *  @param[in]  RgSchCellCb  *cell
11862  *  @return  Void
11863  **/
11864 #ifdef ANSI
11865 PUBLIC Void rgSCHCmnCellDel
11866 (
11867 RgSchCellCb  *cell
11868 )
11869 #else
11870 PUBLIC Void rgSCHCmnCellDel(cell)
11871 RgSchCellCb  *cell;
11872 #endif
11873 {
11874    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11875    TRC2(rgSCHCmnCellDel);
11876
11877 #ifdef LTE_L2_MEAS
11878    glblTtiCnt = 0;
11879 #endif
11880    if (cellSch == NULLP)
11881    {
11882       RETVOID;
11883    }
11884    /* Perform the deinit for the UL scheduler */
11885    rgSCHCmnUlCellDeinit(cell);
11886 #ifdef EMTC_ENABLE
11887    if(TRUE == cell->emtcEnable)
11888    {
11889       if (cellSch->apisEmtcUl)
11890       {
11891          cellSch->apisEmtcUl->rgSCHFreeUlCell(cell);
11892       }
11893    }
11894 #endif 
11895    if (cellSch->apisUl)
11896    {
11897       /* api pointer checks added (here and below in
11898        * this function). pl check. - antriksh */
11899       cellSch->apisUl->rgSCHFreeUlCell(cell);
11900    }
11901
11902    /* Perform the deinit for the DL scheduler */
11903    cmLListInit(&cellSch->dl.taLst);
11904    if (cellSch->apisDl)
11905    {
11906       cellSch->apisDl->rgSCHFreeDlCell(cell);
11907    }
11908 #ifdef EMTC_ENABLE
11909    if (cellSch->apisEmtcDl)
11910    {
11911       rgSCHEmtcInitTaLst(&cellSch->dl);
11912
11913       cellSch->apisEmtcDl->rgSCHFreeDlCell(cell);
11914    }
11915 #endif
11916
11917    /* DLFS de-initialization */
11918    if (cellSch->dl.isDlFreqSel && cellSch->apisDlfs)
11919    {
11920       cellSch->apisDlfs->rgSCHDlfsCellDel(cell);
11921    }
11922
11923    rgSCHPwrCellDel(cell);
11924 #ifdef LTEMAC_SPS
11925    rgSCHCmnSpsCellDel(cell);
11926 #endif
11927
11928    /* ccpu00117052 - MOD - Passing double pointer
11929    for proper NULLP assignment*/
11930    rgSCHUtlFreeSBuf(cell->instIdx,
11931       (Data**)(&(cell->sc.sch)), (sizeof(RgSchCmnCell)));
11932    RETVOID;
11933 }  /* rgSCHCmnCellDel */
11934
11935 \f
11936 /**
11937  * @brief This function validates QOS parameters for DL.
11938  *
11939  * @details
11940  *
11941  *     Function: rgSCHCmnValidateDlQos
11942  *     Purpose:  This function validates QOS parameters for DL.
11943  *
11944  *     Invoked by: Scheduler
11945  *
11946  *  @param[in] CrgLchQosCfg    *dlQos
11947  *  @return                    S16
11948  *
11949  **/
11950 #ifdef ANSI
11951 PRIVATE S16 rgSCHCmnValidateDlQos
11952 (
11953 RgrLchQosCfg            *dlQos
11954 )
11955 #else
11956 PRIVATE S16 rgSCHCmnValidateDlQos(dlQos)
11957 RgrLchQosCfg            *dlQos;
11958 #endif
11959 {
11960    U8 qci = dlQos->qci;
11961
11962    TRC2(rgSCHCmnValidateDlQos);
11963
11964    if ( qci < RG_SCH_CMN_MIN_QCI || qci > RG_SCH_CMN_MAX_QCI )
11965    {
11966       RETVALUE(RFAILED);
11967    }
11968
11969    if ((qci >= RG_SCH_CMN_GBR_QCI_START) &&
11970        (qci <= RG_SCH_CMN_GBR_QCI_END))
11971    {
11972       if ((dlQos->mbr == 0) || (dlQos->mbr < dlQos->gbr))
11973       {
11974          RETVALUE(RFAILED);
11975       }
11976    }
11977    RETVALUE(ROK);
11978 }
11979
11980 /**
11981  * @brief Scheduler invocation on logical channel addition.
11982  *
11983  * @details
11984  *
11985  *     Function : rgSCHCmnRgrLchCfg
11986  *
11987  *     This functions does required processing when a new
11988  *     (dedicated) logical channel is added. Assumes lcg
11989  *     pointer in ulLc is set.
11990  *
11991  *  @param[in]  RgSchCellCb  *cell
11992  *  @param[in]  RgSchUeCb    *ue
11993  *  @param[in]  RgSchDlLcCb  *dlLc
11994  *  @param[int] RgrLchCfg    *lcCfg
11995  *  @param[out] RgSchErrInfo *err
11996  *  @return  S16
11997  *      -# ROK
11998  *      -# RFAILED
11999  **/
12000 #ifdef ANSI
12001 PUBLIC S16 rgSCHCmnRgrLchCfg
12002 (
12003 RgSchCellCb  *cell,
12004 RgSchUeCb    *ue,
12005 RgSchDlLcCb  *dlLc,
12006 RgrLchCfg *lcCfg,
12007 RgSchErrInfo *err
12008 )
12009 #else
12010 PUBLIC S16 rgSCHCmnRgrLchCfg(cell, ue, dlLc, lcCfg, err)
12011 RgSchCellCb  *cell;
12012 RgSchUeCb    *ue;
12013 RgSchDlLcCb  *dlLc;
12014 RgrLchCfg *lcCfg;
12015 RgSchErrInfo *err;
12016 #endif
12017 {
12018    S16 ret;
12019
12020    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12021
12022    TRC2(rgSCHCmnRgrLchCfg);
12023
12024    ret = rgSCHUtlAllocSBuf(cell->instIdx,
12025       (Data**)&((dlLc)->sch), (sizeof(RgSchCmnDlSvc)));
12026    if (ret != ROK)
12027    {
12028       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRgrLchCfg(): "
12029          "SCH struct alloc failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
12030       err->errCause = RGSCHERR_SCH_CFG;
12031       RETVALUE(ret);
12032    }
12033    if(lcCfg->lcType != CM_LTE_LCH_DCCH)
12034    {
12035       ret = rgSCHCmnValidateDlQos(&lcCfg->dlInfo.dlQos);
12036       if (ret != ROK)
12037       {
12038          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSchCmnCrgLcCfg(): "
12039             "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
12040          err->errCause = RGSCHERR_SCH_CFG;
12041          RETVALUE(ret);
12042       }
12043       /* Perform DL service activation in the scheduler */
12044       ((RgSchCmnDlSvc *)(dlLc->sch))->qci = lcCfg->dlInfo.dlQos.qci;
12045       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = rgSchCmnDlQciPrio[lcCfg->dlInfo.dlQos.qci - 1];
12046       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcCfg->dlInfo.dlQos.gbr * \
12047       RG_SCH_CMN_REFRESH_TIME)/100;
12048       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcCfg->dlInfo.dlQos.mbr * \
12049       RG_SCH_CMN_REFRESH_TIME)/100;
12050    }
12051    else
12052    {
12053      /*assigning highest priority to DCCH */
12054     ((RgSchCmnDlSvc *)(dlLc->sch))->prio=RG_SCH_CMN_DCCH_PRIO; 
12055    }   
12056    dlLc->ue = ue;
12057    dlLc->lcType=lcCfg->lcType;
12058
12059 #ifdef EMTC_ENABLE
12060    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
12061    {
12062       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcCfg(cell, ue,dlLc ,lcCfg, err);
12063       if (ret != ROK)
12064       {
12065          RETVALUE(RFAILED);
12066       }
12067    }
12068    else
12069 #endif 
12070    {
12071       ret = cellSch->apisDl->rgSCHRgrDlLcCfg(cell, ue, dlLc, lcCfg, err);
12072       if (ret != ROK)
12073       {
12074          RETVALUE(RFAILED);
12075       }
12076    }
12077    
12078 #ifdef EMTC_ENABLE
12079    if(TRUE == ue->isEmtcUe)
12080    {
12081       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
12082       if (ret != ROK)
12083       {
12084          RETVALUE(RFAILED);
12085       }
12086    }
12087    else
12088 #endif 
12089    {
12090    ret = cellSch->apisUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
12091    if (ret != ROK)
12092    {
12093       RETVALUE(RFAILED);
12094    }
12095    }
12096    
12097 #ifdef LTE_ADV
12098    if (ue->numSCells)
12099    {
12100       rgSCHSCellDlLcCfg(cell, ue, dlLc);
12101    }
12102 #endif
12103
12104
12105 #ifdef LTEMAC_SPS
12106    if(lcCfg->dlInfo.dlSpsCfg.isSpsEnabled)
12107    {
12108       /* Invoke SPS module if SPS is enabled for the service */
12109       ret = rgSCHCmnSpsDlLcCfg(cell, ue, dlLc, lcCfg, err);
12110       if (ret != ROK)
12111       {
12112          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "rgSchCmnRgrLchCfg(): "
12113             "SPS configuration failed for DL LC for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
12114          err->errCause = RGSCHERR_SCH_CFG;
12115          RETVALUE(RFAILED);
12116       }
12117    }
12118 #endif
12119
12120    RETVALUE(ROK);
12121 }
12122
12123 /**
12124  * @brief Scheduler invocation on logical channel addition.
12125  *
12126  * @details
12127  *
12128  *     Function : rgSCHCmnRgrLchRecfg
12129  *
12130  *     This functions does required processing when an existing
12131  *     (dedicated) logical channel is reconfigured. Assumes lcg
12132  *     pointer in ulLc is set to the old value.
12133  *     Independent of whether new LCG is meant to be configured,
12134  *     the new LCG scheduler information is accessed and possibly modified.
12135  *
12136  *  @param[in]  RgSchCellCb  *cell
12137  *  @param[in]  RgSchUeCb    *ue
12138  *  @param[in]  RgSchDlLcCb  *dlLc
12139  *  @param[int] RgrLchRecfg  *lcRecfg
12140  *  @param[out] RgSchErrInfo *err
12141  *  @return  S16
12142  *      -# ROK
12143  *      -# RFAILED
12144  **/
12145 #ifdef ANSI
12146 PUBLIC S16 rgSCHCmnRgrLchRecfg
12147 (
12148 RgSchCellCb  *cell,
12149 RgSchUeCb    *ue,
12150 RgSchDlLcCb  *dlLc,
12151 RgrLchRecfg  *lcRecfg,
12152 RgSchErrInfo *err
12153 )
12154 #else
12155 PUBLIC S16 rgSCHCmnRgrLchRecfg(cell, ue, dlLc, lcRecfg, err)
12156 RgSchCellCb  *cell;
12157 RgSchUeCb    *ue;
12158 RgSchDlLcCb  *dlLc;
12159 RgrLchRecfg  *lcRecfg;
12160 RgSchErrInfo *err;
12161 #endif
12162 {
12163    S16   ret;
12164    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12165
12166    TRC2(rgSCHCmnRgrLchRecfg)
12167
12168    if(dlLc->lcType != CM_LTE_LCH_DCCH)
12169    {
12170       ret = rgSCHCmnValidateDlQos(&lcRecfg->dlRecfg.dlQos);
12171    
12172       if (ret != ROK)
12173       {
12174          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
12175                "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12176          err->errCause = RGSCHERR_SCH_CFG;
12177          RETVALUE(ret);
12178       }
12179       if (((RgSchCmnDlSvc *)(dlLc->sch))->qci != lcRecfg->dlRecfg.dlQos.qci)
12180       {
12181          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Qci, hence lc Priority change "
12182             "not supported for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12183          err->errCause = RGSCHERR_SCH_CFG;
12184          RETVALUE(ret);
12185       }
12186       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcRecfg->dlRecfg.dlQos.gbr * \
12187       RG_SCH_CMN_REFRESH_TIME)/100;
12188       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcRecfg->dlRecfg.dlQos.mbr * \
12189       RG_SCH_CMN_REFRESH_TIME)/100;
12190    }
12191    else
12192    {
12193       /*assigning highest priority to DCCH */
12194       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = RG_SCH_CMN_DCCH_PRIO; 
12195    }
12196    
12197 #ifdef EMTC_ENABLE
12198    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
12199    {
12200       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12201       if (ret != ROK)
12202       {
12203          RETVALUE(RFAILED);
12204       }
12205       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
12206       if (ret != ROK)
12207       {
12208          RETVALUE(RFAILED);
12209       }
12210    }
12211    else
12212 #endif 
12213    {
12214    ret = cellSch->apisDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12215    if (ret != ROK)
12216    {
12217       RETVALUE(RFAILED);
12218    }
12219    ret = cellSch->apisUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
12220    if (ret != ROK)
12221    {
12222       RETVALUE(RFAILED);
12223    }
12224    }
12225     
12226 #ifdef LTEMAC_SPS
12227    if (lcRecfg->recfgTypes & RGR_DL_LC_SPS_RECFG)
12228    {
12229       /* Invoke SPS module if SPS is enabled for the service */
12230       if(lcRecfg->dlRecfg.dlSpsRecfg.isSpsEnabled)
12231       {
12232          ret = rgSCHCmnSpsDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12233          if (ret != ROK)
12234          {
12235             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"SPS re-configuration not "
12236                   "supported for dlLC Ignore this CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12237          }
12238       }
12239       RETVALUE(ROK);
12240    }
12241 #endif
12242
12243    RETVALUE(ROK);
12244 }
12245
12246 /**
12247  * @brief Scheduler invocation on logical channel addition.
12248  *
12249  * @details
12250  *
12251  *     Function : rgSCHCmnRgrLcgCfg
12252  *
12253  *     This functions does required processing when a new
12254  *     (dedicated) logical channel is added. Assumes lcg
12255  *     pointer in ulLc is set.
12256  *
12257  *  @param[in]  RgSchCellCb  *cell,
12258  *  @param[in]  RgSchUeCb    *ue,
12259  *  @param[in]  RgSchLcgCb   *lcg,
12260  *  @param[in]  RgrLcgCfg    *lcgCfg,
12261  *  @param[out] RgSchErrInfo *err
12262  *  @return  S16
12263  *      -# ROK
12264  *      -# RFAILED
12265  **/
12266 #ifdef ANSI
12267 PUBLIC S16 rgSCHCmnRgrLcgCfg
12268 (
12269 RgSchCellCb  *cell,
12270 RgSchUeCb    *ue,
12271 RgSchLcgCb   *lcg,
12272 RgrLcgCfg    *lcgCfg,
12273 RgSchErrInfo *err
12274 )
12275 #else
12276 PUBLIC S16 rgSCHCmnRgrLcgCfg(cell, ue, lcg, lcgCfg, err)
12277 RgSchCellCb  *cell;
12278 RgSchUeCb    *ue;
12279 RgSchLcgCb   *lcg;
12280 RgrLcgCfg    *lcgCfg;
12281 RgSchErrInfo *err;
12282 #endif
12283 {
12284    S16 ret;
12285    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12286    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].sch));
12287
12288    TRC2(rgSCHCmnRgrLcgCfg);
12289
12290    ulLcg->cfgdGbr = (lcgCfg->ulInfo.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
12291    ulLcg->effGbr  = ulLcg->cfgdGbr;
12292    ulLcg->deltaMbr = ((lcgCfg->ulInfo.mbr - lcgCfg->ulInfo.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
12293    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
12294
12295 #ifdef EMTC_ENABLE
12296    if(TRUE == ue->isEmtcUe)
12297    {
12298       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
12299       if (ret != ROK)
12300       {
12301          RETVALUE(RFAILED);
12302       }
12303    }
12304    else
12305 #endif
12306    {
12307    ret = cellSch->apisUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
12308    if (ret != ROK)
12309    {
12310       RETVALUE(RFAILED);
12311    }
12312    }
12313    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
12314    {
12315       /* Indicate MAC that this LCG is GBR LCG */
12316       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcgCfg->ulInfo.lcgId, TRUE);
12317    }
12318    RETVALUE(ROK);
12319 }
12320
12321 /**
12322  * @brief Scheduler invocation on logical channel addition.
12323  *
12324  * @details
12325  *
12326  *     Function : rgSCHCmnRgrLcgRecfg
12327  *
12328  *     This functions does required processing when a new
12329  *     (dedicated) logical channel is added. Assumes lcg
12330  *     pointer in ulLc is set.
12331  *
12332  *  @param[in]  RgSchCellCb  *cell,
12333  *  @param[in]  RgSchUeCb    *ue,
12334  *  @param[in]  RgSchLcgCb   *lcg,
12335  *  @param[in]  RgrLcgRecfg  *reCfg,
12336  *  @param[out] RgSchErrInfo *err
12337  *  @return  S16
12338  *      -# ROK
12339  *      -# RFAILED
12340  **/
12341 #ifdef ANSI
12342 PUBLIC S16 rgSCHCmnRgrLcgRecfg
12343 (
12344 RgSchCellCb  *cell,
12345 RgSchUeCb    *ue,
12346 RgSchLcgCb   *lcg,
12347 RgrLcgRecfg  *reCfg,
12348 RgSchErrInfo *err
12349 )
12350 #else
12351 PUBLIC S16 rgSCHCmnRgrLcgRecfg(cell, ue, lcg, reCfg, err)
12352 RgSchCellCb  *cell;
12353 RgSchUeCb    *ue;
12354 RgSchLcgCb   *lcg;
12355 RgrLcgRecfg  *reCfg;
12356 RgSchErrInfo *err;
12357 #endif
12358 {
12359    S16 ret;
12360    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12361    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[reCfg->ulRecfg.lcgId].sch));
12362    
12363    TRC2(rgSCHCmnRgrLcgRecfg);
12364
12365    ulLcg->cfgdGbr = (reCfg->ulRecfg.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
12366    ulLcg->effGbr  = ulLcg->cfgdGbr;
12367    ulLcg->deltaMbr = ((reCfg->ulRecfg.mbr - reCfg->ulRecfg.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
12368    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
12369  
12370 #ifdef EMTC_ENABLE
12371    if(TRUE == ue->isEmtcUe)
12372    {
12373       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
12374       if (ret != ROK)
12375       {
12376          RETVALUE(RFAILED);
12377       }
12378    }
12379    else
12380 #endif
12381    {
12382    ret = cellSch->apisUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
12383    if (ret != ROK)
12384    {
12385       RETVALUE(RFAILED);
12386    }
12387    }
12388    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
12389    {
12390       /* Indicate MAC that this LCG is GBR LCG */
12391       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, TRUE);
12392    }
12393    else
12394    {
12395       /* In case of RAB modification */
12396       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, FALSE);
12397    }
12398    RETVALUE(ROK);
12399 }
12400
12401 /***********************************************************
12402  *
12403  *     Func : rgSCHCmnRgrLchDel
12404  *
12405  *     Desc : Scheduler handling for a (dedicated)
12406  *             uplink logical channel being deleted.
12407  *
12408  *     Ret  :
12409  *
12410  *     Notes:
12411  *
12412  *     File :
12413  **********************************************************/
12414 #ifdef ANSI
12415 PUBLIC S16 rgSCHCmnRgrLchDel 
12416 (
12417 RgSchCellCb   *cell,
12418 RgSchUeCb     *ue,
12419 CmLteLcId     lcId,
12420 U8            lcgId
12421 )
12422 #else
12423 PUBLIC S16 rgSCHCmnRgrLchDel(cell, ue, lcId, lcgId)
12424 RgSchCellCb   *cell;
12425 RgSchUeCb     *ue;
12426 CmLteLcId     lcId;
12427 U8            lcgId;
12428 #endif
12429 {
12430    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12431    TRC2(rgSCHCmnRgrLchDel);
12432 #ifdef EMTC_ENABLE
12433    if(TRUE == ue->isEmtcUe)
12434    {
12435       cellSch->apisEmtcUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
12436    }
12437    else
12438 #endif
12439    {
12440    cellSch->apisUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
12441    }
12442    RETVALUE(ROK);
12443 }
12444
12445 /***********************************************************
12446  *
12447  *     Func : rgSCHCmnLcgDel
12448  *
12449  *     Desc : Scheduler handling for a (dedicated)
12450  *             uplink logical channel being deleted.
12451  *
12452  *     Ret  :
12453  *
12454  *     Notes:
12455  *
12456  *     File :
12457  *
12458  **********************************************************/
12459 #ifdef ANSI
12460 PUBLIC Void rgSCHCmnLcgDel
12461 (
12462 RgSchCellCb   *cell,
12463 RgSchUeCb     *ue,
12464 RgSchLcgCb    *lcg
12465 )
12466 #else
12467 PUBLIC Void rgSCHCmnLcgDel(cell, ue, lcg)
12468 RgSchCellCb   *cell;
12469 RgSchUeCb     *ue;
12470 RgSchLcgCb    *lcg;
12471 #endif
12472 {
12473    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12474    RgSchCmnLcg  *lcgCmn = RG_SCH_CMN_GET_UL_LCG(lcg);
12475    TRC2(rgSCHCmnLcgDel);
12476
12477    if (lcgCmn == NULLP)
12478    {
12479       RETVOID;
12480    }
12481
12482    if (RGSCH_IS_GBR_BEARER(lcgCmn->cfgdGbr))
12483    {
12484       /* Indicate MAC that this LCG is GBR LCG */
12485       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcg->lcgId, FALSE);
12486    }
12487
12488 #ifdef LTEMAC_SPS
12489    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
12490    {
12491       rgSCHCmnSpsUlLcgDel(cell, ue, lcg);
12492    }
12493 #endif /* LTEMAC_SPS */
12494
12495    lcgCmn->effGbr     = 0;
12496    lcgCmn->reportedBs = 0;
12497    lcgCmn->cfgdGbr    = 0;
12498    /* set lcg bs to 0. Deletion of control block happens
12499     * at the time of UE deletion. */
12500    lcgCmn->bs = 0;
12501 #ifdef EMTC_ENABLE
12502    if(TRUE == ue->isEmtcUe)
12503    {
12504       cellSch->apisEmtcUl->rgSCHFreeUlLcg(cell, ue, lcg);
12505    }
12506    else
12507 #endif
12508    {
12509    cellSch->apisUl->rgSCHFreeUlLcg(cell, ue, lcg);
12510    }
12511    RETVOID;
12512 }
12513
12514 \f
12515 /**
12516  * @brief This function deletes a service from scheduler.
12517  *
12518  * @details
12519  *
12520  *     Function: rgSCHCmnFreeDlLc
12521  *     Purpose:  This function is made available through a FP for
12522  *               making scheduler aware of a service being deleted from UE.
12523  *
12524  *     Invoked by: BO and Scheduler
12525  *
12526  *  @param[in]  RgSchCellCb*  cell
12527  *  @param[in]  RgSchUeCb*    ue
12528  *  @param[in]  RgSchDlLcCb*  svc
12529  *  @return  Void
12530  *
12531  **/
12532 #ifdef ANSI
12533 PUBLIC Void rgSCHCmnFreeDlLc
12534 (
12535 RgSchCellCb                *cell,
12536 RgSchUeCb                  *ue,
12537 RgSchDlLcCb                *svc
12538 )
12539 #else
12540 PUBLIC Void rgSCHCmnFreeDlLc(cell, ue, svc)
12541 RgSchCellCb                *cell;
12542 RgSchUeCb                  *ue;
12543 RgSchDlLcCb                *svc;
12544 #endif
12545 {
12546    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12547    TRC2(rgSCHCmnFreeDlLc);
12548    if (svc->sch == NULLP)
12549    {
12550       RETVOID;
12551    }
12552 #ifdef EMTC_ENABLE
12553     if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
12554     {
12555       cellSch->apisEmtcDl->rgSCHFreeDlLc(cell, ue, svc);
12556     }
12557     else
12558 #endif
12559    {
12560       cellSch->apisDl->rgSCHFreeDlLc(cell, ue, svc);
12561    }
12562
12563 #ifdef LTE_ADV
12564    if (ue->numSCells)
12565    {
12566       rgSCHSCellDlLcDel(cell, ue, svc);
12567    }
12568 #endif
12569
12570 #ifdef LTEMAC_SPS
12571    /* If SPS service, invoke SPS module */
12572    if (svc->dlLcSpsCfg.isSpsEnabled)
12573    {
12574       rgSCHCmnSpsDlLcDel(cell, ue, svc);
12575    }
12576 #endif
12577
12578    /* ccpu00117052 - MOD - Passing double pointer
12579    for proper NULLP assignment*/
12580    rgSCHUtlFreeSBuf(cell->instIdx,
12581          (Data**)(&(svc->sch)), (sizeof(RgSchCmnDlSvc)));
12582
12583 #ifdef LTE_ADV
12584    rgSCHLaaDeInitDlLchCb(cell, svc);
12585 #endif
12586
12587    RETVOID;
12588 }
12589
12590 #ifdef RGR_V1
12591
12592 /**
12593  * @brief This function Processes the Final Allocations
12594  *        made by the RB Allocator against the requested
12595  *        CCCH SDURetx Allocations.
12596  *
12597  * @details
12598  *
12599  *     Function: rgSCHCmnDlCcchSduRetxFnlz
12600  *     Purpose:  This function Processes the Final Allocations
12601  *               made by the RB Allocator against the requested
12602  *               CCCH Retx Allocations.
12603  *               Scans through the scheduled list of ccchSdu retrans
12604  *               fills the corresponding pdcch, adds the hqProc to
12605  *               the corresponding SubFrm and removes the hqP from
12606  *               cells retx List.
12607  *
12608  *     Invoked by: Common Scheduler
12609  *
12610  *  @param[in]  RgSchCellCb           *cell
12611  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12612  *  @return  Void
12613  *
12614  **/
12615 #ifdef ANSI
12616 PRIVATE Void rgSCHCmnDlCcchSduRetxFnlz
12617 (
12618 RgSchCellCb           *cell,
12619 RgSchCmnDlRbAllocInfo *allocInfo
12620 )
12621 #else
12622 PRIVATE Void rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo)
12623 RgSchCellCb           *cell;
12624 RgSchCmnDlRbAllocInfo *allocInfo;
12625 #endif
12626 {
12627    CmLList           *node;
12628    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12629    RgSchDlRbAlloc    *rbAllocInfo;
12630    RgSchDlHqProcCb   *hqP;
12631    RgSchUeCb         *ue;
12632    TRC2(rgSCHCmnDlCcchSduRetxFnlz);
12633
12634    /* Traverse through the Scheduled Retx List */
12635    node = allocInfo->ccchSduAlloc.schdCcchSduRetxLst.first;
12636    while (node)
12637    {
12638       hqP = (RgSchDlHqProcCb *)(node->node);
12639       ue = hqP->hqE->ue;
12640       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
12641       node = node->next;
12642       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12643
12644       /* Remove the HqP from cell's ccchSduRetxLst */
12645       cmLListDelFrm(&cmnCellDl->ccchSduRetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
12646       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
12647
12648       /* Fix: syed dlAllocCb reset should be performed.
12649        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12650       rgSCHCmnDlUeResetTemp(ue, hqP);
12651    }
12652    /* Fix: syed dlAllocCb reset should be performed.
12653     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12654    node = allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst.first;
12655    while(node)
12656    {
12657       hqP = (RgSchDlHqProcCb *)(node->node);
12658       ue = hqP->hqE->ue;
12659       node = node->next;
12660       /* reset the UE allocation Information */
12661       rgSCHCmnDlUeResetTemp(ue, hqP);
12662    }
12663    RETVOID;
12664 }
12665 #endif
12666 /**
12667  * @brief This function Processes the Final Allocations
12668  *        made by the RB Allocator against the requested
12669  *        CCCH Retx Allocations.
12670  *
12671  * @details
12672  *
12673  *     Function: rgSCHCmnDlCcchRetxFnlz
12674  *     Purpose:  This function Processes the Final Allocations
12675  *               made by the RB Allocator against the requested
12676  *               CCCH Retx Allocations.
12677  *               Scans through the scheduled list of msg4 retrans
12678  *               fills the corresponding pdcch, adds the hqProc to
12679  *               the corresponding SubFrm and removes the hqP from
12680  *               cells retx List.
12681  *
12682  *     Invoked by: Common Scheduler
12683  *
12684  *  @param[in]  RgSchCellCb           *cell
12685  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12686  *  @return  Void
12687  *
12688  **/
12689 #ifdef ANSI
12690 PRIVATE Void rgSCHCmnDlCcchRetxFnlz
12691 (
12692 RgSchCellCb           *cell,
12693 RgSchCmnDlRbAllocInfo *allocInfo
12694 )
12695 #else
12696 PRIVATE Void rgSCHCmnDlCcchRetxFnlz(cell, allocInfo)
12697 RgSchCellCb           *cell;
12698 RgSchCmnDlRbAllocInfo *allocInfo;
12699 #endif
12700 {
12701    CmLList           *node;
12702    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12703    RgSchDlRbAlloc    *rbAllocInfo;
12704    RgSchDlHqProcCb   *hqP;
12705    RgSchRaCb         *raCb;
12706    TRC2(rgSCHCmnDlCcchRetxFnlz);
12707
12708    /* Traverse through the Scheduled Retx List */
12709    node = allocInfo->msg4Alloc.schdMsg4RetxLst.first;
12710    while (node)
12711    {
12712       hqP = (RgSchDlHqProcCb *)(node->node);
12713       raCb = hqP->hqE->raCb;
12714       rbAllocInfo = &raCb->rbAllocInfo;
12715       node = node->next;
12716       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12717
12718       /* Remove the HqP from cell's msg4RetxLst */
12719       cmLListDelFrm(&cmnCellDl->msg4RetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
12720       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
12721       /* Fix: syed dlAllocCb reset should be performed.
12722        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12723       cmMemset((U8 *)rbAllocInfo, (U8)0, sizeof(*rbAllocInfo));
12724       rgSCHCmnDlHqPResetTemp(hqP);
12725    }
12726    /* Fix: syed dlAllocCb reset should be performed.
12727     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12728    node = allocInfo->msg4Alloc.nonSchdMsg4RetxLst.first;
12729    while(node)
12730    {
12731       hqP = (RgSchDlHqProcCb *)(node->node);
12732       raCb = hqP->hqE->raCb;
12733       node = node->next;
12734       cmMemset((U8 *)&raCb->rbAllocInfo, (U8)0, sizeof(raCb->rbAllocInfo));
12735       rgSCHCmnDlHqPResetTemp(hqP);
12736    }
12737    RETVOID;
12738 }
12739
12740 #ifdef RGR_V1
12741 /**
12742  * @brief This function Processes the Final Allocations
12743  *        made by the RB Allocator against the requested
12744  *        CCCH SDU tx Allocations.
12745  *
12746  * @details
12747  *
12748  *     Function: rgSCHCmnDlCcchSduTxFnlz
12749  *     Purpose:  This function Processes the Final Allocations
12750  *               made by the RB Allocator against the requested
12751  *               CCCH tx Allocations.
12752  *               Scans through the scheduled list of CCCH SDU trans
12753  *               fills the corresponding pdcch, adds the hqProc to
12754  *               the corresponding SubFrm and removes the hqP from
12755  *               cells tx List.
12756  *
12757  *     Invoked by: Common Scheduler
12758  *
12759  *  @param[in]  RgSchCellCb           *cell
12760  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12761  *  @return  Void
12762  *
12763  **/
12764 #ifdef ANSI
12765 PRIVATE Void rgSCHCmnDlCcchSduTxFnlz
12766 (
12767 RgSchCellCb           *cell,
12768 RgSchCmnDlRbAllocInfo *allocInfo
12769 )
12770 #else
12771 PRIVATE Void rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo)
12772 RgSchCellCb           *cell;
12773 RgSchCmnDlRbAllocInfo *allocInfo;
12774 #endif
12775 {
12776    CmLList           *node;
12777    RgSchUeCb         *ueCb;
12778    RgSchDlRbAlloc    *rbAllocInfo;
12779    RgSchDlHqProcCb   *hqP;
12780    RgSchLchAllocInfo  lchSchdData;
12781    TRC2(rgSCHCmnDlCcchSduTxFnlz);
12782
12783    /* Traverse through the Scheduled Retx List */
12784    node = allocInfo->ccchSduAlloc.schdCcchSduTxLst.first;
12785    while (node)
12786    {
12787       hqP = (RgSchDlHqProcCb *)(node->node);
12788       ueCb = hqP->hqE->ue;
12789       node = node->next;
12790       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
12791
12792       /* fill the pdcch and HqProc */
12793       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12794
12795       /* Remove the raCb from cell's toBeSchdLst */
12796       cmLListDelFrm(&cell->ccchSduUeLst, &ueCb->ccchSduLnk);
12797       ueCb->ccchSduLnk.node = (PTR)NULLP;
12798
12799       /* Fix : Resetting this required to avoid complication
12800        * in reestablishment case */
12801       ueCb->dlCcchInfo.bo = 0;
12802
12803       /* Indicate DHM of the CCCH LC scheduling */
12804       hqP->tbInfo[0].contResCe = NOTPRSNT;
12805       lchSchdData.lcId     = 0;
12806       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
12807                              (RGSCH_MSG4_HDRSIZE);
12808       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
12809
12810       /* Fix: syed dlAllocCb reset should be performed.
12811        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12812       rgSCHCmnDlUeResetTemp(ueCb, hqP);
12813    }
12814    /* Fix: syed dlAllocCb reset should be performed.
12815     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12816    node = allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst.first;
12817    while(node)
12818    {
12819       hqP = (RgSchDlHqProcCb *)(node->node);
12820       ueCb = hqP->hqE->ue;
12821       node = node->next;
12822       /* Release HqProc */
12823       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
12824       /*Fix: Removing releasing of TB1 as it will not exist for CCCH SDU and hence caused a crash*/
12825       /*rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
12826       /* reset the UE allocation Information */
12827       rgSCHCmnDlUeResetTemp(ueCb, hqP);
12828    }
12829    RETVOID;
12830 }
12831
12832 #endif
12833 /**
12834  * @brief This function Processes the Final Allocations
12835  *        made by the RB Allocator against the requested
12836  *        CCCH tx Allocations.
12837  *
12838  * @details
12839  *
12840  *     Function: rgSCHCmnDlCcchTxFnlz
12841  *     Purpose:  This function Processes the Final Allocations
12842  *               made by the RB Allocator against the requested
12843  *               CCCH tx Allocations.
12844  *               Scans through the scheduled list of msg4 trans
12845  *               fills the corresponding pdcch, adds the hqProc to
12846  *               the corresponding SubFrm and removes the hqP from
12847  *               cells tx List.
12848  *
12849  *     Invoked by: Common Scheduler
12850  *
12851  *  @param[in]  RgSchCellCb           *cell
12852  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12853  *  @return  Void
12854  *
12855  **/
12856 #ifdef ANSI
12857 PRIVATE Void rgSCHCmnDlCcchTxFnlz
12858 (
12859 RgSchCellCb           *cell,
12860 RgSchCmnDlRbAllocInfo *allocInfo
12861 )
12862 #else
12863 PRIVATE Void rgSCHCmnDlCcchTxFnlz(cell, allocInfo)
12864 RgSchCellCb           *cell;
12865 RgSchCmnDlRbAllocInfo *allocInfo;
12866 #endif
12867 {
12868    CmLList           *node;
12869    RgSchRaCb         *raCb;
12870    RgSchDlRbAlloc    *rbAllocInfo;
12871    RgSchDlHqProcCb   *hqP;
12872    RgSchLchAllocInfo  lchSchdData;
12873    TRC2(rgSCHCmnDlCcchTxFnlz);
12874
12875    /* Traverse through the Scheduled Retx List */
12876    node = allocInfo->msg4Alloc.schdMsg4TxLst.first;
12877    while (node)
12878    {
12879       hqP = (RgSchDlHqProcCb *)(node->node);
12880       raCb = hqP->hqE->raCb;
12881       node = node->next;
12882       rbAllocInfo = &raCb->rbAllocInfo;
12883
12884       /* fill the pdcch and HqProc */
12885       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12886       /* MSG4 Fix Start */
12887      
12888       rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
12889       /* MSG4 Fix End */     
12890
12891       /* Indicate DHM of the CCCH LC scheduling */
12892       lchSchdData.lcId     = 0;
12893       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
12894          (RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE);
12895       /* TRansmitting presence of cont Res CE across MAC-SCH interface to
12896        * identify CCCH SDU transmissions which need to be done
12897        * without the
12898        * contention resolution CE*/
12899       hqP->tbInfo[0].contResCe = PRSNT_NODEF;
12900       /*Dont add lc if only cont res CE is being transmitted*/
12901       if(raCb->dlCcchInfo.bo)
12902       {
12903          rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
12904       }
12905       else
12906       {
12907       }
12908       /* Fix: syed dlAllocCb reset should be performed.
12909        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12910       cmMemset((U8 *)&raCb->rbAllocInfo, (U8)0, sizeof(raCb->rbAllocInfo));
12911       rgSCHCmnDlHqPResetTemp(hqP);
12912    }
12913    node = allocInfo->msg4Alloc.nonSchdMsg4TxLst.first;
12914    while(node)
12915    {
12916       hqP = (RgSchDlHqProcCb *)(node->node);
12917       raCb = hqP->hqE->raCb;
12918       node = node->next;
12919       rbAllocInfo = &raCb->rbAllocInfo;
12920       /* Release HqProc */
12921       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
12922       /*Fix: Removing releasing of TB1 as it will not exist for MSG4 and hence caused a crash*/
12923       /*      rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
12924       /* reset the UE allocation Information */
12925       cmMemset((U8 *)rbAllocInfo, (U8)0, sizeof(*rbAllocInfo));
12926       rgSCHCmnDlHqPResetTemp(hqP);
12927    }
12928
12929    RETVOID;
12930 }
12931 /* R8 Upgrade */
12932 /**
12933  * @brief This function calculates the BI Index to be sent in the Bi header
12934  * field.
12935  *
12936  * @details
12937  *     Function: rgSCHCmnGetBiIndex
12938  *     Purpose:  This function Processes utilizes the previous BI time value
12939  *     calculated and the difference last BI sent time and current time. To
12940  *     calculate the latest BI Index. It also considers the how many UE's
12941  *     Unserved in this subframe.
12942  *
12943  *     Invoked by: Common Scheduler
12944  *
12945  *  @param[in]  RgSchCellCb           *cell
12946  *  @param[in]  U32                   ueCount
12947  *  @return  U8
12948  *
12949  **/
12950 #ifdef ANSI
12951 PUBLIC U8 rgSCHCmnGetBiIndex
12952 (
12953 RgSchCellCb   *cell,
12954 U32           ueCount
12955 )
12956 #else
12957 PUBLIC U8 rgSCHCmnGetBiIndex(cell, ueCount)
12958 RgSchCellCb   *cell;
12959 U32           ueCount;
12960 #endif
12961 {
12962    S16  prevVal = 0;      /* To Store Intermediate Value */
12963    U16  newBiVal = 0;     /* To store Bi Value in millisecond */
12964    U8   idx = 0;
12965    U16  timeDiff = 0;
12966
12967    TRC2(rgSCHCmnGetBiIndex)
12968
12969    if (cell->biInfo.prevBiTime != 0)
12970    {
12971 #ifdef EMTC_ENABLE
12972       if(cell->emtcEnable == TRUE)
12973       {
12974          timeDiff =(RGSCH_CALC_SF_DIFF_EMTC(cell->crntTime, cell->biInfo.biTime));
12975       }
12976       else
12977 #endif
12978       {
12979          timeDiff =(RGSCH_CALC_SF_DIFF(cell->crntTime, cell->biInfo.biTime));
12980       }
12981
12982       prevVal = cell->biInfo.prevBiTime - timeDiff;
12983    }
12984    if (prevVal < 0)
12985    {
12986       prevVal = 0;
12987    }
12988    newBiVal = RG_SCH_CMN_GET_BI_VAL(prevVal,ueCount);
12989    /* To be used next time when BI is calculated */
12990 #ifdef EMTC_ENABLE
12991    if(cell->emtcEnable == TRUE)
12992    {
12993       RGSCHCPYTIMEINFO_EMTC(cell->crntTime, cell->biInfo.biTime)
12994    }
12995    else
12996 #endif
12997    {
12998       RGSCHCPYTIMEINFO(cell->crntTime, cell->biInfo.biTime)
12999    }
13000
13001   /* Search the actual BI Index from table Backoff Parameters Value  and
13002    * return that Index */
13003    do
13004    {
13005       if (rgSchCmnBiTbl[idx] > newBiVal)
13006       {
13007          break;
13008       }
13009       idx++;
13010    }while(idx < RG_SCH_CMN_NUM_BI_VAL-1);
13011    cell->biInfo.prevBiTime = rgSchCmnBiTbl[idx];
13012    /* For 16 Entries in Table 7.2.1 36.321.880 - 3 reserved so total 13 Entries */
13013    RETVALUE(idx); /* Returning reserved value from table UE treats it has 960 ms */
13014 } /* rgSCHCmnGetBiIndex */
13015
13016
13017 /**
13018  * @brief This function Processes the Final Allocations
13019  *        made by the RB Allocator against the requested
13020  *        RAR allocations. Assumption: The reuqested
13021  *        allocations are always satisfied completely.
13022  *        Hence no roll back.
13023  *
13024  * @details
13025  *
13026  *     Function: rgSCHCmnDlRaRspFnlz
13027  *     Purpose:  This function Processes the Final Allocations
13028  *               made by the RB Allocator against the requested.
13029  *               Takes care of PDCCH filling.
13030  *
13031  *     Invoked by: Common Scheduler
13032  *
13033  *  @param[in]  RgSchCellCb           *cell
13034  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
13035  *  @return  Void
13036  *
13037  **/
13038 #ifdef ANSI
13039 PRIVATE Void rgSCHCmnDlRaRspFnlz
13040 (
13041 RgSchCellCb           *cell,
13042 RgSchCmnDlRbAllocInfo *allocInfo
13043 )
13044 #else
13045 PRIVATE Void rgSCHCmnDlRaRspFnlz(cell, allocInfo)
13046 RgSchCellCb           *cell;
13047 RgSchCmnDlRbAllocInfo *allocInfo;
13048 #endif
13049 {
13050    U32            rarCnt = 0;
13051    RgSchDlRbAlloc *raRspAlloc;
13052    RgSchDlSf      *subFrm = NULLP;
13053    RgSchRaCb      *raCb;
13054    RgSchErrInfo   err;
13055    CmLListCp      *reqLst;
13056    RgSchRaReqInfo *raReq;
13057    Bool           preamGrpA;
13058    RgSchUlAlloc   *ulAllocRef=NULLP;
13059    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
13060    U8              allocRapidCnt = 0;
13061 #ifdef LTE_TDD
13062    U32            msg3SchdIdx = 0;
13063    U8             ulDlCfgIdx = cell->ulDlCfgIdx;
13064    U8             msg3Subfrm;
13065 #endif
13066
13067    TRC2(rgSCHCmnDlRaRspFnlz);
13068
13069    for (rarCnt=0; rarCnt<RG_SCH_CMN_MAX_CMN_PDCCH; rarCnt++)
13070    {
13071       raRspAlloc = &allocInfo->raRspAlloc[rarCnt];
13072       /* Having likely condition first for optimization */
13073       if (!raRspAlloc->pdcch)
13074       {
13075          continue;
13076       }
13077       else
13078       {
13079          subFrm = raRspAlloc->dlSf;
13080          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
13081          /* Corrected RACH handling for multiple RAPIDs per RARNTI */
13082          allocRapidCnt = raRspAlloc->numRapids;
13083          while (allocRapidCnt)
13084          {
13085             raReq = (RgSchRaReqInfo *)(reqLst->first->node);
13086             /* RACHO: If dedicated preamble, then allocate UL Grant
13087              * (consequence of handover/pdcchOrder) and continue */
13088             if (RGSCH_IS_DEDPRM(cell, raReq->raReq.rapId))
13089             {
13090                rgSCHCmnHdlHoPo(cell, &subFrm->raRsp[rarCnt].contFreeUeLst,
13091                      raReq);
13092                cmLListDelFrm(reqLst, reqLst->first);
13093                allocRapidCnt--;
13094                /* ccpu00117052 - MOD - Passing double pointer
13095                for proper NULLP assignment*/
13096                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
13097                      sizeof(RgSchRaReqInfo));
13098                continue;
13099             }
13100             /* ccpu00139815 */
13101             if(cell->overLoadBackOffEnab)
13102             {/* rach Overlaod conrol is triggerd, Skipping this rach */
13103                cmLListDelFrm(reqLst, reqLst->first);
13104                allocRapidCnt--;
13105                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
13106                      sizeof(RgSchRaReqInfo));
13107                continue;
13108             }
13109             /* Attempt to include each RA request into the RSP */
13110             /* Any failure in the procedure is considered to   */
13111             /* affect futher allocations in the same TTI. When */
13112             /* a failure happens, we break out and complete    */
13113             /* the processing for random access                */
13114             if (rgSCHRamCreateRaCb(cell, &raCb, &err) != ROK)
13115             {
13116                break;
13117             }
13118             /* Msg3 allocation request to USM */
13119             if (raReq->raReq.rapId < cell->rachCfg.sizeRaPreambleGrpA)
13120                preamGrpA = TRUE;
13121             else
13122                preamGrpA = FALSE;
13123             /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
13124             rgSCHCmnMsg3GrntReq(cell, raCb->tmpCrnti, preamGrpA, \
13125                   &(raCb->msg3HqProc), &ulAllocRef, &raCb->msg3HqProcId);
13126             if (ulAllocRef == NULLP)
13127             {
13128                rgSCHRamDelRaCb(cell, raCb, TRUE);
13129                break;
13130             }
13131             if (raReq->raReq.cqiPres)
13132             {
13133                raCb->ccchCqi = raReq->raReq.cqiIdx;
13134             }
13135             else
13136             {
13137                raCb->ccchCqi = cellDl->ccchCqi;
13138             }
13139             raCb->rapId = raReq->raReq.rapId;
13140             raCb->ta.pres    = TRUE;
13141             raCb->ta.val = raReq->raReq.ta;
13142             raCb->msg3Grnt = ulAllocRef->grnt;
13143             /* Populating the tpc value received */
13144             raCb->msg3Grnt.tpc = raReq->raReq.tpc;
13145             /* PHR handling for MSG3 */
13146             ulAllocRef->raCb = raCb;
13147 #ifndef LTE_TDD
13148             /* To the crntTime, add the MIN time at which UE will
13149              * actually send MSG3 i.e DL_DELTA+6 */
13150             raCb->msg3AllocTime = cell->crntTime;
13151             RGSCH_INCR_SUB_FRAME(raCb->msg3AllocTime, RG_SCH_CMN_MIN_MSG3_RECP_INTRVL);
13152 #else
13153             msg3SchdIdx = (cell->crntTime.subframe+RG_SCH_CMN_DL_DELTA) % 
13154                                  RGSCH_NUM_SUB_FRAMES;
13155             /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
13156               special subframe */                       
13157             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][msg3SchdIdx] != 
13158                         RG_SCH_TDD_UL_SUBFRAME)
13159             {
13160                RGSCHCMNADDTOCRNTTIME(cell->crntTime,raCb->msg3AllocTime,
13161                                        RG_SCH_CMN_DL_DELTA)
13162                msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][
13163                                        raCb->msg3AllocTime.subframe];
13164                RGSCHCMNADDTOCRNTTIME(raCb->msg3AllocTime, raCb->msg3AllocTime, 
13165                                  msg3Subfrm);
13166             }
13167 #endif
13168             cmLListAdd2Tail(&subFrm->raRsp[rarCnt].raRspLst, &raCb->rspLnk);
13169             raCb->rspLnk.node = (PTR)raCb;
13170             cmLListDelFrm(reqLst, reqLst->first);
13171             allocRapidCnt--;
13172             /* ccpu00117052 - MOD - Passing double pointer
13173             for proper NULLP assignment*/
13174             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
13175                   sizeof(RgSchRaReqInfo));
13176
13177             /* SR_RACH_STATS : RAR scheduled */
13178             rgNumRarSched++;
13179
13180          }
13181          /* R8 Upgrade */
13182          /* Fill subframe data members */
13183          subFrm->raRsp[rarCnt].raRnti = raRspAlloc->rnti;
13184          subFrm->raRsp[rarCnt].pdcch  = raRspAlloc->pdcch;
13185          subFrm->raRsp[rarCnt].tbSz   = raRspAlloc->tbInfo[0].bytesAlloc;
13186          /* Fill PDCCH data members */
13187          rgSCHCmnFillPdcch(cell, subFrm->raRsp[rarCnt].pdcch, raRspAlloc);
13188
13189          /* ccpu00139815 */
13190          if(cell->overLoadBackOffEnab)
13191          {/* rach Overlaod conrol is triggerd, Skipping this rach */
13192             subFrm->raRsp[rarCnt].backOffInd.pres = PRSNT_NODEF;
13193             subFrm->raRsp[rarCnt].backOffInd.val  = cell->overLoadBackOffval;
13194             continue;
13195          }
13196          else
13197          {
13198             subFrm->raRsp[rarCnt].backOffInd.pres = NOTPRSNT;
13199          }
13200
13201          /*[ccpu00125212] Avoiding sending of empty RAR in case of RAR window
13202            is short and UE is sending unauthorised preamble.*/
13203          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
13204          if ((raRspAlloc->biEstmt) && (reqLst->count))
13205          {
13206             subFrm->raRsp[0].backOffInd.pres = PRSNT_NODEF;
13207             /* Added as part of Upgrade */
13208             subFrm->raRsp[0].backOffInd.val =
13209             rgSCHCmnGetBiIndex(cell, reqLst->count);
13210
13211             /* SR_RACH_STATS : Back Off Inds */
13212             rgNumBI++;
13213
13214          }
13215          else if ((subFrm->raRsp[rarCnt].raRspLst.first == NULLP) &&
13216                (subFrm->raRsp[rarCnt].contFreeUeLst.first == NULLP))
13217          {
13218             /* Return the grabbed PDCCH */
13219             rgSCHUtlPdcchPut(cell, &subFrm->pdcchInfo, raRspAlloc->pdcch);
13220             subFrm->raRsp[rarCnt].pdcch = NULLP;
13221             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRaRspAlloc(): "
13222                   "Not even one RaReq.");
13223             RETVOID;
13224          }
13225       }
13226       RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, 
13227             "RNTI:%d Scheduled RAR @ (%u,%u) ",
13228             raRspAlloc->rnti, 
13229             cell->crntTime.sfn,
13230             cell->crntTime.subframe);
13231    }
13232    RETVOID;
13233 }
13234
13235 /**
13236  * @brief This function computes rv.
13237  *
13238  * @details
13239  *
13240  *     Function: rgSCHCmnDlCalcRvForBcch
13241  *     Purpose:  This function computes rv.
13242  *
13243  *     Invoked by: Common Scheduler
13244  *
13245  *  @param[in]   RgSchCellCb     *cell
13246  *  @param[in]   Bool            si
13247  *  @param[in]   U16             i
13248  *  @return  U8
13249  *
13250  **/
13251 #ifdef ANSI
13252 PRIVATE U8 rgSCHCmnDlCalcRvForBcch
13253 (
13254 RgSchCellCb          *cell,
13255 Bool                 si,
13256 U16                  i
13257 )
13258 #else
13259 PRIVATE U8 rgSCHCmnDlCalcRvForBcch(cell, si, i)
13260 RgSchCellCb          *cell;
13261 Bool                 si;
13262 U16                  i;
13263 #endif
13264 {
13265    U8 k, rv;
13266    CmLteTimingInfo   frm;
13267    TRC2(rgSCHCmnDlCalcRvForBcch);
13268
13269    frm   = cell->crntTime;
13270    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
13271
13272    if(si)
13273    {
13274       k = i % 4;
13275    }
13276    else
13277    {
13278       k = (frm.sfn/2) % 4;
13279    }
13280    rv = RGSCH_CEIL(3*k, 2) % 4;
13281    RETVALUE(rv);
13282 }
13283
13284 /**
13285  * @brief This function Processes the Final Allocations
13286  *        made by the RB Allocator against the requested
13287  *        BCCH/PCCH allocations. Assumption: The reuqested
13288  *        allocations are always satisfied completely.
13289  *        Hence no roll back.
13290  *
13291  * @details
13292  *
13293  *     Function: rgSCHCmnDlBcchPcchFnlz
13294  *     Purpose:  This function Processes the Final Allocations
13295  *               made by the RB Allocator against the requested.
13296  *               Takes care of PDCCH filling.
13297  *
13298  *     Invoked by: Common Scheduler
13299  *
13300  *  @param[in]  RgSchCellCb           *cell
13301  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
13302  *  @return  Void
13303  *
13304  **/
13305 #ifdef ANSI
13306 PRIVATE Void rgSCHCmnDlBcchPcchFnlz
13307 (
13308 RgSchCellCb           *cell,
13309 RgSchCmnDlRbAllocInfo *allocInfo
13310 )
13311 #else
13312 PRIVATE Void rgSCHCmnDlBcchPcchFnlz(cell, allocInfo)
13313 RgSchCellCb           *cell;
13314 RgSchCmnDlRbAllocInfo *allocInfo;
13315 #endif
13316 {
13317    RgSchDlRbAlloc *rbAllocInfo;
13318    RgSchDlSf      *subFrm;
13319
13320 #ifdef LTE_TDD
13321    U8             nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
13322 #else
13323 #ifdef LTEMAC_HDFDD
13324    U8             nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13325 #else
13326    U8             nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13327 #endif
13328 #endif
13329
13330    /*  Moving variables to available scope for optimization */
13331    RgSchClcDlLcCb *pcch;
13332    RgSchClcBoRpt  *bo;
13333 #ifndef RGR_SI_SCH
13334    RgSchClcDlLcCb  *bcch;
13335    Bool           sendInd=TRUE;
13336 #endif
13337    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
13338
13339    TRC2(rgSCHCmnDlBcchPcchFnlz);
13340
13341    /* handle PCCH */
13342    rbAllocInfo = &allocInfo->pcchAlloc;
13343    if (rbAllocInfo->pdcch)
13344    {
13345       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
13346
13347       /* Added sfIdx calculation for TDD as well */
13348 #ifndef LTE_TDD
13349 #ifdef LTEMAC_HDFDD
13350       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13351 #else
13352       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13353 #endif
13354 #endif
13355       subFrm = rbAllocInfo->dlSf;
13356       pcch = rgSCHDbmGetPcch(cell);
13357       if(pcch == NULLP)
13358       {
13359          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnDlBcchPcchFnlz( ): "
13360                "No Pcch Present");
13361          RETVOID;
13362       }
13363
13364       /* Added Dl TB count for paging message transmission*/
13365 #ifdef LTE_L2_MEAS
13366       cell->dlUlTbCnt.tbTransDlTotalCnt++;
13367 #endif      
13368       bo = (RgSchClcBoRpt *)pcch->boLst.first->node;
13369       cmLListDelFrm(&pcch->boLst, &bo->boLstEnt);
13370       /* ccpu00117052 - MOD - Passing double pointer
13371          for proper NULLP assignment*/
13372       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
13373       /* Fill subframe data members */
13374       subFrm->pcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
13375       subFrm->pcch.pdcch  = rbAllocInfo->pdcch;
13376       /* Fill PDCCH data members */
13377       rgSCHCmnFillPdcch(cell, subFrm->pcch.pdcch, rbAllocInfo);
13378       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, pcch->lcId, TRUE);
13379       /* ccpu00132314-ADD-Update the tx power allocation info  
13380          TODO-Need to add a check for max tx power per symbol */ 
13381       subfrmAlloc->cmnLcInfo.pcchInfo.txPwrOffset = cellDl->pcchTxPwrOffset;   
13382    }
13383
13384    /* handle BCCH */
13385    rbAllocInfo = &allocInfo->bcchAlloc;
13386    if (rbAllocInfo->pdcch)
13387    {
13388       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
13389 #ifndef LTE_TDD
13390 #ifdef LTEMAC_HDFDD
13391       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13392 #else
13393       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13394 #endif
13395 #endif
13396       subFrm = rbAllocInfo->dlSf;
13397
13398       /* Fill subframe data members */
13399       subFrm->bcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
13400       subFrm->bcch.pdcch  = rbAllocInfo->pdcch;
13401       /* Fill PDCCH data members */
13402       rgSCHCmnFillPdcch(cell, subFrm->bcch.pdcch, rbAllocInfo);
13403
13404       if(rbAllocInfo->schdFirst)
13405       {
13406 #ifndef RGR_SI_SCH
13407          bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
13408          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
13409 #else
13410          /*Copy the SIB1 msg buff into interface buffer */
13411          SCpyMsgMsg(cell->siCb.crntSiInfo.sib1Info.sib1,
13412                rgSchCb[cell->instIdx].rgSchInit.region,
13413                rgSchCb[cell->instIdx].rgSchInit.pool,
13414                &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13415 #endif/*RGR_SI_SCH*/
13416          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
13417             rgSCHCmnDlCalcRvForBcch(cell, FALSE, 0);
13418       }
13419       else
13420       {
13421          U16   i;
13422 #ifdef RGR_SI_SCH
13423          Buffer    *pdu;
13424
13425          i = cell->siCb.siCtx.i;
13426          /*Decrement the retransmission count */
13427          cell->siCb.siCtx.retxCntRem--;
13428
13429          /*Copy the SI msg buff into interface buffer */
13430          if(cell->siCb.siCtx.warningSiFlag == FALSE)
13431          {
13432             SCpyMsgMsg(cell->siCb.siArray[cell->siCb.siCtx.siId-1].si,
13433                   rgSchCb[cell->instIdx].rgSchInit.region,
13434                   rgSchCb[cell->instIdx].rgSchInit.pool,
13435                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13436          }
13437          else
13438          {
13439             pdu = rgSCHUtlGetWarningSiPdu(cell);
13440             RGSCH_NULL_CHECK(cell->instIdx, pdu);
13441             SCpyMsgMsg(pdu,
13442                   rgSchCb[cell->instIdx].rgSchInit.region,
13443                   rgSchCb[cell->instIdx].rgSchInit.pool,
13444                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13445             if(cell->siCb.siCtx.retxCntRem == 0)
13446             {  
13447                rgSCHUtlFreeWarningSiPdu(cell);
13448                cell->siCb.siCtx.warningSiFlag  = FALSE;
13449
13450             }
13451          }
13452 #else
13453          bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
13454          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
13455          bo->retxCnt--;
13456          if(bo->retxCnt != cell->siCfg.retxCnt-1)
13457          {
13458             sendInd=FALSE;
13459          }
13460          i = bo->i;
13461 #endif/*RGR_SI_SCH*/
13462          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
13463             rgSCHCmnDlCalcRvForBcch(cell, TRUE, i);
13464       }
13465
13466       /* Added Dl TB count for SIB1 and SI messages transmission.
13467        * This counter will be incremented only for the first transmission
13468        * (with RV 0) of these messages*/
13469 #ifdef LTE_L2_MEAS
13470       if(subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv == 0)
13471       {   
13472          cell->dlUlTbCnt.tbTransDlTotalCnt++;
13473       }
13474 #endif      
13475 #ifndef RGR_SI_SCH
13476       if(bo->retxCnt == 0)
13477       {
13478          cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
13479          /* ccpu00117052 - MOD - Passing double pointer
13480             for proper NULLP assignment*/
13481          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
13482       }
13483       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, bcch->lcId, sendInd);
13484 #else
13485       /*Fill the interface info */
13486       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, NULLD, NULLD);
13487
13488       /* ccpu00132314-ADD-Update the tx power allocation info  
13489          TODO-Need to add a check for max tx power per symbol */ 
13490       subfrmAlloc->cmnLcInfo.bcchInfo.txPwrOffset = cellDl->bcchTxPwrOffset;   
13491
13492       /*mBuf has been already copied above */
13493 #endif/*RGR_SI_SCH*/
13494    }
13495
13496    RETVOID;
13497 }
13498
13499
13500 #if RG_UNUSED
13501 /**
13502  * @brief
13503  *
13504  * @details
13505  *
13506  *     Function: rgSCHCmnUlSetAllUnSched
13507  *     Purpose:
13508  *
13509  *     Invoked by: Common Scheduler
13510  *
13511  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13512  *  @return  Void
13513  *
13514  **/
13515 #ifdef ANSI
13516 PRIVATE Void rgSCHCmnUlSetAllUnSched
13517 (
13518 RgSchCmnUlRbAllocInfo *allocInfo
13519 )
13520 #else
13521 PRIVATE Void rgSCHCmnUlSetAllUnSched(allocInfo)
13522 RgSchCmnUlRbAllocInfo *allocInfo;
13523 #endif
13524 {
13525    CmLList            *node;
13526
13527    TRC2(rgSCHCmnUlSetAllUnSched);
13528
13529    node = allocInfo->contResLst.first;
13530    while (node)
13531    {
13532       rgSCHCmnUlMov2NonSchdCntResLst(allocInfo, (RgSchUeCb *)node->node);
13533       node = allocInfo->contResLst.first;
13534    }
13535
13536    node = allocInfo->retxUeLst.first;
13537    while (node)
13538    {
13539       rgSCHCmnUlMov2NonSchdRetxUeLst(allocInfo, (RgSchUeCb *)node->node);
13540       node = allocInfo->retxUeLst.first;
13541    }
13542
13543    node = allocInfo->ueLst.first;
13544    while (node)
13545    {
13546       rgSCHCmnUlMov2NonSchdUeLst(allocInfo, (RgSchUeCb *)node->node);
13547       node = allocInfo->ueLst.first;
13548    }
13549
13550    RETVOID;
13551 }
13552 #endif
13553
13554 /**
13555  * @brief
13556  *
13557  * @details
13558  *
13559  *     Function: rgSCHCmnUlAdd2CntResLst
13560  *     Purpose:
13561  *
13562  *     Invoked by: Common Scheduler
13563  *
13564  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13565  *  @param[in]  RgSchUeCb             *ue
13566  *  @return  Void
13567  *
13568  **/
13569 #ifdef ANSI
13570 PUBLIC Void rgSCHCmnUlAdd2CntResLst
13571 (
13572 RgSchCmnUlRbAllocInfo *allocInfo,
13573 RgSchUeCb             *ue
13574 )
13575 #else
13576 PUBLIC Void rgSCHCmnUlAdd2CntResLst(allocInfo, ue)
13577 RgSchCmnUlRbAllocInfo *allocInfo;
13578 RgSchUeCb             *ue;
13579 #endif
13580 {
13581    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,ue->cell))->alloc);
13582    TRC2(rgSCHCmnUlAdd2CntResLst);
13583    cmLListAdd2Tail(&allocInfo->contResLst, &ulAllocInfo->reqLnk);
13584    ulAllocInfo->reqLnk.node = (PTR)ue;
13585    RETVOID;
13586 }
13587
13588 /**
13589  * @brief
13590  *
13591  * @details
13592  *
13593  *     Function: rgSCHCmnUlAdd2UeLst
13594  *     Purpose:
13595  *
13596  *     Invoked by: Common Scheduler
13597  *
13598  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13599  *  @param[in]  RgSchUeCb             *ue
13600  *  @return  Void
13601  *
13602  **/
13603 #ifdef ANSI
13604 PUBLIC Void rgSCHCmnUlAdd2UeLst
13605 (
13606 RgSchCellCb           *cell,
13607 RgSchCmnUlRbAllocInfo *allocInfo,
13608 RgSchUeCb             *ue
13609 )
13610 #else
13611 PUBLIC Void rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue)
13612 RgSchCellCb           *cell;
13613 RgSchCmnUlRbAllocInfo *allocInfo;
13614 RgSchUeCb             *ue;
13615 #endif
13616 {
13617    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,cell))->alloc);
13618    TRC2(rgSCHCmnUlAdd2UeLst);
13619    if (ulAllocInfo->reqLnk.node == NULLP)
13620    {
13621       cmLListAdd2Tail(&allocInfo->ueLst, &ulAllocInfo->reqLnk);
13622       ulAllocInfo->reqLnk.node = (PTR)ue;
13623    }
13624    RETVOID;
13625 }
13626
13627 /**
13628  * @brief
13629  *
13630  * @details
13631  *
13632  *     Function: rgSCHCmnAllocUlRb
13633  *     Purpose:  To do RB allocations for uplink
13634  *
13635  *     Invoked by: Common Scheduler
13636  *
13637  *  @param[in]  RgSchCellCb           *cell
13638  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
13639  *  @return  Void
13640  **/
13641 #ifdef ANSI
13642 PUBLIC Void rgSCHCmnAllocUlRb
13643 (
13644 RgSchCellCb           *cell,
13645 RgSchCmnUlRbAllocInfo *allocInfo
13646 )
13647 #else
13648 PUBLIC Void rgSCHCmnAllocUlRb(cell, allocInfo)
13649 RgSchCellCb           *cell;
13650 RgSchCmnUlRbAllocInfo *allocInfo;
13651 #endif
13652 {
13653    RgSchUlSf         *sf = allocInfo->sf;
13654    TRC2(rgSCHCmnAllocUlRb);
13655
13656    /* Schedule for new transmissions */
13657    rgSCHCmnUlRbAllocForLst(cell, sf, allocInfo->ueLst.count,
13658          &allocInfo->ueLst, &allocInfo->schdUeLst,
13659          &allocInfo->nonSchdUeLst, (Bool)TRUE);
13660    RETVOID;
13661 }
13662
13663 /***********************************************************
13664  *
13665  *     Func : rgSCHCmnUlRbAllocForLst
13666  *
13667  *     Desc : Allocate for a list in cmn rb alloc information passed
13668  *            in a subframe.
13669  *
13670  *     Ret  :
13671  *
13672  *     Notes:
13673  *
13674  *     File :
13675  *
13676  **********************************************************/
13677 #ifdef ANSI
13678 PRIVATE Void rgSCHCmnUlRbAllocForLst
13679 (
13680 RgSchCellCb           *cell,
13681 RgSchUlSf             *sf,
13682 U32                   count,
13683 CmLListCp             *reqLst,
13684 CmLListCp             *schdLst,
13685 CmLListCp             *nonSchdLst,
13686 Bool                  isNewTx
13687 )
13688 #else
13689 PRIVATE Void rgSCHCmnUlRbAllocForLst(cell, sf, count, reqLst, schdLst,
13690                                      nonSchdLst, isNewTx)
13691 RgSchCellCb           *cell;
13692 RgSchUlSf             *sf;
13693 U32                   count;
13694 CmLListCp             *reqLst;
13695 CmLListCp             *schdLst;
13696 CmLListCp             *nonSchdLst;
13697 Bool                  isNewTx;
13698 #endif
13699 {
13700    CmLList          *lnk;
13701    RgSchUlHole      *hole;
13702 #ifdef LTE_L2_MEAS
13703 #ifdef LTE_TDD
13704    U8               k;
13705    CmLteTimingInfo  timeInfo;
13706 #endif    
13707 #endif    
13708    TRC2(rgSCHCmnUlRbAllocForLst);
13709
13710    if(schdLst->count == 0)
13711    {
13712       cmLListInit(schdLst);
13713    }
13714
13715    cmLListInit(nonSchdLst);
13716 #ifdef LTE_L2_MEAS
13717    if(isNewTx == TRUE)
13718    {
13719       cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.numUes = (U8) count;
13720 #ifdef LTE_TDD
13721       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timeInfo, TFU_ULCNTRL_DLDELTA);
13722       k = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][timeInfo.subframe];
13723       RG_SCH_ADD_TO_CRNT_TIME(timeInfo,
13724           cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, k);
13725 #else
13726       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime,cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo,
13727                             (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
13728 #endif
13729    }
13730 #endif
13731
13732    for (lnk = reqLst->first; count; lnk = lnk->next, --count)
13733    {
13734       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
13735       RgSchCmnUlUe          *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
13736       S16                   ret;
13737       U8                    maxRb;
13738
13739
13740       if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
13741       {
13742          break;
13743       }
13744
13745       ueUl->subbandShare = ueUl->subbandRequired;
13746       if(isNewTx == TRUE)
13747       {
13748          maxRb = RGSCH_MIN((ueUl->subbandRequired * MAX_5GTF_VRBG_SIZE), ue->ue5gtfCb.maxPrb);
13749       } 
13750       ret = rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole);
13751       if (ret == ROK)
13752       {
13753          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, schdLst);
13754          rgSCHCmnUlUeFillAllocInfo(cell, ue);
13755       }
13756       else
13757       {
13758          gUl5gtfRbAllocFail++;
13759 #if defined (TENB_STATS) && defined (RG_5GTF)
13760          cell->tenbStats->sch.ul5gtfRbAllocFail++;
13761 #endif
13762          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
13763          ue->isMsg4PdcchWithCrnti = FALSE;
13764          ue->isSrGrant = FALSE;
13765       }
13766 #ifdef LTE_L2_MEAS
13767       if(isNewTx == TRUE)
13768       {
13769          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
13770          ulAllocInfo[count - 1].rnti   = ue->ueId;
13771          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
13772          ulAllocInfo[count - 1].numPrb = ue->ul.nPrb;
13773       }
13774 #endif
13775       ueUl->subbandShare = 0; /* This reset will take care of
13776                                   * all scheduler types */
13777    }
13778    for (; count; lnk = lnk->next, --count)
13779    {
13780       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
13781       rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
13782       ue->isMsg4PdcchWithCrnti = FALSE;
13783    }
13784    RETVOID;
13785 }
13786
13787 #ifdef TFU_UPGRADE
13788 /***********************************************************
13789  *
13790  *     Func : rgSCHCmnUlMdfyGrntForCqi
13791  *
13792  *     Desc : Modify UL Grant to consider presence of 
13793  *            CQI along with PUSCH Data.
13794  *
13795  *     Ret  :
13796  *
13797  *     Notes: 
13798  *          -  Scale down iTbs based on betaOffset and
13799  *             size of Acqi Size.
13800  *          -  Optionally attempt to increase numSb by 1
13801  *             if input payload size does not fit in due 
13802  *             to reduced tbSz as a result of iTbsNew.
13803  *
13804  *     File :
13805  *
13806  **********************************************************/
13807 #ifdef ANSI
13808 PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi
13809 (
13810 RgSchCellCb  *cell,
13811 RgSchUeCb    *ue,
13812 U32          maxRb,
13813 U32          *numSb,
13814 U8           *iTbs,
13815 U32          hqSz,
13816 U32          stepDownItbs,
13817 U32          effTgt
13818 )
13819 #else
13820 PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi(cell, ue, maxRb, numSb, iTbs, hqSz, stepDownItbs, effTgt)
13821 RgSchCellCb  *cell;
13822 RgSchUeCb    *ue;
13823 U32          maxRb;
13824 U32          *numSb;
13825 U8           *iTbs;
13826 U32          hqSz;
13827 U32          stepDownItbs;
13828 U32          effTgt;
13829 #endif
13830 {
13831    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(ue->cell);
13832    U32  nPrb;
13833    U32  totREs;
13834    U32  cqiRiREs;
13835    U32  hqREs;
13836    U32  remREsForPusch;
13837    U32  bitsPerRe;
13838    U32  tbSz;
13839    U32  betaOffVal = ue->ul.betaOffstVal;
13840    U32  cqiRiRptSz = ue->ul.cqiRiSz;
13841    U32  betaOffHqVal = rgSchCmnBetaHqOffstTbl[ue->ul.betaHqOffst];
13842    U32  resNumSb = *numSb;
13843    U32  puschEff = 1000;
13844    U8   modOdr;
13845    U8   iMcs;
13846    Bool mdfyiTbsFlg = FALSE;
13847    U8   resiTbs = *iTbs;
13848
13849    TRC2(rgSCHCmnUlMdfyGrntForCqi)
13850
13851    
13852    do
13853    {
13854       iMcs  = rgSCHCmnUlGetIMcsFrmITbs(resiTbs, RG_SCH_CMN_GET_UE_CTGY(ue));
13855       RG_SCH_UL_MCS_TO_MODODR(iMcs, modOdr);
13856       if (RG_SCH_CMN_GET_UE_CTGY(ue) != CM_LTE_UE_CAT_5)
13857       {
13858          modOdr = RGSCH_MIN(RGSCH_QM_QPSK, modOdr);
13859       }
13860       else
13861       {
13862          modOdr = RGSCH_MIN(RGSCH_QM_64QAM, modOdr);
13863       }
13864       nPrb = resNumSb * cellUl->sbSize;
13865       /* Restricting the minumum iTbs requried to modify to 10 */
13866       if ((nPrb >= maxRb) && (resiTbs <= 10))
13867       {
13868          /* Could not accomodate ACQI */
13869          RETVALUE(RFAILED);
13870       }
13871       totREs = nPrb * RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
13872       tbSz = rgTbSzTbl[0][resiTbs][nPrb-1];
13873       /*  totalREs/tbSz = num of bits perRE.  */
13874       cqiRiREs = (totREs * betaOffVal * cqiRiRptSz)/(1000 * tbSz); /* betaOffVal is represented 
13875                                                                    as parts per 1000 */
13876       hqREs = (totREs * betaOffHqVal * hqSz)/(1000 * tbSz);
13877       if ((cqiRiREs + hqREs) < totREs)
13878       {
13879          remREsForPusch = totREs - cqiRiREs - hqREs;
13880          bitsPerRe = (tbSz * 1000)/remREsForPusch; /* Multiplying by 1000 for Interger Oper */
13881          puschEff = bitsPerRe/modOdr;
13882       }
13883       if (puschEff < effTgt)
13884       {
13885           /* ensure resultant efficiency for PUSCH Data is within 0.93*/
13886           break;
13887       }
13888       else
13889       {
13890          /* Alternate between increasing SB or decreasing iTbs until eff is met */
13891          if (mdfyiTbsFlg == FALSE)
13892          {
13893             if (nPrb < maxRb)
13894             {
13895               resNumSb = resNumSb + 1;
13896             }
13897             mdfyiTbsFlg = TRUE;
13898          }
13899          else
13900          {
13901             if (resiTbs > 10)
13902             {
13903                resiTbs-= stepDownItbs;
13904             }
13905             mdfyiTbsFlg = FALSE;
13906          }
13907       }
13908    }while (1); /* Loop breaks if efficency is met 
13909                   or returns RFAILED if not able to meet the efficiency */
13910               
13911    *numSb = resNumSb;
13912    *iTbs = resiTbs;
13913
13914    RETVALUE(ROK);
13915 }
13916 #endif
13917 /***********************************************************
13918  *
13919  *     Func : rgSCHCmnUlRbAllocForUe
13920  *
13921  *     Desc : Do uplink RB allocation for an UE.
13922  *
13923  *     Ret  :
13924  *
13925  *     Notes: Note that as of now, for retx, maxRb
13926  *            is not considered. Alternatives, such
13927  *            as dropping retx if it crosses maxRb
13928  *            could be considered.
13929  *
13930  *     File :
13931  *
13932  **********************************************************/
13933 #ifdef ANSI
13934 PRIVATE S16 rgSCHCmnUlRbAllocForUe
13935 (
13936 RgSchCellCb           *cell,
13937 RgSchUlSf             *sf,
13938 RgSchUeCb             *ue,
13939 U8                    maxRb,
13940 RgSchUlHole           *hole
13941 )
13942 #else
13943 PRIVATE S16 rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole)
13944 RgSchCellCb           *cell;
13945 RgSchUlSf             *sf;
13946 RgSchUeCb             *ue;
13947 U8                    maxRb;
13948 RgSchUlHole           *hole;
13949 #endif
13950 {
13951    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
13952    RgSchCmnUlUe    *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
13953    RgSchUlAlloc     *alloc = NULLP;
13954    U32              nPrb = 0;
13955    U8               numVrbg;
13956    U8               iMcs;
13957    U8               iMcsCrnt;
13958 #ifndef RG_5GTF
13959    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->schdHqProcIdx];
13960 #else
13961    RgSchUlHqProcCb  *proc = NULLP;
13962 #endif
13963    RgSchPdcch       *pdcch;
13964    U32              reqVrbg;
13965    U8               numVrbgTemp;
13966 #ifdef RG_5GTF
13967    TfuDciFormat     dciFrmt;
13968    U8               numLyr;
13969 #endif
13970
13971    TRC2(rgSCHCmnUlRbAllocForUe);
13972 #ifdef RG_5GTF
13973    rgSCHUhmGetAvlHqProc(cell, ue, &proc);
13974    if (proc == NULLP)
13975    {
13976       //printf("UE [%d] HQ Proc unavailable\n", ue->ueId);
13977       RETVALUE(RFAILED);
13978    }
13979 #endif
13980
13981    if (ue->ue5gtfCb.rank == 2)
13982    {
13983       dciFrmt = TFU_DCI_FORMAT_A2;
13984       numLyr = 2;
13985    }
13986    else
13987    {
13988       dciFrmt = TFU_DCI_FORMAT_A1;
13989       numLyr = 1;
13990    }
13991    /* 5gtf TODO : To pass dci frmt to this function */
13992    pdcch = rgSCHCmnPdcchAllocCrntSf(cell, ue);
13993    if(pdcch == NULLP)
13994    {
13995       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, 
13996          "rgSCHCmnUlRbAllocForUe(): Could not get PDCCH for CRNTI:%d",ue->ueId);
13997       RETVALUE(RFAILED);
13998    }
13999         gUl5gtfPdcchSchd++;
14000 #if defined (TENB_STATS) && defined (RG_5GTF)
14001    cell->tenbStats->sch.ul5gtfPdcchSchd++;
14002 #endif
14003
14004    //TODO_SID using configured prb as of now
14005    nPrb = ue->ue5gtfCb.maxPrb;
14006    reqVrbg = nPrb/MAX_5GTF_VRBG_SIZE;
14007    iMcs  = ue->ue5gtfCb.mcs; //gSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
14008    iMcsCrnt = iMcs;
14009    numVrbg = reqVrbg;
14010
14011    if((sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart > MAX_5GTF_VRBG)
14012          || (sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated > MAX_5GTF_VRBG))
14013    {
14014       printf("5GTF_ERROR vrbg > 25 valstart = %d valalloc %d\n", sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart
14015             , sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated);
14016       int *p=NULLP;
14017       *p = 10;
14018    }
14019
14020    /*TODO_SID: Workaround for alloc. Currently alloc is ulsf based. To handle multiple beams, we need a different
14021      design. Now alloc are formed based on MAX_5GTF_UE_SCH macro. */
14022    numVrbgTemp = MAX_5GTF_VRBG/MAX_5GTF_UE_SCH;
14023    if(numVrbg)
14024    {
14025       alloc = rgSCHCmnUlSbAlloc(sf, numVrbgTemp,\
14026                                 hole);
14027    }
14028    if (alloc == NULLP)
14029    {
14030       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
14031          "rgSCHCmnUlRbAllocForUe(): Could not get UlAlloc %d CRNTI:%d",numVrbg,ue->ueId);
14032       rgSCHCmnPdcchRlsCrntSf(cell, pdcch);
14033       RETVALUE(RFAILED);
14034    }
14035    gUl5gtfAllocAllocated++;
14036 #if defined (TENB_STATS) && defined (RG_5GTF)
14037    cell->tenbStats->sch.ul5gtfAllocAllocated++;
14038 #endif
14039    alloc->grnt.vrbgStart = sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart;
14040    alloc->grnt.numVrbg = numVrbg;
14041    alloc->grnt.numLyr = numLyr;
14042    alloc->grnt.dciFrmt = dciFrmt;
14043
14044    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart += numVrbg;
14045    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated += numVrbg;
14046
14047    //rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
14048 #ifdef LTE_L2_MEAS
14049    sf->totPrb  += alloc->grnt.numRb;
14050    ue->ul.nPrb = alloc->grnt.numRb;
14051 #endif
14052    if (ue->csgMmbrSta != TRUE)
14053    {
14054       cellUl->ncsgPrbCnt += alloc->grnt.numRb;
14055    }
14056    cellUl->totPrbCnt += (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
14057    alloc->pdcch = pdcch;
14058    alloc->grnt.iMcs = iMcs;
14059    alloc->grnt.iMcsCrnt = iMcsCrnt;
14060    alloc->grnt.hop = 0;
14061    /* Initial Num RBs support for UCI on PUSCH */
14062 #ifdef TFU_UPGRADE
14063    ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
14064 #endif
14065    alloc->forMsg3 = FALSE;
14066    //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTb5gtfSzTbl[0], (iTbs)); 
14067
14068    //ueUl->alloc.allocdBytes = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
14069    /* TODO_SID Allocating based on configured MCS as of now.
14070          Currently for format A2. When doing multi grp per tti, need to update this. */
14071    ueUl->alloc.allocdBytes = (rgSch5gtfTbSzTbl[iMcs]/8) * ue->ue5gtfCb.rank;
14072
14073    alloc->grnt.datSz = ueUl->alloc.allocdBytes;
14074    //TODO_SID Need to check mod order.
14075    RG_SCH_CMN_TBS_TO_MODODR(iMcs, alloc->grnt.modOdr);
14076         //alloc->grnt.modOdr = 6;
14077    alloc->grnt.isRtx = FALSE;
14078
14079    alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
14080    alloc->grnt.SCID = 0;
14081    alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
14082    alloc->grnt.PMI = 0;
14083    alloc->grnt.uciOnxPUSCH = 0;
14084    alloc->grnt.hqProcId = proc->procId;
14085
14086    alloc->hqProc = proc;
14087    alloc->hqProc->ulSfIdx = cellUl->schdIdx;
14088    alloc->ue = ue;
14089    /*commenting to retain the rnti used for transmission SPS/c-rnti */
14090    alloc->rnti = ue->ueId;
14091    ueUl->alloc.alloc = alloc;
14092    /*rntiwari-Adding the debug for generating the graph.*/
14093    /* No grant attr recorded now */
14094    RETVALUE(ROK);
14095 }
14096
14097 /***********************************************************
14098  *
14099  *     Func : rgSCHCmnUlRbAllocAddUeToLst
14100  *
14101  *     Desc : Add UE to list (scheduled/non-scheduled list)
14102  *            for UL RB allocation information.
14103  *
14104  *     Ret  :
14105  *
14106  *     Notes:
14107  *
14108  *     File :
14109  *
14110  **********************************************************/
14111 #ifdef ANSI
14112 PUBLIC Void rgSCHCmnUlRbAllocAddUeToLst
14113 (
14114 RgSchCellCb           *cell,
14115 RgSchUeCb             *ue,
14116 CmLListCp             *lst
14117 )
14118 #else
14119 PUBLIC Void rgSCHCmnUlRbAllocAddUeToLst(cell, ue, lst)
14120 RgSchCellCb           *cell;
14121 RgSchUeCb             *ue;
14122 CmLListCp             *lst;
14123 #endif
14124 {
14125    RgSchCmnUlUe   *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
14126    TRC2(rgSCHCmnUlRbAllocAddUeToLst);
14127    UNUSED(cell);
14128
14129    gUl5gtfUeRbAllocDone++;
14130 #if defined (TENB_STATS) && defined (RG_5GTF)
14131    cell->tenbStats->sch.ul5gtfUeRbAllocDone++;
14132 #endif
14133    cmLListAdd2Tail(lst, &ueUl->alloc.schdLstLnk);
14134    ueUl->alloc.schdLstLnk.node = (PTR)ue;
14135 }
14136
14137
14138 /**
14139  * @brief This function Processes the Final Allocations
14140  *        made by the RB Allocator against the requested.
14141  *
14142  * @details
14143  *
14144  *     Function: rgSCHCmnUlAllocFnlz
14145  *     Purpose:  This function Processes the Final Allocations
14146  *               made by the RB Allocator against the requested.
14147  *
14148  *     Invoked by: Common Scheduler
14149  *
14150  *  @param[in]  RgSchCellCb           *cell
14151  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
14152  *  @return  Void
14153  *
14154  **/
14155 #ifdef ANSI
14156 PRIVATE Void rgSCHCmnUlAllocFnlz
14157 (
14158 RgSchCellCb           *cell,
14159 RgSchCmnUlRbAllocInfo *allocInfo
14160 )
14161 #else
14162 PRIVATE Void rgSCHCmnUlAllocFnlz(cell, allocInfo)
14163 RgSchCellCb           *cell;
14164 RgSchCmnUlRbAllocInfo *allocInfo;
14165 #endif
14166 {
14167    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
14168    TRC2(rgSCHCmnUlAllocFnlz);
14169
14170    /* call scheduler specific Finalization */
14171    cellSch->apisUl->rgSCHUlAllocFnlz(cell, allocInfo);
14172
14173    RETVOID;
14174 }
14175
14176 /**
14177  * @brief This function Processes the Final Allocations
14178  *        made by the RB Allocator against the requested.
14179  *
14180  * @details
14181  *
14182  *     Function: rgSCHCmnDlAllocFnlz
14183  *     Purpose:  This function Processes the Final Allocations
14184  *               made by the RB Allocator against the requested.
14185  *
14186  *     Invoked by: Common Scheduler
14187  *
14188  *  @param[in]  RgSchCellCb           *cell
14189  *  @return  Void
14190  *
14191  **/
14192 #ifdef ANSI
14193 PUBLIC Void rgSCHCmnDlAllocFnlz
14194 (
14195 RgSchCellCb           *cell
14196 )
14197 #else
14198 PUBLIC Void rgSCHCmnDlAllocFnlz(cell)
14199 RgSchCellCb           *cell;
14200 #endif
14201 {
14202    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14203    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo; 
14204
14205    TRC2(rgSCHCmnDlAllocFnlz);
14206
14207    rgSCHCmnDlCcchRetxFnlz(cell, allocInfo);
14208    rgSCHCmnDlCcchTxFnlz(cell, allocInfo);
14209 #ifdef RGR_V1
14210    /* Added below functions for handling CCCH SDU transmission received
14211     * after
14212     *     * guard timer expiry*/
14213    rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo);
14214    rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo);
14215 #endif
14216    rgSCHCmnDlRaRspFnlz(cell, allocInfo);
14217       /* call scheduler specific Finalization */
14218    cellSch->apisDl->rgSCHDlAllocFnlz(cell, allocInfo);
14219
14220    /* Stack Crash problem for TRACE5 Changes. Added the return below */
14221    RETVOID;
14222
14223 }
14224
14225 #ifdef RG_UNUSED
14226 /**
14227  * @brief Update an uplink subframe.
14228  *
14229  * @details
14230  *
14231  *     Function : rgSCHCmnUlUpdSf
14232  *
14233  *     For each allocation
14234  *      - if no more tx needed
14235  *         - Release allocation
14236  *      - else
14237  *         - Perform retransmission
14238  *
14239  *  @param[in]  RgSchUlSf *sf
14240  *  @return  Void
14241  **/
14242 #ifdef ANSI
14243 PRIVATE Void rgSCHCmnUlUpdSf
14244 (
14245 RgSchCellCb           *cell,
14246 RgSchCmnUlRbAllocInfo *allocInfo,
14247 RgSchUlSf *sf
14248 )
14249 #else
14250 PRIVATE Void rgSCHCmnUlUpdSf(cell, allocInfo, sf)
14251 RgSchCellCb           *cell;
14252 RgSchCmnUlRbAllocInfo *allocInfo;
14253 RgSchUlSf *sf;
14254 #endif
14255 {
14256    CmLList        *lnk;
14257    TRC2(rgSCHCmnUlUpdSf);
14258
14259    while ((lnk = sf->allocs.first))
14260    {
14261       RgSchUlAlloc  *alloc = (RgSchUlAlloc *)lnk->node;
14262       lnk = lnk->next;
14263
14264       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
14265       {
14266       }
14267       else
14268       {
14269          /* If need to handle all retx together, run another loop separately */
14270          rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc);
14271       }
14272       rgSCHCmnUlRlsUlAlloc(cell, sf, alloc);
14273    }
14274
14275    /* By this time, all allocs would have been cleared and
14276     * SF is reset to be made ready for new allocations. */
14277    rgSCHCmnUlSfReset(cell, sf);
14278    /* In case there are timing problems due to msg3
14279     * allocations being done in advance, (which will
14280     * probably happen with the current FDD code that
14281     * handles 8 subframes) one solution
14282     * could be to hold the (recent) msg3 allocs in a separate
14283     * list, and then possibly add that to the actual
14284     * list later. So at this time while allocations are
14285     * traversed, the recent msg3 ones are not seen. Anytime after
14286     * this (a good time is when the usual allocations
14287     * are made), msg3 allocations could be transferred to the
14288     * normal list. Not doing this now as it is assumed
14289     * that incorporation of TDD shall take care of this.
14290     */
14291
14292
14293    RETVOID;
14294 }
14295
14296 /**
14297  * @brief Handle uplink allocation for retransmission.
14298  *
14299  * @details
14300  *
14301  *     Function : rgSCHCmnUlHndlAllocRetx
14302  *
14303  *     Processing Steps:
14304  *     - Add to queue for retx.
14305  *     - Do not release here, release happends as part
14306  *       of the loop that calls this function.
14307  *
14308  *  @param[in]  RgSchCellCb           *cell
14309  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
14310  *  @param[in]  RgSchUlSf *sf
14311  *  @param[in]  RgSchUlAlloc  *alloc
14312  *  @return  Void
14313  **/
14314 #ifdef ANSI
14315 PRIVATE Void rgSCHCmnUlHndlAllocRetx
14316 (
14317 RgSchCellCb           *cell,
14318 RgSchCmnUlRbAllocInfo *allocInfo,
14319 RgSchUlSf     *sf,
14320 RgSchUlAlloc  *alloc
14321 )
14322 #else
14323 PRIVATE Void rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc)
14324 RgSchCellCb           *cell;
14325 RgSchCmnUlRbAllocInfo *allocInfo;
14326 RgSchUlSf     *sf;
14327 RgSchUlAlloc  *alloc;
14328 #endif
14329 {
14330    U32            bytes;
14331    RgSchCmnUlUe   *ueUl;
14332    TRC2(rgSCHCmnUlHndlAllocRetx);
14333    bytes = \
14334       rgTbSzTbl[0][rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs)]\
14335                                      [alloc->grnt.numRb-1]/8;
14336    if (!alloc->forMsg3)
14337    {
14338       ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue);
14339       ueUl->alloc.reqBytes = bytes;
14340       rgSCHUhmRetx(alloc->hqProc);
14341       rgSCHCmnUlAdd2RetxUeLst(allocInfo, alloc->ue);
14342    }
14343    else
14344    {
14345       /* RACHO msg3 retx handling. Part of RACH procedure changes. */
14346       retxAlloc = rgSCHCmnUlGetUlAlloc(cell, sf, alloc->numSb);
14347       if (retxAlloc == NULLP)
14348       {
14349          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
14350                "rgSCHCmnUlRbAllocForUe():Could not get UlAlloc for msg3Retx RNTI:%d",
14351                alloc->rnti);
14352          RETVOID;
14353       }
14354       retxAlloc->grnt.iMcs = alloc->grnt.iMcs;
14355       retxAlloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl\
14356                                  [alloc->hqProc->rvIdx];
14357       retxAlloc->grnt.nDmrs    = 0;
14358       retxAlloc->grnt.hop      = 0;
14359       retxAlloc->grnt.delayBit = 0;
14360       retxAlloc->rnti          = alloc->rnti;
14361       retxAlloc->ue            = NULLP;
14362       retxAlloc->pdcch         = FALSE;
14363       retxAlloc->forMsg3       = TRUE;
14364       retxAlloc->raCb          = alloc->raCb;
14365       retxAlloc->hqProc        = alloc->hqProc;
14366       rgSCHUhmRetx(retxAlloc->hqProc);
14367    }
14368    RETVOID;
14369 }
14370 #endif
14371
14372 /**
14373  * @brief Uplink Scheduling Handler.
14374  *
14375  * @details
14376  *
14377  *     Function: rgSCHCmnUlAlloc
14378  *     Purpose:  This function Handles Uplink Scheduling.
14379  *
14380  *     Invoked by: Common Scheduler
14381  *
14382  *  @param[in]  RgSchCellCb *cell
14383  *  @return  Void
14384  **/
14385 /* ccpu00132653- The definition of this function made common for TDD and FDD*/
14386 #ifdef ANSI
14387 PRIVATE Void rgSCHCmnUlAlloc
14388 (
14389 RgSchCellCb  *cell
14390 )
14391 #else
14392 PRIVATE Void rgSCHCmnUlAlloc(cell)
14393 RgSchCellCb  *cell;
14394 #endif
14395 {
14396    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14397    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
14398    RgSchCmnDlCell         *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
14399    RgSchCmnUlRbAllocInfo  allocInfo;
14400    RgSchCmnUlRbAllocInfo  *allocInfoRef = &allocInfo;
14401 #ifdef RG_5GTF
14402    U8 idx;
14403
14404 #endif
14405
14406    TRC2(rgSCHCmnUlAlloc);
14407
14408    /* Initializing RgSchCmnUlRbAllocInfo structure */
14409    rgSCHCmnInitUlRbAllocInfo(allocInfoRef);
14410
14411    /* Get Uplink Subframe */
14412    allocInfoRef->sf = &cellUl->ulSfArr[cellUl->schdIdx];
14413 #ifdef LTE_L2_MEAS
14414    /* initializing the UL PRB count */
14415    allocInfoRef->sf->totPrb = 0;
14416 #endif
14417
14418 #ifdef LTEMAC_SPS
14419    rgSCHCmnSpsUlTti(cell, allocInfoRef);
14420 #endif
14421
14422    if(*allocInfoRef->sf->allocCountRef == 0)
14423    {            
14424       RgSchUlHole     *hole;
14425
14426       if ((hole = rgSCHUtlUlHoleFirst(allocInfoRef->sf)) != NULLP)
14427       {
14428          /* Sanity check of holeDb */
14429          if (allocInfoRef->sf->holeDb->count == 1 && hole->start == 0) 
14430          {
14431             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
14432             /* Re-Initialize available subbands because of CFI change*/
14433             allocInfoRef->sf->availSubbands = cell->dynCfiCb.\
14434                                               bwInfo[cellDl->currCfi].numSb;
14435             /*Currently initializing 5gtf ulsf specific initialization here.
14436               need to do at proper place */
14437 #ifdef RG_5GTF
14438        allocInfoRef->sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
14439        allocInfoRef->sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
14440             for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
14441             {
14442                allocInfoRef->sf->sfBeamInfo[idx].totVrbgAllocated = 0;
14443                allocInfoRef->sf->sfBeamInfo[idx].totVrbgRequired = 0;
14444                allocInfoRef->sf->sfBeamInfo[idx].vrbgStart = 0;
14445             }    
14446 #endif
14447          }
14448          else
14449          {
14450             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
14451                   "Error! holeDb sanity check failed");
14452          }
14453       }
14454    }
14455
14456    /* Fix: Adaptive re-transmissions prioritised over other transmissions */
14457    /* perform adaptive retransmissions */
14458    rgSCHCmnUlSfReTxAllocs(cell, allocInfoRef->sf);
14459
14460         g5gtfTtiCnt++;
14461
14462    /* Fix: syed Adaptive Msg3 Retx crash. Release all
14463     Harq processes for which adap Retx failed, to avoid 
14464     blocking. This step should be done before New TX 
14465     scheduling to make hqProc available. Right now we
14466     dont check if proc is in adap Retx list for considering
14467     it to be available. But now with this release that 
14468     functionality would be correct. */
14469 #ifndef RG_5GTF
14470    rgSCHCmnUlSfRlsRetxProcs(cell, allocInfoRef->sf);  
14471 #endif
14472
14473    /* Specific UL scheduler to perform UE scheduling */
14474    cellSch->apisUl->rgSCHUlSched(cell, allocInfoRef);
14475
14476    /* Call UL RB allocator module */
14477    rgSCHCmnAllocUlRb(cell, allocInfoRef);
14478
14479    /* Do group power control for PUSCH */
14480    rgSCHCmnGrpPwrCntrlPusch(cell, allocInfoRef->sf);
14481
14482    cell->sc.apis->rgSCHDrxStrtInActvTmrInUl(cell);
14483
14484    rgSCHCmnUlAllocFnlz(cell, allocInfoRef);
14485         if(5000 == g5gtfTtiCnt)
14486         {
14487       ul5gtfsidDlAlreadyMarkUl = 0;
14488                 ul5gtfsidDlSchdPass = 0;
14489                 ul5gtfsidUlMarkUl = 0;
14490       ul5gtfTotSchdCnt = 0;
14491                 g5gtfTtiCnt = 0;
14492         }
14493
14494    RETVOID;
14495 }
14496
14497 /**
14498  * @brief send Subframe Allocations.
14499  *
14500  * @details
14501  *
14502  *     Function: rgSCHCmnSndCnsldtInfo
14503  *     Purpose:  Send the scheduled
14504  *     allocations to MAC for StaInd generation to Higher layers and
14505  *     for MUXing. PST's RgInfSfAlloc to MAC instance.
14506  *
14507  *     Invoked by: Common Scheduler
14508  *
14509  *  @param[in]  RgSchCellCb *cell
14510  *  @return  Void
14511  **/
14512 #ifdef ANSI
14513 PUBLIC Void rgSCHCmnSndCnsldtInfo
14514 (
14515 RgSchCellCb  *cell
14516 )
14517 #else
14518 PUBLIC Void rgSCHCmnSndCnsldtInfo(cell)
14519 RgSchCellCb  *cell;
14520 #endif
14521 {
14522    RgInfSfAlloc           *subfrmAlloc;
14523    Pst                    pst;
14524    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14525
14526    TRC2(rgSCHCmnSndCnsldtInfo);
14527
14528    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
14529
14530    /* Send the allocations to MAC for MUXing */
14531    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
14532    subfrmAlloc->cellId = cell->cellId;
14533    /* Populate the List of UEs needing PDB-based Flow control */
14534    cellSch->apisDl->rgSCHDlFillFlwCtrlInfo(cell, subfrmAlloc);
14535 #ifdef LTE_L2_MEAS
14536    if((subfrmAlloc->rarInfo.numRaRntis) ||
14537 #ifdef EMTC_ENABLE
14538       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
14539       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
14540       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
14541 #endif
14542       (subfrmAlloc->ueInfo.numUes)      ||
14543       (subfrmAlloc->cmnLcInfo.bitMask)  ||
14544          (subfrmAlloc->ulUeInfo.numUes)    ||
14545          (subfrmAlloc->flowCntrlInfo.numUes))
14546 #else
14547    if((subfrmAlloc->rarInfo.numRaRntis) ||
14548 #ifdef EMTC_ENABLE
14549       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
14550       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
14551       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
14552 #endif
14553       (subfrmAlloc->ueInfo.numUes)      ||
14554             (subfrmAlloc->cmnLcInfo.bitMask)  ||
14555             (subfrmAlloc->flowCntrlInfo.numUes))
14556 #endif
14557    {
14558       RgSchMacSfAlloc(&pst, subfrmAlloc);
14559    }
14560 #ifndef LTE_TDD
14561    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
14562 #else
14563    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_SF_ALLOC_SIZE;
14564 #endif
14565    
14566    RETVOID;
14567 }
14568 /**
14569  * @brief Consolidate Subframe Allocations.
14570  *
14571  * @details
14572  *
14573  *     Function: rgSCHCmnCnsldtSfAlloc
14574  *     Purpose:  Consolidate Subframe Allocations.
14575  *
14576  *     Invoked by: Common Scheduler
14577  *
14578  *  @param[in]  RgSchCellCb *cell
14579  *  @return  Void
14580  **/
14581 #ifdef ANSI
14582 PUBLIC Void rgSCHCmnCnsldtSfAlloc
14583 (
14584 RgSchCellCb  *cell
14585 )
14586 #else
14587 PUBLIC Void rgSCHCmnCnsldtSfAlloc(cell)
14588 RgSchCellCb  *cell;
14589 #endif
14590 {
14591    RgInfSfAlloc           *subfrmAlloc;
14592    CmLteTimingInfo        frm;
14593    RgSchDlSf              *dlSf;
14594    CmLListCp              dlDrxInactvTmrLst;
14595    CmLListCp              dlInActvLst;
14596    CmLListCp              ulInActvLst;
14597    RgSchCmnCell           *cellSch = NULLP;
14598
14599    TRC2(rgSCHCmnCnsldtSfAlloc);
14600
14601    cmLListInit(&dlDrxInactvTmrLst);
14602    cmLListInit(&dlInActvLst);
14603    cmLListInit(&ulInActvLst);
14604
14605    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
14606
14607    /* Get Downlink Subframe */
14608    frm   = cell->crntTime;
14609    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
14610    dlSf = rgSCHUtlSubFrmGet(cell, frm);
14611
14612    /* Fill the allocation Info */
14613    rgSCHUtlFillRgInfRarInfo(dlSf, subfrmAlloc, cell);
14614
14615   /* CA dev Start */
14616    rgSCHUtlFillRgInfUeInfo(dlSf, cell, &dlDrxInactvTmrLst, 
14617                            &dlInActvLst, &ulInActvLst);
14618 #ifdef RG_PFS_STATS
14619    cell->totalPrb += dlSf->bwAssigned;
14620 #endif
14621    /* Mark the following Ues inactive for UL*/
14622    cellSch = RG_SCH_CMN_GET_CELL(cell);
14623
14624    /* Calling Scheduler specific function with DRX inactive UE list*/
14625    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInActvLst);
14626    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInActvLst);
14627     
14628   /* CA dev End */
14629    /*re/start DRX inactivity timer for the UEs*/
14630    (Void)rgSCHDrxStrtInActvTmr(cell,&dlDrxInactvTmrLst,RG_SCH_DRX_DL);
14631
14632    RETVOID;
14633 }
14634
14635 /**
14636  * @brief Initialize the DL Allocation Information Structure.
14637  *
14638  * @details
14639  *
14640  *     Function: rgSCHCmnInitDlRbAllocInfo
14641  *     Purpose:  Initialize the DL Allocation Information Structure.
14642  *
14643  *     Invoked by: Common Scheduler
14644  *
14645  *  @param[out]  RgSchCmnDlRbAllocInfo  *allocInfo
14646  *  @return  Void
14647  **/
14648 #ifdef ANSI
14649 PRIVATE Void rgSCHCmnInitDlRbAllocInfo
14650 (
14651 RgSchCmnDlRbAllocInfo  *allocInfo
14652 )
14653 #else
14654 PRIVATE Void rgSCHCmnInitDlRbAllocInfo(allocInfo)
14655 RgSchCmnDlRbAllocInfo  *allocInfo;
14656 #endif
14657 {
14658    TRC2(rgSCHCmnInitDlRbAllocInfo);
14659    cmMemset((U8 *)&allocInfo->pcchAlloc, (U8)0, sizeof(RgSchDlRbAlloc));
14660    cmMemset((U8 *)&allocInfo->bcchAlloc, (U8)0, sizeof(RgSchDlRbAlloc));
14661    cmMemset((U8 *)allocInfo->raRspAlloc, (U8)0,
14662          RG_SCH_CMN_MAX_CMN_PDCCH*sizeof(RgSchDlRbAlloc));
14663
14664    allocInfo->msg4Alloc.msg4DlSf = NULLP;
14665    cmLListInit(&allocInfo->msg4Alloc.msg4TxLst);
14666    cmLListInit(&allocInfo->msg4Alloc.msg4RetxLst);
14667    cmLListInit(&allocInfo->msg4Alloc.schdMsg4TxLst);
14668    cmLListInit(&allocInfo->msg4Alloc.schdMsg4RetxLst);
14669    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4TxLst);
14670    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4RetxLst);
14671 #ifdef RGR_V1
14672    allocInfo->ccchSduAlloc.ccchSduDlSf = NULLP;
14673    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduTxLst);
14674    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduRetxLst);
14675    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduTxLst);
14676    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduRetxLst);
14677    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst);
14678    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst);
14679 #endif
14680
14681    allocInfo->dedAlloc.dedDlSf = NULLP;
14682    cmLListInit(&allocInfo->dedAlloc.txHqPLst);
14683    cmLListInit(&allocInfo->dedAlloc.retxHqPLst);
14684    cmLListInit(&allocInfo->dedAlloc.schdTxHqPLst);
14685    cmLListInit(&allocInfo->dedAlloc.schdRetxHqPLst);
14686    cmLListInit(&allocInfo->dedAlloc.nonSchdTxHqPLst);
14687    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxHqPLst);
14688
14689    cmLListInit(&allocInfo->dedAlloc.txRetxHqPLst);
14690    cmLListInit(&allocInfo->dedAlloc.schdTxRetxHqPLst);
14691    cmLListInit(&allocInfo->dedAlloc.nonSchdTxRetxHqPLst);
14692 #ifdef LTEMAC_SPS
14693    cmLListInit(&allocInfo->dedAlloc.txSpsHqPLst);
14694    cmLListInit(&allocInfo->dedAlloc.retxSpsHqPLst);
14695    cmLListInit(&allocInfo->dedAlloc.schdTxSpsHqPLst);
14696    cmLListInit(&allocInfo->dedAlloc.schdRetxSpsHqPLst);
14697    cmLListInit(&allocInfo->dedAlloc.nonSchdTxSpsHqPLst);
14698    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxSpsHqPLst);
14699 #endif
14700
14701 #ifdef LTE_ADV
14702    rgSCHLaaCmnInitDlRbAllocInfo (allocInfo);
14703 #endif
14704
14705    cmLListInit(&allocInfo->dedAlloc.errIndTxHqPLst);
14706    cmLListInit(&allocInfo->dedAlloc.schdErrIndTxHqPLst);
14707    cmLListInit(&allocInfo->dedAlloc.nonSchdErrIndTxHqPLst);
14708    RETVOID;
14709 }
14710
14711 /**
14712  * @brief Initialize the UL Allocation Information Structure.
14713  *
14714  * @details
14715  *
14716  *     Function: rgSCHCmnInitUlRbAllocInfo
14717  *     Purpose:  Initialize the UL Allocation Information Structure.
14718  *
14719  *     Invoked by: Common Scheduler
14720  *
14721  *  @param[out]  RgSchCmnUlRbAllocInfo  *allocInfo
14722  *  @return  Void
14723  **/
14724 #ifdef ANSI
14725 PUBLIC Void rgSCHCmnInitUlRbAllocInfo
14726 (
14727 RgSchCmnUlRbAllocInfo  *allocInfo
14728 )
14729 #else
14730 PUBLIC Void rgSCHCmnInitUlRbAllocInfo(allocInfo)
14731 RgSchCmnUlRbAllocInfo  *allocInfo;
14732 #endif
14733 {
14734    TRC2(rgSCHCmnInitUlRbAllocInfo);
14735    allocInfo->sf = NULLP;
14736    cmLListInit(&allocInfo->contResLst);
14737    cmLListInit(&allocInfo->schdContResLst);
14738    cmLListInit(&allocInfo->nonSchdContResLst);
14739    cmLListInit(&allocInfo->ueLst);
14740    cmLListInit(&allocInfo->schdUeLst);
14741    cmLListInit(&allocInfo->nonSchdUeLst);
14742
14743    RETVOID;
14744 }
14745
14746 /**
14747  * @brief Scheduling for PUCCH group power control.
14748  *
14749  * @details
14750  *
14751  *     Function: rgSCHCmnGrpPwrCntrlPucch
14752  *     Purpose: This function does group power control for PUCCH
14753  *     corresponding to the subframe for which DL UE allocations
14754  *     have happended.
14755  *
14756  *     Invoked by: Common Scheduler
14757  *
14758  *  @param[in]  RgSchCellCb *cell
14759  *  @return  Void
14760  **/
14761 #ifdef ANSI
14762 PRIVATE Void rgSCHCmnGrpPwrCntrlPucch
14763 (
14764 RgSchCellCb            *cell,
14765 RgSchDlSf              *dlSf
14766 )
14767 #else
14768 PRIVATE Void rgSCHCmnGrpPwrCntrlPucch(cell, dlSf)
14769 RgSchCellCb            *cell;
14770 RgSchDlSf              *dlSf;
14771 #endif
14772 {
14773    TRC2(rgSCHCmnGrpPwrCntrlPucch);
14774
14775    rgSCHPwrGrpCntrlPucch(cell, dlSf);
14776
14777    RETVOID;
14778 }
14779
14780 /**
14781  * @brief Scheduling for PUSCH group power control.
14782  *
14783  * @details
14784  *
14785  *     Function: rgSCHCmnGrpPwrCntrlPusch
14786  *     Purpose: This function does group power control, for
14787  *     the subframe for which UL allocation has (just) happened.
14788  *
14789  *     Invoked by: Common Scheduler
14790  *
14791  *  @param[in]  RgSchCellCb *cell
14792  *  @param[in]  RgSchUlSf   *ulSf
14793  *  @return  Void
14794  **/
14795 #ifdef ANSI
14796 PRIVATE Void rgSCHCmnGrpPwrCntrlPusch
14797 (
14798 RgSchCellCb            *cell,
14799 RgSchUlSf              *ulSf
14800 )
14801 #else
14802 PRIVATE Void rgSCHCmnGrpPwrCntrlPusch(cell, ulSf)
14803 RgSchCellCb            *cell;
14804 RgSchUlSf              *ulSf;
14805 #endif
14806 {
14807    /*removed unused variable *cellSch*/
14808    CmLteTimingInfo        frm;
14809    RgSchDlSf              *dlSf;
14810
14811    TRC2(rgSCHCmnGrpPwrCntrlPusch);
14812
14813    /* Got to pass DL SF corresponding to UL SF, so get that first.
14814     * There is no easy way of getting dlSf by having the RgSchUlSf*,
14815     * so use the UL delta from current time to get the DL SF. */
14816    frm   = cell->crntTime;
14817
14818 #ifdef EMTC_ENABLE
14819    if(cell->emtcEnable == TRUE)
14820    {
14821       RGSCH_INCR_SUB_FRAME_EMTC(frm, TFU_DLCNTRL_DLDELTA);
14822    }
14823    else
14824 #endif
14825    {
14826       RGSCH_INCR_SUB_FRAME(frm, TFU_DLCNTRL_DLDELTA);
14827    }
14828    /* Del filling of dl.time */
14829    dlSf = rgSCHUtlSubFrmGet(cell, frm);
14830
14831    rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf);
14832
14833    RETVOID;
14834 }
14835
14836 /* Fix: syed align multiple UEs to refresh at same time */
14837 /***********************************************************
14838  *
14839  *     Func : rgSCHCmnApplyUeRefresh 
14840  *
14841  *     Desc : Apply UE refresh in CMN and Specific 
14842  *     schedulers. Data rates and corresponding 
14843  *     scratchpad variables are updated.
14844  *
14845  *     Ret  :
14846  *
14847  *     Notes:
14848  *
14849  *     File :
14850  *
14851  **********************************************************/
14852 #ifdef ANSI
14853 PRIVATE S16 rgSCHCmnApplyUeRefresh 
14854 (
14855 RgSchCellCb     *cell,
14856 RgSchUeCb       *ue
14857 )
14858 #else
14859 PRIVATE S16 rgSCHCmnApplyUeRefresh(cell, ue)
14860 RgSchCellCb     *cell;
14861 RgSchUeCb       *ue;
14862 #endif
14863 {
14864    RgSchCmnCell    *cellSch     = RG_SCH_CMN_GET_CELL(cell);
14865    U32             effGbrBsr    = 0;
14866    U32             effNonGbrBsr = 0;
14867    U32             lcgId;
14868
14869    TRC2(rgSCHCmnApplyUeRefresh);
14870
14871    /* Reset the refresh cycle variableCAP */
14872    ue->ul.effAmbr = ue->ul.cfgdAmbr;
14873
14874    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
14875    {
14876       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
14877       {
14878          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
14879
14880          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
14881          {
14882             cmnLcg->effGbr = cmnLcg->cfgdGbr;
14883             cmnLcg->effDeltaMbr = cmnLcg->deltaMbr;
14884             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
14885             /* Considering GBR LCG will be prioritised by UE */
14886             effGbrBsr += cmnLcg->bs;
14887          }/* Else no remaing BS so nonLcg0 will be updated when BSR will be received */
14888          else
14889          {
14890             effNonGbrBsr += cmnLcg->reportedBs;
14891             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
14892          }
14893       }
14894    }
14895    effNonGbrBsr = RGSCH_MIN(effNonGbrBsr,ue->ul.effAmbr);
14896    ue->ul.nonGbrLcgBs = effNonGbrBsr;
14897
14898    ue->ul.nonLcg0Bs = effGbrBsr + effNonGbrBsr;
14899    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
14900                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
14901
14902
14903    /* call scheduler specific event handlers
14904     * for refresh timer expiry */
14905    cellSch->apisUl->rgSCHUlUeRefresh(cell, ue);
14906    cellSch->apisDl->rgSCHDlUeRefresh(cell, ue);
14907
14908    RETVALUE(ROK);
14909 }
14910
14911 /***********************************************************
14912  *
14913  *     Func : rgSCHCmnTmrExpiry
14914  *
14915  *     Desc : Adds an UE to refresh queue, so that the UE is
14916  *            periodically triggered to refresh it's GBR and
14917  *            AMBR values.
14918  *
14919  *     Ret  :
14920  *
14921  *     Notes:
14922  *
14923  *     File :
14924  *
14925  **********************************************************/
14926 #ifdef ANSI
14927 PRIVATE S16 rgSCHCmnTmrExpiry
14928 (
14929 PTR cb,               /* Pointer to timer control block */
14930 S16 tmrEvnt           /* Timer Event */
14931 )
14932 #else
14933 PRIVATE S16 rgSCHCmnTmrExpiry(cb, tmrEvnt)
14934 PTR cb;               /* Pointer to timer control block */
14935 S16 tmrEvnt;           /* Timer Event */
14936 #endif
14937 {
14938    RgSchUeCb       *ue = (RgSchUeCb *)cb;
14939    RgSchCellCb     *cell = ue->cell;
14940 #if (ERRCLASS & ERRCLS_DEBUG)
14941 #endif
14942
14943    TRC2(rgSCHCmnTmrExpiry);
14944
14945 #if (ERRCLASS & ERRCLS_DEBUG)
14946    if (tmrEvnt != RG_SCH_CMN_EVNT_UE_REFRESH)
14947    {
14948       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnTmrExpiry(): Invalid "
14949          "timer event CRNTI:%d",ue->ueId);
14950       RETVALUE(RFAILED);
14951    }
14952 #else
14953    UNUSED(tmrEvnt);
14954 #endif
14955
14956    rgSCHCmnApplyUeRefresh(cell, ue);
14957
14958    rgSCHCmnAddUeToRefreshQ(cell, ue, RG_SCH_CMN_REFRESH_TIME);
14959
14960    RETVALUE(ROK);
14961 }
14962
14963 /***********************************************************
14964  *
14965  *     Func : rgSCHCmnTmrProc
14966  *
14967  *     Desc : Timer entry point per cell. Timer
14968  *            processing is triggered at every frame boundary
14969  *            (every 10 ms).
14970  *
14971  *     Ret  :
14972  *
14973  *     Notes:
14974  *
14975  *     File :
14976  *
14977  **********************************************************/
14978 #ifdef ANSI
14979 PRIVATE S16 rgSCHCmnTmrProc
14980 (
14981 RgSchCellCb *cell
14982 )
14983 #else
14984 PRIVATE S16 rgSCHCmnTmrProc(cell)
14985 RgSchCellCb *cell;
14986 #endif
14987 {
14988    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
14989    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
14990    /* Moving the assignment of scheduler pointer
14991      to available scope for optimization */
14992    TRC2(rgSCHCmnTmrProc);
14993
14994    if ((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES_5G) == 0)
14995    {
14996       /* Reset the counters periodically */
14997       if ((cell->crntTime.sfn % RG_SCH_CMN_CSG_REFRESH_TIME) == 0)
14998       {
14999          RG_SCH_RESET_HCSG_DL_PRB_CNTR(cmnDlCell);
15000          RG_SCH_RESET_HCSG_UL_PRB_CNTR(cmnUlCell);
15001       }
15002       if ((cell->crntTime.sfn % RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME) == 0)
15003       {
15004
15005          cell->measurements.ulTpt =  ((cell->measurements.ulTpt * 95) + ( cell->measurements.ulBytesCnt * 5))/100;
15006          cell->measurements.dlTpt =  ((cell->measurements.dlTpt * 95) + ( cell->measurements.dlBytesCnt * 5))/100;
15007
15008          rgSCHUtlCpuOvrLdAdjItbsCap(cell);
15009          /* reset cell level tpt measurements for next cycle */
15010          cell->measurements.ulBytesCnt = 0;
15011          cell->measurements.dlBytesCnt = 0;
15012       }
15013       /* Comparing with Zero instead of % is being done for efficiency.
15014        * If Timer resolution changes then accordingly update the
15015        * macro RG_SCH_CMN_REFRESH_TIMERES */    
15016       RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
15017       cmPrcTmr(&sched->tmrTqCp, sched->tmrTq, (PFV)rgSCHCmnTmrExpiry);
15018    }
15019
15020    RETVALUE(ROK);
15021 }
15022
15023
15024 /***********************************************************
15025  *
15026  *     Func : rgSchCmnUpdCfiVal 
15027  *
15028  *     Desc : Update the CFI value if CFI switch was done 
15029  *
15030  *     Ret  :
15031  *
15032  *     Notes:
15033  *
15034  *     File :
15035  *
15036  **********************************************************/
15037 #ifdef ANSI
15038 PRIVATE Void rgSchCmnUpdCfiVal
15039 (
15040 RgSchCellCb     *cell,
15041 U8              delta
15042 )
15043 #else
15044 PRIVATE Void rgSchCmnUpdCfiVal(cell, delta)
15045 RgSchCellCb     *cell;
15046 U8              delta;
15047 #endif  
15048 {
15049    RgSchDlSf        *dlSf;
15050    CmLteTimingInfo  pdsch;
15051    RgSchCmnDlCell  *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); 
15052    U8               dlIdx;
15053 #ifdef LTE_TDD
15054    U8               mPhich;
15055    RgSchDlSf        *tddSf;
15056    U8               idx;
15057    U8               splSfCfi = 0;
15058 #endif    
15059
15060    TRC2(rgSchCmnUpdCfiVal);
15061
15062    pdsch  = cell->crntTime;
15063    RGSCH_INCR_SUB_FRAME(pdsch, delta);
15064    dlSf = rgSCHUtlSubFrmGet(cell, pdsch);
15065    /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
15066     *change happens in that SF then UL PDCCH allocation happens with old CFI
15067     *but CFI in control Req goes updated one since it was stored in the CELL
15068     */
15069    dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
15070    if(cell->dynCfiCb.pdcchSfIdx != 0xFF) 
15071    {
15072 #ifdef LTE_TDD
15073       dlIdx = rgSCHUtlGetDlSfIdx(cell, &pdsch);
15074 #else
15075       dlIdx = (((pdsch.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (pdsch.subframe % RGSCH_NUM_SUB_FRAMES));
15076       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
15077 #endif  
15078       /* If current downlink subframe index is same as pdcch SF index,
15079        * perform the switching of CFI in this subframe */
15080       if(cell->dynCfiCb.pdcchSfIdx == dlIdx)
15081       {
15082          cellCmnDl->currCfi  = cellCmnDl->newCfi;
15083          cell->dynCfiCb.pdcchSfIdx = 0xFF;
15084
15085          /* Updating the nCce value based on the new CFI */
15086 #ifdef LTE_TDD
15087          splSfCfi = cellCmnDl->newCfi;
15088          for(idx = 0; idx < cell->numDlSubfrms; idx++)
15089          {   
15090             tddSf = cell->subFrms[idx];
15091
15092             mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][tddSf->sfNum];
15093
15094             if(tddSf->sfType == RG_SCH_SPL_SF_DATA)
15095             {
15096                RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
15097
15098                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
15099             }
15100             else
15101             {   
15102                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][cellCmnDl->currCfi];
15103             }
15104          }
15105          /* Setting the switch over window length based on config index.
15106           * During switch over period all the UL trnsmissions are Acked 
15107           * to UEs */
15108          cell->dynCfiCb.switchOvrWinLen = 
15109                rgSchCfiSwitchOvrWinLen[cell->ulDlCfgIdx];
15110 #else
15111          cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCmnDl->currCfi];
15112          /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
15113           *change happens in that SF then UL PDCCH allocation happens with old CFI
15114           *but CFI in control Req goes updated one since it was stored in the CELL
15115           */
15116          dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
15117          cell->dynCfiCb.switchOvrWinLen = rgSchCfiSwitchOvrWinLen[7];
15118 #endif
15119       }   
15120    }   
15121
15122    RETVOID;
15123 }
15124
15125 /***********************************************************
15126  *
15127  *     Func : rgSchCmnUpdtPdcchSfIdx 
15128  *
15129  *     Desc : Update the switch over window length
15130  *
15131  *     Ret  : void
15132  *
15133  *     Notes:
15134  *
15135  *     File :
15136  *
15137  **********************************************************/
15138 #ifdef LTE_TDD
15139 #ifdef ANSI
15140 PRIVATE Void rgSchCmnUpdtPdcchSfIdx 
15141 (
15142 RgSchCellCb     *cell,
15143 U8              dlIdx,
15144 U8              sfNum
15145 )
15146 #else
15147 PRIVATE Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, sfNum)
15148 RgSchCellCb     *cell;
15149 U8              dlIdx;
15150 U8              sfNum;
15151 #endif   
15152 #else
15153 #ifdef ANSI
15154 PRIVATE Void rgSchCmnUpdtPdcchSfIdx 
15155 (
15156 RgSchCellCb     *cell,
15157 U8              dlIdx
15158 )
15159 #else
15160 PRIVATE Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx)
15161 RgSchCellCb     *cell;
15162 U8              dlIdx;
15163 #endif    
15164 #endif
15165 {
15166    U8         idx;
15167
15168    TRC2(rgSchCmnUpdtPdcchSfIdx);
15169
15170    /* Resetting the parameters on CFI switching */
15171    cell->dynCfiCb.cceUsed = 0;
15172    cell->dynCfiCb.lowCceCnt = 0;
15173
15174    cell->dynCfiCb.cceFailSum = 0;
15175    cell->dynCfiCb.cceFailCnt = 0;
15176    cell->dynCfiCb.prevCceFailIdx = 0;
15177
15178    cell->dynCfiCb.switchOvrInProgress = TRUE;
15179
15180    for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++)
15181    {
15182       cell->dynCfiCb.cceFailSamples[idx] = 0;
15183    }   
15184
15185    cell->dynCfiCb.ttiCnt = 0;
15186
15187    cell->dynCfiCb.cfiSwitches++;
15188    cfiSwitchCnt = cell->dynCfiCb.cfiSwitches;
15189
15190 #ifdef LTE_TDD 
15191    cell->dynCfiCb.pdcchSfIdx = (dlIdx + 
15192       rgSchTddPdcchSfIncTbl[cell->ulDlCfgIdx][sfNum]) % cell->numDlSubfrms;
15193 #else
15194    cell->dynCfiCb.pdcchSfIdx = (dlIdx + RG_SCH_CFI_APPLY_DELTA) % \
15195         RGSCH_NUM_DL_SUBFRAMES;
15196 #endif
15197 }
15198
15199 /***********************************************************
15200  *
15201  *     Func : rgSchCmnUpdCfiDb 
15202  *
15203  *     Desc : Update the counters related to dynamic
15204  *            CFI feature in cellCb. 
15205  *
15206  *     Ret  :
15207  *
15208  *     Notes:
15209  *
15210  *     File :
15211  *
15212  **********************************************************/
15213 #ifdef ANSI
15214 PUBLIC Void rgSchCmnUpdCfiDb 
15215 (
15216 RgSchCellCb     *cell,
15217 U8              delta 
15218 )
15219 #else
15220 PUBLIC Void rgSchCmnUpdCfiDb(cell, delta)
15221 RgSchCellCb     *cell;
15222 U8              delta;
15223 #endif 
15224 {
15225    CmLteTimingInfo        frm;
15226    RgSchDlSf              *dlSf;
15227 #ifdef LTE_TDD
15228    U8                     mPhich;
15229    Bool                   isHiDci0; 
15230 #endif      
15231    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell); 
15232    U8                     nCceLowerCfi = 0;
15233    U8                     currCfi;
15234    U8                     cceFailIdx;
15235    U32                    totalCce;
15236    U8                     dlIdx;
15237    U16                    ttiMod;
15238
15239    TRC2(rgSchCmnUpdCfiDb);
15240
15241    /* Get Downlink Subframe */   
15242    frm   = cell->crntTime;
15243    RGSCH_INCR_SUB_FRAME(frm, delta);
15244
15245 #ifdef LTE_TDD
15246    dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
15247    dlSf = cell->subFrms[dlIdx];
15248    isHiDci0 = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][dlSf->sfNum];
15249 #else
15250    /* Changing the idexing
15251       so that proper subframe is selected */
15252    dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.subframe % RGSCH_NUM_SUB_FRAMES));
15253    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
15254    dlSf = cell->subFrms[dlIdx];
15255 #endif 
15256
15257    currCfi = cellSch->dl.currCfi;
15258
15259    if(!cell->dynCfiCb.switchOvrInProgress)
15260    {   
15261       do{
15262          if(!cell->dynCfiCb.isDynCfiEnb)
15263          {
15264             if(currCfi != cellSch->cfiCfg.cfi)
15265             {
15266                if(currCfi < cellSch->cfiCfg.cfi)
15267                {
15268                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
15269                   cfiIncr = cell->dynCfiCb.cfiIncr;   
15270                }
15271                else
15272                {
15273                   RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
15274                   cfiDecr = cell->dynCfiCb.cfiDecr;
15275                }
15276             }
15277             break;
15278          }
15279
15280 #ifdef LTE_TDD         
15281          /* Setting ttiMod to 0 for ttiCnt > 1000 in case if this 
15282           * function was not called in UL subframe*/
15283          if(cell->dynCfiCb.ttiCnt > RGSCH_CFI_TTI_MON_INTRVL)
15284          {   
15285             ttiMod = 0;
15286          }
15287          else
15288 #endif
15289          {   
15290             ttiMod = cell->dynCfiCb.ttiCnt % RGSCH_CFI_TTI_MON_INTRVL;
15291          }
15292
15293          dlSf->dlUlBothCmplt++;
15294 #ifdef LTE_TDD      
15295          if((dlSf->dlUlBothCmplt == 2) || (!isHiDci0))
15296 #else
15297          if(dlSf->dlUlBothCmplt == 2)
15298 #endif         
15299          {
15300             /********************STEP UP CRITERIA********************/
15301             /* Updating the CCE failure count parameter */
15302             cell->dynCfiCb.cceFailCnt += dlSf->isCceFailure;
15303             cell->dynCfiCb.cceFailSum += dlSf->isCceFailure;
15304
15305             /* Check if cfi step up can be performed */
15306             if(currCfi < cell->dynCfiCb.maxCfi)
15307             {
15308                if(cell->dynCfiCb.cceFailSum >= cell->dynCfiCb.cfiStepUpTtiCnt) 
15309                {
15310                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
15311                   cfiIncr = cell->dynCfiCb.cfiIncr;   
15312                   break;
15313                }
15314             } 
15315
15316             /********************STEP DOWN CRITERIA********************/
15317
15318             /* Updating the no. of CCE used in this dl subframe */
15319             cell->dynCfiCb.cceUsed += dlSf->cceCnt;
15320
15321             if(currCfi > RGSCH_MIN_CFI_VAL)
15322             {   
15323                /* calculating the number of CCE for next lower CFI */
15324 #ifdef LTE_TDD      
15325                mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][dlSf->sfNum];
15326                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[mPhich][currCfi-1];
15327 #else
15328                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[0][currCfi-1];
15329 #endif     
15330                if(dlSf->cceCnt < nCceLowerCfi)
15331                {
15332                   /* Updating the count of TTIs in which no. of CCEs
15333                    * used were less than the CCEs of next lower CFI */
15334                   cell->dynCfiCb.lowCceCnt++;
15335                }   
15336
15337                if(ttiMod == 0)
15338                {
15339                   totalCce = (nCceLowerCfi * cell->dynCfiCb.cfiStepDownTtiCnt * 
15340                         RGSCH_CFI_CCE_PERCNTG)/100;
15341
15342                   if((!cell->dynCfiCb.cceFailSum) && 
15343                         (cell->dynCfiCb.lowCceCnt >= 
15344                          cell->dynCfiCb.cfiStepDownTtiCnt) && 
15345                         (cell->dynCfiCb.cceUsed < totalCce))  
15346                   {
15347                      RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
15348                      cfiDecr = cell->dynCfiCb.cfiDecr; 
15349                      break;
15350                   }
15351                }   
15352             }
15353
15354             cceFailIdx = ttiMod/cell->dynCfiCb.failSamplePrd;
15355
15356             if(cceFailIdx != cell->dynCfiCb.prevCceFailIdx)
15357             {   
15358                /* New sample period has started. Subtract the old count  
15359                 * from the new sample period */
15360                cell->dynCfiCb.cceFailSum -= cell->dynCfiCb.cceFailSamples[cceFailIdx];
15361
15362                /* Store the previous sample period data */
15363                cell->dynCfiCb.cceFailSamples[cell->dynCfiCb.prevCceFailIdx]
15364                   = cell->dynCfiCb.cceFailCnt;
15365
15366                cell->dynCfiCb.prevCceFailIdx = cceFailIdx;
15367
15368                /* Resetting the CCE failure count as zero for next sample period */
15369                cell->dynCfiCb.cceFailCnt = 0;  
15370             }
15371
15372             if(ttiMod == 0)
15373             {   
15374                /* Restting the parametrs after Monitoring Interval expired */
15375                cell->dynCfiCb.cceUsed = 0;
15376                cell->dynCfiCb.lowCceCnt = 0;
15377                cell->dynCfiCb.ttiCnt = 0;
15378             }
15379
15380             cell->dynCfiCb.ttiCnt++;
15381          }
15382       }while(0);
15383
15384       if(cellSch->dl.newCfi != cellSch->dl.currCfi)
15385       {
15386 #ifdef LTE_TDD      
15387          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, dlSf->sfNum);
15388 #else
15389          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx);
15390 #endif      
15391       }  
15392    }
15393 }   
15394
15395 /**
15396  * @brief Dl Scheduler for Broadcast and Common channel scheduling.
15397  *
15398  * @details
15399  *
15400  *     Function: rgSCHCmnDlCommonChSch
15401  *     Purpose:  This function schedules DL Common channels for LTE. 
15402  *               Invoked by TTI processing in TOM. Scheduling is done for 
15403  *               BCCH, PCCH, Msg4, CCCH SDU, RAR in that order 
15404  *
15405  *     Invoked by: TOM (TTI processing)
15406  *
15407  *  @param[in]  RgSchCellCb *cell
15408  *  @return  Void
15409  **/
15410 #ifdef ANSI
15411 PUBLIC Void rgSCHCmnDlCommonChSch
15412 (
15413 RgSchCellCb  *cell
15414 )
15415 #else
15416 PUBLIC Void rgSCHCmnDlCommonChSch(cell)
15417 RgSchCellCb  *cell;
15418 #endif
15419 {
15420    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
15421
15422    TRC2(rgSCHCmnDlCommonChSch);
15423
15424    cellSch->apisDl->rgSCHDlTickForPdbTrkng(cell);
15425    rgSchCmnUpdCfiVal(cell, RG_SCH_CMN_DL_DELTA);
15426
15427    /* handle Inactive UEs for DL */
15428    rgSCHCmnHdlDlInactUes(cell);
15429
15430    /* Send a Tick to Refresh Timer */
15431    rgSCHCmnTmrProc(cell);
15432
15433    if (cell->isDlDataAllwd && (cell->stopSiSch == FALSE)) 
15434    {
15435       rgSCHCmnInitRbAlloc(cell); 
15436       /* Perform DL scheduling of BCCH, PCCH */
15437       rgSCHCmnDlBcchPcchAlloc(cell);
15438    }
15439    else
15440    {
15441       if(cell->siCb.inWindow != 0)
15442       {
15443          cell->siCb.inWindow--;
15444       }
15445    }
15446    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
15447    {
15448       rgSCHCmnDlCcchRarAlloc(cell);
15449    }
15450    RETVOID;
15451 }
15452
15453 /**
15454  * @brief Scheduler invocation per TTI.
15455  *
15456  * @details
15457  *
15458  *     Function: rgSCHCmnUlSch
15459  *     Purpose:  This function implements UL scheduler alone. This is to
15460  *               be able to perform scheduling with more flexibility.
15461  *
15462  *     Invoked by: TOM (TTI processing)
15463  *
15464  *  @param[in]  RgSchCellCb *cell
15465  *  @return  Void
15466  **/
15467 #ifdef ANSI
15468 PUBLIC Void rgSCHCmnUlSch
15469 (
15470 RgSchCellCb  *cell
15471 )
15472 #else
15473 PUBLIC Void  rgSCHCmnUlSch(cell)
15474 RgSchCellCb  *cell;
15475 #endif
15476 {
15477    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
15478    
15479    TRC2(rgSCHCmnUlSch);
15480
15481 #ifdef LTE_ADV
15482    /* LAA_SCELL: */
15483    if(TRUE == rgSCHLaaSCellEnabled(cell))
15484    {
15485       RETVOID;   
15486    }
15487 #endif
15488    
15489    if(cellSch->ul.schdIdx != RGSCH_INVALID_INFO)
15490    {   
15491       rgSchCmnUpdCfiVal(cell, TFU_ULCNTRL_DLDELTA);
15492
15493       /* Handle Inactive UEs for UL */
15494       rgSCHCmnHdlUlInactUes(cell);
15495       /* Perform UL Scheduling EVERY TTI */
15496       rgSCHCmnUlAlloc(cell);
15497
15498       /* Calling function to update CFI parameters*/
15499       rgSchCmnUpdCfiDb(cell, TFU_ULCNTRL_DLDELTA);   
15500
15501       if(cell->dynCfiCb.switchOvrWinLen > 0)
15502       {
15503          /* Decrementing the switchover window length */
15504          cell->dynCfiCb.switchOvrWinLen--;
15505
15506          if(!cell->dynCfiCb.switchOvrWinLen)
15507          {   
15508             if(cell->dynCfiCb.dynCfiRecfgPend)
15509             {  
15510                /* Toggling the Dynamic CFI enabling */
15511                cell->dynCfiCb.isDynCfiEnb ^= 1;
15512                rgSCHDynCfiReCfg(cell, cell->dynCfiCb.isDynCfiEnb); 
15513                cell->dynCfiCb.dynCfiRecfgPend = FALSE;
15514             }   
15515             cell->dynCfiCb.switchOvrInProgress = FALSE;
15516          }
15517       }
15518    }
15519 #ifdef LTE_TDD
15520 #ifdef LTEMAC_SPS
15521    else
15522    {
15523       rgSCHCmnSpsUlTti(cell, NULLP); 
15524    }
15525 #endif
15526 #endif
15527
15528    RETVOID;
15529 }
15530
15531 \f
15532 /**
15533  * @brief This function updates the scheduler with service for an UE.
15534  *
15535  * @details
15536  *
15537  *     Function: rgSCHCmnDlDedBoUpd
15538  *     Purpose:  This function should be called whenever there is a
15539  *               change BO for a service.
15540  *
15541  *     Invoked by: BO and Scheduler
15542  *
15543  *  @param[in]  RgSchCellCb*  cell
15544  *  @param[in]  RgSchUeCb*    ue
15545  *  @param[in]  RgSchDlLcCb*  svc
15546  *  @return  Void
15547  *
15548  **/
15549 #ifdef ANSI
15550 PUBLIC Void rgSCHCmnDlDedBoUpd
15551 (
15552 RgSchCellCb                *cell,
15553 RgSchUeCb                  *ue,
15554 RgSchDlLcCb                *svc
15555 )
15556 #else
15557 PUBLIC Void rgSCHCmnDlDedBoUpd(cell, ue, svc)
15558 RgSchCellCb                *cell;
15559 RgSchUeCb                  *ue;
15560 RgSchDlLcCb                *svc;
15561 #endif
15562 {
15563    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15564    TRC2(rgSCHCmnDlDedBoUpd);
15565
15566    /* RACHO : if UEs idle time exceeded and a BO update
15567     * is received, then add UE to the pdcch Order Q */
15568    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
15569    {
15570       RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
15571       /* If PDCCH order is already triggered and we are waiting for
15572        * RACH from UE then do not add to PdcchOdrQ. */
15573       if (ueDl->rachInfo.rapIdLnk.node == NULLP)
15574       {
15575          rgSCHCmnDlAdd2PdcchOdrQ(cell, ue);
15576       }
15577    }
15578
15579 #ifdef LTEMAC_SPS
15580
15581    /* If SPS service, invoke SPS module */
15582    if (svc->dlLcSpsCfg.isSpsEnabled)
15583    {
15584       rgSCHCmnSpsDlDedBoUpd(cell, ue, svc);
15585       /* Note: Retrun from here, no update needed in other schedulers */
15586       RETVOID;
15587    }
15588 #endif
15589 #ifdef EMTC_ENABLE
15590    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
15591    {
15592       cellSch->apisEmtcDl->rgSCHDlDedBoUpd(cell, ue, svc);
15593       //printf("rgSCHEMTCDlDedBoUpd\n");
15594    }
15595    else
15596 #endif
15597    {
15598       cellSch->apisDl->rgSCHDlDedBoUpd(cell, ue, svc);
15599    }
15600 #ifdef LTE_ADV
15601    if (ue->numSCells)
15602    {
15603       rgSCHSCellDlDedBoUpd(cell, ue, svc);
15604    }
15605 #endif
15606    RETVOID;
15607 }
15608
15609 \f
15610 /**
15611  * @brief Removes an UE from Cell's TA List.
15612  *
15613  * @details
15614  *
15615  *     Function: rgSCHCmnRmvFrmTaLst
15616  *     Purpose:  Removes an UE from Cell's TA List.
15617  *
15618  *     Invoked by: Specific Scheduler
15619  *
15620  *  @param[in]  RgSchCellCb*     cell
15621  *  @param[in]  RgSchUeCb*       ue
15622  *  @return  Void
15623  *
15624  **/
15625 #ifdef ANSI
15626 PUBLIC Void rgSCHCmnRmvFrmTaLst
15627 (
15628 RgSchCellCb                *cell,
15629 RgSchUeCb                  *ue
15630 )
15631 #else
15632 PUBLIC Void rgSCHCmnRmvFrmTaLst(cell, ue)
15633 RgSchCellCb                *cell;
15634 RgSchUeCb                  *ue;
15635 #endif
15636 {
15637    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
15638    TRC2(rgSCHCmnRmvFrmTaLst);
15639
15640 #ifdef EMTC_ENABLE
15641    if(cell->emtcEnable && ue->isEmtcUe)
15642    {
15643       rgSCHEmtcRmvFrmTaLst(cellCmnDl,ue);
15644    }
15645    else
15646 #endif
15647    {
15648       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
15649       ue->dlTaLnk.node = (PTR)NULLP;
15650    }
15651    RETVOID;
15652 }
15653
15654 /* Fix: syed Remove the msg4Proc from cell
15655  * msg4Retx Queue. I have used CMN scheduler function
15656  * directly. Please define a new API and call this
15657  * function through that. */        
15658 \f
15659 /**
15660  * @brief This function removes MSG4 HARQ process from cell RETX Queues.
15661  *
15662  * @details
15663  *
15664  *     Function: rgSCHCmnDlMsg4ProcRmvFrmRetx
15665  *     Purpose:  This function removes MSG4 HARQ process from cell RETX Queues.
15666  *
15667  *     Invoked by: UE/RACB deletion. 
15668  *
15669  *  @param[in]  RgSchCellCb*     cell
15670  *  @param[in]  RgSchDlHqProc*   hqP
15671  *  @return  Void
15672  *
15673  **/
15674 #ifdef ANSI
15675 PUBLIC Void rgSCHCmnDlMsg4ProcRmvFrmRetx 
15676 (
15677 RgSchCellCb                *cell,
15678 RgSchDlHqProcCb            *hqP
15679 )
15680 #else
15681 PUBLIC Void rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, hqP)
15682 RgSchCellCb                *cell;
15683 RgSchDlHqProcCb            *hqP;
15684 #endif
15685 {
15686    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15687    TRC2(rgSCHCmnDlMsg4ProcRmvFrmRetx);
15688
15689    if (hqP->tbInfo[0].ccchSchdInfo.retxLnk.node)
15690    {
15691       if (hqP->hqE->msg4Proc == hqP)
15692       {
15693          cmLListDelFrm(&cellSch->dl.msg4RetxLst, \
15694                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15695          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
15696       }
15697 #ifdef RGR_V1
15698       else if(hqP->hqE->ccchSduProc == hqP)
15699       {
15700          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
15701                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15702          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
15703       }
15704 #endif
15705    }
15706    RETVOID;
15707 }
15708
15709 \f
15710 /**
15711  * @brief This function adds a HARQ process for retx.
15712  *
15713  * @details
15714  *
15715  *     Function: rgSCHCmnDlProcAddToRetx
15716  *     Purpose:  This function adds a HARQ process to retransmission
15717  *               queue. This may be performed when a HARQ ack is
15718  *               unsuccessful.
15719  *
15720  *     Invoked by: HARQ feedback processing
15721  *
15722  *  @param[in]  RgSchCellCb*     cell
15723  *  @param[in]  RgSchDlHqProc*   hqP
15724  *  @return  Void
15725  *
15726  **/
15727 #ifdef ANSI
15728 PUBLIC Void rgSCHCmnDlProcAddToRetx
15729 (
15730 RgSchCellCb                *cell,
15731 RgSchDlHqProcCb            *hqP
15732 )
15733 #else
15734 PUBLIC Void rgSCHCmnDlProcAddToRetx(cell, hqP)
15735 RgSchCellCb                *cell;
15736 RgSchDlHqProcCb            *hqP;
15737 #endif
15738 {
15739    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15740    TRC2(rgSCHCmnDlProcAddToRetx);
15741
15742    if (hqP->hqE->msg4Proc == hqP) /* indicating msg4 transmission */
15743    {
15744       cmLListAdd2Tail(&cellSch->dl.msg4RetxLst, \
15745             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15746       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
15747    }
15748 #ifdef RGR_V1
15749    else if(hqP->hqE->ccchSduProc == hqP)
15750    {
15751       /*If CCCH SDU being transmitted without cont res CE*/
15752       cmLListAdd2Tail(&cellSch->dl.ccchSduRetxLst,
15753             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15754       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
15755    }
15756 #endif
15757    else
15758    {
15759 #ifdef LTEMAC_SPS
15760       if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
15761       {
15762          /* Invoke SPS module for SPS HARQ proc re-transmission handling */
15763          rgSCHCmnSpsDlProcAddToRetx(cell, hqP);
15764          RETVOID;
15765       }
15766 #endif /* LTEMAC_SPS */
15767 #ifdef EMTC_ENABLE      
15768       if((TRUE == cell->emtcEnable)
15769          && (TRUE == hqP->hqE->ue->isEmtcUe))
15770       {
15771          cellSch->apisEmtcDl->rgSCHDlProcAddToRetx(cell, hqP);
15772       }
15773       else
15774 #endif         
15775       {
15776          cellSch->apisDl->rgSCHDlProcAddToRetx(cell, hqP);
15777       }
15778    }
15779    RETVOID;
15780 }
15781
15782 \f
15783 /**
15784  * @brief This function performs RI validation and
15785  *        updates it to the ueCb.
15786  *
15787  * @details
15788  *
15789  *     Function: rgSCHCmnDlSetUeRi
15790  *     Purpose:  This function performs RI validation and
15791  *        updates it to the ueCb.
15792  *
15793  *     Invoked by: rgSCHCmnDlCqiInd
15794  *
15795  *  @param[in]  RgSchCellCb        *cell
15796  *  @param[in]  RgSchUeCb          *ue
15797  *  @param[in]  U8                 ri
15798  *  @param[in]  Bool               isPeriodic
15799  *  @return  Void
15800  *
15801  **/
15802 #ifdef ANSI
15803 PRIVATE Void rgSCHCmnDlSetUeRi
15804 (
15805 RgSchCellCb        *cell,
15806 RgSchUeCb          *ue,
15807 U8                 ri,
15808 Bool               isPer
15809 )
15810 #else
15811 PRIVATE Void rgSCHCmnDlSetUeRi(cell, ue, ri, isPer)
15812 RgSchCellCb        *cell;
15813 RgSchUeCb          *ue;
15814 U8                 ri;
15815 Bool               isPer;
15816 #endif
15817 {
15818    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15819    RgSchCmnUeInfo    *ueSchCmn = RG_SCH_CMN_GET_CMN_UE(ue);
15820    TRC2(rgSCHCmnDlSetUeRi);
15821    
15822 #ifdef TFU_UPGRADE
15823    RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell);
15824    UNUSED(isPer);
15825 #endif
15826
15827
15828    /* FIX for RRC Reconfiguration issue */
15829    /* ccpu00140894- During Tx Mode transition RI report will not entertained for 
15830     * specific during which SCH expecting UE can complete TX mode transition*/
15831    if (ue->txModeTransCmplt == FALSE)
15832    {
15833       RETVOID;
15834    }
15835
15836    /* Restrict the Number of TX layers to cell->numTxAntPorts.
15837     * Protection from invalid RI values. */
15838    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
15839    
15840    /* Special case of converting PMI to sane value when
15841     * there is a switch in RI from 1 to 2 and PMI reported 
15842     * for RI=1 is invalid for RI=2 */
15843    if ((cell->numTxAntPorts == 2) && (ue->mimoInfo.txMode == RGR_UE_TM_4))
15844    {
15845       if ((ri == 2) && ( ueDl->mimoInfo.ri == 1))
15846       {
15847          ueDl->mimoInfo.pmi = (ueDl->mimoInfo.pmi < 2)? 1:2;
15848       }
15849    }
15850
15851    /* Restrict the Number of TX layers according to the UE Category */
15852    ueDl->mimoInfo.ri = RGSCH_MIN(ri, rgUeCatTbl[ueSchCmn->ueCat].maxTxLyrs);
15853 #ifdef TENB_STATS
15854    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].riCnt[ueDl->mimoInfo.ri-1]++;
15855    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
15856 #endif
15857
15858 #ifdef TENB_STATS
15859    ue->tenbStats->stats.nonPersistent.sch[0].riCnt[ueDl->mimoInfo.ri-1]++;
15860    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
15861 #endif
15862
15863 #ifdef TFU_UPGRADE
15864    if (isPer)
15865    {
15866       /* If RI is from Periodic CQI report */
15867       cqiCb->perRiVal = ueDl->mimoInfo.ri;
15868       /* Reset at every Periodic RI Reception */ 
15869       cqiCb->invalidateCqi = FALSE;
15870    }
15871    else
15872    {
15873       /* If RI is from Aperiodic CQI report */
15874       if (cqiCb->perRiVal != ueDl->mimoInfo.ri)
15875       {
15876          /* if this aperRI is different from last reported
15877           * perRI then invalidate all CQI reports till next
15878           * perRI */
15879          cqiCb->invalidateCqi = TRUE;
15880       }
15881       else
15882       {
15883          cqiCb->invalidateCqi = FALSE;
15884       }
15885    }
15886 #endif   
15887
15888    if (ueDl->mimoInfo.ri > 1)
15889    {
15890       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
15891    }
15892    else if (ue->mimoInfo.txMode == RGR_UE_TM_3) /* ri == 1 */
15893    {
15894       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
15895    }
15896
15897    RETVOID;
15898 }
15899
15900 \f
15901 /**
15902  * @brief This function performs PMI validation and
15903  *        updates it to the ueCb.
15904  *
15905  * @details
15906  *
15907  *     Function: rgSCHCmnDlSetUePmi
15908  *     Purpose:  This function performs PMI validation and
15909  *        updates it to the ueCb.
15910  *
15911  *     Invoked by: rgSCHCmnDlCqiInd
15912  *
15913  *  @param[in]  RgSchCellCb        *cell
15914  *  @param[in]  RgSchUeCb          *ue
15915  *  @param[in]  U8                 pmi
15916  *  @return  Void
15917  *
15918  **/
15919 #ifdef ANSI
15920 PRIVATE S16 rgSCHCmnDlSetUePmi
15921 (
15922 RgSchCellCb        *cell,
15923 RgSchUeCb          *ue,
15924 U8                 pmi
15925 )
15926 #else
15927 PRIVATE S16 rgSCHCmnDlSetUePmi(cell, ue, pmi)
15928 RgSchCellCb        *cell;
15929 RgSchUeCb          *ue;
15930 U8                 pmi;
15931 #endif
15932 {
15933    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15934    TRC2(rgSCHCmnDlSetUePmi);
15935
15936    if (ue->txModeTransCmplt == FALSE)
15937    {
15938        RETVALUE(RFAILED);
15939    }
15940  
15941    if (cell->numTxAntPorts == 2)
15942    {
15943       if (pmi > 3)
15944       {
15945          RETVALUE(RFAILED);
15946       }
15947       if (ueDl->mimoInfo.ri == 2)
15948       {
15949          /*ccpu00118150 - MOD - changed pmi value validation from 0 to 2*/
15950          /* PMI 2 and 3 are invalid incase of 2 TxAnt and 2 Layered SM */
15951          if (pmi == 2 || pmi == 3)
15952          {
15953             RETVALUE(RFAILED);
15954          }
15955          ueDl->mimoInfo.pmi = pmi+1;
15956       }
15957       else
15958       {
15959          ueDl->mimoInfo.pmi = pmi;
15960       }
15961    }
15962    else if (cell->numTxAntPorts == 4)
15963    {
15964       if (pmi > 15)
15965       {
15966          RETVALUE(RFAILED);
15967       }
15968       ueDl->mimoInfo.pmi = pmi;
15969    }
15970    /* Reset the No PMI Flag in forceTD */
15971    RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
15972    RETVALUE(ROK);
15973 }
15974
15975 /**
15976  * @brief This function Updates the DL CQI on PUCCH for the UE.
15977  *
15978  * @details
15979  *
15980  *     Function: rgSCHCmnDlProcCqiMode10
15981  *
15982  *     This function updates the DL CQI on PUCCH for the UE.
15983  *
15984  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
15985  *
15986  *     Processing Steps:
15987  *
15988  *  @param[in] RgSchCellCb     *cell
15989  *  @param[in] RgSchUeCb       *ue
15990  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
15991  *  @return  S16
15992  *      -# ROK
15993  *      -# RFAILED
15994  **/
15995 #ifdef RGR_CQI_REPT
15996 #ifdef ANSI
15997 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10
15998 (
15999  RgSchCellCb        *cell,
16000  RgSchUeCb          *ue,
16001  TfuDlCqiPucch      *pucchCqi,
16002  Bool               *isCqiAvail
16003  )
16004 #else
16005 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail)
16006  RgSchCellCb        *cell;
16007  RgSchUeCb          *ue;
16008  TfuDlCqiPucch      *pucchCqi;
16009  Bool               *isCqiAvail;
16010 #endif
16011 #else
16012 #ifdef ANSI
16013 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10
16014 (
16015  RgSchCellCb        *cell,
16016  RgSchUeCb          *ue,
16017  TfuDlCqiPucch      *pucchCqi
16018  )
16019 #else
16020 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi)
16021  RgSchCellCb        *cell;
16022  RgSchUeCb          *ue;
16023  TfuDlCqiPucch      *pucchCqi;
16024 #endif
16025 #endif
16026 {
16027    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16028    TRC2(rgSCHCmnDlProcCqiMode10);
16029
16030    if (pucchCqi->u.mode10Info.type == TFU_RPT_CQI)
16031    {
16032       /*ccpu00109787 - ADD - Check for non-zero CQI*/
16033       /* Checking whether the decoded CQI is a value between 1 and 15*/
16034       if((pucchCqi->u.mode10Info.u.cqi) && (pucchCqi->u.mode10Info.u.cqi
16035                < RG_SCH_CMN_MAX_CQI))
16036       {
16037          ueDl->cqiFlag = TRUE;
16038          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode10Info.u.cqi;
16039          ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16040          /* ccpu00117452 - MOD - Changed macro name from
16041             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16042 #ifdef RGR_CQI_REPT
16043          *isCqiAvail = TRUE;
16044 #endif
16045       }
16046       else
16047       {
16048          RETVOID;
16049       }
16050    }
16051    else if (pucchCqi->u.mode10Info.type == TFU_RPT_RI)
16052    {
16053       if ( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode10Info.u.ri) )
16054       {
16055          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode10Info.u.ri,
16056                            TRUE);
16057       }
16058       else
16059       {
16060          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
16061             pucchCqi->u.mode10Info.u.ri,ue->ueId);
16062          RETVOID;
16063       }
16064    }
16065 }
16066
16067 /**
16068  * @brief This function Updates the DL CQI on PUCCH for the UE.
16069  *
16070  * @details
16071  *
16072  *     Function: rgSCHCmnDlProcCqiMode11
16073  *
16074  *     This function updates the DL CQI on PUCCH for the UE.
16075  *
16076  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
16077  *
16078  *     Processing Steps:
16079  *       Process CQI MODE 11
16080  *  @param[in] RgSchCellCb     *cell
16081  *  @param[in] RgSchUeCb       *ue
16082  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16083  *  @return  S16
16084  *      -# ROK
16085  *      -# RFAILED
16086  **/
16087 #ifdef RGR_CQI_REPT
16088 #ifdef ANSI
16089 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11
16090 (
16091  RgSchCellCb        *cell,
16092  RgSchUeCb          *ue,
16093  TfuDlCqiPucch      *pucchCqi,
16094  Bool               *isCqiAvail,
16095  Bool               *is2ndCwCqiAvail
16096  )
16097 #else
16098 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail)
16099  RgSchCellCb        *cell;
16100  RgSchUeCb          *ue;
16101  TfuDlCqiPucch      *pucchCqi;
16102  Bool               *isCqiAvail;
16103  Bool               *is2ndCwCqiAvail;
16104 #endif
16105 #else
16106 #ifdef ANSI
16107 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11
16108 (
16109  RgSchCellCb        *cell,
16110  RgSchUeCb          *ue,
16111  TfuDlCqiPucch      *pucchCqi
16112  )
16113 #else
16114 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi)
16115  RgSchCellCb        *cell;
16116  RgSchUeCb          *ue;
16117  TfuDlCqiPucch      *pucchCqi;
16118 #endif
16119 #endif
16120 {
16121    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16122    TRC2(rgSCHCmnDlProcCqiMode11);
16123
16124    if (pucchCqi->u.mode11Info.type == TFU_RPT_CQI)
16125    {
16126       ue->mimoInfo.puschFdbkVld  = FALSE;
16127       /*ccpu00109787 - ADD - Check for non-zero CQI*/
16128       if((pucchCqi->u.mode11Info.u.cqi.cqi) &&
16129             (pucchCqi->u.mode11Info.u.cqi.cqi < RG_SCH_CMN_MAX_CQI))
16130       {
16131          ueDl->cqiFlag = TRUE;
16132          /* ccpu00117452 - MOD - Changed macro name from
16133             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16134 #ifdef RGR_CQI_REPT
16135          *isCqiAvail = TRUE;
16136 #endif
16137          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode11Info.u.cqi.cqi;
16138          if (pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.pres)
16139          {
16140             RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
16141                                      ueDl->mimoInfo.cwInfo[1].cqi, \
16142                                      pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.val);
16143 #ifdef RGR_CQI_REPT
16144             /* ccpu00117259 - ADD - Considering second codeword CQI info
16145                incase of MIMO for CQI Reporting */
16146             *is2ndCwCqiAvail = TRUE;
16147 #endif
16148          }
16149       }
16150       else
16151       {
16152          RETVOID;
16153       }
16154       rgSCHCmnDlSetUePmi(cell, ue, \
16155             pucchCqi->u.mode11Info.u.cqi.pmi);
16156    }
16157    else if (pucchCqi->u.mode11Info.type == TFU_RPT_RI)
16158    {
16159       if( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode11Info.u.ri))
16160       {
16161          rgSCHCmnDlSetUeRi(cell, ue,  pucchCqi->u.mode11Info.u.ri,
16162                            TRUE);
16163       }
16164       else
16165       {
16166          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Invalid RI value(%x) CRNTI:%d",
16167             pucchCqi->u.mode11Info.u.ri,ue->ueId);
16168          RETVOID;
16169       }
16170    }
16171 }
16172
16173 /**
16174  * @brief This function Updates the DL CQI on PUCCH for the UE.
16175  *
16176  * @details
16177  *
16178  *     Function: rgSCHCmnDlProcCqiMode20
16179  *
16180  *     This function updates the DL CQI on PUCCH for the UE.
16181  *
16182  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
16183  *
16184  *     Processing Steps:
16185  *       Process CQI MODE 20
16186  *  @param[in] RgSchCellCb     *cell
16187  *  @param[in] RgSchUeCb       *ue
16188  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16189  *  @return  S16
16190  *      -# ROK
16191  *      -# RFAILED
16192  **/
16193 #ifdef RGR_CQI_REPT
16194 #ifdef ANSI
16195 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20
16196 (
16197  RgSchCellCb        *cell,
16198  RgSchUeCb          *ue,
16199  TfuDlCqiPucch      *pucchCqi,
16200  Bool               *isCqiAvail
16201  )
16202 #else
16203 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail )
16204  RgSchCellCb        *cell;
16205  RgSchUeCb          *ue;
16206  TfuDlCqiPucch      *pucchCqi;
16207  Bool               *isCqiAvail;
16208 #endif
16209 #else
16210 #ifdef ANSI
16211 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20
16212 (
16213  RgSchCellCb        *cell,
16214  RgSchUeCb          *ue,
16215  TfuDlCqiPucch      *pucchCqi
16216  )
16217 #else
16218 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi)
16219  RgSchCellCb        *cell;
16220  RgSchUeCb          *ue;
16221  TfuDlCqiPucch      *pucchCqi;
16222 #endif
16223 #endif
16224 {
16225    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16226    TRC2(rgSCHCmnDlProcCqiMode20);
16227
16228    if (pucchCqi->u.mode20Info.type == TFU_RPT_CQI)
16229    {
16230       if (pucchCqi->u.mode20Info.u.cqi.isWideband)
16231       {
16232          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16233          if((pucchCqi->u.mode20Info.u.cqi.u.wideCqi) &&
16234                (pucchCqi->u.mode20Info.u.cqi.u.wideCqi < RG_SCH_CMN_MAX_CQI))
16235          {
16236             ueDl->cqiFlag = TRUE;
16237             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode20Info.u.cqi.\
16238                                            u.wideCqi;
16239             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16240             /* ccpu00117452 - MOD - Changed macro name from
16241                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16242 #ifdef RGR_CQI_REPT
16243             *isCqiAvail = TRUE;
16244 #endif
16245          }
16246          else
16247          {
16248             RETVOID;
16249          }
16250       }
16251    }
16252    else if (pucchCqi->u.mode20Info.type == TFU_RPT_RI)
16253    {
16254       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode20Info.u.ri))
16255       {
16256          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode20Info.u.ri, 
16257                            TRUE);
16258       }
16259       else
16260       {
16261          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
16262             pucchCqi->u.mode20Info.u.ri,ue->ueId);
16263          RETVOID;
16264       }
16265    }
16266 }
16267
16268
16269 /**
16270  * @brief This function Updates the DL CQI on PUCCH for the UE.
16271  *
16272  * @details
16273  *
16274  *     Function: rgSCHCmnDlProcCqiMode21
16275  *
16276  *     This function updates the DL CQI on PUCCH for the UE.
16277  *
16278  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
16279  *
16280  *     Processing Steps:
16281  *       Process CQI MODE 21
16282  *  @param[in] RgSchCellCb     *cell
16283  *  @param[in] RgSchUeCb       *ue
16284  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16285  *  @return  S16
16286  *      -# ROK
16287  *      -# RFAILED
16288  **/
16289 #ifdef RGR_CQI_REPT
16290 #ifdef ANSI
16291 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21
16292 (
16293  RgSchCellCb        *cell,
16294  RgSchUeCb          *ue,
16295  TfuDlCqiPucch      *pucchCqi,
16296  Bool               *isCqiAvail,
16297  Bool               *is2ndCwCqiAvail
16298  )
16299 #else
16300 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail)
16301    RgSchCellCb        *cell;
16302    RgSchUeCb          *ue;
16303  TfuDlCqiPucch        *pucchCqi;
16304    TfuDlCqiRpt        *dlCqiRpt;
16305    Bool               *isCqiAvail;
16306    Bool               *is2ndCwCqiAvail;
16307 #endif
16308 #else
16309 #ifdef ANSI
16310 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21
16311 (
16312  RgSchCellCb        *cell,
16313  RgSchUeCb          *ue,
16314  TfuDlCqiPucch      *pucchCqi
16315  )
16316 #else
16317 PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi)
16318  RgSchCellCb        *cell;
16319  RgSchUeCb          *ue;
16320  TfuDlCqiPucch      *pucchCqi;
16321 #endif
16322 #endif
16323 {
16324    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16325    TRC2(rgSCHCmnDlProcCqiMode21);
16326
16327    if (pucchCqi->u.mode21Info.type == TFU_RPT_CQI)
16328    {
16329       ue->mimoInfo.puschFdbkVld  = FALSE;
16330       if (pucchCqi->u.mode21Info.u.cqi.isWideband)
16331       {
16332          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16333          if((pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi) &&
16334                (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi < RG_SCH_CMN_MAX_CQI))
16335          {
16336             ueDl->cqiFlag = TRUE;
16337             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode21Info.u.cqi.\
16338                                            u.wideCqi.cqi;
16339             if (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.pres)
16340             {
16341                RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
16342                                      ueDl->mimoInfo.cwInfo[1].cqi, \
16343                                      pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.val);
16344 #ifdef RGR_CQI_REPT
16345                /* ccpu00117259 - ADD - Considering second codeword CQI info
16346                   incase of MIMO for CQI Reporting */
16347                *is2ndCwCqiAvail = TRUE;
16348 #endif
16349             }
16350             /* ccpu00117452 - MOD - Changed macro name from
16351                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16352 #ifdef RGR_CQI_REPT
16353             *isCqiAvail = TRUE;
16354 #endif
16355          }
16356          else
16357          {
16358             RETVOID;
16359          }
16360          rgSCHCmnDlSetUePmi(cell, ue, \
16361                pucchCqi->u.mode21Info.u.cqi.u.wideCqi.pmi);
16362       }
16363    }
16364    else if (pucchCqi->u.mode21Info.type == TFU_RPT_RI)
16365    {
16366       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode21Info.u.ri))
16367       {
16368          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode21Info.u.ri,
16369                            TRUE);
16370       }
16371       else
16372       {
16373          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Invalid RI value(%x) CRNTI:%d",
16374             pucchCqi->u.mode21Info.u.ri,ue->ueId);
16375          RETVOID;
16376       }
16377    }
16378 }
16379
16380
16381 /**
16382  * @brief This function Updates the DL CQI on PUCCH for the UE.
16383  *
16384  * @details
16385  *
16386  *     Function: rgSCHCmnDlCqiOnPucchInd
16387  *
16388  *     This function updates the DL CQI on PUCCH for the UE.
16389  *
16390  *     Invoked by: rgSCHCmnDlCqiInd
16391  *
16392  *     Processing Steps:
16393  *     - Depending on the reporting mode of the PUCCH, the CQI/PMI/RI values
16394  *       are updated and stored for each UE
16395  *
16396  *  @param[in] RgSchCellCb     *cell
16397  *  @param[in] RgSchUeCb       *ue
16398  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16399  *  @return  S16
16400  *      -# ROK
16401  *      -# RFAILED
16402  **/
16403 #ifdef RGR_CQI_REPT
16404 #ifdef ANSI
16405 PRIVATE Void rgSCHCmnDlCqiOnPucchInd
16406 (
16407  RgSchCellCb        *cell,
16408  RgSchUeCb          *ue,
16409  TfuDlCqiPucch      *pucchCqi,
16410  RgrUeCqiRept       *ueCqiRept,
16411  Bool               *isCqiAvail,
16412  Bool               *is2ndCwCqiAvail
16413  )
16414 #else
16415 PRIVATE Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail)
16416  RgSchCellCb        *cell;
16417  RgSchUeCb          *ue;
16418  TfuDlCqiPucch      *pucchCqi;
16419  RgrUeCqiRept       *ueCqiRept;
16420  Bool               *isCqiAvail;
16421  Bool               *is2ndCwCqiAvail;
16422 #endif
16423 #else
16424 #ifdef ANSI
16425 PRIVATE Void rgSCHCmnDlCqiOnPucchInd
16426 (
16427  RgSchCellCb        *cell,
16428  RgSchUeCb          *ue,
16429  TfuDlCqiPucch      *pucchCqi
16430  )
16431 #else
16432 PRIVATE Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi)
16433  RgSchCellCb        *cell;
16434  RgSchUeCb          *ue;
16435  TfuDlCqiPucch      *pucchCqi;
16436 #endif
16437 #endif
16438 {
16439    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16440    TRC2(rgSCHCmnDlCqiOnPucchInd);
16441
16442    /* ccpu00117452 - MOD - Changed
16443       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16444 #ifdef RGR_CQI_REPT
16445    /* Save CQI mode information in the report */
16446    ueCqiRept->cqiMode = pucchCqi->mode;
16447 #endif
16448
16449    switch(pucchCqi->mode)
16450    {
16451       case TFU_PUCCH_CQI_MODE10:
16452 #ifdef RGR_CQI_REPT
16453          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail);
16454 #else
16455          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi);
16456 #endif
16457          ueDl->cqiFlag = TRUE;
16458          break;
16459       case TFU_PUCCH_CQI_MODE11:
16460 #ifdef RGR_CQI_REPT
16461          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail,
16462                 is2ndCwCqiAvail);
16463 #else
16464          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi);
16465 #endif
16466          ueDl->cqiFlag = TRUE;
16467          break;
16468       case TFU_PUCCH_CQI_MODE20:
16469 #ifdef RGR_CQI_REPT
16470          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail);
16471 #else
16472          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi);
16473 #endif
16474          ueDl->cqiFlag = TRUE;
16475          break;
16476       case TFU_PUCCH_CQI_MODE21:
16477 #ifdef RGR_CQI_REPT
16478          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail,
16479                 is2ndCwCqiAvail);
16480 #else
16481          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi);
16482 #endif
16483          ueDl->cqiFlag = TRUE;
16484          break;
16485       default:
16486          {
16487             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unknown CQI Mode %d",
16488                pucchCqi->mode,ue->ueId);
16489             /* ccpu00117452 - MOD - Changed macro name from
16490                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16491 #ifdef RGR_CQI_REPT
16492             *isCqiAvail = FALSE;
16493 #endif
16494          }
16495          break;
16496    }
16497
16498   RETVOID;
16499 }  /* rgSCHCmnDlCqiOnPucchInd */
16500
16501
16502 /**
16503  * @brief This function Updates the DL CQI on PUSCH for the UE.
16504  *
16505  * @details
16506  *
16507  *     Function: rgSCHCmnDlCqiOnPuschInd
16508  *
16509  *     This function updates the DL CQI on PUSCH for the UE.
16510  *
16511  *     Invoked by: rgSCHCmnDlCqiInd
16512  *
16513  *     Processing Steps:
16514  *     - Depending on the reporting mode of the PUSCH, the CQI/PMI/RI values
16515  *       are updated and stored for each UE
16516  *
16517  *  @param[in] RgSchCellCb     *cell
16518  *  @param[in] RgSchUeCb       *ue
16519  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16520  *  @return  S16
16521  *      -# ROK
16522  *      -# RFAILED
16523  **/
16524 #ifdef RGR_CQI_REPT
16525 #ifdef ANSI
16526 PRIVATE Void rgSCHCmnDlCqiOnPuschInd
16527 (
16528  RgSchCellCb        *cell,
16529  RgSchUeCb          *ue,
16530  TfuDlCqiPusch      *puschCqi,
16531  RgrUeCqiRept       *ueCqiRept,
16532  Bool               *isCqiAvail,
16533  Bool               *is2ndCwCqiAvail
16534  )
16535 #else
16536 PRIVATE Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail)
16537  RgSchCellCb        *cell;
16538  RgSchUeCb          *ue;
16539  TfuDlCqiPusch      *puschCqi;
16540  RgrUeCqiRept       *ueCqiRept;
16541  Bool               *isCqiAvail;
16542  Bool               *is2ndCwCqiAvail;
16543 #endif
16544 #else
16545 #ifdef ANSI
16546 PRIVATE Void rgSCHCmnDlCqiOnPuschInd
16547 (
16548  RgSchCellCb        *cell,
16549  RgSchUeCb          *ue,
16550  TfuDlCqiPusch      *puschCqi
16551  )
16552 #else
16553 PRIVATE Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi)
16554    RgSchCellCb        *cell;
16555    RgSchUeCb          *ue;
16556    TfuDlCqiPusch      *puschCqi;
16557 #endif
16558 #endif
16559 {
16560    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16561    U32 prevRiVal = 0; 
16562    TRC2(rgSCHCmnDlCqiOnPuschInd);
16563    if (puschCqi->ri.pres == PRSNT_NODEF)
16564    {
16565       if (RG_SCH_CMN_IS_RI_VALID(puschCqi->ri.val))
16566       {
16567          /* Saving the previous ri value to revert back
16568             in  case PMI update failed */
16569          if (RGR_UE_TM_4 == ue->mimoInfo.txMode ) /* Cheking for TM4. TM8 check later */
16570          {
16571             prevRiVal = ueDl->mimoInfo.ri;
16572          }
16573          rgSCHCmnDlSetUeRi(cell, ue, puschCqi->ri.val, FALSE);
16574       }
16575       else
16576       {
16577          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
16578             puschCqi->ri.val,ue->ueId);
16579          RETVOID;
16580       }
16581    }
16582    ue->mimoInfo.puschFdbkVld  = FALSE;
16583    /* ccpu00117452 - MOD - Changed macro name from
16584       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16585 #ifdef RGR_CQI_REPT
16586    /* Save CQI mode information in the report */
16587    ueCqiRept->cqiMode = puschCqi->mode;
16588    /* ccpu00117259 - DEL - removed default setting of isCqiAvail to TRUE */
16589 #endif
16590
16591    switch(puschCqi->mode)
16592    {
16593       case TFU_PUSCH_CQI_MODE_20:
16594          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16595          /* Checking whether the decoded CQI is a value between 1 and 15*/
16596          if((puschCqi->u.mode20Info.wideBandCqi) &&
16597                (puschCqi->u.mode20Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
16598          {
16599             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode20Info.wideBandCqi;
16600             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16601             /* ccpu00117452 - MOD - Changed macro name from
16602                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16603 #ifdef RGR_CQI_REPT
16604            *isCqiAvail = TRUE;
16605 #endif
16606          }
16607          else
16608          {
16609             RETVOID;
16610          }
16611          break;
16612       case TFU_PUSCH_CQI_MODE_30:
16613          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16614          if((puschCqi->u.mode30Info.wideBandCqi) &&
16615                (puschCqi->u.mode30Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
16616          {
16617             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode30Info.wideBandCqi;
16618             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16619             /* ccpu00117452 - MOD - Changed macro name from
16620                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16621 #ifdef RGR_CQI_REPT
16622             *isCqiAvail = TRUE;
16623 #endif
16624 #ifdef CA_DBG
16625             {
16626                extern U32 gACqiRcvdCount;
16627                gACqiRcvdCount++;
16628             
16629             }
16630 #endif
16631          }
16632          else
16633          {
16634             RETVOID;
16635          }
16636          break;
16637       case TFU_PUSCH_CQI_MODE_12:
16638          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16639          if((puschCqi->u.mode12Info.cqiIdx[0]) &&
16640                (puschCqi->u.mode12Info.cqiIdx[0] < RG_SCH_CMN_MAX_CQI))
16641          {
16642             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode12Info.cqiIdx[0];
16643             /* ccpu00117452 - MOD - Changed macro name from
16644                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16645 #ifdef RGR_CQI_REPT
16646             *isCqiAvail = TRUE;
16647 #endif
16648          }
16649          else
16650          {
16651             RETVOID;
16652          }
16653          if((puschCqi->u.mode12Info.cqiIdx[1]) &&
16654                (puschCqi->u.mode12Info.cqiIdx[1] < RG_SCH_CMN_MAX_CQI))
16655          {
16656             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode12Info.cqiIdx[1];
16657             /* ccpu00117452 - MOD - Changed macro name from
16658                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16659 #ifdef RGR_CQI_REPT
16660             /* ccpu00117259 - ADD - Considering second codeword CQI info
16661                incase of MIMO for CQI Reporting */
16662             *is2ndCwCqiAvail = TRUE;
16663 #endif
16664          }
16665          else
16666          {
16667             RETVOID;
16668          }
16669          ue->mimoInfo.puschFdbkVld  = TRUE;
16670          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_12;
16671          ue->mimoInfo.puschPmiInfo.u.mode12Info = puschCqi->u.mode12Info;
16672          /*  : resetting this is time based. Make use of CQI reporting
16673           * periodicity, DELTA's in determining the exact time at which this
16674           * need to be reset. */
16675          break;
16676       case TFU_PUSCH_CQI_MODE_22:
16677          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16678          if((puschCqi->u.mode22Info.wideBandCqi[0]) &&
16679                (puschCqi->u.mode22Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
16680          {
16681             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode22Info.wideBandCqi[0];
16682             /* ccpu00117452 - MOD - Changed macro name from
16683                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16684 #ifdef RGR_CQI_REPT
16685             *isCqiAvail = TRUE;
16686 #endif
16687          }
16688          else
16689          {
16690             RETVOID;
16691          }
16692          if((puschCqi->u.mode22Info.wideBandCqi[1]) &&
16693                (puschCqi->u.mode22Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
16694          {
16695             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode22Info.wideBandCqi[1];
16696             /* ccpu00117452 - MOD - Changed macro name from
16697                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16698 #ifdef RGR_CQI_REPT
16699             /* ccpu00117259 - ADD - Considering second codeword CQI info
16700                incase of MIMO for CQI Reporting */
16701             *is2ndCwCqiAvail = TRUE;
16702 #endif
16703          }
16704          else
16705          {
16706             RETVOID;
16707          }
16708          rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode22Info.wideBandPmi);
16709          ue->mimoInfo.puschFdbkVld  = TRUE;
16710          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_22;
16711          ue->mimoInfo.puschPmiInfo.u.mode22Info = puschCqi->u.mode22Info;
16712          break;
16713       case TFU_PUSCH_CQI_MODE_31:
16714          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16715          if((puschCqi->u.mode31Info.wideBandCqi[0]) &&
16716                (puschCqi->u.mode31Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
16717          {
16718             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode31Info.wideBandCqi[0];
16719             /* ccpu00117452 - MOD - Changed macro name from
16720                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16721 #ifdef RGR_CQI_REPT
16722             *isCqiAvail = TRUE;
16723 #endif
16724          }
16725          if (ueDl->mimoInfo.ri > 1)
16726          {
16727            if((puschCqi->u.mode31Info.wideBandCqi[1]) &&
16728                (puschCqi->u.mode31Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
16729            {
16730              ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode31Info.wideBandCqi[1];
16731             /* ccpu00117452 - MOD - Changed macro name from
16732                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16733 #ifdef RGR_CQI_REPT
16734             /* ccpu00117259 - ADD - Considering second codeword CQI info
16735                incase of MIMO for CQI Reporting */
16736              *is2ndCwCqiAvail = TRUE;
16737 #endif
16738            }
16739          }
16740          if (rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode31Info.pmi) != ROK)
16741          {
16742             /* To avoid Rank and PMI inconsistency */
16743             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
16744                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
16745             {
16746                ueDl->mimoInfo.ri = prevRiVal;
16747             }
16748          }
16749          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_31;
16750          ue->mimoInfo.puschPmiInfo.u.mode31Info = puschCqi->u.mode31Info;
16751          break;
16752       default:
16753          {
16754             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Unknown CQI Mode %d CRNTI:%d",
16755                puschCqi->mode,ue->ueId);
16756             /*  CQI decoding failed revert the RI to previous value */
16757             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
16758                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
16759             {
16760                ueDl->mimoInfo.ri = prevRiVal;
16761             }
16762             /* ccpu00117452 - MOD - Changed macro name from
16763                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16764 #ifdef RGR_CQI_REPT
16765            *isCqiAvail = FALSE;
16766             /* ccpu00117259 - ADD - Considering second codeword CQI info
16767                incase of MIMO for CQI Reporting */
16768             *is2ndCwCqiAvail = FALSE;
16769 #endif
16770          }
16771          break;
16772    }
16773
16774    RETVOID;
16775 }  /* rgSCHCmnDlCqiOnPuschInd */
16776
16777 \f
16778 /**
16779  * @brief This function Updates the DL CQI for the UE.
16780  *
16781  * @details
16782  *
16783  *     Function: rgSCHCmnDlCqiInd
16784  *     Purpose:  Updates the DL CQI for the UE
16785  *
16786  *     Invoked by: TOM
16787  *
16788  *  @param[in]  RgSchCellCb        *cell
16789  *  @param[in]  RgSchUeCb          *ue
16790  *  @param[in]  TfuDlCqiRpt        *dlCqi
16791  *  @return  Void
16792  *
16793  **/
16794 #ifdef ANSI
16795 PUBLIC Void rgSCHCmnDlCqiInd
16796 (
16797 RgSchCellCb        *cell,
16798 RgSchUeCb          *ue,
16799 Bool               isPucchInfo,
16800 Void               *dlCqi,
16801 CmLteTimingInfo    timingInfo
16802 )
16803 #else
16804 PUBLIC Void rgSCHCmnDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo)
16805 RgSchCellCb        *cell;
16806 RgSchUeCb          *ue;
16807 Bool               isPucchInfo;
16808 Void               *dlCqi;
16809 CmLteTimingInfo    timingInfo;
16810 #endif
16811 {
16812    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
16813 /* ccpu00117452 - MOD - Changed macro name from
16814    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16815 #ifdef RGR_CQI_REPT
16816    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16817    RgrUeCqiRept   ueCqiRept = {{0}};
16818    Bool           isCqiAvail = FALSE;
16819    /* ccpu00117259 - ADD - Considering second codeword CQI info
16820       incase of MIMO for CQI Reporting */
16821    Bool           is2ndCwCqiAvail = FALSE;
16822 #endif
16823
16824    TRC2(rgSCHCmnDlCqiInd);
16825
16826 #ifdef RGR_CQI_REPT
16827    if (isPucchInfo)
16828    {
16829       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail);
16830    }
16831    else
16832    {
16833       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi, &ueCqiRept,  &isCqiAvail, &is2ndCwCqiAvail);
16834    }
16835 #else
16836    if (isPucchInfo)
16837    {
16838       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi);
16839    }
16840    else
16841    {
16842       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi);
16843    }
16844 #endif
16845
16846 #ifdef CQI_CONFBITMASK_DROP
16847    if(!ue->cqiConfBitMask)
16848    {
16849       if (ueDl->mimoInfo.cwInfo[0].cqi >15)
16850       {
16851          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
16852          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
16853       }
16854       else if ( ueDl->mimoInfo.cwInfo[0].cqi >= ue->prevCqi)
16855       {
16856          ue->prevCqi = ueDl->mimoInfo.cwInfo[0].cqi;
16857       }
16858       else
16859       {
16860          U8 dlCqiDeltaPrev = 0;
16861          dlCqiDeltaPrev = ue->prevCqi - ueDl->mimoInfo.cwInfo[0].cqi;
16862          if (dlCqiDeltaPrev > 3)
16863             dlCqiDeltaPrev = 3;
16864          if ((ue->prevCqi - dlCqiDeltaPrev) < 6)
16865          {
16866             ue->prevCqi = 6;
16867          }
16868          else 
16869          {
16870             ue->prevCqi = ue->prevCqi - dlCqiDeltaPrev;
16871          }
16872          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
16873          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
16874
16875       }
16876    }
16877 #endif
16878
16879 /* ccpu00117452 - MOD - Changed macro name from
16880    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16881 #ifdef RGR_CQI_REPT
16882    /* ccpu00117259 - ADD - Considering second codeword CQI info
16883       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail\
16884       in 'if' condition*/
16885    if (RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(ue) && (isCqiAvail || is2ndCwCqiAvail))
16886    {
16887       ueCqiRept.cqi[0] = ueDl->mimoInfo.cwInfo[0].cqi;
16888
16889    /* ccpu00117259 - ADD - Considering second codeword CQI info
16890       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail
16891       in 'if' condition*/
16892       ueCqiRept.cqi[1] = 0;
16893       if(is2ndCwCqiAvail)
16894       {
16895          ueCqiRept.cqi[1] = ueDl->mimoInfo.cwInfo[1].cqi;
16896       }
16897       rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, &ueCqiRept);
16898
16899    }
16900 #endif
16901 #ifdef DL_LA
16902    rgSCHCmnDlSetUeAllocLmtLa(cell, ue);
16903    rgSCHCheckAndSetTxScheme(cell, ue);
16904 #else
16905 #ifdef EMTC_ENABLE   
16906    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), ue->isEmtcUe);
16907 #else 
16908    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), FALSE);
16909 #endif   
16910 #endif
16911
16912    if (cellSch->dl.isDlFreqSel)
16913    {
16914       cellSch->apisDlfs->rgSCHDlfsDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo);
16915    }
16916 #ifdef LTEMAC_SPS
16917    /* Call SPS module to update CQI indication */
16918    rgSCHCmnSpsDlCqiIndHndlr(cell, ue, timingInfo);
16919 #endif
16920    /* Call Specific scheduler to process on dlCqiInd */
16921 #ifdef EMTC_ENABLE
16922    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
16923    {
16924       cellSch->apisEmtcDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
16925    }
16926    else
16927 #endif
16928    {
16929       cellSch->apisDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
16930    }
16931
16932 #ifdef RG_PFS_STATS
16933    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].avgCqi += 
16934       ueDl->mimoInfo.cwInfo[0].cqi;
16935    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].totalCqiOcc++; 
16936 #endif
16937
16938 #ifdef SCH_STATS
16939    ueDl->avgCqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16940    ueDl->numCqiOccns++;
16941    if (ueDl->mimoInfo.ri == 1)
16942    {
16943       ueDl->numRi1++;
16944    }
16945    else
16946    {
16947       ueDl->numRi2++;
16948    }
16949 #endif
16950
16951 #ifdef TENB_STATS
16952    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16953    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
16954    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw0Cqi ++;
16955    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw1Cqi ++;
16956    cell->tenbStats->sch.dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16957    cell->tenbStats->sch.dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
16958    cell->tenbStats->sch.dlNumCw0Cqi ++;
16959    cell->tenbStats->sch.dlNumCw1Cqi ++;
16960 #endif
16961    RETVOID;
16962 }
16963
16964 #ifdef TFU_UPGRADE
16965 /**
16966  * @brief This function calculates the wideband CQI from SNR
16967  *            reported for each RB.
16968  *
16969  * @details
16970  *
16971  *     Function: rgSCHCmnCalcWcqiFrmSnr
16972  *     Purpose:  Wideband CQI calculation from SNR
16973  *
16974  *     Invoked by: RG SCH
16975  *
16976  *  @param[in]  RgSchCellCb        *cell
16977  *  @param[in]  TfuSrsRpt        *srsRpt,
16978  *  @return  Wideband CQI
16979  *
16980  **/
16981 #ifdef ANSI
16982 PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr
16983 (
16984  RgSchCellCb        *cell,
16985  TfuSrsRpt        *srsRpt
16986  )
16987 #else
16988 PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr(cell,srsRpt)
16989    RgSchCellCb        *cell;
16990    TfuSrsRpt            *srsRpt;
16991 #endif
16992 {
16993    U8 wideCqi=1; /*Calculated value from SNR*/
16994    TRC2(rgSCHCmnCalcWcqiFrmSnr);
16995    /*Need to map a certain SNR with a WideCQI value.
16996     * The CQI calculation is still primitive. Further, need to
16997     * use a improvized method for calculating WideCQI from SNR*/
16998        if (srsRpt->snr[0] <=50)
16999        {
17000            wideCqi=3;
17001        }
17002        else if (srsRpt->snr[0]>=51 && srsRpt->snr[0] <=100)
17003        {
17004            wideCqi=6;
17005        }
17006        else if (srsRpt->snr[0]>=101 && srsRpt->snr[0] <=150)
17007        {
17008            wideCqi=9;
17009        }
17010        else if (srsRpt->snr[0]>=151 && srsRpt->snr[0] <=200)
17011        {
17012            wideCqi=12;
17013        }
17014        else if (srsRpt->snr[0]>=201 && srsRpt->snr[0] <=250)
17015        {
17016            wideCqi=14;
17017        }
17018        else
17019        {
17020            wideCqi=15;
17021        }
17022    RETVALUE(wideCqi);
17023 }/*rgSCHCmnCalcWcqiFrmSnr*/
17024
17025
17026 /**
17027  * @brief This function Updates the SRS for the UE.
17028  *
17029  * @details
17030  *
17031  *     Function: rgSCHCmnSrsInd
17032  *     Purpose:  Updates the UL SRS for the UE
17033  *
17034  *     Invoked by: TOM
17035  *
17036  *  @param[in]  RgSchCellCb        *cell
17037  *  @param[in]  RgSchUeCb          *ue
17038  *  @param[in]  TfuSrsRpt        *srsRpt,
17039  *  @return  Void
17040  *
17041  **/
17042 #ifdef ANSI
17043 PUBLIC Void rgSCHCmnSrsInd
17044 (
17045  RgSchCellCb        *cell,
17046  RgSchUeCb          *ue,
17047  TfuSrsRpt        *srsRpt,
17048  CmLteTimingInfo    timingInfo
17049  )
17050 #else
17051 PUBLIC Void rgSCHCmnSrsInd(cell, ue, srsRpt, timingInfo)
17052     RgSchCellCb        *cell;
17053     RgSchUeCb          *ue;
17054     TfuSrsRpt            *srsRpt;
17055     CmLteTimingInfo    timingInfo;
17056 #endif
17057 {
17058     U8 wideCqi; /*Calculated value from SNR*/
17059     U32 recReqTime; /*Received Time in TTI*/
17060     TRC2(rgSCHCmnSrsInd);
17061
17062     recReqTime = (timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + timingInfo.subframe;
17063     ue->srsCb.selectedAnt = (recReqTime/ue->srsCb.peri)%2;
17064     if(srsRpt->wideCqiPres)
17065     {
17066         wideCqi = srsRpt->wideCqi;
17067     }
17068     else
17069     {
17070         wideCqi = rgSCHCmnCalcWcqiFrmSnr(cell, srsRpt);
17071     }
17072     rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi);
17073     RETVOID;
17074 }/*rgSCHCmnSrsInd*/
17075 #endif
17076
17077 \f
17078 /**
17079  * @brief This function is a handler for TA report for an UE.
17080  *
17081  * @details
17082  *
17083  *     Function: rgSCHCmnDlTARpt
17084  *     Purpose:  Determine based on UE_IDLE_TIME threshold,
17085  *     whether UE needs to be Linked to the scheduler's TA list OR
17086  *     if it needs a PDCCH Order.
17087  *
17088  *
17089  *     Invoked by: TOM
17090  *
17091  *  @param[in]  RgSchCellCb        *cell
17092  *  @param[in]  RgSchUeCb          *ue
17093  *  @return  Void
17094  *
17095  **/
17096 #ifdef ANSI
17097 PUBLIC Void rgSCHCmnDlTARpt
17098 (
17099 RgSchCellCb        *cell,
17100 RgSchUeCb          *ue
17101 )
17102 #else
17103 PUBLIC Void rgSCHCmnDlTARpt(cell, ue)
17104 RgSchCellCb        *cell;
17105 RgSchUeCb          *ue;
17106 #endif
17107 {
17108    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
17109    RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
17110    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
17111    CmLListCp       poInactvLst;
17112
17113    TRC2(rgSCHCmnDlTARpt);
17114
17115    /* RACHO: If UE idle time is more than threshold, then
17116     * set its poInactv pdcch order inactivity  */
17117    /* Fix : syed Ignore if TaTmr is not configured */
17118    if ((ue->dl.taCb.cfgTaTmr) && (rgSCHCmnUeIdleExdThrsld(cell, ue) == ROK))
17119    {
17120       U32 prevDlMsk = ue->dl.dlInactvMask;
17121       U32 prevUlMsk = ue->ul.ulInactvMask;
17122       ue->dl.dlInactvMask |= RG_PDCCHODR_INACTIVE;
17123       ue->ul.ulInactvMask |= RG_PDCCHODR_INACTIVE;
17124       /* Indicate Specific scheduler for this UEs inactivity */
17125       cmLListInit(&poInactvLst);
17126       cmLListAdd2Tail(&poInactvLst, &ueDl->rachInfo.inActUeLnk);
17127       ueDl->rachInfo.inActUeLnk.node = (PTR)ue;
17128       /* Send inactivate ind only if not already sent */
17129       if (prevDlMsk == 0)
17130       {
17131          cellSch->apisDl->rgSCHDlInactvtUes(cell, &poInactvLst);
17132       }
17133       if (prevUlMsk == 0)
17134       {
17135          cellSch->apisUl->rgSCHUlInactvtUes(cell, &poInactvLst);
17136       }
17137    }
17138    else
17139    {
17140       /* Fix: ccpu00124009 Fix for loop in the linked list "cellDl->taLst" */
17141       if (!ue->dlTaLnk.node)
17142       {
17143 #ifdef EMTC_ENABLE
17144          if(cell->emtcEnable)
17145          {
17146             if(ue->isEmtcUe)
17147             {
17148                rgSCHEmtcAddToTaLst(cellDl,ue);
17149             }
17150          }
17151          else
17152 #endif
17153          {
17154
17155             cmLListAdd2Tail(&cellDl->taLst, &ue->dlTaLnk);
17156             ue->dlTaLnk.node = (PTR)ue;
17157          }
17158       }
17159       else
17160       {
17161          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
17162                "<TA>TA duplicate entry attempt failed: UEID:%u", 
17163                ue->ueId);
17164       }
17165    }
17166    RETVOID;
17167 }
17168
17169 #ifdef TFU_UPGRADE
17170 /**
17171  * @brief Indication of UL CQI.
17172  *
17173  * @details
17174  *
17175  *     Function : rgSCHCmnFindUlCqiUlTxAnt
17176  *
17177  *     - Finds the Best Tx Antenna amongst the CQIs received
17178  *         from Two Tx Antennas.
17179  *
17180  *  @param[in]  RgSchCellCb         *cell
17181  *  @param[in]  RgSchUeCb           *ue
17182  *  @param[in]   U8                 wideCqi
17183  *  @return  Void
17184  **/
17185 #ifdef ANSI
17186 PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt
17187 (
17188 RgSchCellCb     *cell,
17189 RgSchUeCb       *ue,
17190 U8              wideCqi
17191 )
17192 #else
17193 PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi)
17194 RgSchCellCb     *cell;
17195 RgSchUeCb       *ue;
17196 U8              wideCqi;
17197 #endif
17198 {
17199    ue->validTxAnt = 1;
17200    RETVOID;
17201 }  /* rgSCHCmnFindUlCqiUlTxAnt */
17202 #endif
17203
17204 /**
17205  * @brief Indication of UL CQI.
17206  *
17207  * @details
17208  *
17209  *     Function : rgSCHCmnUlCqiInd
17210  *
17211  *     - Updates uplink CQI information for the UE. Computes and
17212  *       stores the lowest CQI of CQIs reported in all subbands.
17213  *
17214  *  @param[in]  RgSchCellCb         *cell
17215  *  @param[in]  RgSchUeCb           *ue
17216  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
17217  *  @return  Void
17218  **/
17219 #ifdef ANSI
17220 PUBLIC Void rgSCHCmnUlCqiInd
17221 (
17222 RgSchCellCb          *cell,
17223 RgSchUeCb            *ue,
17224 TfuUlCqiRpt          *ulCqiInfo
17225 )
17226 #else
17227 PUBLIC Void rgSCHCmnUlCqiInd(cell, ue, ulCqiInfo)
17228 RgSchCellCb          *cell;
17229 RgSchUeCb            *ue;
17230 TfuUlCqiRpt          *ulCqiInfo;
17231 #endif
17232 {
17233    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17234    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
17235 #ifdef UL_LA
17236    U8            iTbsNew;
17237    S32           previTbs;
17238 #endif
17239 #if (defined(SCH_STATS) || defined(TENB_STATS))
17240      CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
17241 #endif   
17242                   
17243    TRC2(rgSCHCmnUlCqiInd);
17244    /*  consider inputs from SRS handlers about SRS occassions
17245     * in determining the UL TX Antenna selection */
17246    ueUl->crntUlCqi[0] = ulCqiInfo->wideCqi;
17247 #ifdef TFU_UPGRADE
17248    ueUl->validUlCqi = ueUl->crntUlCqi[0];
17249    ue->validTxAnt = 0;
17250 #ifdef UL_LA
17251    iTbsNew  =  rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][ueUl->validUlCqi];
17252    previTbs =  (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
17253
17254    if (RG_ITBS_DIFF(iTbsNew, previTbs) > 5)
17255    {
17256       /* Ignore this iTBS report and mark that last iTBS report was */
17257       /* ignored so that subsequently we reset the LA algorithm     */
17258       ueUl->ulLaCb.lastiTbsIgnored = TRUE;
17259    }
17260    else
17261    {
17262       if (ueUl->ulLaCb.lastiTbsIgnored != TRUE)
17263       {
17264          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
17265                                        (80 * ueUl->ulLaCb.cqiBasediTbs))/100;
17266       }
17267       else
17268       {
17269          /* Reset the LA as iTbs in use caught up with the value   */
17270          /* reported by UE.                                        */
17271          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
17272                                         (80 * previTbs * 100))/100;
17273          ueUl->ulLaCb.deltaiTbs = 0;
17274          ueUl->ulLaCb.lastiTbsIgnored = FALSE;
17275       }
17276    }
17277 #endif 
17278 #endif
17279    rgSCHPwrUlCqiInd(cell, ue);
17280 #ifdef LTEMAC_SPS
17281    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
17282    {
17283       rgSCHCmnSpsUlCqiInd(cell, ue);
17284    }
17285 #endif
17286    /* Applicable to only some schedulers */
17287 #ifdef EMTC_ENABLE
17288    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
17289    {
17290       cellSch->apisEmtcUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
17291    }
17292    else
17293 #endif
17294    {
17295       cellSch->apisUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
17296    }
17297
17298 #ifdef SCH_STATS
17299    ueUl->numCqiOccns++;
17300    ueUl->avgCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17301 #endif
17302
17303 #ifdef TENB_STATS
17304    {
17305       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17306       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNumCqi ++;
17307       cell->tenbStats->sch.ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17308       cell->tenbStats->sch.ulNumCqi ++;
17309    }
17310 #endif
17311
17312    RETVOID;
17313 }  /* rgSCHCmnUlCqiInd */
17314
17315 /**
17316  * @brief Returns HARQ proc for which data expected now.
17317  *
17318  * @details
17319  *
17320  *     Function: rgSCHCmnUlHqProcForUe
17321  *     Purpose:  This function returns the harq process for
17322  *               which data is expected in the current subframe.
17323  *               It does not validate that the HARQ process
17324  *               has an allocation.
17325  *
17326  *     Invoked by: TOM
17327  *
17328  *  @param[in]  RgSchCellCb        *cell
17329  *  @param[in]  CmLteTimingInfo    frm
17330  *  @param[in]  RgSchUeCb          *ue
17331  *  @param[out] RgSchUlHqProcCb    **procRef
17332  *  @return  Void
17333  **/
17334 #ifdef ANSI
17335 PUBLIC Void rgSCHCmnUlHqProcForUe
17336 (
17337 RgSchCellCb         *cell,
17338 CmLteTimingInfo     frm,
17339 RgSchUeCb           *ue,
17340 RgSchUlHqProcCb     **procRef
17341 )
17342 #else
17343 PUBLIC Void rgSCHCmnUlHqProcForUe(cell, frm, ue, procRef)
17344 RgSchCellCb         *cell;
17345 CmLteTimingInfo     frm;
17346 RgSchUeCb           *ue;
17347 RgSchUlHqProcCb     **procRef;
17348 #endif
17349 {
17350 #ifndef RG_5GTF
17351    U8 procId = rgSCHCmnGetUlHqProcIdx(&frm, cell);
17352 #endif
17353    TRC2(rgSCHCmnUlHqProcForUe);
17354 #ifndef RG_5GTF
17355    *procRef = rgSCHUhmGetUlHqProc(cell, ue, procId);
17356 #else
17357    *procRef = rgSCHUhmGetUlProcByTime(cell, ue, frm);
17358 #endif
17359    RETVOID;
17360 }
17361
17362 #ifdef RG_UNUSED
17363 /**
17364  * @brief Update harq process for allocation.
17365  *
17366  * @details
17367  *
17368  *     Function : rgSCHCmnUpdUlHqProc
17369  *
17370  *     This function is invoked when harq process
17371  *     control block is now in a new memory location
17372  *     thus requiring a pointer/reference update.
17373  *
17374  *  @param[in] RgSchCellCb      *cell
17375  *  @param[in] RgSchUlHqProcCb  *curProc
17376  *  @param[in] RgSchUlHqProcCb  *oldProc
17377  *  @return  S16
17378  *      -# ROK
17379  *      -# RFAILED
17380  **/
17381 #ifdef ANSI
17382 PUBLIC S16 rgSCHCmnUpdUlHqProc
17383 (
17384 RgSchCellCb      *cell,
17385 RgSchUlHqProcCb  *curProc,
17386 RgSchUlHqProcCb  *oldProc
17387 )
17388 #else
17389 PUBLIC S16 rgSCHCmnUpdUlHqProc(cell, curProc, oldProc)
17390 RgSchCellCb      *cell;
17391 RgSchUlHqProcCb  *curProc;
17392 RgSchUlHqProcCb  *oldProc;
17393 #endif
17394 {
17395    TRC2(rgSCHCmnUpdUlHqProc);
17396
17397    UNUSED(cell);
17398    UNUSED(oldProc);
17399 #if (ERRCLASS & ERRCLS_DEBUG)
17400    if (curProc->alloc == NULLP)
17401    {
17402       RETVALUE(RFAILED);
17403    }
17404 #endif
17405    curProc->alloc->hqProc = curProc;
17406    RETVALUE(ROK);
17407 }  /* rgSCHCmnUpdUlHqProc */
17408 #endif
17409
17410 /*MS_WORKAROUND for CR FIXME */
17411 /**
17412  * @brief Hsndles BSR timer expiry
17413  *
17414  * @details
17415  *
17416  *     Function : rgSCHCmnBsrTmrExpry
17417  *
17418  *     This function is invoked when periodic BSR timer expires for a UE.
17419  *
17420  *  @param[in] RgSchUeCb        *ue
17421  *  @return  S16
17422  *      -# ROK
17423  *      -# RFAILED
17424  **/
17425 #ifdef ANSI
17426 PUBLIC S16 rgSCHCmnBsrTmrExpry
17427 (
17428 RgSchUeCb  *ueCb
17429 )
17430 #else
17431 PUBLIC S16 rgSCHCmnBsrTmrExpry(ueCb)
17432 RgSchUeCb  *ueCb;
17433 #endif
17434 {
17435    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ueCb->cell);
17436
17437    TRC2(rgSCHCmnBsrTmrExpry)
17438
17439    ueCb->isSrGrant = TRUE;
17440
17441 #ifdef EMTC_ENABLE
17442    emtcStatsUlBsrTmrTxp++;
17443 #endif
17444
17445 #ifdef EMTC_ENABLE
17446    if(ueCb->cell->emtcEnable)
17447    {
17448       if(ueCb->isEmtcUe)
17449       {
17450          cellSch->apisEmtcUl->rgSCHSrRcvd(ueCb->cell, ueCb);
17451          RETVALUE(ROK);
17452       }
17453    }
17454    else
17455 #endif
17456    {
17457       cellSch->apisUl->rgSCHSrRcvd(ueCb->cell, ueCb);
17458    }
17459
17460    RETVALUE (ROK);
17461 }
17462
17463 /**
17464  * @brief Short BSR update.
17465  *
17466  * @details
17467  *
17468  *     Function : rgSCHCmnUpdBsrShort
17469  *
17470  *     This functions does requisite updates to handle short BSR reporting.
17471  *
17472  *  @param[in]  RgSchCellCb  *cell
17473  *  @param[in]  RgSchUeCb    *ue
17474  *  @param[in]  RgSchLcgCb *ulLcg
17475  *  @param[in]  U8           bsr
17476  *  @param[out] RgSchErrInfo *err
17477  *  @return  S16
17478  *      -# ROK
17479  *      -# RFAILED
17480  **/
17481 #ifdef ANSI
17482 PUBLIC S16 rgSCHCmnUpdBsrShort
17483 (
17484 RgSchCellCb  *cell,
17485 RgSchUeCb    *ue,
17486 RgSchLcgCb *ulLcg,
17487 U8           bsr,
17488 RgSchErrInfo *err
17489 )
17490 #else
17491 PUBLIC S16 rgSCHCmnUpdBsrShort(cell, ue, ulLcg, bsr, err)
17492 RgSchCellCb  *cell;
17493 RgSchUeCb    *ue;
17494 RgSchLcgCb *ulLcg;
17495 U8           bsr;
17496 RgSchErrInfo *err;
17497 #endif
17498 {
17499    U8  lcgCnt;
17500 #ifdef LTE_L2_MEAS
17501    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17502 #endif
17503    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17504    RgSchCmnLcg  *cmnLcg  = NULLP;
17505
17506 #ifdef LTE_L2_MEAS
17507    U8             idx;
17508 #endif
17509    TRC2(rgSCHCmnUpdBsrShort);
17510
17511    if (!RGSCH_LCG_ISCFGD(ulLcg))
17512    {
17513       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
17514       RETVALUE(RFAILED);
17515    }
17516    for (lcgCnt=0; lcgCnt<4; lcgCnt++)
17517    {
17518 #ifdef LTE_L2_MEAS
17519       /* Set BS of all other LCGs to Zero.
17520          If Zero BSR is reported in Short BSR include this LCG too */
17521       if ((lcgCnt != ulLcg->lcgId) ||
17522             (!bsr && !ueUl->hqEnt.numBusyHqProcs))
17523       {
17524          /* If old BO is zero do nothing */
17525          if(((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs != 0)
17526          {
17527             for(idx = 0; idx < ue->ul.lcgArr[lcgCnt].numLch; idx++)
17528             {
17529                if((ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount) &&
17530                  (ue->ulActiveLCs & (1 << 
17531                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1))))
17532                {
17533           /* L2_COUNTER */
17534                  ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount--;
17535                  ue->ulActiveLCs &= ~(1 << 
17536                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1));
17537                }
17538             }
17539          }
17540       }
17541 #endif
17542       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgCnt]))
17543       {
17544          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs = 0;
17545          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->reportedBs = 0;
17546       }
17547    }
17548
17549 #ifdef LTE_L2_MEAS
17550    if(ulLcg->lcgId && bsr && (((RgSchCmnLcg *)(ulLcg->sch))->bs == 0))
17551    {
17552       for(idx = 0; idx < ulLcg->numLch; idx++)
17553       {
17554           /* L2_COUNTER */
17555           if (!(ue->ulActiveLCs & (1 << (ulLcg->lcArray[idx]->qciCb->qci -1))))
17556           {
17557              ulLcg->lcArray[idx]->qciCb->ulUeCount++;
17558              ue->ulActiveLCs |= (1 << (ulLcg->lcArray[idx]->qciCb->qci -1));
17559           }
17560       }
17561    }
17562 #endif
17563    /* Resetting the nonGbrLcgBs info here */
17564    ue->ul.nonGbrLcgBs = 0;
17565    ue->ul.nonLcg0Bs = 0;
17566
17567    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
17568    
17569    if (TRUE == ue->ul.useExtBSRSizes)
17570    {
17571       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
17572    }
17573    else
17574    {
17575       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
17576    }
17577    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17578    {
17579       /* TBD check for effGbr != 0 */    
17580       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17581    }
17582    else if (0 == ulLcg->lcgId) 
17583    {
17584       /* This is added for handling LCG0 */
17585       cmnLcg->bs = cmnLcg->reportedBs;
17586    }
17587    else 
17588    {
17589       /* Update non GBR LCG's BS*/
17590       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
17591       cmnLcg->bs     = ue->ul.nonGbrLcgBs;
17592    }
17593    ue->ul.totalBsr = cmnLcg->bs;
17594
17595 #ifdef RGR_V1
17596    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (bsr == 0))
17597    {
17598       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
17599    }
17600 #endif
17601 #ifdef LTEMAC_SPS
17602    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
17603    {
17604       rgSCHCmnSpsBsrRpt(cell, ue, ulLcg);
17605    }
17606 #endif
17607    rgSCHCmnUpdUlCompEffBsr(ue);
17608
17609 #ifdef EMTC_ENABLE
17610    if(cell->emtcEnable)
17611    {
17612       if(ue->isEmtcUe)
17613       {
17614          cellSch->apisEmtcUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
17615          RETVALUE(ROK);
17616       }
17617    }
17618    else
17619 #endif
17620    {
17621    cellSch->apisUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
17622    }
17623
17624 #ifdef LTE_ADV
17625    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17626    {
17627       for(U8 sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
17628       {
17629 #ifndef PAL_ENABLE_UL_CA
17630          if((ue->cellInfo[sCellIdx] != NULLP) &&
17631                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
17632 #else
17633          if(ue->cellInfo[sCellIdx] != NULLP)
17634 #endif
17635          {
17636             cellSch->apisUl->rgSCHUpdBsrShort(ue->cellInfo[sCellIdx]->cell, 
17637                   ue, ulLcg, bsr);
17638          }
17639       }
17640    }
17641 #endif 
17642
17643    RETVALUE(ROK);
17644 }
17645
17646 /**
17647  * @brief Truncated BSR update.
17648  *
17649  * @details
17650  *
17651  *     Function : rgSCHCmnUpdBsrTrunc
17652  *
17653  *     This functions does required updates to handle truncated BSR report.
17654  *
17655  *
17656  *  @param[in]  RgSchCellCb  *cell
17657  *  @param[in]  RgSchUeCb    *ue
17658  *  @param[in]  RgSchLcgCb *ulLcg
17659  *  @param[in]  U8           bsr
17660  *  @param[out] RgSchErrInfo *err
17661  *  @return  S16
17662  *      -# ROK
17663  *      -# RFAILED
17664  **/
17665 #ifdef ANSI
17666 PUBLIC S16 rgSCHCmnUpdBsrTrunc
17667 (
17668 RgSchCellCb  *cell,
17669 RgSchUeCb    *ue,
17670 RgSchLcgCb *ulLcg,
17671 U8           bsr,
17672 RgSchErrInfo *err
17673 )
17674 #else
17675 PUBLIC S16 rgSCHCmnUpdBsrTrunc(cell, ue, ulLcg, bsr, err)
17676 RgSchCellCb  *cell;
17677 RgSchUeCb    *ue;
17678 RgSchLcgCb *ulLcg;
17679 U8           bsr;
17680 RgSchErrInfo *err;
17681 #endif
17682 {
17683    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17684    RgSchCmnLcg  *cmnLcg = NULLP;
17685    S32          cnt;
17686 #ifdef LTE_L2_MEAS
17687    U8     idx;
17688 #endif
17689
17690    TRC2(rgSCHCmnUpdBsrTrunc);
17691
17692    if (!RGSCH_LCG_ISCFGD(ulLcg))
17693    {
17694       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
17695       RETVALUE(RFAILED);
17696    }
17697    /* set all higher prio lcgs bs to 0 and update this lcgs bs and
17698       total bsr= sumofall lcgs bs */
17699    if (ulLcg->lcgId)
17700    {
17701       for (cnt = ulLcg->lcgId-1; cnt >= 0; cnt--)
17702       {
17703 #ifdef LTE_L2_MEAS
17704          /* If Existing BO is zero the don't do anything */
17705          if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs != 0)
17706          {
17707             for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
17708             {
17709                /* L2_COUNTERS */
17710                if((ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount) &&
17711                      (ue->ulActiveLCs & (1 << 
17712                                          (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
17713                {
17714                   ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount--;
17715                   ue->ulActiveLCs &= ~(1 << 
17716                         (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
17717                }
17718             }
17719          }
17720 #endif
17721          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs = 0;
17722          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->reportedBs = 0;
17723       }
17724    }
17725
17726 #ifdef LTE_L2_MEAS
17727    for (cnt = ulLcg->lcgId; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
17728    {
17729       if (ulLcg->lcgId == 0)
17730       {
17731          continue;
17732       }
17733       /* If Existing BO is zero the don't do anything */
17734       if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs == 0)
17735       {
17736          for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
17737          {
17738             /* L2_COUNTERS */
17739             if (!(ue->ulActiveLCs & (1 << 
17740                (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
17741             {
17742                ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount++;
17743                ue->ulActiveLCs |= (1 << 
17744                      (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
17745             }
17746          }
17747       }
17748    }
17749 #endif
17750    ue->ul.nonGbrLcgBs = 0;
17751    ue->ul.nonLcg0Bs = 0;
17752    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
17753    if (TRUE == ue->ul.useExtBSRSizes)
17754    {
17755       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
17756    }
17757    else
17758    {
17759       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
17760    }
17761    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17762    {
17763       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17764    }
17765    else if(ulLcg->lcgId == 0)
17766    {
17767       /* This is for handeling LCG0 */
17768       cmnLcg->bs = cmnLcg->reportedBs;
17769    }
17770    else
17771    {
17772       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
17773       cmnLcg->bs = ue->ul.nonGbrLcgBs;
17774    }
17775    ue->ul.totalBsr = cmnLcg->bs;
17776
17777    for (cnt = ulLcg->lcgId+1; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
17778    {
17779       /* TODO: The bs for the other LCGs may be stale because some or all of
17780        * the part of bs may have been already scheduled/data received. Please 
17781        * consider this when truncated BSR is tested/implemented */
17782       ue->ul.totalBsr += ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs;
17783    }
17784
17785    rgSCHCmnUpdUlCompEffBsr(ue);
17786
17787 #ifdef EMTC_ENABLE
17788    if(cell->emtcEnable)
17789    {
17790       if(ue->isEmtcUe)
17791       {
17792          cellSch->apisEmtcUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
17793          RETVALUE(ROK);
17794       }
17795    }
17796    else
17797 #endif
17798    {
17799       cellSch->apisUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
17800    }
17801
17802 #ifdef LTE_ADV
17803    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17804    {
17805       for(U8 sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
17806       {
17807 #ifndef PAL_ENABLE_UL_CA
17808          if((ue->cellInfo[sCellIdx] != NULLP) &&
17809                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
17810 #else
17811          if(ue->cellInfo[sCellIdx] != NULLP)
17812 #endif
17813          {
17814             cellSch->apisUl->rgSCHUpdBsrTrunc(ue->cellInfo[sCellIdx]->cell, ue, ulLcg, bsr);
17815          }
17816       }
17817    }
17818 #endif 
17819
17820    RETVALUE(ROK);
17821 }
17822
17823 /**
17824  * @brief Long BSR update.
17825  *
17826  * @details
17827  *
17828  *     Function : rgSCHCmnUpdBsrLong
17829  *
17830  *     - Update BSRs for all configured LCGs.
17831  *     - Update priority of LCGs if needed.
17832  *     - Update UE's position within/across uplink scheduling queues.
17833  *
17834  *
17835  *  @param[in]  RgSchCellCb  *cell
17836  *  @param[in]  RgSchUeCb    *ue
17837  *  @param[in]  U8 bsArr[]
17838  *  @param[out] RgSchErrInfo *err
17839  *  @return  S16
17840  *      -# ROK
17841  *      -# RFAILED
17842  **/
17843 #ifdef ANSI
17844 PUBLIC S16 rgSCHCmnUpdBsrLong
17845 (
17846 RgSchCellCb  *cell,
17847 RgSchUeCb    *ue,
17848 U8           *bsArr,
17849 RgSchErrInfo *err
17850 )
17851 #else
17852 PUBLIC S16 rgSCHCmnUpdBsrLong(cell, ue, bsArr, err)
17853 RgSchCellCb  *cell;
17854 RgSchUeCb    *ue;
17855 U8           *bsArr;
17856 RgSchErrInfo *err;
17857 #endif
17858 {
17859    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17860    U32           tmpBsArr[4] = {0, 0, 0, 0};
17861    U32           nonGbrBs = 0;
17862 #ifdef LTE_L2_MEAS
17863    U8            idx1;
17864    U8            idx2;
17865 #endif
17866    U32           lcgId;
17867
17868    TRC2(rgSCHCmnUpdBsrLong);
17869
17870 #ifdef LTE_L2_MEAS
17871    for(idx1 = 1; idx1 < RGSCH_MAX_LCG_PER_UE; idx1++)
17872    {
17873      /* If Old BO is non zero then do nothing */
17874      if ((((RgSchCmnLcg *)(ue->ul.lcgArr[idx1].sch))->bs == 0)
17875         && bsArr[idx1] )
17876      {
17877        for(idx2 = 0; idx2 < ue->ul.lcgArr[idx1].numLch; idx2++)
17878        {
17879           /* L2_COUNTERS */
17880           if (!(ue->ulActiveLCs & (1 << 
17881              (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1))))
17882           {
17883              ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->ulUeCount++;
17884              ue->ulActiveLCs |= (1 << 
17885                (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1));
17886           }
17887        }
17888      }
17889    }
17890 #endif
17891    ue->ul.nonGbrLcgBs = 0;
17892    ue->ul.nonLcg0Bs = 0;
17893
17894    if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[0]))
17895    {
17896       if (TRUE == ue->ul.useExtBSRSizes)
17897       {
17898          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnExtBsrTbl[bsArr[0]];
17899          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnExtBsrTbl[bsArr[0]];
17900          tmpBsArr[0] = rgSchCmnExtBsrTbl[bsArr[0]];
17901       }
17902       else
17903       {
17904          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnBsrTbl[bsArr[0]];
17905          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnBsrTbl[bsArr[0]];
17906          tmpBsArr[0] = rgSchCmnBsrTbl[bsArr[0]];
17907       }
17908    }
17909    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
17910    {
17911       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
17912       {
17913          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
17914
17915          if (TRUE == ue->ul.useExtBSRSizes)
17916          {
17917             cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsArr[lcgId]];
17918          }
17919          else
17920          {
17921             cmnLcg->reportedBs = rgSchCmnBsrTbl[bsArr[lcgId]];
17922          }
17923          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17924          {
17925             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17926             tmpBsArr[lcgId] = cmnLcg->bs;
17927          }
17928          else
17929          {
17930             nonGbrBs += cmnLcg->reportedBs;
17931             tmpBsArr[lcgId] = cmnLcg->reportedBs;
17932             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
17933          }
17934       }
17935    }
17936    ue->ul.nonGbrLcgBs = RGSCH_MIN(nonGbrBs,ue->ul.effAmbr);
17937
17938    ue->ul.totalBsr = tmpBsArr[0] + tmpBsArr[1] + tmpBsArr[2] + tmpBsArr[3];
17939 #ifdef RGR_V1
17940    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (ue->ul.totalBsr == 0))
17941    {
17942       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
17943    }
17944 #endif
17945
17946 #ifdef LTEMAC_SPS
17947    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) /* SPS_FIX */
17948    {
17949      if(ue->ul.totalBsr - tmpBsArr[1] == 0)
17950      {/* Updaing the BSR to SPS only if LCG1 BS is present in sps active state */
17951         rgSCHCmnSpsBsrRpt(cell, ue, &ue->ul.lcgArr[1]);
17952      }
17953    }
17954 #endif
17955    rgSCHCmnUpdUlCompEffBsr(ue);
17956
17957 #ifdef EMTC_ENABLE
17958    if(cell->emtcEnable)
17959    {
17960       if(ue->isEmtcUe)
17961       {
17962          cellSch->apisEmtcUl->rgSCHUpdBsrLong(cell, ue, bsArr);
17963          RETVALUE(ROK);
17964       }
17965    }
17966    else
17967 #endif
17968    {
17969    cellSch->apisUl->rgSCHUpdBsrLong(cell, ue, bsArr);
17970    }
17971
17972 #ifdef LTE_ADV
17973    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17974    {
17975       for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
17976       {
17977 #ifndef PAL_ENABLE_UL_CA
17978          if((ue->cellInfo[idx] != NULLP) &&
17979                (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE))
17980 #else
17981          if(ue->cellInfo[idx] != NULLP)
17982 #endif
17983          {
17984             cellSch->apisUl->rgSCHUpdBsrLong(ue->cellInfo[idx]->cell, ue, bsArr);
17985          }
17986       }
17987    }
17988 #endif 
17989
17990    RETVALUE(ROK);
17991 }
17992
17993 /**
17994  * @brief PHR update.
17995  *
17996  * @details
17997  *
17998  *     Function : rgSCHCmnUpdExtPhr
17999  *
18000  *     Updates extended power headroom information for an UE.
18001  *
18002  *  @param[in]  RgSchCellCb  *cell
18003  *  @param[in]  RgSchUeCb    *ue
18004  *  @param[in]  U8           phr
18005  *  @param[out] RgSchErrInfo *err
18006  *  @return  S16
18007  *      -# ROK
18008  *      -# RFAILED
18009  **/
18010 #ifdef ANSI
18011 PUBLIC S16 rgSCHCmnUpdExtPhr
18012 (
18013 RgSchCellCb    *cell,
18014 RgSchUeCb      *ue,
18015 RgInfExtPhrCEInfo *extPhr,
18016 RgSchErrInfo   *err
18017 )
18018 #else
18019 PUBLIC S16 rgSCHCmnUpdExtPhr(cell, ue, extPhr, err)
18020 RgSchCellCb    *cell;
18021 RgSchUeCb      *ue;
18022 RgInfExtPhrCEInfo *extPhr;
18023 RgSchErrInfo   *err;
18024 #endif
18025 {
18026    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18027    RgSchCmnAllocRecord *allRcd;
18028    CmLList             *node = ueUl->ulAllocLst.last;
18029
18030 #ifdef LTEMAC_SPS
18031    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
18032 #endif
18033    TRC2(rgSCHCmnUpdExtPhr);
18034
18035    UNUSED(err);
18036
18037    while (node)
18038    {
18039       allRcd = (RgSchCmnAllocRecord *)node->node;
18040       node = node->prev;
18041       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
18042       {
18043          rgSCHPwrUpdExtPhr(cell, ue, extPhr, allRcd);
18044          break;
18045       }
18046    }
18047 #ifdef LTEMAC_SPS
18048    if(ulSpsUe->isUlSpsActv)
18049    {
18050       rgSCHCmnSpsPhrInd(cell,ue);
18051    }
18052 #endif
18053
18054    RETVALUE(ROK);
18055 }  /* rgSCHCmnUpdExtPhr */
18056
18057
18058
18059
18060 /**
18061  * @brief PHR update.
18062  *
18063  * @details
18064  *
18065  *     Function : rgSCHCmnUpdPhr
18066  *
18067  *     Updates power headroom information for an UE.
18068  *
18069  *  @param[in]  RgSchCellCb  *cell
18070  *  @param[in]  RgSchUeCb    *ue
18071  *  @param[in]  U8           phr
18072  *  @param[out] RgSchErrInfo *err
18073  *  @return  S16
18074  *      -# ROK
18075  *      -# RFAILED
18076  **/
18077 #ifdef ANSI
18078 PUBLIC S16 rgSCHCmnUpdPhr
18079 (
18080 RgSchCellCb    *cell,
18081 RgSchUeCb      *ue,
18082 U8             phr,
18083 RgSchErrInfo   *err
18084 )
18085 #else
18086 PUBLIC S16 rgSCHCmnUpdPhr(cell, ue, phr, err)
18087 RgSchCellCb    *cell;
18088 RgSchUeCb      *ue;
18089 U8             phr;
18090 RgSchErrInfo   *err;
18091 #endif
18092 {
18093    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18094    RgSchCmnAllocRecord *allRcd;
18095    CmLList             *node = ueUl->ulAllocLst.last;
18096
18097 #ifdef LTEMAC_SPS
18098    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
18099 #endif
18100    TRC2(rgSCHCmnUpdPhr);
18101
18102    UNUSED(err);
18103
18104    while (node)
18105    {
18106       allRcd = (RgSchCmnAllocRecord *)node->node;
18107       node = node->prev;
18108       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
18109       {
18110          rgSCHPwrUpdPhr(cell, ue, phr, allRcd, RG_SCH_CMN_PWR_USE_CFG_MAX_PWR);
18111          break;
18112       }
18113    }
18114 #ifdef LTEMAC_SPS
18115    if(ulSpsUe->isUlSpsActv)
18116    {
18117       rgSCHCmnSpsPhrInd(cell,ue);
18118    }
18119 #endif
18120
18121    RETVALUE(ROK);
18122 }  /* rgSCHCmnUpdPhr */
18123
18124 /**
18125  * @brief UL grant for contention resolution.
18126  *
18127  * @details
18128  *
18129  *     Function : rgSCHCmnContResUlGrant
18130  *
18131  *     Add UE to another queue specifically for CRNTI based contention
18132  *     resolution.
18133  *
18134  *
18135  *  @param[in]  RgSchUeCb    *ue
18136  *  @param[out] RgSchErrInfo *err
18137  *  @return  S16
18138  *      -# ROK
18139  *      -# RFAILED
18140  **/
18141 #ifdef ANSI
18142 PUBLIC S16 rgSCHCmnContResUlGrant
18143 (
18144 RgSchCellCb  *cell,
18145 RgSchUeCb    *ue,
18146 RgSchErrInfo *err
18147 )
18148 #else
18149 PUBLIC S16 rgSCHCmnContResUlGrant(cell, ue, err)
18150 RgSchCellCb  *cell;
18151 RgSchUeCb    *ue;
18152 RgSchErrInfo *err;
18153 #endif
18154 {
18155    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18156    TRC2(rgSCHCmnContResUlGrant);
18157
18158    #ifdef EMTC_ENABLE
18159    if(cell->emtcEnable)
18160    {
18161       if(ue->isEmtcUe)
18162       {
18163          cellSch->apisEmtcUl->rgSCHContResUlGrant(cell, ue);
18164          RETVALUE(ROK);
18165       }
18166    }
18167    else
18168 #endif
18169    {
18170       cellSch->apisUl->rgSCHContResUlGrant(cell, ue);
18171    }
18172    RETVALUE(ROK);
18173 }
18174
18175 /**
18176  * @brief SR reception handling.
18177  *
18178  * @details
18179  *
18180  *     Function : rgSCHCmnSrRcvd
18181  *
18182  *     - Update UE's position within/across uplink scheduling queues
18183  *     - Update priority of LCGs if needed.
18184  *
18185  *  @param[in]  RgSchCellCb  *cell
18186  *  @param[in]  RgSchUeCb    *ue
18187  *  @param[in]  CmLteTimingInfo frm
18188  *  @param[out] RgSchErrInfo *err
18189  *  @return  S16
18190  *      -# ROK
18191  *      -# RFAILED
18192  **/
18193 #ifdef ANSI
18194 PUBLIC S16 rgSCHCmnSrRcvd
18195 (
18196 RgSchCellCb  *cell,
18197 RgSchUeCb    *ue,
18198 CmLteTimingInfo frm,
18199 RgSchErrInfo *err
18200 )
18201 #else
18202 PUBLIC S16 rgSCHCmnSrRcvd(cell, ue, frm, err)
18203 RgSchCellCb  *cell;
18204 RgSchUeCb    *ue;
18205 CmLteTimingInfo frm;
18206 RgSchErrInfo *err;
18207 #endif
18208 {
18209    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18210    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18211    CmLList      *node    = ueUl->ulAllocLst.last;
18212
18213    TRC2(rgSCHCmnSrRcvd);
18214
18215 #ifdef EMTC_ENABLE
18216    emtcStatsUlTomSrInd++;
18217 #endif
18218
18219    RGSCH_INCR_SUB_FRAME(frm, 1); /* 1 TTI after the time SR was sent */
18220    while (node)
18221    {
18222       RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)node->node;
18223       if (RGSCH_TIMEINFO_SAME(frm, allRcd->allocTime))
18224       {
18225          break;
18226       }
18227       node = node->prev;
18228    }
18229    //TODO_SID Need to check when it is getting triggered
18230    ue->isSrGrant = TRUE;
18231 #ifdef EMTC_ENABLE
18232    if(cell->emtcEnable)
18233    {
18234       if(ue->isEmtcUe)
18235       {
18236          cellSch->apisEmtcUl->rgSCHSrRcvd(cell, ue);
18237          RETVALUE(ROK);
18238       }
18239    }
18240    else
18241 #endif
18242    {
18243       cellSch->apisUl->rgSCHSrRcvd(cell, ue);
18244    }
18245    RETVALUE(ROK);
18246 }
18247
18248 /**
18249  * @brief Returns first uplink allocation to send reception
18250  *        request to PHY.
18251  *
18252  * @details
18253  *
18254  *     Function: rgSCHCmnFirstRcptnReq(cell)
18255  *     Purpose:  This function returns the first uplink allocation
18256  *               (or NULLP if there is none) in the subframe
18257  *               in which is expected to prepare and send reception
18258  *               request to PHY.
18259  *
18260  *     Invoked by: TOM
18261  *
18262  *  @param[in]  RgSchCellCb      *cell
18263  *  @return  RgSchUlAlloc*
18264  **/
18265 #ifdef ANSI
18266 PUBLIC RgSchUlAlloc *rgSCHCmnFirstRcptnReq
18267 (
18268 RgSchCellCb      *cell
18269 )
18270 #else
18271 PUBLIC RgSchUlAlloc *rgSCHCmnFirstRcptnReq(cell)
18272 RgSchCellCb      *cell;
18273 #endif
18274 {
18275    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18276 /* ACC_TDD */
18277    RgSchUlAlloc* alloc = NULLP;
18278
18279    TRC2(rgSCHCmnFirstRcptnReq);
18280
18281    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
18282    {
18283            RgSchUlSf* sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18284            alloc = rgSCHUtlUlAllocFirst(sf);
18285
18286            if (alloc && alloc->hqProc == NULLP)
18287            {
18288                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18289            }
18290    }
18291
18292    RETVALUE(alloc);
18293 }
18294
18295 /**
18296  * @brief Returns first uplink allocation to send reception
18297  *        request to PHY.
18298  *
18299  * @details
18300  *
18301  *     Function: rgSCHCmnNextRcptnReq(cell)
18302  *     Purpose:  This function returns the next uplink allocation
18303  *               (or NULLP if there is none) in the subframe
18304  *               in which is expected to prepare and send reception
18305  *               request to PHY.
18306  *
18307  *     Invoked by: TOM
18308  *
18309  *  @param[in]  RgSchCellCb      *cell
18310  *  @return  RgSchUlAlloc*
18311  **/
18312 #ifdef ANSI
18313 PUBLIC RgSchUlAlloc *rgSCHCmnNextRcptnReq
18314 (
18315 RgSchCellCb      *cell,
18316 RgSchUlAlloc     *alloc
18317 )
18318 #else
18319 PUBLIC RgSchUlAlloc *rgSCHCmnNextRcptnReq(cell, alloc)
18320 RgSchCellCb      *cell;
18321 RgSchUlAlloc     *alloc;
18322 #endif
18323 {
18324    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18325 /* ACC-TDD */
18326    //RgSchUlSf      *sf   = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18327
18328    TRC2(rgSCHCmnNextRcptnReq);
18329 /* ACC-TDD */
18330    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
18331    {
18332            RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18333
18334            alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18335            if (alloc && alloc->hqProc == NULLP)
18336            {
18337                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18338            }
18339    }
18340    else
18341    {
18342            alloc = NULLP;
18343    }
18344
18345    RETVALUE(alloc);
18346 }
18347 /**
18348  * @brief Collates DRX enabled UE's scheduled in this SF
18349  *
18350  * @details
18351  *
18352  *     Function: rgSCHCmnDrxStrtInActvTmrInUl(cell)
18353  *     Purpose:  This function collates the link
18354  *               of UE's scheduled in this SF who
18355  *               have drx enabled. It then calls
18356  *               DRX specific function to start/restart
18357  *               inactivity timer in Ul
18358  *
18359  *     Invoked by: TOM
18360  *
18361  *  @param[in]  RgSchCellCb      *cell
18362  *  @return Void
18363  **/
18364 #ifdef ANSI
18365 PUBLIC Void rgSCHCmnDrxStrtInActvTmrInUl
18366 (
18367 RgSchCellCb      *cell
18368 )
18369 #else
18370 PUBLIC Void rgSCHCmnDrxStrtInActvTmrInUl(cell)
18371 RgSchCellCb      *cell;
18372 #endif
18373 {
18374    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18375    RgSchUlSf      *sf     = &(cellUl->ulSfArr[cellUl->schdIdx]);
18376    RgSchUlAlloc   *alloc  = rgSCHUtlUlAllocFirst(sf);
18377    CmLListCp       ulUeLst;
18378    RgSchUeCb       *ueCb;
18379
18380
18381    TRC2(rgSCHCmnDrxStrtInActvTmrInUl);
18382
18383    cmLListInit(&ulUeLst);
18384
18385    while(alloc)
18386    {
18387       ueCb = alloc->ue;
18388
18389       if (ueCb)
18390       {
18391          if (!(alloc->grnt.isRtx) && ueCb->isDrxEnabled && !(ueCb->isSrGrant)
18392 #ifdef LTEMAC_SPS
18393              /* ccpu00139513- DRX inactivity timer should not be started for 
18394               * UL SPS occasions */
18395              && (alloc->hqProc->isSpsOccnHqP == FALSE) 
18396 #endif
18397              )
18398          {
18399             cmLListAdd2Tail(&ulUeLst,&(ueCb->ulDrxInactvTmrLnk));
18400             ueCb->ulDrxInactvTmrLnk.node = (PTR)ueCb;
18401          }
18402       }
18403
18404       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18405    }/*while(alloc)*/
18406
18407    (Void)rgSCHDrxStrtInActvTmr(cell,&ulUeLst,RG_SCH_DRX_UL);
18408
18409    RETVOID;
18410 }
18411
18412
18413 /**
18414  * @brief Returns first uplink allocation to send HARQ feedback
18415  *        request to PHY.
18416  *
18417  * @details
18418  *
18419  *     Function: rgSCHCmnFirstHqFdbkAlloc
18420  *     Purpose:  This function returns the first uplink allocation
18421  *               (or NULLP if there is none) in the subframe
18422  *               for which it is expected to prepare and send HARQ
18423  *               feedback to PHY.
18424  *
18425  *     Invoked by: TOM
18426  *
18427  *  @param[in]  RgSchCellCb      *cell
18428  *  @param[in]  U8               idx
18429  *  @return  RgSchUlAlloc*
18430  **/
18431 #ifdef ANSI
18432 PUBLIC RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc
18433 (
18434 RgSchCellCb      *cell,
18435 U8               idx 
18436 )
18437 #else
18438 PUBLIC RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc(cell, idx)
18439 RgSchCellCb      *cell;
18440 U8               idx;
18441 #endif
18442 {
18443    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18444 /* ACC-TDD */
18445    RgSchUlAlloc  *alloc = NULLP;
18446
18447    TRC2(rgSCHCmnFirstHqFdbkAlloc);
18448
18449    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
18450    {
18451           RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
18452           alloc    = rgSCHUtlUlAllocFirst(sf);
18453
18454           while (alloc && (alloc->hqProc == NULLP))
18455           {
18456                   alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18457           }
18458    }
18459
18460    RETVALUE(alloc);
18461 }
18462
18463 /**
18464  * @brief Returns next allocation to send HARQ feedback for.
18465  *
18466  * @details
18467  *
18468  *     Function: rgSCHCmnNextHqFdbkAlloc(cell)
18469  *     Purpose:  This function returns the next uplink allocation
18470  *               (or NULLP if there is none) in the subframe
18471  *               for which HARQ feedback needs to be sent.
18472  *
18473  *     Invoked by: TOM
18474  *
18475  *  @param[in]  RgSchCellCb      *cell
18476  *  @return  RgSchUlAlloc*
18477  **/
18478 #ifdef ANSI
18479 PUBLIC RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc
18480 (
18481 RgSchCellCb      *cell,
18482 RgSchUlAlloc     *alloc,
18483 U8               idx 
18484 )
18485 #else
18486 PUBLIC RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc(cell, alloc, idx)
18487 RgSchCellCb      *cell;
18488 RgSchUlAlloc     *alloc;
18489 U8               idx; 
18490 #endif
18491 {
18492    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18493    TRC2(rgSCHCmnNextHqFdbkAlloc);
18494
18495    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
18496    {
18497       RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
18498
18499       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18500       while (alloc && (alloc->hqProc == NULLP))
18501       {
18502          alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18503       }
18504    }
18505    else
18506    {
18507           alloc = NULLP;
18508    }
18509    RETVALUE(alloc);
18510 }
18511
18512 /***********************************************************
18513  *
18514  *     Func : rgSCHCmnUlGetITbsFrmIMcs
18515  *
18516  *     Desc : Returns the Itbs that is mapped to an Imcs
18517  *            for the case of uplink.
18518  *
18519  *     Ret  :
18520  *
18521  *     Notes:
18522  *
18523  *     File :
18524  *
18525  **********************************************************/
18526 #ifdef ANSI
18527 PUBLIC U8 rgSCHCmnUlGetITbsFrmIMcs
18528 (
18529 U8          iMcs
18530 )
18531 #else
18532 PUBLIC U8 rgSCHCmnUlGetITbsFrmIMcs(iMcs)
18533 U8          iMcs;
18534 #endif
18535 {
18536    TRC2(rgSCHCmnUlGetITbsFrmIMcs);
18537
18538    RETVALUE(rgUlIMcsTbl[iMcs].iTbs);
18539 }
18540
18541 /***********************************************************
18542  *
18543  *     Func : rgSCHCmnUlGetIMcsFrmITbs
18544  *
18545  *     Desc : Returns the Imcs that is mapped to an Itbs
18546  *            for the case of uplink.
18547  *
18548  *     Ret  :
18549  *
18550  *     Notes: For iTbs 19, iMcs is dependant on modulation order.
18551  *            Refer to 36.213, Table 8.6.1-1 and 36.306 Table 4.1-2
18552  *            for UE capability information
18553  *
18554  *     File :
18555  *
18556  **********************************************************/
18557 #ifdef ANSI
18558 PUBLIC U8 rgSCHCmnUlGetIMcsFrmITbs
18559 (
18560 U8                iTbs,
18561 CmLteUeCategory   ueCtg
18562 )
18563 #else
18564 PUBLIC U8 rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg)
18565 U8                iTbs;
18566 CmLteUeCategory   ueCtg;
18567 #endif
18568 {
18569    U8 iMcs;
18570    TRC2(rgSCHCmnUlGetIMcsFrmITbs);
18571
18572    if (iTbs <= 10)
18573    {
18574       iMcs = iTbs;
18575    }
18576    /*a higher layer can force a 64QAM UE to transmit at 16QAM.
18577     * We currently do not support this. Once the support for such
18578     * is added, ueCtg should be replaced by current transmit
18579     * modulation configuration.Refer to 36.213 -8.6.1
18580     */
18581    else if ( iTbs < 19 )
18582    {
18583       iMcs = iTbs + 1;
18584    }
18585    else if ((iTbs == 19) && (ueCtg != CM_LTE_UE_CAT_5))
18586    {
18587       iMcs = iTbs + 1;
18588    }
18589    else
18590    {
18591       iMcs = iTbs + 2;
18592    }
18593
18594 #ifdef LTE_TDD
18595    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
18596       was seen when IMCS exceeds 20  on T2k TDD*/
18597    if (iMcs > 20)
18598    {
18599       iMcs = 20;
18600    }
18601 #endif
18602
18603    RETVALUE(iMcs);
18604 }
18605
18606 /***********************************************************
18607  *
18608  *     Func : rgSCHCmnUlMinTbBitsForITbs
18609  *
18610  *     Desc : Returns the minimum number of bits that can
18611  *            be given as grant for a specific CQI.
18612  *
18613  *     Ret  :
18614  *
18615  *     Notes:
18616  *
18617  *     File :
18618  *
18619  **********************************************************/
18620 #ifdef ANSI
18621 PUBLIC U32 rgSCHCmnUlMinTbBitsForITbs
18622 (
18623 RgSchCmnUlCell     *cellUl,
18624 U8                 iTbs
18625 )
18626 #else
18627 PUBLIC U32 rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs)
18628 RgSchCmnUlCell   *cellUl;
18629 U8               iTbs;
18630 #endif
18631 {
18632    TRC2(rgSCHCmnUlMinTbBitsForITbs);
18633
18634    RGSCH_ARRAY_BOUND_CHECK(0, rgTbSzTbl[0], iTbs); 
18635
18636    RETVALUE(rgTbSzTbl[0][iTbs][cellUl->sbSize-1]);
18637 }
18638
18639 /***********************************************************
18640  *
18641  *     Func : rgSCHCmnUlSbAlloc
18642  *
18643  *     Desc : Given a required 'number of subbands' and a hole,
18644  *            returns a suitable alloc such that the subband
18645  *            allocation size is valid
18646  *
18647  *     Ret  :
18648  *
18649  *     Notes: Does not assume either passed numSb or hole size
18650  *            to be valid for allocation, and hence arrives at
18651  *            an acceptable value.
18652  *     File :
18653  *
18654  **********************************************************/
18655 #ifdef ANSI
18656 PUBLIC RgSchUlAlloc *rgSCHCmnUlSbAlloc
18657 (
18658 RgSchUlSf       *sf,
18659 U8              numSb,
18660 RgSchUlHole     *hole
18661 )
18662 #else
18663 PUBLIC RgSchUlAlloc *rgSCHCmnUlSbAlloc(sf, numSb, hole)
18664 RgSchUlSf       *sf;
18665 U8              numSb;
18666 RgSchUlHole     *hole;
18667 #endif
18668 {
18669    U8           holeSz; /* valid hole size */
18670    RgSchUlAlloc *alloc;
18671    TRC2(rgSCHCmnUlSbAlloc);
18672
18673    if ((holeSz = rgSchCmnMult235Tbl[hole->num].prvMatch) == hole->num)
18674    {
18675       numSb = rgSchCmnMult235Tbl[numSb].match;
18676       if (numSb >= holeSz)
18677       {
18678          alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
18679       }
18680       else
18681       {
18682          alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
18683       }
18684    }
18685    else
18686    {
18687       if (numSb < holeSz)
18688       {
18689          numSb = rgSchCmnMult235Tbl[numSb].match;
18690       }
18691       else
18692       {
18693          numSb = rgSchCmnMult235Tbl[numSb].prvMatch;
18694       }
18695
18696       if ( numSb >= holeSz )
18697       {
18698          numSb = holeSz;
18699       }
18700       alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
18701    }
18702    RETVALUE(alloc);
18703 }
18704
18705 /**
18706  * @brief To fill the RgSchCmnUeUlAlloc structure of UeCb.
18707  *
18708  * @details
18709  *
18710  *     Function: rgSCHCmnUlUeFillAllocInfo
18711  *     Purpose:  Specific scheduler to call this API to fill the alloc
18712  *               information.
18713  *
18714  *     Invoked by: Scheduler
18715  *
18716  *  @param[in]  RgSchCellCb      *cell
18717  *  @param[out] RgSchUeCb        *ue
18718  *  @return   Void
18719  **/
18720 #ifdef ANSI
18721 PUBLIC Void rgSCHCmnUlUeFillAllocInfo
18722 (
18723 RgSchCellCb      *cell,
18724 RgSchUeCb        *ue
18725 )
18726 #else
18727 PUBLIC Void rgSCHCmnUlUeFillAllocInfo(cell, ue)
18728 RgSchCellCb      *cell;
18729 RgSchUeCb        *ue;
18730 #endif
18731 {
18732    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18733    RgSchCmnUeUlAlloc  *ulAllocInfo;
18734    RgSchCmnUlUe       *ueUl;
18735
18736    TRC2(rgSCHCmnUlUeFillAllocInfo);
18737
18738    ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18739    ulAllocInfo = &ueUl->alloc;
18740
18741    /* Fill alloc structure */
18742    rgSCHCmnUlAllocFillTpc(cell, ue, ulAllocInfo->alloc);
18743    rgSCHCmnUlAllocFillNdmrs(cellUl, ulAllocInfo->alloc);
18744    rgSCHCmnUlAllocLnkHqProc(ue, ulAllocInfo->alloc, ulAllocInfo->alloc->hqProc,
18745                      ulAllocInfo->alloc->hqProc->isRetx);
18746    /* Fill PDCCH */
18747    rgSCHCmnUlFillPdcchWithAlloc(ulAllocInfo->alloc->pdcch,
18748          ulAllocInfo->alloc, ue);
18749    /* Recording information about this allocation */
18750    rgSCHCmnUlRecordUeAlloc(cell, ue);
18751
18752    /* Update the UE's outstanding allocation */
18753    if (!ulAllocInfo->alloc->hqProc->isRetx)
18754    {
18755       rgSCHCmnUlUpdOutStndAlloc(cell, ue, ulAllocInfo->allocdBytes);
18756    }
18757
18758    RETVOID;
18759 }
18760
18761 /**
18762  * @brief Update the UEs outstanding alloc based on the BSR report's timing.
18763  *
18764  *
18765  * @details
18766  *
18767  *     Function: rgSCHCmnUpdUlCompEffBsr
18768  *     Purpose:  Clear off all the allocations from outstanding allocation that
18769  *     are later than or equal to BSR timing information (stored in UEs datIndTime).
18770  *
18771  *     Invoked by: Scheduler
18772  *
18773  *  @param[in]  RgSchUeCb *ue
18774  *  @return  Void
18775  **/
18776 #ifdef ANSI
18777 PRIVATE Void rgSCHCmnUpdUlCompEffBsr
18778 (
18779 RgSchUeCb *ue
18780 )
18781 #else
18782 PRIVATE Void rgSCHCmnUpdUlCompEffBsr(ue)
18783 RgSchUeCb *ue;
18784 #endif
18785 {
18786    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,ue->cell);
18787    CmLList   *node = ueUl->ulAllocLst.last;
18788    RgSchCmnAllocRecord *allRcd;
18789    U32 outStndAlloc=0;
18790    U32 nonLcg0OutStndAllocBs=0;
18791    U32 nonLcg0Bsr=0;
18792    U8  lcgId;
18793    RgSchCmnLcg *cmnLcg = NULLP;
18794    TRC2(rgSCHCmnUpdUlCompEffBsr);
18795
18796    while (node)
18797    {
18798       allRcd = (RgSchCmnAllocRecord *)node->node;
18799       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
18800       {
18801          node = node->next;
18802          break;
18803       }
18804       node = node->prev;
18805    }
18806    while (node)
18807    {
18808       allRcd = (RgSchCmnAllocRecord *)node->node;
18809       node = node->next;
18810       outStndAlloc += allRcd->alloc;
18811    }
18812  
18813    cmnLcg = (RgSchCmnLcg *)(ue->ul.lcgArr[0].sch);
18814    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
18815    if (cmnLcg->bs > outStndAlloc)
18816    {
18817       cmnLcg->bs -= outStndAlloc;
18818       ue->ul.minReqBytes = cmnLcg->bs;
18819       outStndAlloc = 0;
18820    }
18821    else
18822    {
18823       nonLcg0OutStndAllocBs = outStndAlloc - cmnLcg->bs;
18824       cmnLcg->bs = 0;
18825    }
18826
18827    for(lcgId = 1;lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
18828    {
18829       if(RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
18830       {
18831          cmnLcg = ((RgSchCmnLcg *) (ue->ul.lcgArr[lcgId].sch));
18832          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
18833          {
18834             nonLcg0Bsr += cmnLcg->bs;
18835          }
18836       }
18837    }
18838    nonLcg0Bsr += ue->ul.nonGbrLcgBs;  
18839    if (nonLcg0OutStndAllocBs > nonLcg0Bsr)
18840    {
18841       nonLcg0Bsr = 0;
18842    }
18843    else
18844    {
18845       nonLcg0Bsr -= nonLcg0OutStndAllocBs;
18846    }
18847    ue->ul.nonLcg0Bs = nonLcg0Bsr;
18848    /* Cap effBsr with nonLcg0Bsr and append lcg0 bs.
18849     * nonLcg0Bsr limit applies only to lcg1,2,3 */
18850    /* better be handled in individual scheduler */
18851    ue->ul.effBsr = nonLcg0Bsr +\
18852                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
18853    RETVOID;
18854 }
18855
18856 /**
18857  * @brief  Records information about the current allocation.
18858  *
18859  * @details
18860  *
18861  *     Function: rgSCHCmnUlRecordUeAlloc
18862  *     Purpose:  Records information about the curent allocation.
18863  *               This includes the allocated bytes, as well
18864  *               as some power information.
18865  *
18866  *     Invoked by: Scheduler
18867  *
18868  *  @param[in]  RgSchCellCb *cell
18869  *  @param[in]  RgSchUeCb   *ue
18870  *  @return  Void
18871  **/
18872 #ifdef ANSI
18873 PUBLIC Void rgSCHCmnUlRecordUeAlloc
18874 (
18875 RgSchCellCb *cell,
18876 RgSchUeCb   *ue
18877 )
18878 #else
18879 PUBLIC Void rgSCHCmnUlRecordUeAlloc(cell, ue)
18880 RgSchCellCb *cell;
18881 RgSchUeCb   *ue;
18882 #endif
18883 {
18884 #ifdef LTE_TDD
18885    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18886 #endif
18887    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18888    CmLListCp           *lst = &ueUl->ulAllocLst;
18889    CmLList             *node = ueUl->ulAllocLst.first;
18890    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
18891    RgSchCmnUeUlAlloc  *ulAllocInfo = &ueUl->alloc;
18892    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
18893    TRC2(rgSCHCmnUlRecordUeAlloc);
18894
18895    cmLListDelFrm(lst, &allRcd->lnk);
18896 #ifndef LTE_TDD
18897    /* To the crntTime, add the MIN time at which UE will
18898     * actually send the BSR i.e DELTA+4 */
18899    allRcd->allocTime = cell->crntTime;
18900    /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
18901 #ifdef EMTC_ENABLE
18902    if(ue->isEmtcUe == TRUE)
18903    {
18904       RGSCH_INCR_SUB_FRAME_EMTC(allRcd->allocTime,
18905                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
18906    }
18907    else
18908 #endif
18909    {
18910       RGSCH_INCR_SUB_FRAME(allRcd->allocTime,
18911                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
18912    }
18913 #else
18914    allRcd->allocTime = cellUl->schdTime;
18915 #endif
18916    cmLListAdd2Tail(lst, &allRcd->lnk);
18917
18918    /* Filling in the parameters to be recorded */
18919    allRcd->alloc = ulAllocInfo->allocdBytes;
18920    //allRcd->numRb = ulAllocInfo->alloc->grnt.numRb;
18921    allRcd->numRb = (ulAllocInfo->alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
18922    /*Recording the UL CQI derived from the maxUlCqi */
18923    allRcd->cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
18924    allRcd->tpc   = ulAllocInfo->alloc->grnt.tpc;
18925
18926    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
18927
18928    cell->measurements.ulBytesCnt += ulAllocInfo->allocdBytes;
18929
18930    RETVOID;
18931 }
18932
18933 /** PHR handling for MSG3
18934  * @brief  Records allocation information of msg3 in the the UE.
18935  *
18936  * @details
18937  *
18938  *     Function: rgSCHCmnUlRecMsg3Alloc
18939  *     Purpose:  Records information about msg3 allocation.
18940  *               This includes the allocated bytes, as well
18941  *               as some power information.
18942  *
18943  *     Invoked by: Scheduler
18944  *
18945  *  @param[in]  RgSchCellCb *cell
18946  *  @param[in]  RgSchUeCb   *ue
18947  *  @param[in]  RgSchRaCb   *raCb
18948  *  @return  Void
18949  **/
18950 #ifdef ANSI
18951 PUBLIC Void rgSCHCmnUlRecMsg3Alloc
18952 (
18953 RgSchCellCb *cell,
18954 RgSchUeCb   *ue,
18955 RgSchRaCb   *raCb
18956 )
18957 #else
18958 PUBLIC Void rgSCHCmnUlRecMsg3Alloc(cell, ue, raCb)
18959 RgSchCellCb *cell;
18960 RgSchUeCb   *ue;
18961 RgSchRaCb   *raCb;
18962 #endif
18963 {
18964    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18965    CmLListCp           *lst = &ueUl->ulAllocLst;
18966    CmLList             *node = ueUl->ulAllocLst.first;
18967    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
18968
18969    /* Stack Crash problem for TRACE5 changes */
18970    TRC2(rgSCHCmnUlRecMsg3Alloc);
18971
18972    cmLListDelFrm(lst, node);
18973    allRcd->allocTime = raCb->msg3AllocTime;
18974    cmLListAdd2Tail(lst, node);
18975
18976    /* Filling in the parameters to be recorded */
18977    allRcd->alloc = raCb->msg3Grnt.datSz;
18978    allRcd->numRb = raCb->msg3Grnt.numRb;
18979    allRcd->cqi   = raCb->ccchCqi;
18980    allRcd->tpc   = raCb->msg3Grnt.tpc;
18981
18982    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
18983
18984    RETVOID;
18985 }
18986 /**
18987  * @brief Keeps track of the most recent RG_SCH_CMN_MAX_ALLOC_TRACK
18988  * allocations to track. Adds this allocation to the ueUl's ulAllocLst.
18989  *
18990  *
18991  * @details
18992  *
18993  *     Function: rgSCHCmnUlUpdOutStndAlloc
18994  *     Purpose:  Recent Allocation shall be at First Pos'n.
18995  *               Remove the last node, update the fields
18996  *                with the new allocation and add at front.
18997  *
18998  *     Invoked by: Scheduler
18999  *
19000  *  @param[in]  RgSchCellCb *cell
19001  *  @param[in]  RgSchUeCb   *ue
19002  *  @param[in]  U32 alloc
19003  *  @return  Void
19004  **/
19005 #ifdef ANSI
19006 PUBLIC Void rgSCHCmnUlUpdOutStndAlloc
19007 (
19008 RgSchCellCb *cell,
19009 RgSchUeCb   *ue,
19010 U32 alloc
19011 )
19012 #else
19013 PUBLIC Void rgSCHCmnUlUpdOutStndAlloc(cell, ue, alloc)
19014 RgSchCellCb *cell;
19015 RgSchUeCb   *ue;
19016 U32 alloc;
19017 #endif
19018 {
19019    U32                 nonLcg0Alloc=0;
19020    TRC2(rgSCHCmnUlUpdOutStndAlloc);
19021
19022    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
19023    if (((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs > alloc)
19024    {
19025       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs -= alloc;
19026    }
19027    else
19028    {
19029       nonLcg0Alloc = alloc - ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
19030       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = 0;
19031    }
19032
19033    if (nonLcg0Alloc >= ue->ul.nonLcg0Bs)
19034    {
19035       ue->ul.nonLcg0Bs  = 0;
19036    }
19037    else
19038    {
19039       ue->ul.nonLcg0Bs  -= nonLcg0Alloc;
19040    }
19041    /* Cap effBsr with effAmbr and append lcg0 bs.
19042     * effAmbr limit applies only to lcg1,2,3 non GBR LCG's*/
19043    /* better be handled in individual scheduler */
19044    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
19045                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
19046 #ifdef RGR_V1
19047    if (ue->ul.effBsr == 0)
19048    {
19049       if (ue->bsrTmr.tmrEvnt != TMR_NONE)
19050       {
19051          rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
19052       }
19053       /* ccpu00133008 */
19054       if (FALSE == ue->isSrGrant)
19055       {
19056          if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
19057          {
19058             /*
19059             rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR,
19060                   ue->ul.bsrTmrCfg.prdBsrTmr);
19061             */
19062          }
19063       }
19064    }
19065 #endif
19066    /* Resetting UEs lower Cap */
19067    ue->ul.minReqBytes = 0;
19068
19069    RETVOID;
19070 }
19071
19072
19073 /**
19074  * @brief Returns the "Itbs" for a given UE.
19075  *
19076  * @details
19077  *
19078  *     Function: rgSCHCmnUlGetITbs
19079  *     Purpose:  This function returns the "Itbs" for a given UE.
19080  *
19081  *     Invoked by: Scheduler
19082  *
19083  *  @param[in]  RgSchUeCb        *ue
19084  *  @return     U8
19085  **/
19086 #ifdef ANSI
19087 PUBLIC U8 rgSCHCmnUlGetITbs
19088 (
19089 RgSchCellCb      *cell,
19090 RgSchUeCb        *ue,
19091 Bool             isEcp
19092 )
19093 #else
19094 PUBLIC U8 rgSCHCmnUlGetITbs(cell, ue, isEcp)
19095 RgSchCellCb      *cell;
19096 RgSchUeCb        *ue;
19097 Bool             isEcp;
19098 #endif
19099 {
19100    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
19101    /* CQI will be capped to maxUlCqi for 16qam UEs */
19102    CmLteUeCategory  ueCtgy = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
19103    U8            cqi;
19104 #ifdef UL_LA
19105    S32            iTbs;
19106    U8            maxiTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ueUl->maxUlCqi]; 
19107 #endif
19108
19109    TRC2(rgSCHCmnUlGetITbs);
19110
19111    /* #ifdef RG_SCH_CMN_EXT_CP_SUP For ECP pick index 1 */
19112 #ifdef TFU_UPGRADE
19113    if ( (ueCtgy != CM_LTE_UE_CAT_5) &&
19114         (ueUl->validUlCqi > ueUl->maxUlCqi)
19115       )
19116    {
19117       cqi = ueUl->maxUlCqi;
19118    }
19119    else
19120    {
19121       cqi = ueUl->validUlCqi;
19122    }
19123
19124 #ifdef UL_LA
19125    iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
19126
19127    RG_SCH_CHK_ITBS_RANGE(iTbs, maxiTbs); 
19128
19129    iTbs = RGSCH_MIN(iTbs,  ue->cell->thresholds.maxUlItbs);
19130
19131 #ifdef LTE_TDD
19132    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
19133       was seen when IMCS exceeds 20 on T2k TDD */
19134    if (iTbs > 19)
19135    {
19136       iTbs = 19;
19137    }
19138 #endif
19139    RETVALUE(iTbs);
19140 #endif 
19141 #else
19142    if ( (ueCtgy != CM_LTE_UE_CAT_5) && (ueUl->crntUlCqi[0] > ueUl->maxUlCqi ))
19143    {
19144       cqi = ueUl->maxUlCqi;
19145    }
19146    else
19147    {
19148       cqi = ueUl->crntUlCqi[0];
19149    }
19150 #endif
19151    RETVALUE(rgSchCmnUlCqiToTbsTbl[(U8)isEcp][cqi]);
19152 }
19153
19154 /**
19155  * @brief This function adds the UE to DLRbAllocInfo TX lst.
19156  *
19157  * @details
19158  *
19159  *     Function: rgSCHCmnDlRbInfoAddUeTx
19160  *     Purpose:  This function adds the UE to DLRbAllocInfo TX lst.
19161  *
19162  *     Invoked by: Common Scheduler
19163  *
19164  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19165  *  @param[in]  RgSchUeCb             *ue
19166  *  @param[in]  RgSchDlHqProcCb       *hqP
19167  *  @return  Void
19168  *
19169  **/
19170 #ifdef ANSI
19171 PRIVATE Void rgSCHCmnDlRbInfoAddUeTx
19172 (
19173 RgSchCellCb        *cell,
19174 RgSchCmnDlRbAllocInfo *allocInfo,
19175 RgSchUeCb             *ue,
19176 RgSchDlHqProcCb       *hqP
19177 )
19178 #else
19179 PRIVATE Void rgSCHCmnDlRbInfoAddUeTx(cell, allocInfo, ue, hqP)
19180 RgSchCellCb        *cell;
19181 RgSchCmnDlRbAllocInfo *allocInfo;
19182 RgSchUeCb             *ue;
19183 RgSchDlHqProcCb       *hqP;
19184 #endif
19185 {
19186    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
19187
19188    TRC2(rgSCHCmnDlRbInfoAddUeTx);
19189
19190    if (hqP->reqLnk.node == NULLP)
19191    {
19192       if (cellSch->dl.isDlFreqSel)
19193       {
19194          cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
19195            &allocInfo->dedAlloc.txHqPLst, hqP);
19196       }
19197       else
19198       {
19199          {
19200             cmLListAdd2Tail(&allocInfo->dedAlloc.txHqPLst, &hqP->reqLnk);
19201          }
19202          hqP->reqLnk.node = (PTR)hqP;
19203       }
19204    }
19205    RETVOID;
19206 }
19207
19208 /**
19209  * @brief This function adds the UE to DLRbAllocInfo RETX lst.
19210  *
19211  * @details
19212  *
19213  *     Function: rgSCHCmnDlRbInfoAddUeRetx
19214  *     Purpose:  This function adds the UE to DLRbAllocInfo RETX lst.
19215  *
19216  *     Invoked by: Common Scheduler
19217  *
19218  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19219  *  @param[in]  RgSchUeCb             *ue
19220  *  @param[in]  RgSchDlHqProcCb       *hqP
19221  *  @return  Void
19222  *
19223  **/
19224 #ifdef ANSI
19225 PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx
19226 (
19227 RgSchCellCb        *cell,
19228 RgSchCmnDlRbAllocInfo *allocInfo,
19229 RgSchUeCb             *ue,
19230 RgSchDlHqProcCb       *hqP
19231 )
19232 #else
19233 PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx(cell, allocInfo, ue, hqP)
19234 RgSchCellCb        *cell;
19235 RgSchCmnDlRbAllocInfo *allocInfo;
19236 RgSchUeCb             *ue;
19237 RgSchDlHqProcCb       *hqP;
19238 #endif
19239 {
19240    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
19241
19242    TRC2(rgSCHCmnDlRbInfoAddUeRetx);
19243
19244    if (cellSch->dl.isDlFreqSel)
19245    {
19246       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
19247         &allocInfo->dedAlloc.retxHqPLst, hqP);
19248    }
19249    else
19250    {
19251       /* checking UE's presence in this lst is unnecessary */
19252       cmLListAdd2Tail(&allocInfo->dedAlloc.retxHqPLst, &hqP->reqLnk);
19253       hqP->reqLnk.node = (PTR)hqP;
19254    }
19255    RETVOID;
19256 }
19257
19258 /**
19259  * @brief This function adds the UE to DLRbAllocInfo TX-RETX lst.
19260  *
19261  * @details
19262  *
19263  *     Function: rgSCHCmnDlRbInfoAddUeRetxTx
19264  *     Purpose:  This adds the UE to DLRbAllocInfo TX-RETX lst.
19265  *
19266  *     Invoked by: Common Scheduler
19267  *
19268  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19269  *  @param[in]  RgSchUeCb             *ue
19270  *  @param[in]  RgSchDlHqProcCb       *hqP
19271  *  @return  Void
19272  *
19273  **/
19274 #ifdef ANSI
19275 PRIVATE Void rgSCHCmnDlRbInfoAddUeRetxTx
19276 (
19277 RgSchCellCb        *cell,
19278 RgSchCmnDlRbAllocInfo *allocInfo,
19279 RgSchUeCb             *ue,
19280 RgSchDlHqProcCb       *hqP
19281 )
19282 #else
19283 PRIVATE Void rgSCHCmnDlRbInfoAddUeRetxTx(allocInfo, ue, hqP)
19284 RgSchCellCb        *cell;
19285 RgSchCmnDlRbAllocInfo *allocInfo;
19286 RgSchUeCb             *ue;
19287 RgSchDlHqProcCb       *hqP;
19288 #endif
19289 {
19290    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
19291
19292    TRC2(rgSCHCmnDlRbInfoAddUeRetxTx);
19293
19294    if (cellSch->dl.isDlFreqSel)
19295    {
19296       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
19297         &allocInfo->dedAlloc.txRetxHqPLst, hqP);
19298    }
19299    else
19300    {
19301       cmLListAdd2Tail(&allocInfo->dedAlloc.txRetxHqPLst, &hqP->reqLnk);
19302       hqP->reqLnk.node = (PTR)hqP;
19303    }
19304    RETVOID;
19305 }
19306
19307 /**
19308  * @brief This function adds the UE to DLRbAllocInfo NonSchdRetxLst.
19309  *
19310  * @details
19311  *
19312  *     Function: rgSCHCmnDlAdd2NonSchdRetxLst 
19313  *     Purpose:  During RB estimation for RETX, if allocation fails
19314  *               then appending it to NonSchdRetxLst, the further
19315  *               action is taken as part of Finalization in
19316  *               respective schedulers.
19317  *
19318  *     Invoked by: Common Scheduler
19319  *
19320  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19321  *  @param[in]  RgSchUeCb             *ue
19322  *  @param[in]  RgSchDlHqProcCb       *hqP
19323  *  @return  Void
19324  *
19325  **/
19326 #ifdef ANSI
19327 PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst 
19328 (
19329 RgSchCmnDlRbAllocInfo *allocInfo,
19330 RgSchUeCb             *ue,
19331 RgSchDlHqProcCb       *hqP
19332 )
19333 #else
19334 PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst(allocInfo, ue, hqP)
19335 RgSchCmnDlRbAllocInfo *allocInfo;
19336 RgSchUeCb             *ue;
19337 RgSchDlHqProcCb       *hqP;
19338 #endif
19339 {
19340    CmLList         *schdLnkNode;
19341
19342    TRC2(rgSCHCmnDlAdd2NonSchdRetxLst);
19343
19344 #ifdef LTEMAC_SPS
19345    if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && 
19346          (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)))
19347    {
19348       RETVOID;
19349    }
19350 #endif
19351
19352    schdLnkNode = &hqP->schdLstLnk;
19353    RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
19354    cmLListAdd2Tail(&allocInfo->dedAlloc.nonSchdRetxHqPLst, schdLnkNode);
19355
19356    RETVOID;
19357 }
19358
19359
19360
19361 /**
19362  * @brief This function adds the UE to DLRbAllocInfo NonSchdTxRetxLst.
19363  *
19364  * @details
19365  *
19366  *     Function: rgSCHCmnDlAdd2NonSchdTxRetxLst 
19367  *     Purpose:  During RB estimation for TXRETX, if allocation fails
19368  *               then appending it to NonSchdTxRetxLst, the further
19369  *               action is taken as part of Finalization in
19370  *               respective schedulers.
19371  *
19372  *     Invoked by: Common Scheduler
19373  *
19374  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19375  *  @param[in]  RgSchUeCb             *ue
19376  *  @param[in]  RgSchDlHqProcCb       *hqP
19377  *  @return  Void
19378  *
19379  **/
19380 #ifdef LTE_TDD
19381 /**
19382  * @brief This function handles the initialisation of DL HARQ/ACK feedback
19383  *        timing information for eaach DL subframe.
19384  *
19385  * @details
19386  *
19387  *     Function: rgSCHCmnDlANFdbkInit
19388  *     Purpose:  Each DL subframe stores the sfn and subframe
19389  *               information of UL subframe in which it expects
19390  *               HARQ ACK/NACK feedback for this subframe.It
19391  *               generates the information based on Downlink
19392  *               Association Set Index table.
19393  *
19394  *     Invoked by: Scheduler
19395  *
19396  *  @param[in]  RgSchCellCb*     cell
19397  *  @return     S16
19398  *
19399  **/
19400 #ifdef ANSI
19401 PRIVATE S16 rgSCHCmnDlANFdbkInit
19402 (
19403 RgSchCellCb                *cell
19404 )
19405 #else
19406 PRIVATE S16 rgSCHCmnDlANFdbkInit(cell)
19407 RgSchCellCb                *cell;
19408 #endif
19409 {
19410  U8                   sfCount;
19411  U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
19412  U8                   maxDlSubfrms = cell->numDlSubfrms;
19413  U8                   sfNum;
19414  U8                   idx;
19415  U8                   dlIdx;
19416  U8                   calcSfnOffset;
19417  S8                   calcSfNum;
19418  U8                   ulSfCnt =0;
19419  RgSchTddSubfrmInfo   ulSubfrmInfo;
19420  U8                   maxUlSubfrms;
19421
19422    TRC2(rgSCHCmnDlANFdbkInit);
19423
19424    ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19425    maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19426
19427    /* Generate HARQ ACK/NACK feedback information for each DL sf in a radio frame
19428     * Calculate this information based on DL Association set Index table */
19429    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19430    {
19431       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19432             RG_SCH_TDD_UL_SUBFRAME)
19433       {
19434          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19435       }
19436       ulSfCnt++;
19437
19438       for(idx=0; idx < rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
19439             numFdbkSubfrms; idx++)
19440       {
19441          calcSfNum = sfNum - rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
19442                      subfrmNum[idx];
19443          if(calcSfNum < 0)
19444          {
19445             calcSfnOffset = RGSCH_CEIL(-calcSfNum, RGSCH_NUM_SUB_FRAMES);
19446          }
19447          else
19448          {
19449             calcSfnOffset = 0;
19450          }
19451
19452          calcSfNum = ((RGSCH_NUM_SUB_FRAMES * calcSfnOffset) + calcSfNum)\
19453                      % RGSCH_NUM_SUB_FRAMES;
19454
19455          if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19456          {
19457             dlIdx = calcSfNum;
19458          }
19459          else if((ulSubfrmInfo.switchPoints == 2) && (calcSfNum <= \
19460                   RG_SCH_CMN_SPL_SUBFRM_6))
19461          {
19462             dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19463          }
19464          else
19465          {
19466             dlIdx = calcSfNum - maxUlSubfrms;
19467          }
19468
19469          cell->subFrms[dlIdx]->dlFdbkInfo.subframe = sfNum;
19470          cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = calcSfnOffset;
19471          cell->subFrms[dlIdx]->dlFdbkInfo.m = idx;
19472       }
19473       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19474    }
19475
19476    /* DL subframes in the subsequent radio frames are initialized
19477     * with the previous radio frames  */
19478    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;\
19479          dlIdx++)
19480    {
19481       sfNum = dlIdx - rgSchTddNumDlSubfrmTbl[ulDlCfgIdx]\
19482               [RGSCH_NUM_SUB_FRAMES-1];
19483       cell->subFrms[dlIdx]->dlFdbkInfo.subframe = \
19484                                                   cell->subFrms[sfNum]->dlFdbkInfo.subframe;
19485       cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = \
19486                                                    cell->subFrms[sfNum]->dlFdbkInfo.sfnOffset;
19487       cell->subFrms[dlIdx]->dlFdbkInfo.m = cell->subFrms[sfNum]->dlFdbkInfo.m;
19488    }
19489    RETVALUE(ROK);
19490 }
19491
19492 /**
19493  * @brief This function handles the initialization of uplink association
19494  *        set information for each DL subframe.
19495  *
19496  *
19497  * @details
19498  *
19499  *     Function: rgSCHCmnDlKdashUlAscInit
19500  *     Purpose:  Each DL sf stores the sfn and sf information of UL sf
19501  *               in which it expects HQ ACK/NACK trans. It generates the information
19502  *               based on k` in UL association set index table.
19503  *
19504  *     Invoked by: Scheduler
19505  *
19506  *  @param[in]  RgSchCellCb*     cell
19507  *  @return     S16
19508  *
19509  **/
19510 #ifdef ANSI
19511 PRIVATE S16 rgSCHCmnDlKdashUlAscInit
19512 (
19513 RgSchCellCb                *cell
19514 )
19515 #else
19516 PRIVATE S16 rgSCHCmnDlKdashUlAscInit(cell)
19517 RgSchCellCb                *cell;
19518 #endif
19519 {
19520  U8                   sfCount;
19521  U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
19522  U8                   maxDlSubfrms = cell->numDlSubfrms;
19523  U8                   sfNum;
19524  U8                   dlIdx;
19525  S8                   calcSfnOffset;
19526  S8                   calcSfNum;
19527  U8                   ulSfCnt =0;
19528  RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19529  U8                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19530                                      [RGSCH_NUM_SUB_FRAMES-1];
19531  U8                   dlPres = 0;
19532
19533    TRC2(rgSCHCmnDlKdashUlAscInit);
19534
19535    /* Generate ACK/NACK offset information for each DL subframe in a radio frame
19536     * Calculate this information based on K` in UL Association Set table */
19537    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19538    {
19539       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19540             RG_SCH_TDD_UL_SUBFRAME)
19541       {
19542          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19543       }
19544       ulSfCnt++;
19545
19546       calcSfNum = (sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum] + \
19547             RGSCH_NUM_SUB_FRAMES) % RGSCH_NUM_SUB_FRAMES;
19548       calcSfnOffset = sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum];
19549       if(calcSfnOffset < 0)
19550       {
19551          calcSfnOffset = RGSCH_CEIL(-calcSfnOffset, RGSCH_NUM_SUB_FRAMES);
19552       }
19553       else
19554       {
19555          calcSfnOffset = 0;
19556       }
19557
19558       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19559       {
19560          dlIdx = calcSfNum;
19561       }
19562       else if((ulSubfrmInfo.switchPoints == 2) &&
19563             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
19564       {
19565          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19566       }
19567       else
19568       {
19569          dlIdx = calcSfNum - maxUlSubfrms;
19570       }
19571
19572       cell->subFrms[dlIdx]->ulAscInfo.subframe = sfNum;
19573       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = calcSfnOffset;
19574
19575       /* set dlIdx for which ulAscInfo is updated */
19576       dlPres = dlPres | (1 << dlIdx);
19577       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19578    }
19579
19580    /* Set Invalid information for which ulAscInfo is not present */
19581    for (sfCount = 0;
19582          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19583          sfCount++)
19584    {
19585       /* If dlPres is 0, ulAscInfo is not present in that DL index */
19586       if(! ((dlPres >> sfCount)&0x01))
19587       {
19588          cell->subFrms[sfCount]->ulAscInfo.sfnOffset =
19589             RGSCH_INVALID_INFO;
19590          cell->subFrms[sfCount]->ulAscInfo.subframe =
19591             RGSCH_INVALID_INFO;
19592       }
19593    }
19594
19595    /* DL subframes in the subsequent radio frames are initialized
19596     * with the previous radio frames  */
19597    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;
19598          dlIdx++)
19599    {
19600       sfNum = dlIdx - \
19601               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19602       cell->subFrms[dlIdx]->ulAscInfo.subframe =
19603          cell->subFrms[sfNum]->ulAscInfo.subframe;
19604       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset =
19605          cell->subFrms[sfNum]->ulAscInfo.sfnOffset;
19606    }
19607    RETVALUE(ROK);
19608 }
19609
19610
19611 /**
19612  * @brief This function initialises the 'Np' value for 'p'
19613  *
19614  * @details
19615  *
19616  *     Function: rgSCHCmnDlNpValInit
19617  *     Purpose:  To initialise the 'Np' value for each 'p'. It is used
19618  *               to find the mapping between nCCE and 'p' and used in
19619  *               HARQ ACK/NACK reception.
19620  *
19621  *     Invoked by: Scheduler
19622  *
19623  *  @param[in]  RgSchCellCb*     cell
19624  *  @return     S16
19625  *
19626  **/
19627 #ifdef ANSI
19628 PRIVATE S16 rgSCHCmnDlNpValInit
19629 (
19630 RgSchCellCb                *cell
19631 )
19632 #else
19633 PRIVATE S16 rgSCHCmnDlNpValInit(cell)
19634 RgSchCellCb                *cell;
19635 #endif
19636 {
19637    U8    idx;
19638    U16   np;
19639    TRC2(rgSCHCmnDlNpValInit);
19640
19641    /* Always Np is 0 for p=0 */
19642    cell->rgSchTddNpValTbl[0] = 0;
19643
19644    for(idx=1; idx < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; idx++)
19645    {
19646       np = cell->bwCfg.dlTotalBw * (idx * RG_SCH_CMN_NUM_SUBCAR - 4);
19647       cell->rgSchTddNpValTbl[idx] = (U8) (np/36);
19648    }
19649
19650    RETVALUE(ROK);
19651 }
19652
19653 /**
19654  * @brief This function handles the creation of RACH preamble
19655  *        list to queue the preambles and process at the scheduled
19656  *        time.
19657  *
19658  * @details
19659  *
19660  *     Function: rgSCHCmnDlCreateRachPrmLst
19661  *     Purpose:  To create RACH preamble list based on RA window size.
19662  *               It is used to queue the preambles and process it at the
19663  *               scheduled time.
19664  *
19665  *     Invoked by: Scheduler
19666  *
19667  *  @param[in]  RgSchCellCb*     cell
19668  *  @return     S16
19669  *
19670  **/
19671 #ifdef ANSI
19672 PRIVATE S16 rgSCHCmnDlCreateRachPrmLst
19673 (
19674 RgSchCellCb                *cell
19675 )
19676 #else
19677 PRIVATE S16 rgSCHCmnDlCreateRachPrmLst(cell)
19678 RgSchCellCb                *cell;
19679 #endif
19680 {
19681  U8       raArrSz;
19682  S16       ret;
19683  U8       lstSize;
19684
19685    TRC2(rgSCHCmnDlCreateRachPrmLst);
19686
19687    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
19688
19689    lstSize = raArrSz * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES;
19690
19691    cell->raInfo.maxRaSize = raArrSz;
19692    ret = rgSCHUtlAllocSBuf(cell->instIdx,
19693          (Data **)(&cell->raInfo.raReqLst), (Size)(lstSize * sizeof(CmLListCp)));
19694    if (ret != ROK)
19695    {
19696       RETVALUE(ret);
19697    }
19698
19699    cell->raInfo.lstSize = lstSize;
19700
19701    RETVALUE(ROK);
19702 }
19703
19704
19705 /**
19706  * @brief This function handles the initialization of RACH Response
19707  *        information at each DL subframe.
19708  *
19709  * @details
19710  *
19711  *     Function: rgSCHCmnDlRachInfoInit
19712  *     Purpose:  Each DL subframe stores the sfn and subframe information of
19713  *               possible RACH response allowed for UL subframes. It generates
19714  *               the information based on PRACH configuration.
19715  *
19716  *     Invoked by: Scheduler
19717  *
19718  *  @param[in]  RgSchCellCb*     cell
19719  *  @return     S16
19720  *
19721  **/
19722 #ifdef ANSI
19723 PRIVATE S16 rgSCHCmnDlRachInfoInit
19724 (
19725 RgSchCellCb                *cell
19726 )
19727 #else
19728 PRIVATE S16 rgSCHCmnDlRachInfoInit(cell)
19729 RgSchCellCb                *cell;
19730 #endif
19731 {
19732    U8                   sfCount;
19733    U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
19734    U8                   sfNum;
19735    U8                   ulSfCnt =0;
19736    U8                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19737                                        [RGSCH_NUM_SUB_FRAMES-1];
19738    U8                   raArrSz;
19739    RgSchTddRachRspLst   rachRspLst[3][RGSCH_NUM_SUB_FRAMES];
19740    U8                   startWin;
19741    U8                   endWin;
19742    U8                   sfnIdx;
19743    U8                   subfrmIdx;
19744    U8                   endSubfrmIdx;
19745    U8                   startSubfrmIdx;
19746    S16                   ret;
19747    RgSchTddRachDelInfo  *delInfo;
19748    S8                   sfnOffset;
19749    U8                   numSubfrms;
19750
19751    TRC2(rgSCHCmnDlRachInfoInit);
19752
19753    cmMemset((U8 *)rachRspLst, 0, sizeof(rachRspLst));
19754
19755    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
19756
19757    /* Include Special subframes */
19758    maxUlSubfrms = maxUlSubfrms + \
19759                   rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx].switchPoints;
19760    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19761    {
19762       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
19763             RG_SCH_TDD_DL_SUBFRAME)
19764       {
19765          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19766       }
19767       ulSfCnt++;
19768
19769       startWin = (sfNum + RG_SCH_CMN_RARSP_WAIT_PRD + \
19770             ((RgSchCmnCell *)cell->sc.sch)->dl.numRaSubFrms);
19771       endWin = (startWin + cell->rachCfg.raWinSize - 1);
19772       startSubfrmIdx =
19773          rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][startWin%RGSCH_NUM_SUB_FRAMES];
19774       /* Find the next DL subframe starting from Subframe 0 */
19775       if((startSubfrmIdx % RGSCH_NUM_SUB_FRAMES) == 0)
19776       {
19777          startWin = RGSCH_CEIL(startWin, RGSCH_NUM_SUB_FRAMES);
19778          startWin = startWin * RGSCH_NUM_SUB_FRAMES;
19779       }
19780
19781       endSubfrmIdx =
19782          rgSchTddLowDlSubfrmIdxTbl[ulDlCfgIdx][endWin%RGSCH_NUM_SUB_FRAMES];
19783       endWin = (endWin/RGSCH_NUM_SUB_FRAMES) * RGSCH_NUM_SUB_FRAMES \
19784                + endSubfrmIdx;
19785       if(startWin > endWin)
19786       {
19787          continue;
19788       }
19789       /* Find all the possible RACH Response transmission
19790        * time within the RA window size */
19791       startSubfrmIdx = startWin%RGSCH_NUM_SUB_FRAMES;
19792       for(sfnIdx = startWin/RGSCH_NUM_SUB_FRAMES;
19793             sfnIdx <= endWin/RGSCH_NUM_SUB_FRAMES; sfnIdx++)
19794       {
19795          if(sfnIdx == endWin/RGSCH_NUM_SUB_FRAMES)
19796          {
19797             endSubfrmIdx = endWin%RGSCH_NUM_SUB_FRAMES;
19798          }
19799          else
19800          {
19801             endSubfrmIdx = RGSCH_NUM_SUB_FRAMES-1;
19802          }
19803
19804          /* Find all the possible RACH Response transmission
19805           * time within radio frame */
19806          for(subfrmIdx = startSubfrmIdx;
19807                subfrmIdx <= endSubfrmIdx; subfrmIdx++)
19808          {
19809             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][subfrmIdx] ==
19810                   RG_SCH_TDD_UL_SUBFRAME)
19811             {
19812                continue;
19813             }
19814             subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
19815             /* Find the next DL subframe starting from Subframe 0 */
19816             if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
19817             {
19818                break;
19819             }
19820             RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx], subfrmIdx);
19821             numSubfrms =
19822                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
19823             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset = sfnIdx;
19824             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].subframe[numSubfrms]
19825                = sfNum;
19826             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms++;
19827          }
19828          startSubfrmIdx = RG_SCH_CMN_SUBFRM_0;
19829       }
19830       /* Update the subframes to be deleted at this subframe */
19831       /* Get the subframe after the end of RA window size */
19832       endWin++;
19833       endSubfrmIdx++;
19834       sfnOffset = endWin/RGSCH_NUM_SUB_FRAMES;
19835       if(sfnOffset < 0)
19836       {
19837          sfnOffset += raArrSz;
19838       }
19839       sfnIdx = (endWin/RGSCH_NUM_SUB_FRAMES) % raArrSz;
19840
19841       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx],endSubfrmIdx-1);
19842       if((endSubfrmIdx == RGSCH_NUM_SUB_FRAMES) ||
19843             (rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx] ==
19844              RGSCH_NUM_SUB_FRAMES))
19845       {
19846          subfrmIdx =
19847             rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][RG_SCH_CMN_SUBFRM_0];
19848       }
19849       else
19850       {
19851          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx];
19852       }
19853
19854       delInfo = &rachRspLst[sfnIdx][subfrmIdx].delInfo;
19855       delInfo->sfnOffset = sfnOffset;
19856       delInfo->subframe[delInfo->numSubfrms] = sfNum;
19857       delInfo->numSubfrms++;
19858
19859       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19860    }
19861
19862    ret = rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz);
19863    if (ret != ROK)
19864    {
19865       RETVALUE(ret);
19866    }
19867
19868    RETVALUE(ROK);
19869 }
19870
19871 /**
19872  * @brief This function handles the initialization of PHICH information
19873  *        for each DL subframe based on PHICH table.
19874  *
19875  * @details
19876  *
19877  *     Function: rgSCHCmnDlPhichOffsetInit
19878  *     Purpose:  Each DL subf stores the sfn and subf information of UL subframe
19879  *               for which it trnsmts PHICH in this subframe. It generates the information
19880  *               based on PHICH table.
19881  *
19882  *     Invoked by: Scheduler
19883  *
19884  *  @param[in]  RgSchCellCb*     cell
19885  *  @return     S16
19886  *
19887  **/
19888 #ifdef ANSI
19889 PRIVATE S16 rgSCHCmnDlPhichOffsetInit
19890 (
19891 RgSchCellCb                *cell
19892 )
19893 #else
19894 PRIVATE S16 rgSCHCmnDlPhichOffsetInit(cell)
19895 RgSchCellCb                *cell;
19896 #endif
19897 {
19898    U8                   sfCount;
19899    U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
19900    U8                   maxDlSubfrms = cell->numDlSubfrms;
19901    U8                   sfNum;
19902    U8                   dlIdx;
19903    U8                   dlPres = 0;
19904    U8                   calcSfnOffset;
19905    U8                   calcSfNum;
19906    U8                   ulSfCnt =0;
19907    RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19908    U8                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19909                                        [RGSCH_NUM_SUB_FRAMES-1];
19910
19911    TRC2(rgSCHCmnDlPhichOffsetInit);
19912
19913    /* Generate PHICH offset information for each DL subframe in a radio frame
19914     * Calculate this information based on K in PHICH table */
19915    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19916    {
19917       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19918             RG_SCH_TDD_UL_SUBFRAME)
19919       {
19920          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19921       }
19922       ulSfCnt++;
19923
19924       calcSfNum = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) % \
19925                   RGSCH_NUM_SUB_FRAMES;
19926       calcSfnOffset = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) / \
19927                       RGSCH_NUM_SUB_FRAMES;
19928
19929       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19930       {
19931          dlIdx = calcSfNum;
19932       }
19933       else if((ulSubfrmInfo.switchPoints == 2) &&
19934             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
19935       {
19936          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19937       }
19938       else
19939       {
19940          dlIdx = calcSfNum - maxUlSubfrms;
19941       }
19942
19943       cell->subFrms[dlIdx]->phichOffInfo.subframe = sfNum;
19944       cell->subFrms[dlIdx]->phichOffInfo.numSubfrms = 1;
19945
19946       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = calcSfnOffset;
19947
19948       /* set dlIdx for which phich offset is updated */
19949       dlPres = dlPres | (1 << dlIdx);
19950       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19951    }
19952
19953    /* Set Invalid information for which phich offset is not present */
19954    for (sfCount = 0;
19955          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19956          sfCount++)
19957    {
19958       /* If dlPres is 0, phich offset is not present in that DL index */
19959       if(! ((dlPres >> sfCount)&0x01))
19960       {
19961          cell->subFrms[sfCount]->phichOffInfo.sfnOffset =
19962             RGSCH_INVALID_INFO;
19963          cell->subFrms[sfCount]->phichOffInfo.subframe =
19964             RGSCH_INVALID_INFO;
19965          cell->subFrms[sfCount]->phichOffInfo.numSubfrms = 0;
19966       }
19967    }
19968
19969    /* DL subframes in the subsequent radio frames are
19970     * initialized with the previous radio frames  */
19971    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms;
19972          dlIdx < maxDlSubfrms; dlIdx++)
19973    {
19974       sfNum = dlIdx - \
19975               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19976
19977       cell->subFrms[dlIdx]->phichOffInfo.subframe =
19978          cell->subFrms[sfNum]->phichOffInfo.subframe;
19979
19980       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset =
19981          cell->subFrms[sfNum]->phichOffInfo.sfnOffset;
19982    }
19983    RETVALUE(ROK);
19984 }
19985
19986
19987 /**
19988  * @brief Updation of Sch vars per TTI.
19989  *
19990  * @details
19991  *
19992  *     Function: rgSCHCmnUpdVars
19993  *     Purpose:  Updation of Sch vars per TTI.
19994  *
19995  *  @param[in]  RgSchCellCb *cell
19996  *  @return  Void
19997  *
19998  **/
19999 #ifdef ANSI
20000 PUBLIC Void rgSCHCmnUpdVars
20001 (
20002 RgSchCellCb *cell
20003 )
20004 #else
20005 PUBLIC Void rgSCHCmnUpdVars(cell)
20006 RgSchCellCb *cell;
20007 #endif
20008 {
20009    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
20010    CmLteTimingInfo   timeInfo;
20011    U8                idx;
20012    U8                ulSubframe;
20013    U8                ulDlCfgIdx = cell->ulDlCfgIdx;
20014    U8                msg3Subfrm;
20015    U8                Mval;
20016    TRC2(rgSCHCmnUpdVars);
20017  
20018    /* ccpu00132654-ADD- Initializing all the indices in every subframe*/ 
20019    rgSCHCmnInitVars(cell);
20020
20021    idx = (cell->crntTime.subframe + TFU_ULCNTRL_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
20022    /* Calculate the UL scheduling subframe idx based on the 
20023       Pusch k table */
20024    if(rgSchTddPuschTxKTbl[ulDlCfgIdx][idx] != 0)
20025    {
20026       /* PUSCH transmission is based on offset from DL
20027        * PDCCH scheduling */
20028       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); 
20029       ulSubframe = rgSchTddPuschTxKTbl[ulDlCfgIdx][timeInfo.subframe];
20030       /* Add the DCI-0 to PUSCH time to get the time of UL subframe */
20031       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, ulSubframe);
20032 #ifdef LTEMAC_SPS
20033       cellUl->schdTti = timeInfo.sfn * 10 + timeInfo.subframe;
20034 #endif
20035       /* Fetch the corresponding  UL subframe Idx in UL sf array */ 
20036       cellUl->schdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
20037       /* Fetch the corresponding  UL Harq Proc ID */ 
20038       cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
20039       cellUl->schdTime = timeInfo;
20040    }
20041    Mval = rgSchTddPhichMValTbl[ulDlCfgIdx][idx]; 
20042    if(Mval)
20043    {
20044       /* Fetch the tx time for DL HIDCI-0 */
20045       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA);
20046       /* Fetch the corresponding n-k tx time of PUSCH */
20047       cellUl->hqFdbkIdx[0] = rgSCHCmnGetPhichUlSfIdx(&timeInfo, cell);
20048       /* Retx will happen according to the Pusch k table */
20049       cellUl->reTxIdx[0] = cellUl->schdIdx;
20050       
20051       if(ulDlCfgIdx == 0) 
20052       {
20053          /* Calculate the ReTxIdx corresponding to hqFdbkIdx[0] */
20054          cellUl->reTxIdx[0] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
20055                                                 cellUl->hqFdbkIdx[0]);
20056          if(Mval == 2)
20057          {
20058             /* At Idx 1 store the UL SF adjacent(left) to the UL SF
20059                given at idx 0 */  
20060             cellUl->hqFdbkIdx[1] = (cellUl->hqFdbkIdx[0]-1 + 
20061                                    cellUl->numUlSubfrms) % cellUl->numUlSubfrms;
20062             /* Calculate the ReTxIdx corresponding to hqFdbkIdx[1] */
20063             cellUl->reTxIdx[1] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
20064                                                 cellUl->hqFdbkIdx[1]);
20065          }                               
20066       }
20067    }
20068
20069    idx = (cell->crntTime.subframe + TFU_RECPREQ_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
20070    if (rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == RG_SCH_TDD_UL_SUBFRAME)
20071    {
20072       RGSCHCMNADDTOCRNTTIME(cell->crntTime, timeInfo, TFU_RECPREQ_DLDELTA)
20073       cellUl->rcpReqIdx   = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
20074    }
20075    idx = (cell->crntTime.subframe+RG_SCH_CMN_DL_DELTA) % RGSCH_NUM_SUB_FRAMES;
20076    
20077    /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
20078      special subframe */                       
20079    if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] != RG_SCH_TDD_UL_SUBFRAME)
20080    {
20081       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
20082       msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
20083       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, msg3Subfrm);
20084       cellUl->msg3SchdIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
20085       cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
20086    }
20087 #ifdef LTEMAC_SPS
20088    if(!rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][idx])
20089    {
20090       cellUl->spsUlRsrvIdx = RGSCH_INVALID_INFO;
20091    }
20092    else
20093    {
20094       /* introduce some reuse with above code? */
20095       U8    offst;
20096       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
20097       //offst = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
20098       offst = rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][timeInfo.subframe];
20099       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, offst);
20100       cellUl->spsUlRsrvIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
20101       /* The harq proc continues to be accessed and used the same delta before
20102        * actual data occurance, and hence use the same idx */
20103       cellUl->spsUlRsrvHqProcIdx = cellUl->schdHqProcIdx;
20104    }
20105 #endif
20106
20107    /* RACHO: update cmn sched specific RACH variables,
20108     * mainly the prachMaskIndex */
20109    rgSCHCmnUpdRachParam(cell);
20110
20111    RETVOID;
20112 }
20113
20114 /**
20115  * @brief To get 'p' value from nCCE.
20116  *
20117  * @details
20118  *
20119  *     Function: rgSCHCmnGetPValFrmCCE
20120  *     Purpose:  Gets 'p' value for HARQ ACK/NACK reception from CCE.
20121  *
20122  *  @param[in]  RgSchCellCb   *cell
20123  *  @param[in]  U8            cce
20124  *  @return U8
20125  *
20126  **/
20127 #ifdef ANSI
20128 PUBLIC U8  rgSCHCmnGetPValFrmCCE
20129 (
20130 RgSchCellCb *cell,
20131 U8          cce
20132 )
20133 #else
20134 PUBLIC U8  rgSCHCmnGetPValFrmCCE(cell, cce)
20135 RgSchCellCb *cell;
20136 U8          cce;
20137 #endif
20138 {
20139    U8 i;
20140    TRC2(rgSCHCmnGetPValFrmCCE);
20141
20142    for(i=1; i < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; i++)
20143    {
20144       if(cce < cell->rgSchTddNpValTbl[i])
20145       {
20146          RETVALUE(i-1);
20147       }
20148    }
20149    RETVALUE(0);
20150 }
20151 #endif
20152
20153 /***********************************************************
20154  *
20155  *     Func : rgSCHCmnUlAdapRetx
20156  *
20157  *     Desc : Adaptive retransmission for an allocation.
20158  *
20159  *     Ret  :
20160  *
20161  *     Notes:
20162  *
20163  *     File :
20164  *
20165  **********************************************************/
20166 #ifdef ANSI
20167 PRIVATE Void rgSCHCmnUlAdapRetx
20168 (
20169 RgSchUlAlloc    *alloc,
20170 RgSchUlHqProcCb *proc
20171 )
20172 #else
20173 PRIVATE Void rgSCHCmnUlAdapRetx(alloc, proc)
20174 RgSchUlAlloc    *alloc;
20175 RgSchUlHqProcCb *proc;
20176 #endif
20177 {
20178    TRC2(rgSCHCmnUlAdapRetx);
20179
20180    rgSCHUhmRetx(proc, alloc);
20181 #ifndef RG_5GTF
20182    if (proc->rvIdx != 0)
20183    {
20184       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[proc->rvIdx];
20185    }
20186    else
20187 #endif
20188    {
20189       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
20190    }
20191    RETVOID;
20192 }
20193
20194 /**
20195  * @brief Scheduler invocation per TTI.
20196  *
20197  * @details
20198  *
20199  *     Function: rgSCHCmnHdlUlInactUes
20200  *     Purpose:
20201  *
20202  *     Invoked by: Common Scheduler
20203  *
20204  *  @param[in]  RgSchCellCb *cell
20205  *  @return  Void
20206  **/
20207 #ifdef ANSI
20208 PRIVATE Void rgSCHCmnHdlUlInactUes
20209 (
20210 RgSchCellCb  *cell
20211 )
20212 #else
20213 PRIVATE Void rgSCHCmnHdlUlInactUes(cell)
20214 RgSchCellCb  *cell;
20215 #endif
20216 {
20217    RgSchCmnCell  *cellSch  = RG_SCH_CMN_GET_CELL(cell);
20218    CmLListCp     ulInactvLst;
20219    TRC2(rgSCHCmnHdlUlInactUes);
20220    /* Get a List of Inactv UEs for UL*/
20221    cmLListInit(&ulInactvLst);
20222
20223    /* Trigger Spfc Schedulers with Inactive UEs */
20224    rgSCHMeasGapANRepGetUlInactvUe (cell, &ulInactvLst);
20225    /* take care of this in UL retransmission */
20226    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst);
20227
20228    RETVOID;
20229 }
20230
20231 /**
20232  * @brief Scheduler invocation per TTI.
20233  *
20234  * @details
20235  *
20236  *     Function: rgSCHCmnHdlDlInactUes
20237  *     Purpose:
20238  *
20239  *     Invoked by: Common Scheduler
20240  *
20241  *  @param[in]  RgSchCellCb *cell
20242  *  @return  Void
20243  **/
20244 #ifdef ANSI
20245 PRIVATE Void rgSCHCmnHdlDlInactUes
20246 (
20247 RgSchCellCb  *cell
20248 )
20249 #else
20250 PRIVATE Void rgSCHCmnHdlDlInactUes(cell)
20251 RgSchCellCb  *cell;
20252 #endif
20253 {
20254    RgSchCmnCell *cellSch  = RG_SCH_CMN_GET_CELL(cell);
20255    CmLListCp    dlInactvLst;
20256    TRC2(rgSCHCmnHdlDlInactUes);
20257    /* Get a List of Inactv UEs for DL */
20258    cmLListInit(&dlInactvLst);
20259
20260    /* Trigger Spfc Schedulers with Inactive UEs */
20261    rgSCHMeasGapANRepGetDlInactvUe (cell, &dlInactvLst);
20262
20263    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst);
20264    RETVOID;
20265 }
20266
20267 /* RACHO: Rach handover functions start here */
20268 /***********************************************************
20269  *
20270  *     Func : rgSCHCmnUeIdleExdThrsld
20271  *
20272  *     Desc : RETURN ROK if UE has been idle more
20273  *            than threshold.
20274  *
20275  *     Ret  :
20276  *
20277  *     Notes:
20278  *
20279  *     File :
20280  *
20281  **********************************************************/
20282 #ifdef ANSI
20283 PRIVATE S16 rgSCHCmnUeIdleExdThrsld
20284 (
20285 RgSchCellCb     *cell,
20286 RgSchUeCb       *ue
20287 )
20288 #else
20289 PRIVATE S16 rgSCHCmnUeIdleExdThrsld(cell, ue)
20290 RgSchCellCb     *cell;
20291 RgSchUeCb       *ue;
20292 #endif
20293 {
20294    /* Time difference in subframes */
20295    U32 sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, ue->ul.ulTransTime);
20296
20297    TRC2(rgSCHCmnUeIdleExdThrsld);
20298
20299    if (sfDiff > (U32)RG_SCH_CMN_UE_IDLE_THRSLD(ue))
20300    {
20301       RETVALUE(ROK);
20302    }
20303    else
20304    {
20305       RETVALUE(RFAILED);
20306    }
20307 }
20308
20309 \f
20310 /**
20311  * @brief Scheduler processing for Ded Preambles on cell configuration.
20312  *
20313  * @details
20314  *
20315  *     Function : rgSCHCmnCfgRachDedPrm
20316  *
20317  *     This function does requisite initialisation
20318  *     for RACH Ded Preambles.
20319  *
20320  *
20321  *  @param[in]  RgSchCellCb   *cell
20322  *  @return  Void
20323  **/
20324 #ifdef ANSI
20325 PRIVATE Void rgSCHCmnCfgRachDedPrm
20326 (
20327 RgSchCellCb   *cell
20328 )
20329 #else
20330 PRIVATE Void rgSCHCmnCfgRachDedPrm(cell)
20331 RgSchCellCb   *cell;
20332 #endif
20333 {
20334    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20335    U32          gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
20336    U32          sfDiff;
20337    U8           cnt;
20338    TRC2(rgSCHCmnCfgRachDedPrm);
20339
20340    if (cell->macPreambleSet.pres == NOTPRSNT)
20341    {
20342       RETVOID;
20343    }
20344    cellSch->rachCfg.numDedPrm = cell->macPreambleSet.size;
20345    cellSch->rachCfg.dedPrmStart = cell->macPreambleSet.start;
20346    /* Initialize handover List */
20347    cmLListInit(&cellSch->rachCfg.hoUeLst);
20348    /* Initialize pdcch Order List */
20349    cmLListInit(&cellSch->rachCfg.pdcchOdrLst);
20350
20351    /* Intialize the rapId to UE mapping structure */
20352    for (cnt = 0; cnt<cellSch->rachCfg.numDedPrm; cnt++)
20353    {
20354       cellSch->rachCfg.rapIdMap[cnt].rapId = cellSch->rachCfg.dedPrmStart + \
20355                                              cnt;
20356       cmLListInit(&cellSch->rachCfg.rapIdMap[cnt].assgndUes);
20357    }
20358    /* Perform Prach Mask Idx, remDedPrm, applFrm initializations */
20359    /* Set remDedPrm as numDedPrm */
20360    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
20361    /* Initialize applFrm */
20362    cellSch->rachCfg.prachMskIndx = 0;
20363    if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_EVEN)
20364    {
20365       cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + \
20366             (cell->crntTime.sfn % 2)) % RGSCH_MAX_SFN;
20367    }
20368 #ifdef LTE_TDD
20369    else if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ODD)
20370    {
20371       if((cell->crntTime.sfn%2) == 0)
20372       {
20373          cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + 1)\
20374                                         % RGSCH_MAX_SFN;
20375       }
20376    }
20377 #endif
20378    else /* ANY sfn */
20379    {
20380       cellSch->rachCfg.applFrm.sfn = cell->crntTime.sfn;
20381    }
20382    /* Initialize cellSch->rachCfg.applFrm as >= crntTime.
20383     * This is because of RGSCH_CALC_SF_DIFF logic */
20384    if (cellSch->rachCfg.applFrm.sfn == cell->crntTime.sfn)
20385    {
20386       while (cellSch->rachCfg.prachMskIndx < cell->rachCfg.raOccasion.size)
20387       {
20388          if (cell->crntTime.subframe <\
20389                cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx])
20390          {
20391             break;
20392          }
20393          cellSch->rachCfg.prachMskIndx++;
20394       }
20395       if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size)
20396       {
20397          if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
20398          {
20399             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) %\
20400                                            RGSCH_MAX_SFN;
20401          }
20402          else
20403          {
20404             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) %\
20405                                            RGSCH_MAX_SFN;
20406          }
20407          cellSch->rachCfg.prachMskIndx = 0;
20408       }
20409       cellSch->rachCfg.applFrm.subframe = \
20410                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20411    }
20412    else
20413    {
20414       cellSch->rachCfg.applFrm.subframe = \
20415                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20416    }
20417
20418    /* Note first param to this macro should always be the latest in time */
20419    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
20420    while (sfDiff <= gap)
20421    {
20422       rgSCHCmnUpdNxtPrchMskIdx(cell);
20423       sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
20424    }
20425
20426    RETVOID;
20427 }
20428
20429 /**
20430  * @brief Updates the PRACH MASK INDEX.
20431  *
20432  * @details
20433  *
20434  *     Function: rgSCHCmnUpdNxtPrchMskIdx
20435  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
20436  *     CFG is always >= "n"+"DELTA", where "n" is the crntTime
20437  *     of the cell. If not, applFrm is updated to the next avl
20438  *     PRACH oppurtunity as per the PRACH Cfg Index configuration.
20439  *
20440  *
20441  *     Invoked by: Common Scheduler
20442  *
20443  *  @param[in]  RgSchCellCb *cell
20444  *  @return  Void
20445  **/
20446 #ifdef ANSI
20447 PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx
20448 (
20449 RgSchCellCb  *cell
20450 )
20451 #else
20452 PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx(cell)
20453 RgSchCellCb  *cell;
20454 #endif
20455 {
20456    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20457    TRC2(rgSCHCmnUpdNxtPrchMskIdx);
20458
20459    /* Determine the next prach mask Index */
20460    if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size - 1)
20461    {
20462       /* PRACH within applFrm.sfn are done, go to next AVL sfn */
20463       cellSch->rachCfg.prachMskIndx = 0;
20464       if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
20465       {
20466          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) % \
20467                                         RGSCH_MAX_SFN;
20468       }
20469       else/* RGR_SFN_EVEN or RGR_SFN_ODD */
20470       {
20471          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) % \
20472                                         RGSCH_MAX_SFN;
20473       }
20474       cellSch->rachCfg.applFrm.subframe = cell->rachCfg.raOccasion.\
20475                                           subFrameNum[0];
20476    }
20477    else /* applFrm.sfn is still valid */
20478    {
20479       cellSch->rachCfg.prachMskIndx += 1;
20480       if ( cellSch->rachCfg.prachMskIndx < RGR_MAX_SUBFRAME_NUM )
20481       {
20482          cellSch->rachCfg.applFrm.subframe = \
20483                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20484       }
20485    }
20486    RETVOID;
20487 }
20488
20489 /**
20490  * @brief Updates the Ded preamble RACH parameters
20491  *        every TTI.
20492  *
20493  * @details
20494  *
20495  *     Function: rgSCHCmnUpdRachParam
20496  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
20497  *     CFG is always >= "n"+"6"+"DELTA", where "n" is the crntTime
20498  *     of the cell. If not, applFrm is updated to the next avl
20499  *     PRACH oppurtunity as per the PRACH Cfg Index configuration,
20500  *     accordingly the "remDedPrm" is reset to "numDedPrm" and
20501  *     "prachMskIdx" field is updated as per "applFrm".
20502  *
20503  *
20504  *     Invoked by: Common Scheduler
20505  *
20506  *  @param[in]  RgSchCellCb *cell
20507  *  @return  Void
20508  **/
20509 #ifdef ANSI
20510 PRIVATE Void rgSCHCmnUpdRachParam
20511 (
20512 RgSchCellCb  *cell
20513 )
20514 #else
20515 PRIVATE Void rgSCHCmnUpdRachParam(cell)
20516 RgSchCellCb  *cell;
20517 #endif
20518 {
20519
20520    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20521    U32             gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
20522    U32             sfDiff;
20523    TRC2(rgSCHCmnUpdRachParam);
20524
20525    if (cell->macPreambleSet.pres == NOTPRSNT)
20526    {
20527       RETVOID;
20528    }
20529    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, \
20530          cell->crntTime);
20531    if (sfDiff > gap)
20532    {
20533       /* applFrm is still a valid next Prach Oppurtunity */
20534       RETVOID;
20535    }
20536    rgSCHCmnUpdNxtPrchMskIdx(cell);
20537    /* Reset remDedPrm as numDedPrm */
20538    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
20539
20540    RETVOID;
20541 }
20542
20543 /**
20544  * @brief Dedicated Preamble allocation function.
20545  *
20546  * @details
20547  *
20548  *     Function: rgSCHCmnAllocPOParam
20549  *     Purpose:  Allocate pdcch, rapId and PrachMskIdx.
20550  *     Set mapping of UE with the allocated rapId.
20551  *
20552  *     Invoked by: Common Scheduler
20553  *
20554  *  @param[in]   RgSchCellCb *cell
20555  *  @param[in]   RgSchDlSf   *dlSf
20556  *  @param[in]   RgSchUeCb   *ue
20557  *  @param[out]  RgSchPdcch  **pdcch
20558  *  @param[out]  U8          *rapId
20559  *  @param[out]  U8          *prachMskIdx
20560  *  @return  Void
20561  **/
20562 #ifdef ANSI
20563 PRIVATE S16 rgSCHCmnAllocPOParam
20564 (
20565 RgSchCellCb  *cell,
20566 RgSchDlSf    *dlSf,
20567 RgSchUeCb    *ue,
20568 RgSchPdcch   **pdcch,
20569 U8           *rapId,
20570 U8           *prachMskIdx
20571 )
20572 #else
20573 PRIVATE S16 rgSCHCmnAllocPOParam(cell, dlSf, ue, pdcch, rapId, prachMskIdx)
20574 RgSchCellCb  *cell;
20575 RgSchDlSf    *dlSf;
20576 RgSchUeCb    *ue;
20577 RgSchPdcch   **pdcch;
20578 U8           *rapId;
20579 U8           *prachMskIdx;
20580 #endif
20581 {
20582
20583    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20584    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20585
20586    TRC2(rgSCHCmnAllocPOParam);
20587
20588    if (cell->macPreambleSet.pres == PRSNT_NODEF)
20589    {
20590       if (cellSch->rachCfg.remDedPrm == 0)
20591       {
20592          RETVALUE(RFAILED);
20593       }
20594       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
20595       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
20596       {
20597          RETVALUE(RFAILED);
20598       }
20599       /* The stored prachMskIdx is the index of PRACH Oppurtunities in
20600        * raOccasions.subframes[].
20601        * Converting the same to the actual PRACHMskIdx to be transmitted. */
20602       *prachMskIdx = cellSch->rachCfg.prachMskIndx + 1;
20603       /* Distribution starts from dedPrmStart till dedPrmStart + numDedPrm */
20604       *rapId =  cellSch->rachCfg.dedPrmStart +
20605          cellSch->rachCfg.numDedPrm - cellSch->rachCfg.remDedPrm;
20606       cellSch->rachCfg.remDedPrm--;
20607       /* Map UE with the allocated RapId */
20608       ueDl->rachInfo.asgnOppr = cellSch->rachCfg.applFrm;
20609       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, cellSch->rachCfg.rapIdMap, (*rapId - cellSch->rachCfg.dedPrmStart));
20610       cmLListAdd2Tail(&cellSch->rachCfg.rapIdMap[*rapId - cellSch->rachCfg.dedPrmStart].assgndUes, 
20611              &ueDl->rachInfo.rapIdLnk);
20612       ueDl->rachInfo.rapIdLnk.node = (PTR)ue;
20613       ueDl->rachInfo.poRapId = *rapId;
20614    }
20615    else /* if dedicated preambles not configured */
20616    {
20617       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
20618       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
20619       {
20620          RETVALUE(RFAILED);
20621       }
20622       *prachMskIdx = 0;
20623       *rapId       = 0;
20624    }
20625
20626    RETVALUE(ROK);
20627 }
20628
20629 /**
20630  * @brief Dowlink Scheduling Handler.
20631  *
20632  * @details
20633  *
20634  *     Function: rgSCHCmnGenPdcchOrder
20635  *     Purpose:  For each UE in PO Q, grab a PDCCH,
20636  *     get an available ded RapId and fill PDCCH
20637  *     with PO information.
20638  *
20639  *     Invoked by: Common Scheduler
20640  *
20641  *  @param[in]  RgSchCellCb *cell
20642  *  @param[in]  RgSchDlSf   *dlSf
20643  *  @return  Void
20644  **/
20645 #ifdef ANSI
20646 PRIVATE Void rgSCHCmnGenPdcchOrder
20647 (
20648 RgSchCellCb  *cell,
20649 RgSchDlSf    *dlSf
20650 )
20651 #else
20652 PRIVATE Void rgSCHCmnGenPdcchOrder(cell, dlSf)
20653 RgSchCellCb  *cell;
20654 RgSchDlSf    *dlSf;
20655 #endif
20656 {
20657    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
20658    CmLList           *node = cellSch->rachCfg.pdcchOdrLst.first;
20659    RgSchUeCb         *ue;
20660    U8                rapId;
20661    U8                prachMskIdx;
20662    RgSchPdcch        *pdcch = NULLP;
20663
20664    TRC2(rgSCHCmnGenPdcchOrder);
20665
20666    while (node)
20667    {
20668       ue = (RgSchUeCb *)node->node;
20669       node = node->next;
20670       /* Skip sending for this subframe is Measuring or inActive in UL due
20671        * to MeasGap or inactie due to DRX
20672        */
20673       if  ((ue->measGapCb.isMeasuring == TRUE) ||
20674            (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) ||
20675            (ue->isDrxEnabled &&
20676              ue->dl.dlInactvMask & RG_DRX_INACTIVE)
20677            )
20678       {
20679          continue;
20680       }
20681       if (rgSCHCmnAllocPOParam(cell, dlSf, ue, &pdcch, &rapId,\
20682                &prachMskIdx) != ROK)
20683       {
20684          /* No More rapIds left for the valid next avl Oppurtunity.
20685           * Unsatisfied UEs here would be given a chance, when the
20686           * prach Mask Index changes as per rachUpd every TTI */
20687
20688          /* PDDCH can also be ordered with rapId=0, prachMskIdx=0
20689           * so that UE triggers a RACH procedure with non-dedicated preamble.
20690           * But the implementation here does not do this. Instead, the "break"
20691           * here implies, that PDCCH Odr always given with valid rapId!=0,
20692           * prachMskIdx!=0 if dedicated preambles are configured.
20693           * If not configured, then trigger a PO with rapId=0,prchMskIdx=0*/
20694          break;
20695       }
20696       /* Fill pdcch with pdcch odr information */
20697       rgSCHCmnFillPdcchOdr2Sf(cell, ue, pdcch, rapId, prachMskIdx);
20698       /* Remove this UE from the PDCCH ORDER QUEUE */
20699       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
20700       /* Reset UE's power state */
20701       rgSCHPwrUeReset(cell, ue);
20702    }
20703    RETVOID;
20704 }
20705
20706 \f
20707 /**
20708  * @brief This function add UE to PdcchOdr Q if not already present.
20709  *
20710  * @details
20711  *
20712  *     Function: rgSCHCmnDlAdd2PdcchOdrQ
20713  *     Purpose:
20714  *
20715  *     Invoked by: CMN Scheduler
20716  *
20717  *  @param[in]  RgSchCellCb*  cell
20718  *  @param[in]  RgSchUeCb*    ue
20719  *  @return  Void
20720  *
20721  **/
20722 #ifdef ANSI
20723 PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ
20724 (
20725 RgSchCellCb                *cell,
20726 RgSchUeCb                  *ue
20727 )
20728 #else
20729 PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ(cell, ue)
20730 RgSchCellCb                *cell;
20731 RgSchUeCb                  *ue;
20732 #endif
20733 {
20734    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20735    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20736
20737    TRC2(rgSCHCmnDlAdd2PdcchOdrQ);
20738
20739    if (ueDl->rachInfo.poLnk.node == NULLP)
20740    {
20741       cmLListAdd2Tail(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
20742       ueDl->rachInfo.poLnk.node = (PTR)ue;
20743    }
20744    RETVOID;
20745 }
20746
20747 \f
20748 /**
20749  * @brief This function rmvs UE to PdcchOdr Q if not already present.
20750  *
20751  * @details
20752  *
20753  *     Function: rgSCHCmnDlRmvFrmPdcchOdrQ
20754  *     Purpose:
20755  *
20756  *     Invoked by: CMN Scheduler
20757  *
20758  *  @param[in]  RgSchCellCb*  cell
20759  *  @param[in]  RgSchUeCb*    ue
20760  *  @return  Void
20761  *
20762  **/
20763 #ifdef ANSI
20764 PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ
20765 (
20766 RgSchCellCb                *cell,
20767 RgSchUeCb                  *ue
20768 )
20769 #else
20770 PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue)
20771 RgSchCellCb                *cell;
20772 RgSchUeCb                  *ue;
20773 #endif
20774 {
20775    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20776    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20777
20778    TRC2(rgSCHCmnDlRmvFrmPdcchOdrQ);
20779
20780    cmLListDelFrm(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
20781    ueDl->rachInfo.poLnk.node = NULLP;
20782    RETVOID;
20783 }
20784
20785 /**
20786  * @brief Fill pdcch with PDCCH order information.
20787  *
20788  * @details
20789  *
20790  *     Function: rgSCHCmnFillPdcchOdr2Sf
20791  *     Purpose:  Fill PDCCH with PDCCH order information,
20792  *
20793  *     Invoked by: Common Scheduler
20794  *
20795  *  @param[in]  RgSchUeCb   *ue
20796  *  @param[in]  RgSchPdcch  *pdcch
20797  *  @param[in]  U8          rapId
20798  *  @param[in]  U8          prachMskIdx
20799  *  @return  Void
20800  **/
20801 #ifdef ANSI
20802 PRIVATE Void rgSCHCmnFillPdcchOdr2Sf
20803 (
20804 RgSchCellCb *cell,
20805 RgSchUeCb   *ue,
20806 RgSchPdcch  *pdcch,
20807 U8          rapId,
20808 U8          prachMskIdx
20809 )
20810 #else
20811 PRIVATE Void rgSCHCmnFillPdcchOdr2Sf(ue, pdcch, rapId, prachMskIdx)
20812 RgSchCellCb *cell;
20813 RgSchUeCb   *ue;
20814 RgSchPdcch  *pdcch;
20815 U8          rapId;
20816 U8          prachMskIdx;
20817 #endif
20818 {
20819    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
20820
20821    TRC2(rgSCHCmnFillPdcchOdr2Sf);
20822
20823    pdcch->rnti                                         = ue->ueId;
20824    pdcch->dci.dciFormat                                = TFU_DCI_FORMAT_1A;
20825    pdcch->dci.u.format1aInfo.isPdcchOrder = TRUE;
20826    pdcch->dci.u.format1aInfo.t.pdcchOrder.preambleIdx  = rapId;
20827    pdcch->dci.u.format1aInfo.t.pdcchOrder.prachMaskIdx = prachMskIdx;
20828
20829    /* Request for APer CQI immediately after PDCCH Order */
20830    /* CR ccpu00144525 */
20831 #ifdef TFU_UPGRADE
20832    if(ue->dl.ueDlCqiCfg.aprdCqiCfg.pres)
20833    {
20834       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
20835       acqiCb->aCqiTrigWt = 0;
20836    }
20837 #endif   
20838
20839    RETVOID;
20840 }
20841
20842 \f
20843 /**
20844  * @brief UE deletion for scheduler.
20845  *
20846  * @details
20847  *
20848  *     Function : rgSCHCmnDelRachInfo
20849  *
20850  *     This functions deletes all scheduler information
20851  *     pertaining to an UE.
20852  *
20853  *  @param[in]  RgSchCellCb  *cell
20854  *  @param[in]  RgSchUeCb    *ue
20855  *  @return  Void
20856  **/
20857 #ifdef ANSI
20858 PRIVATE Void rgSCHCmnDelRachInfo
20859 (
20860 RgSchCellCb  *cell,
20861 RgSchUeCb    *ue
20862 )
20863 #else
20864 PRIVATE Void rgSCHCmnDelRachInfo(cell, ue)
20865 RgSchCellCb  *cell;
20866 RgSchUeCb    *ue;
20867 #endif
20868 {
20869    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20870    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20871    U8            rapIdIdx;
20872
20873    TRC2(rgSCHCmnDelRachInfo);
20874
20875    if (ueDl->rachInfo.poLnk.node)
20876    {
20877       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
20878    }
20879    if (ueDl->rachInfo.hoLnk.node)
20880    {
20881       cmLListDelFrm(&cellSch->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
20882       ueDl->rachInfo.hoLnk.node = NULLP;
20883    }
20884    if (ueDl->rachInfo.rapIdLnk.node)
20885    {
20886       rapIdIdx = ueDl->rachInfo.poRapId - cellSch->rachCfg.dedPrmStart;
20887       cmLListDelFrm(&cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes, 
20888           &ueDl->rachInfo.rapIdLnk);
20889       ueDl->rachInfo.rapIdLnk.node = NULLP;
20890    }
20891    RETVOID;
20892 }
20893
20894 /**
20895  * @brief This function retrieves the ue which has sent this raReq
20896  * and it allocates grant for UEs undergoing (for which RAR
20897  * is being generated) HandOver/PdcchOrder.
20898  *
20899  *
20900  * @details
20901  *
20902  *     Function: rgSCHCmnHdlHoPo
20903  *     Purpose:  This function  retrieves the ue which has sent this raReq
20904  *               and it allocates grant for UEs undergoing (for which RAR
20905  *               is being generated) HandOver/PdcchOrder.
20906  *
20907  *     Invoked by: Common Scheduler
20908  *
20909  *  @param[in]  RgSchCellCb           *cell
20910  *  @param[out] CmLListCp             *raRspLst
20911  *  @param[in]  RgSchRaReqInfo        *raReq
20912  *  @return  Void
20913  *
20914  **/
20915 #ifdef ANSI
20916 PRIVATE Void rgSCHCmnHdlHoPo
20917 (
20918 RgSchCellCb           *cell,
20919 CmLListCp             *raRspLst,
20920 RgSchRaReqInfo        *raReq
20921 )
20922 #else
20923 PRIVATE Void rgSCHCmnHdlHoPo(cell, raRspLst, raReq)
20924 RgSchCellCb           *cell;
20925 CmLListCp             *raRspLst;
20926 RgSchRaReqInfo        *raReq;
20927 #endif
20928 {
20929    RgSchUeCb             *ue = raReq->ue;
20930    TRC2(rgSCHCmnHdlHoPo);
20931
20932    if ( ue->isDrxEnabled )
20933    {
20934       rgSCHDrxDedRa(cell,ue);
20935    }
20936    rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq);
20937    RETVOID;
20938 }
20939
20940 /**
20941  * @brief This function retrieves the UE which has sent this raReq
20942  * for handover case.
20943  *
20944  *
20945  * @details
20946  *
20947  *     Function: rgSCHCmnGetHoUe
20948  *     Purpose:  This function retrieves the UE which has sent this raReq
20949  *     for handover case.
20950  *
20951  *     Invoked by: Common Scheduler
20952  *
20953  *  @param[in]  RgSchCellCb           *cell
20954  *  @param[in]  RgSchRaReqInfo        *raReq
20955  *  @return  RgSchUeCb*
20956  *
20957  **/
20958 #ifdef ANSI
20959 PUBLIC RgSchUeCb* rgSCHCmnGetHoUe
20960 (
20961 RgSchCellCb           *cell,
20962 U16                   rapId
20963 )
20964 #else
20965 PUBLIC RgSchUeCb* rgSCHCmnGetHoUe(cell, rapId)
20966 RgSchCellCb           *cell;
20967 U16                   rapId
20968 #endif
20969 {
20970    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20971    CmLList               *node;
20972    CmLListCp             *ueLst;
20973    RgSchUeCb             *ue;
20974    RgSchCmnDlUe          *ueDl;
20975    TRC2(rgSCHCmnGetHoUe);
20976
20977    ueLst = &cellSch->rachCfg.hoUeLst;
20978    node = ueLst->first;
20979    while (node)
20980    {
20981       ue = (RgSchUeCb *)node->node;
20982       node = node->next;
20983       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20984       if (ueDl->rachInfo.hoRapId == rapId)
20985       {
20986          RETVALUE(ue);
20987       }
20988    }
20989    RETVALUE(NULLP);
20990 }
20991
20992 #ifdef ANSI
20993 PRIVATE Void rgSCHCmnDelDedPreamble
20994 (
20995 RgSchCellCb           *cell,
20996 U8                    preambleId
20997 )
20998 #else
20999 PRIVATE rgSCHCmnDelDedPreamble(cell, preambleId)
21000 RgSchCellCb           *cell;
21001 U8                    preambleId;
21002 #endif
21003 {
21004    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
21005    CmLList               *node;
21006    CmLListCp             *ueLst;
21007    RgSchUeCb             *ue;
21008    RgSchCmnDlUe          *ueDl;
21009    TRC2(rgSCHCmnDelDedPreamble);
21010
21011    ueLst = &cellSch->rachCfg.hoUeLst;
21012    node = ueLst->first;
21013    while (node)
21014    {
21015       ue = (RgSchUeCb *)node->node;
21016       node = node->next;
21017       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
21018       if (ueDl->rachInfo.hoRapId == preambleId)
21019       {
21020          cmLListDelFrm(ueLst, &ueDl->rachInfo.hoLnk);
21021          ueDl->rachInfo.hoLnk.node = (PTR)NULLP;
21022       }
21023    }
21024 }
21025
21026 /**
21027  * @brief This function retrieves the UE which has sent this raReq
21028  * for PDCCh Order case.
21029  *
21030  *
21031  * @details
21032  *
21033  *     Function: rgSCHCmnGetPoUe
21034  *     Purpose:  This function retrieves the UE which has sent this raReq
21035  *     for PDCCH Order case.
21036  *
21037  *     Invoked by: Common Scheduler
21038  *
21039  *  @param[in]  RgSchCellCb           *cell
21040  *  @param[in]  RgSchRaReqInfo        *raReq
21041  *  @return  RgSchUeCb*
21042  *
21043  **/
21044 #ifdef ANSI
21045 PUBLIC RgSchUeCb* rgSCHCmnGetPoUe
21046 (
21047 RgSchCellCb           *cell,
21048 U16                   rapId,
21049 CmLteTimingInfo       timingInfo
21050 )
21051 #else
21052 PUBLIC RgSchUeCb* rgSCHCmnGetPoUe(cell, rapId, timingInfo)
21053 RgSchCellCb           *cell;
21054 U16                   rapId;
21055 CmLteTimingInfo       timingInfo;
21056 #endif
21057 {
21058    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
21059    CmLList               *node;
21060    CmLListCp             *ueLst;
21061    RgSchUeCb             *ue;
21062    RgSchCmnDlUe          *ueDl;
21063    U8                    rapIdIdx;
21064    TRC2(rgSCHCmnGetPoUe);
21065
21066    rapIdIdx = rapId -cellSch->rachCfg.dedPrmStart;
21067    ueLst = &cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes;
21068    node = ueLst->first;
21069    while (node)
21070    {
21071       ue = (RgSchUeCb *)node->node;
21072       node = node->next;
21073       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
21074       /* Remove UEs irrespective.
21075        * Old UE associations are removed.*/
21076       cmLListDelFrm(ueLst, &ueDl->rachInfo.rapIdLnk);
21077       ueDl->rachInfo.rapIdLnk.node = (PTR)NULLP;
21078       if (RGSCH_TIMEINFO_SAME(ueDl->rachInfo.asgnOppr, timingInfo))
21079       {
21080          RETVALUE(ue);
21081       }
21082    }
21083
21084    RETVALUE(NULLP);
21085 }
21086
21087
21088 /**
21089  * @brief This function returns the valid UL cqi for a given UE.
21090  *
21091  * @details
21092  *
21093  *     Function: rgSCHCmnUlGetCqi
21094  *     Purpose:  This function returns the "valid UL cqi" for a given UE
21095  *               based on UE category
21096  *
21097  *     Invoked by: Scheduler
21098  *     
21099  *  @param[in]  RgSchUeCb        *ue
21100  *  @param[in]  U8               ueCtgy
21101  *  @return     U8 
21102  **/
21103 #ifdef ANSI
21104 PUBLIC U8 rgSCHCmnUlGetCqi
21105 (
21106 RgSchCellCb      *cell,
21107 RgSchUeCb        *ue,
21108 CmLteUeCategory  ueCtgy
21109 )
21110 #else
21111 PUBLIC U8 rgSCHCmnUlGetCqi(cell, ue, ueCtgy)
21112 RgSchCellCb      *cell;
21113 RgSchUeCb        *ue;
21114 CmLteUeCategory  ueCtgy;
21115 #endif
21116 {
21117    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
21118    U8            cqi;
21119
21120    TRC2(rgSCHCmnUlGetCqi);
21121    
21122    cqi = ueUl->maxUlCqi;
21123 #ifdef TFU_UPGRADE
21124    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
21125         (ueUl->validUlCqi > ueUl->maxUlCqi)))
21126    {
21127       cqi = ueUl->validUlCqi;
21128    }
21129 #else   
21130    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
21131          (ueUl->crntUlCqi[0] > ueUl->maxUlCqi )))
21132    {
21133       cqi = ueUl->crntUlCqi[0];
21134    }
21135 #endif    
21136    RETVALUE(cqi);
21137 }/* End of rgSCHCmnUlGetCqi */
21138
21139 /***********************************************************
21140  *
21141  *     Func : rgSCHCmnUlRbAllocForPoHoUe
21142  *
21143  *     Desc : Do uplink RB allocation for a HO/PO UE.
21144  *
21145  *     Ret  :
21146  *
21147  *     Notes: Note that as of now, for retx, maxRb
21148  *            is not considered. Alternatives, such
21149  *            as dropping retx if it crosses maxRb
21150  *            could be considered.
21151  *
21152  *     File :
21153  *
21154  **********************************************************/
21155 #ifdef ANSI
21156 PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe
21157 (
21158 RgSchCellCb           *cell,
21159 RgSchUlSf             *sf,
21160 RgSchUeCb             *ue,
21161 U8                    maxRb
21162 )
21163 #else
21164 PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, maxRb)
21165 RgSchCellCb           *cell;
21166 RgSchUlSf             *sf;
21167 RgSchUeCb             *ue;
21168 U8                    maxRb;
21169 #endif
21170 {
21171    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21172    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
21173    U8           sbSize  = cellUl->sbSize;
21174    U32          maxBits = ue->ul.maxBytesPerUePerTti*8;
21175    U32          bits;
21176    RgSchUlAlloc *alloc;
21177    U32          nPrb;
21178    U8           iTbs;
21179    U32          eff;
21180    U32          numSb;
21181    U8           iMcs;
21182    U8           iMcsCrnt;
21183    U8           cqi;
21184    U8           modOdr;
21185    RgSchUlHole      *hole;
21186    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->msg3SchdHqProcIdx];
21187    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
21188
21189    TRC2(rgSCHCmnUlRbAllocForPoHoUe);
21190    if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
21191    {
21192       RETVALUE(RFAILED);
21193    }
21194    /*MS_WORKAROUND for HO ccpu00121116*/
21195    cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
21196    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend], cqi);
21197    iTbs  = rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend][cqi];
21198    iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
21199    while(iMcs > RG_SCH_CMN_MAX_MSG3_IMCS)
21200    {
21201        cqi--;
21202        iTbs  = rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend][cqi];
21203        iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg);
21204    }
21205    /* Filling the modorder in the grant structure*/
21206    RG_SCH_UL_MCS_TO_MODODR(iMcs,modOdr);
21207    if (!cell->isCpUlExtend)
21208    {
21209       eff   = rgSchCmnNorUlEff[0][iTbs];
21210    }
21211    else
21212    {
21213       eff   = rgSchCmnExtUlEff[0][iTbs];
21214    }
21215
21216    bits = ueUl->alloc.reqBytes * 8;
21217
21218 #if (ERRCLASS & ERRCLS_DEBUG)
21219    if (!bits)
21220    {
21221       RETVALUE(RFAILED);
21222    }
21223 #endif
21224
21225    if (bits < rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs))
21226    {
21227       numSb = 1;
21228       nPrb = numSb * sbSize;
21229    }
21230    else
21231    {
21232       if (bits > maxBits)
21233       {
21234          bits  = maxBits;
21235          nPrb  = bits * 1024 / eff / RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
21236          if (nPrb > maxRb)
21237          {
21238             nPrb = maxRb;
21239          }
21240          numSb = nPrb / sbSize;
21241       }
21242       else
21243       {
21244          /*ccpu00128775:MOD-Change to get upper threshold nPrb*/
21245          nPrb = RGSCH_CEIL((RGSCH_CEIL(bits * 1024, eff)),
21246                   RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl));
21247          if (nPrb > maxRb)
21248          {
21249             nPrb = maxRb;
21250          }
21251          numSb = RGSCH_DIV_ROUND(nPrb, sbSize);
21252       }
21253    }
21254    iMcsCrnt = iMcs;
21255
21256    alloc = rgSCHCmnUlSbAlloc(sf, (U8)RGSCH_MIN(numSb, cellUl->maxSbPerUe),\
21257                              hole);
21258    if (alloc == NULLP)
21259    {
21260       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
21261          "rgSCHCmnUlRbAllocForPoHoUe(): Could not get UlAlloc");
21262       RETVALUE(RFAILED);
21263    }
21264    rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
21265    
21266    /* Filling the modorder in the grant structure start*/
21267    alloc->grnt.modOdr = (TfuModScheme) modOdr;
21268    alloc->grnt.iMcs = iMcs;
21269    alloc->grnt.iMcsCrnt = iMcsCrnt;
21270    alloc->grnt.hop = 0;
21271    /* Fix for ccpu00123915*/
21272    alloc->forMsg3 = TRUE;
21273    alloc->hqProc = proc;
21274    alloc->hqProc->ulSfIdx = cellUl->msg3SchdIdx;
21275    alloc->ue = ue;
21276    alloc->rnti = ue->ueId;
21277    /* updating initNumRbs in case of HO */
21278 #ifdef TFU_UPGRADE
21279    ue->initNumRbs = alloc->grnt.numRb;
21280 #endif
21281    ueUl->alloc.alloc = alloc;
21282    iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
21283    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs);
21284    alloc->grnt.datSz    = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
21285    /* MS_WORKAROUND for HO ccpu00121124*/
21286    /*[Adi temp change] Need to fil modOdr */
21287    RG_SCH_UL_MCS_TO_MODODR(alloc->grnt.iMcsCrnt,alloc->grnt.modOdr);
21288    rgSCHUhmNewTx(proc, ueUl->hqEnt.maxHqRetx, alloc);
21289    /* No grant attr recorded now */
21290    RETVALUE(ROK);
21291 }
21292
21293 /**
21294  * @brief This function allocates grant for UEs undergoing (for which RAR
21295  * is being generated) HandOver/PdcchOrder.
21296  *
21297  *
21298  * @details
21299  *
21300  *     Function: rgSCHCmnAllocPoHoGrnt
21301  *     Purpose:  This function allocates grant for UEs undergoing (for which RAR
21302  *               is being generated) HandOver/PdcchOrder.
21303  *
21304  *     Invoked by: Common Scheduler
21305  *
21306  *  @param[in]  RgSchCellCb           *cell
21307  *  @param[out] CmLListCp             *raRspLst,
21308  *  @param[in]  RgSchUeCb             *ue
21309  *  @param[in]  RgSchRaReqInfo        *raReq
21310  *  @return  Void
21311  *
21312  **/
21313 #ifdef ANSI
21314 PRIVATE Void rgSCHCmnAllocPoHoGrnt
21315 (
21316 RgSchCellCb           *cell,
21317 CmLListCp             *raRspLst,
21318 RgSchUeCb             *ue,
21319 RgSchRaReqInfo        *raReq
21320 )
21321 #else
21322 PRIVATE Void rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq)
21323 RgSchCellCb           *cell;
21324 CmLListCp             *raRspLst;
21325 RgSchUeCb             *ue;
21326 RgSchRaReqInfo        *raReq;
21327 #endif
21328 {
21329    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21330    RgSchCmnUlUe    *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
21331    RgSchUlGrnt     *grnt;
21332    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
21333
21334    TRC2(rgSCHCmnAllocPoHoGrnt);
21335
21336    /* Clearing previous allocs if any*/
21337    rgSCHCmnUlUeDelAllocs(cell, ue);
21338    /* Fix : syed allocs are limited */
21339    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
21340    {
21341       RETVOID;
21342    }
21343    ueUl->alloc.reqBytes = RG_SCH_MIN_GRNT_HOPO;
21344    if (rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, RGSCH_MAX_UL_RB) != ROK)
21345    {
21346       RETVOID;
21347    }
21348
21349    /* Fill grant information */
21350    grnt = &ueUl->alloc.alloc->grnt;
21351
21352    /* KWork fix */
21353    if (grnt == NULLP)
21354    {
21355       RLOG_ARG1(L_ERROR,DBG_INSTID,cell->instIdx,  "Failed to get"
21356         "the grant for HO/PDCCH Order. CRNTI:%d",ue->ueId);
21357       RETVOID;
21358    }
21359    ue->ul.rarGrnt.rapId = raReq->raReq.rapId;
21360    ue->ul.rarGrnt.hop = grnt->hop;
21361    ue->ul.rarGrnt.rbStart = grnt->rbStart;
21362    ue->ul.rarGrnt.numRb = grnt->numRb;
21363    ue->ul.rarGrnt.tpc = grnt->tpc;
21364    ue->ul.rarGrnt.iMcsCrnt = grnt->iMcsCrnt;
21365    ue->ul.rarGrnt.ta.pres = TRUE;
21366    ue->ul.rarGrnt.ta.val = raReq->raReq.ta;
21367    ue->ul.rarGrnt.datSz = grnt->datSz;
21368    if((sf->numACqiCount < RG_SCH_MAX_ACQI_PER_ULSF) && (RG_SCH_APCQI_NO != ue->dl.reqForCqi)) 
21369    {
21370 #ifdef LTE_ADV
21371       U8    idx = 0; 
21372       /* Send two bits cqireq field if more than one cells are configured else one*/
21373       for (idx = 1;idx < CM_LTE_MAX_CELLS;idx++)
21374       {
21375          if (ue->cellInfo[idx] != NULLP)
21376          {
21377             ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
21378             break;
21379          }
21380       }
21381       if (idx == CM_LTE_MAX_CELLS)
21382 #endif
21383       {
21384          ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
21385       }
21386       ue->dl.reqForCqi = RG_SCH_APCQI_NO;
21387       sf->numACqiCount++;
21388    }
21389    else
21390    {
21391       ue->ul.rarGrnt.cqiReqBit = 0;
21392    }
21393    /* Attach Ho/Po allocation to RAR Rsp cont free Lst */
21394    cmLListAdd2Tail(raRspLst, &ue->ul.rarGrnt.raRspLnk);
21395    ue->ul.rarGrnt.raRspLnk.node = (PTR)ue;
21396
21397    RETVOID;
21398 }
21399
21400 /**
21401  * @brief This is a utility function to set the fields in
21402  * an UL harq proc which is identified for non-adaptive retx
21403  *
21404  * @details
21405  *
21406  *     Function: rgSCHCmnUlNonadapRetx 
21407  *     Purpose:  Sets the fields in UL Harq  proc for non-adaptive retx 
21408  *
21409  * @param[in]  RgSchCmnUlCell  *cellUl 
21410  * @param[out] RgSchUlAlloc    *alloc
21411  * @param[in]  U8              idx 
21412  * @return  Void
21413  *
21414  **/
21415 #ifdef ANSI
21416 PRIVATE Void rgSCHCmnUlNonadapRetx
21417 (
21418 RgSchCmnUlCell  *cellUl,
21419 RgSchUlAlloc    *alloc,
21420 U8              idx
21421 )
21422 #else
21423 PRIVATE Void rgSCHCmnUlNonadapRetx(cellUl, alloc, idx)
21424 RgSchCmnUlCell  *cellUl;
21425 RgSchUlAlloc    *alloc;
21426 U8              idx;
21427 #endif
21428 {
21429    TRC2(rgSCHCmnUlNonadapRetx);
21430    rgSCHUhmRetx(alloc->hqProc, alloc);
21431
21432    /* Update alloc to retx */
21433    alloc->hqProc->isRetx = TRUE;
21434    alloc->hqProc->ulSfIdx = cellUl->reTxIdx[idx];
21435
21436    if (alloc->hqProc->rvIdx != 0)
21437    {
21438       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[alloc->hqProc->rvIdx];
21439    }
21440    else
21441    {
21442       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
21443    }
21444    alloc->grnt.isRtx = TRUE;
21445    alloc->pdcch = NULLP;
21446    RETVOID;
21447 }
21448
21449 /**
21450  * @brief Check if 2 allocs overlap
21451  *
21452  * @details
21453  *
21454  *     Function : rgSCHCmnUlAllocsOvrLap
21455  *
21456  *      - Return TRUE if alloc1 and alloc2 overlap.
21457  *
21458  *  @param[in]  RgSchUlAlloc  *alloc1
21459  *  @param[in]  RgSchUlAlloc  *alloc2
21460  *  @return  Bool
21461  **/
21462 #ifdef ANSI
21463 PRIVATE Bool rgSCHCmnUlAllocsOvrLap
21464 (
21465 RgSchUlAlloc    *alloc1,
21466 RgSchUlAlloc    *alloc2
21467 )
21468 #else
21469 PRIVATE Bool rgSCHCmnUlAllocsOvrLap(alloc1, alloc2)
21470 RgSchUlAlloc    *alloc1;
21471 RgSchUlAlloc    *alloc2;
21472 #endif
21473 {
21474
21475    TRC2(rgSCHCmnUlAllocsOvrLap);
21476
21477    if (((alloc1->sbStart >= alloc2->sbStart) &&
21478          (alloc1->sbStart <= alloc2->sbStart + alloc2->numSb-1)) ||
21479         ((alloc2->sbStart >= alloc1->sbStart) &&
21480          (alloc2->sbStart <= alloc1->sbStart + alloc1->numSb-1)))
21481    {
21482       RETVALUE(TRUE);
21483    }
21484    RETVALUE(FALSE);
21485 }
21486
21487 /**
21488  * @brief Copy allocation Info from src to dst.
21489  *
21490  * @details
21491  *
21492  *     Function : rgSCHCmnUlCpyAllocInfo
21493  *
21494  *      - Copy allocation Info from src to dst.
21495  *
21496  *  @param[in]  RgSchUlAlloc  *srcAlloc
21497  *  @param[in]  RgSchUlAlloc  *dstAlloc
21498  *  @return  Void
21499  **/
21500 #ifdef ANSI
21501 PRIVATE Void rgSCHCmnUlCpyAllocInfo
21502 (
21503 RgSchCellCb     *cell,
21504 RgSchUlAlloc    *srcAlloc,
21505 RgSchUlAlloc    *dstAlloc
21506 )
21507 #else
21508 PRIVATE Void rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc)
21509 RgSchCellCb     *cell;
21510 RgSchUlAlloc    *srcAlloc;
21511 RgSchUlAlloc    *dstAlloc;
21512 #endif
21513 {
21514    RgSchCmnUlUe *ueUl;
21515    TRC2(rgSCHCmnUlCpyAllocInfo);
21516
21517    dstAlloc->grnt = srcAlloc->grnt;
21518    dstAlloc->hqProc = srcAlloc->hqProc;
21519    /* Fix : syed During UE context release, hqProc->alloc
21520     * was pointing to srcAlloc instead of dstAlloc and
21521     * freeing from incorrect sf->allocDb was
21522     * corrupting the list. */
21523     /* In case of SPS Occasion Allocation is done in advance and 
21524        at a later time Hq Proc is linked. Hence HqProc
21525        pointer in alloc shall be NULL */
21526 #ifdef LTEMAC_SPS
21527    if (dstAlloc->hqProc)
21528 #endif
21529    {
21530       dstAlloc->hqProc->alloc = dstAlloc;
21531    }
21532    dstAlloc->ue = srcAlloc->ue;
21533    dstAlloc->rnti = srcAlloc->rnti;
21534    dstAlloc->forMsg3 = srcAlloc->forMsg3;
21535    dstAlloc->raCb  = srcAlloc->raCb;
21536    dstAlloc->pdcch = srcAlloc->pdcch;
21537    /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
21538    if (dstAlloc->ue)
21539    {
21540       ueUl = RG_SCH_CMN_GET_UL_UE(dstAlloc->ue,cell);
21541       ueUl->alloc.alloc = dstAlloc;
21542 #ifdef LTEMAC_SPS
21543       if (dstAlloc->ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
21544       {
21545          if((dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc != NULLP)
21546                && (dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc == srcAlloc))
21547          {
21548             dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc = dstAlloc;
21549          }
21550       }
21551 #endif
21552    }
21553
21554    RETVOID;
21555 }
21556
21557
21558 /**
21559  * @brief Update TX and RETX subframe's allocation
21560  *        markings.
21561  *
21562  * @details
21563  *
21564  *     Function : rgSCHCmnUlInsAllocFrmNewSf2OldSf
21565  *
21566  *      - Release all preassigned allocations of newSf and merge
21567  *        them to oldSf.
21568  *      - If alloc of newSf collide with one or more allocs of oldSf
21569  *        - mark all such allocs of oldSf for Adaptive Retx.
21570  *      - Swap the alloc and hole DB references of oldSf and newSf.
21571  *
21572  *  @param[in]  RgSchCellCb   *cell
21573  *  @param[in]  RgSchUlSf     *newSf
21574  *  @param[in]  RgSchUlSf     *oldSf
21575  *  @param[in]  RgSchUlAlloc  *srcAlloc
21576  *  @return  Void
21577  **/
21578 #ifdef ANSI
21579 PRIVATE Void rgSCHCmnUlInsAllocFrmNewSf2OldSf
21580 (
21581 RgSchCellCb     *cell,
21582 RgSchUlSf       *newSf,
21583 RgSchUlSf       *oldSf,
21584 RgSchUlAlloc    *srcAlloc
21585 )
21586 #else
21587 PRIVATE Void rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, srcAlloc)
21588 RgSchCellCb     *cell;
21589 RgSchUlSf       *newSf;
21590 RgSchUlSf       *oldSf;
21591 RgSchUlAlloc    *srcAlloc;
21592 #endif
21593 {
21594    RgSchUlAlloc   *alloc, *dstAlloc, *nxtAlloc;
21595
21596    /* MS_WORKAROUND ccpu00120827 */
21597    RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
21598    U8 remAllocs;
21599    TRC2(rgSCHCmnUlInsAllocFrmNewSf2OldSf);
21600
21601    if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
21602    {
21603       do
21604       {
21605          nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);
21606          /* If there is an overlap between alloc and srcAlloc
21607           * then alloc is marked for Adaptive retx and it is released
21608           * from txSf */
21609          if (rgSCHCmnUlAllocsOvrLap(alloc, srcAlloc) == TRUE)
21610          {
21611             rgSCHCmnUlUpdAllocRetx(cell, alloc);
21612             rgSCHUtlUlAllocRls(oldSf, alloc);
21613          }
21614          /* No further allocs spanning the srcAlloc subbands */
21615          if (srcAlloc->sbStart + srcAlloc->numSb - 1  <= alloc->sbStart)
21616          {
21617             break;
21618          }
21619       } while ((alloc = nxtAlloc) != NULLP);
21620    }
21621
21622    /* After freeing all the colliding allocs, request for an allocation
21623     * specifying the start and numSb with in txSf. This function should
21624     * always return positively with a nonNULL dstAlloc */
21625     /* MS_WORKAROUND ccpu00120827 */
21626    remAllocs = schCmnCell->ul.maxAllocPerUlSf - *oldSf->allocCountRef;
21627    if (!remAllocs)
21628    {
21629       /* Fix : If oldSf already has max Allocs then release the
21630        * old RETX alloc to make space for new alloc of newSf.
21631        * newSf allocs(i.e new Msg3s) are given higher priority
21632        * over retx allocs. */      
21633       if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
21634       {
21635          do
21636          {
21637             nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);           
21638             if (!alloc->mrgdNewTxAlloc)
21639             {
21640                /* If alloc is for RETX */                   
21641                /* TODO: Incase of this ad also in case of choosing
21642                 * and alloc for ADAP RETX, we need to send ACK for
21643                 * the corresponding alloc in PHICH */               
21644 #ifndef EMTC_ENABLE
21645                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc);
21646 #else
21647                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc,FALSE);
21648 #endif
21649                break;
21650             }               
21651          }while((alloc = nxtAlloc) != NULLP);
21652       }
21653    }
21654    dstAlloc = rgSCHUtlUlGetSpfcAlloc(oldSf, srcAlloc->sbStart, srcAlloc->numSb);
21655 #ifdef ERRCLS_KW
21656    /* This should never happen */
21657    if (dstAlloc == NULLP)
21658    {
21659       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d "
21660          "rgSCHUtlUlGetSpfcAlloc failed in rgSCHCmnUlInsAllocFrmNewSf2OldSf",
21661          srcAlloc->rnti);
21662       RETVOID;
21663    }
21664 #endif
21665    /* Copy the srcAlloc's state information in to dstAlloc */
21666    rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc);
21667    /* Set new Tx merged Alloc Flag to TRUE, indicating that this
21668     * alloc shall not be processed for non-adaptive retransmission */
21669    dstAlloc->mrgdNewTxAlloc = TRUE;
21670    RETVOID;
21671 }
21672
21673 /**
21674  * @brief Merge all allocations of newSf to oldSf.
21675  *
21676  * @details
21677  *
21678  *     Function : rgSCHCmnUlMergeSfAllocs
21679  *
21680  *      - Merge all allocations of newSf to oldSf.
21681  *      - If newSf's alloc collides with oldSf's alloc
21682  *        then oldSf's alloc is marked for adaptive Retx
21683  *        and is released from oldSf to create space for
21684  *        newSf's alloc.
21685  *
21686  *  @param[in]  RgSchCellCb  *cell
21687  *  @param[in]  RgSchUlSf    *oldSf
21688  *  @param[in]  RgSchUlSf    *newSf
21689  *  @return  Void
21690  **/
21691 #ifdef ANSI
21692 PRIVATE Void rgSCHCmnUlMergeSfAllocs
21693 (
21694 RgSchCellCb  *cell,
21695 RgSchUlSf    *oldSf,
21696 RgSchUlSf    *newSf
21697 )
21698 #else
21699 PRIVATE Void rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf)
21700 RgSchCellCb  *cell;
21701 RgSchUlSf    *oldSf;
21702 RgSchUlSf    *newSf;
21703 #endif
21704 {
21705    RgSchUlAlloc    *alloc, *nxtAlloc;
21706    TRC2(rgSCHCmnUlMergeSfAllocs);
21707    UNUSED(cell);
21708
21709    /* Merge each alloc of newSf in to oldSf
21710     * and release it from newSf */
21711    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
21712    {
21713       do
21714       {
21715          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
21716          rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, alloc);
21717          rgSCHUtlUlAllocRls(newSf, alloc);
21718       } while((alloc = nxtAlloc) != NULLP);
21719    }
21720    RETVOID;
21721 }
21722
21723 /**
21724  * @brief Swap Hole/Alloc DB context of newSf and oldSf.
21725  *
21726  * @details
21727  *
21728  *     Function : rgSCHCmnUlSwapSfAllocs
21729  *
21730  *      - Swap Hole/Alloc DB context of newSf and oldSf.
21731  *
21732  *  @param[in]  RgSchCellCb  *cell
21733  *  @param[in]  RgSchUlSf    *oldSf
21734  *  @param[in]  RgSchUlSf    *newSf
21735  *  @return  Void
21736  **/
21737 #ifdef ANSI
21738 PRIVATE Void rgSCHCmnUlSwapSfAllocs
21739 (
21740 RgSchCellCb  *cell,
21741 RgSchUlSf    *oldSf,
21742 RgSchUlSf    *newSf
21743 )
21744 #else
21745 PRIVATE Void rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf)
21746 RgSchCellCb  *cell;
21747 RgSchUlSf    *oldSf;
21748 RgSchUlSf    *newSf;
21749 #endif
21750 {
21751    RgSchUlAllocDb *tempAllocDb  = newSf->allocDb;
21752    RgSchUlHoleDb  *tempHoleDb   = newSf->holeDb;
21753    U8              tempAvailSbs = newSf->availSubbands;
21754
21755    TRC2(rgSCHCmnUlSwapSfAllocs);
21756    UNUSED(cell);
21757
21758    newSf->allocDb       = oldSf->allocDb;
21759    newSf->holeDb        = oldSf->holeDb;
21760    newSf->availSubbands = oldSf->availSubbands;
21761
21762    oldSf->allocDb = tempAllocDb;
21763    oldSf->holeDb  = tempHoleDb;
21764    oldSf->availSubbands = tempAvailSbs;
21765       
21766    /* Fix ccpu00120610*/
21767    newSf->allocCountRef = &newSf->allocDb->count;
21768    oldSf->allocCountRef = &oldSf->allocDb->count;
21769    RETVOID;
21770 }
21771
21772 /**
21773  * @brief Perform non-adaptive RETX for non-colliding allocs.
21774  *
21775  * @details
21776  *
21777  *     Function : rgSCHCmnUlPrcNonAdptRetx
21778  *
21779  *      - Perform non-adaptive RETX for non-colliding allocs.
21780  *
21781  *  @param[in]  RgSchCellCb  *cell
21782  *  @param[in]  RgSchUlSf    *newSf
21783  *  @param[in]  U8           idx
21784  *  @return  Void
21785  **/
21786 #ifdef ANSI
21787 PRIVATE Void rgSCHCmnUlPrcNonAdptRetx
21788 (
21789 RgSchCellCb  *cell,
21790 RgSchUlSf    *newSf,
21791 U8           idx
21792 )
21793 #else
21794 PRIVATE Void rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx)
21795 RgSchCellCb  *cell;
21796 RgSchUlSf    *newSf;
21797 U8           idx;
21798 #endif
21799 {
21800    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21801    RgSchUlAlloc    *alloc, *nxtAlloc;
21802    TRC2(rgSCHCmnUlPrcNonAdptRetx);
21803
21804    /* perform non-adaptive retx allocation(adjustment) */
21805    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
21806    {
21807       do
21808       {
21809          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
21810          /* A merged new TX alloc, reset the state and skip */
21811          if (alloc->mrgdNewTxAlloc)
21812          {
21813             alloc->mrgdNewTxAlloc = FALSE;
21814             continue;
21815          }
21816          
21817
21818          rgSCHCmnUlNonadapRetx(cellUl, alloc, idx);
21819
21820       } while((alloc = nxtAlloc) != NULLP);
21821    }
21822    RETVOID;
21823 }
21824
21825 /**
21826  * @brief Update TX and RETX subframe's allocation
21827  *        markings.
21828  *
21829  * @details
21830  *
21831  *     Function : rgSCHCmnUlPrfmSfMerge
21832  *
21833  *      - Release all preassigned allocations of newSf and merge
21834  *        them to oldSf.
21835  *      - If alloc of newSf collide with one or more allocs of oldSf
21836  *        - mark all such allocs of oldSf for Adaptive Retx.
21837  *      - Swap the alloc and hole DB references of oldSf and newSf.
21838  *      - The allocs which did not collide with pre-assigned msg3
21839  *        allocs are marked for non-adaptive RETX.
21840  *
21841  *  @param[in]  RgSchCellCb  *cell
21842  *  @param[in]  RgSchUlSf    *oldSf
21843  *  @param[in]  RgSchUlSf    *newSf
21844  *  @param[in]  U8           idx 
21845  *  @return  Void
21846  **/
21847 #ifdef ANSI
21848 PRIVATE Void rgSCHCmnUlPrfmSfMerge
21849 (
21850 RgSchCellCb  *cell,
21851 RgSchUlSf    *oldSf,
21852 RgSchUlSf    *newSf,
21853 U8           idx
21854 )
21855 #else
21856 PRIVATE Void rgSCHCmnUlPrfmSfMerge(cell, oldSf, newSf, idx)
21857 RgSchCellCb  *cell;
21858 RgSchUlSf    *oldSf;
21859 RgSchUlSf    *newSf;
21860 U8           idx;
21861 #endif
21862 {
21863    TRC2(rgSCHCmnUlPrfmSfMerge);
21864    /* Preassigned resources for msg3 in newSf.
21865     * Hence do adaptive retx for all NACKED TXs */
21866    rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf);
21867    /* swap alloc and hole DBs of oldSf and newSf. */
21868    rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf);
21869    /* Here newSf has the resultant merged allocs context */
21870    /* Perform non-adaptive RETX for non-colliding allocs */
21871    rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx);
21872    
21873    RETVOID;
21874 }
21875
21876 /**
21877  * @brief Update TX and RETX subframe's allocation
21878  *        markings.
21879  *
21880  * @details
21881  *
21882  *     Function : rgSCHCmnUlRmvCmpltdAllocs
21883  *
21884  *      - Free all Transmission which are ACKED
21885  *        OR for which MAX retransmission have
21886  *        occurred.
21887  *
21888  *
21889  *  @param[in]  RgSchCellCb    *cell,
21890  *  @param[in]  RgSchUlSf      *sf
21891  *  @return  Void
21892  **/
21893 #ifdef ANSI
21894 PRIVATE Void rgSCHCmnUlRmvCmpltdAllocs
21895 (
21896 RgSchCellCb    *cell,
21897 RgSchUlSf      *sf
21898 )
21899 #else
21900 PRIVATE Void rgSCHCmnUlRmvCmpltdAllocs(cell, sf)
21901 RgSchCellCb    *cell;
21902 RgSchUlSf      *sf;
21903 #endif
21904 {
21905    RgSchUlAlloc    *alloc, *nxtAlloc;
21906    TRC2(rgSCHCmnUlRmvCmpltdAllocs);
21907
21908    if ((alloc = rgSCHUtlUlAllocFirst(sf)) == NULLP)
21909    {
21910       RETVOID;
21911    }
21912    do
21913    {
21914       nxtAlloc = rgSCHUtlUlAllocNxt(sf, alloc);
21915 #ifdef UL_ADPT_DBG      
21916       printf("rgSCHCmnUlRmvCmpltdAllocs:time(%d %d) alloc->hqProc->remTx %d hqProcId(%d) \n",cell->crntTime.sfn,cell->crntTime.subframe,alloc->hqProc->remTx, alloc->grnt.hqProcId);
21917 #endif
21918       alloc->hqProc->rcvdCrcInd = TRUE;
21919       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
21920       {
21921
21922         /* SR_RACH_STATS : MSG 3 MAX RETX FAIL*/
21923          if ((alloc->forMsg3 == TRUE) && (alloc->hqProc->remTx == 0))
21924          {
21925             rgNumMsg3FailMaxRetx++;
21926 #ifdef TENB_STATS
21927             cell->tenbStats->sch.msg3Fail++;
21928 #endif
21929          }
21930
21931 #ifdef MAC_SCH_STATS
21932     if(alloc->ue != NULLP)
21933     {
21934        /* access from ulHarqProc*/
21935        RgSchUeCb       *ueCb  = alloc->ue;
21936        RgSchCmnUe      *cmnUe = (RgSchCmnUe*)ueCb->sch;
21937        RgSchCmnUlUe    *ulUe  = &(cmnUe->ul);
21938        U8              cqi    = ulUe->crntUlCqi[0];  
21939        U16             numUlRetx = ueCb->ul.hqEnt.maxHqRetx - alloc->hqProc->remTx;
21940
21941        hqRetxStats.ulCqiStat[(cqi - 1)].mcs = alloc->grnt.iMcs;
21942
21943        switch (numUlRetx)
21944        {
21945           case 1:
21946              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1++;
21947              break;
21948           case 2:
21949              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2++;
21950              break;
21951          case 3:
21952             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3++;
21953             break;
21954          case 4:
21955             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4++;
21956             break;
21957       }
21958       hqRetxStats.ulCqiStat[(cqi - 1)].totalTx = \
21959              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1 + \
21960             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
21961             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
21962             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4 * 4);
21963    }
21964
21965 #endif /*MAC_SCH_STATS*/
21966          rgSCHCmnUlFreeAllocation(cell, sf, alloc);
21967       }
21968       /*ccpu00106104 MOD added check for AckNackRep */
21969       /*added check for acknack so that adaptive retx considers ue
21970        inactivity due to ack nack repetition*/
21971       else if((alloc->ue != NULLP) && (TRUE != alloc->forMsg3))
21972       {
21973         rgSCHCmnUlUpdAllocRetx(cell, alloc);
21974         rgSCHUtlUlAllocRls(sf, alloc);
21975       }
21976    } while ((alloc = nxtAlloc) != NULLP);
21977
21978    RETVOID;
21979 }
21980
21981 /**
21982  * @brief Update an uplink subframe.
21983  *
21984  * @details
21985  *
21986  *     Function : rgSCHCmnRlsUlSf
21987  *
21988  *     For each allocation
21989  *      - if no more tx needed
21990  *         - Release allocation
21991  *      - else
21992  *         - Perform retransmission
21993  *
21994  *  @param[in]  RgSchUlSf *sf
21995  *  @param[in]  U8        idx 
21996  *  @return  Void
21997  **/
21998 #ifdef ANSI
21999 PUBLIC Void rgSCHCmnRlsUlSf
22000 (
22001 RgSchCellCb    *cell,
22002 U8              idx
22003 )
22004 #else
22005 PUBLIC Void rgSCHCmnRlsUlSf(cell, idx)
22006 RgSchCellCb    *cell;
22007 U8              idx;
22008 #endif
22009 {
22010    TRC2(rgSCHCmnRlsUlSf);
22011
22012    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22013    
22014    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) 
22015    {
22016       RgSchUlSf   *oldSf  = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
22017
22018       /* Initialize the reTxLst of UL HqProcs for RETX subframe */
22019       if (rgSCHUtlUlAllocFirst(oldSf) == NULLP)
22020       {
22021          RETVOID;
22022       }
22023       /* Release all completed TX allocs from sf */
22024       rgSCHCmnUlRmvCmpltdAllocs(cell, oldSf);
22025
22026       oldSf->numACqiCount = 0;
22027    }
22028    RETVOID;
22029 }
22030
22031 /**
22032  * @brief Handle uplink allocation for retransmission.
22033  *
22034  * @details
22035  *
22036  *     Function : rgSCHCmnUlUpdAllocRetx
22037  *
22038  *     - Perform adaptive retransmission
22039  *
22040  *  @param[in]  RgSchUlSf *sf
22041  *  @param[in]  RgSchUlAlloc  *alloc
22042  *  @return  Void
22043  **/
22044 #ifdef ANSI
22045 PRIVATE Void rgSCHCmnUlUpdAllocRetx
22046 (
22047 RgSchCellCb    *cell,
22048 RgSchUlAlloc   *alloc
22049 )
22050 #else
22051 PRIVATE Void rgSCHCmnUlUpdAllocRetx(cell, alloc)
22052 RgSchCellCb    *cell;
22053 RgSchUlAlloc   *alloc;
22054 #endif
22055 {
22056    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
22057
22058    TRC2(rgSCHCmnUlUpdAllocRetx);
22059
22060    alloc->hqProc->reTxAlloc.rnti    =  alloc->rnti;
22061    alloc->hqProc->reTxAlloc.numSb   =  alloc->numSb;
22062    alloc->hqProc->reTxAlloc.iMcs   =  alloc->grnt.iMcs;
22063 #ifdef RG_5GTF
22064    alloc->hqProc->reTxAlloc.dciFrmt =  alloc->grnt.dciFrmt;
22065    alloc->hqProc->reTxAlloc.numLyr   =  alloc->grnt.numLyr;
22066    alloc->hqProc->reTxAlloc.vrbgStart =  alloc->grnt.vrbgStart;
22067    alloc->hqProc->reTxAlloc.numVrbg   =  alloc->grnt.numVrbg;
22068    alloc->hqProc->reTxAlloc.modOdr   =  alloc->grnt.modOdr;
22069 #endif
22070    //iTbs = rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
22071    //iTbs = alloc->grnt.iMcs;
22072    //RGSCH_ARRAY_BOUND_CHECK( 0, rgTbSzTbl[0], iTbs);
22073    alloc->hqProc->reTxAlloc.tbSz = alloc->grnt.datSz;
22074       //rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1]/8;
22075    alloc->hqProc->reTxAlloc.ue      = alloc->ue;
22076    alloc->hqProc->reTxAlloc.forMsg3 = alloc->forMsg3;
22077    alloc->hqProc->reTxAlloc.raCb = alloc->raCb;
22078
22079    /* Set as retransmission is pending */
22080    alloc->hqProc->isRetx = TRUE;
22081    alloc->hqProc->alloc = NULLP;
22082    alloc->hqProc->ulSfIdx = RGSCH_INVALID_INFO;
22083 #ifdef UL_ADPT_DBG  
22084    printf("Adding Harq Proc Id in the retx list  hqProcId %d \n",alloc->grnt.hqProcId); 
22085 #endif
22086    cmLListAdd2Tail(&cmnUlCell->reTxLst, &alloc->hqProc->reTxLnk);
22087    alloc->hqProc->reTxLnk.node = (PTR)alloc->hqProc;
22088    RETVOID;
22089 }
22090
22091 /**
22092  * @brief Attempts allocation for msg3s for which ADAP retransmissions
22093  *     are required.
22094  *
22095  * @details
22096  *
22097  *     Function : rgSCHCmnUlAdapRetxAlloc
22098  *
22099  *     Attempts allocation for msg3s for which ADAP retransmissions
22100  *     are required.
22101  *
22102  *  @param[in]  RgSchCellCb       *cell
22103  *  @param[in]  RgSchUlSf         *sf
22104  *  @param[in]  RgSchUlHqProcCb   *proc;
22105  *  @param[in]  RgSchUlHole       *hole;
22106  *  @return  U8
22107  **/
22108 #ifdef ANSI
22109 PRIVATE Bool rgSCHCmnUlAdapRetxAlloc
22110 (
22111 RgSchCellCb       *cell,
22112 RgSchUlSf         *sf,
22113 RgSchUlHqProcCb   *proc,
22114 RgSchUlHole       *hole
22115 )
22116 #else
22117 PRIVATE Bool rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole)
22118 RgSchCellCb       *cell;
22119 RgSchUlSf         *sf;
22120 RgSchUlHqProcCb   *proc;
22121 RgSchUlHole       *hole;
22122 #endif
22123 {
22124    U8              numSb = proc->reTxAlloc.numSb;
22125    U8              iMcs  = proc->reTxAlloc.iMcs;
22126    CmLteTimingInfo frm = cell->crntTime;
22127    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22128    RgSchDlSf       *dlSf;
22129    RgSchPdcch      *pdcch;
22130    RgSchUlAlloc    *alloc;
22131    TRC2(rgSCHCmnUlAdapRetxAlloc);
22132
22133    /* Fetch PDCCH for msg3 */
22134    /* ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
22135    /* Introduced timing delta for UL control */
22136    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
22137    dlSf = rgSCHUtlSubFrmGet(cell, frm);
22138    pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
22139    if (pdcch == NULLP)
22140    {
22141       RETVALUE(FALSE);
22142    }
22143
22144    /* Fetch UL Alloc for msg3 */
22145    if (numSb <= hole->num)
22146    {
22147       alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
22148       
22149       /* KWork fix */
22150          if(alloc == NULLP)
22151          {
22152             rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
22153             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
22154                   "UL Alloc fail for msg3 retx for rnti: %d\n", 
22155                   proc->reTxAlloc.rnti);
22156             RETVALUE(FALSE);
22157          }
22158
22159       rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
22160       alloc->grnt.iMcs     = iMcs;
22161       alloc->grnt.datSz    = proc->reTxAlloc.tbSz;
22162 #ifdef RG_5GTF
22163 #else
22164       //RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
22165 #endif
22166       /* Fill UL Alloc for msg3 */
22167       /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
22168       alloc->grnt.nDmrs    = 0;
22169       alloc->grnt.hop      = 0;
22170       alloc->grnt.delayBit = 0;
22171       alloc->grnt.isRtx    = TRUE;
22172       proc->ulSfIdx        = cellUl->schdIdx;
22173 #ifdef RG_5GTF
22174       proc->schdTime = cellUl->schdTime;
22175       alloc->grnt.hqProcId = proc->procId;
22176       alloc->grnt.dciFrmt = proc->reTxAlloc.dciFrmt;
22177       alloc->grnt.numLyr = proc->reTxAlloc.numLyr;
22178       alloc->grnt.vrbgStart = proc->reTxAlloc.vrbgStart;
22179       alloc->grnt.numVrbg = proc->reTxAlloc.numVrbg;
22180       alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
22181       alloc->grnt.modOdr = proc->reTxAlloc.modOdr;
22182
22183       /* TODO : Hardcoding these as of now */
22184       alloc->grnt.hop = 0;
22185       alloc->grnt.SCID = 0;
22186       alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
22187       alloc->grnt.PMI = 0;
22188       alloc->grnt.uciOnxPUSCH = 0;
22189 #endif
22190       alloc->rnti          = proc->reTxAlloc.rnti;
22191       /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
22192       alloc->ue            = proc->reTxAlloc.ue;
22193       alloc->pdcch         = pdcch;
22194       alloc->forMsg3       = proc->reTxAlloc.forMsg3;
22195       alloc->raCb          = proc->reTxAlloc.raCb;
22196       alloc->hqProc        = proc;
22197       alloc->isAdaptive    = TRUE;
22198 #ifdef LTE_L2_MEAS
22199       sf->totPrb  += alloc->grnt.numRb;
22200 #endif
22201       /* FIX : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
22202       if (alloc->raCb)
22203       {
22204          alloc->raCb->msg3Grnt= alloc->grnt;
22205 #ifndef LTE_TDD
22206          /* To the crntTime, add the time at which UE will
22207           * actually send MSG3 */
22208          alloc->raCb->msg3AllocTime = cell->crntTime;
22209          RGSCH_INCR_SUB_FRAME(alloc->raCb->msg3AllocTime, RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL);
22210 #else
22211          alloc->raCb->msg3AllocTime =  cellUl->schdTime;
22212 #endif
22213          rgSCHCmnUlAdapRetx(alloc, proc);
22214          /* Fill PDCCH with alloc info */
22215          pdcch->rnti                           = alloc->rnti;
22216          pdcch->dci.dciFormat                  = TFU_DCI_FORMAT_0;
22217          pdcch->dci.u.format0Info.hoppingEnbld = alloc->grnt.hop;
22218          pdcch->dci.u.format0Info.rbStart      = alloc->grnt.rbStart;
22219          pdcch->dci.u.format0Info.numRb        = alloc->grnt.numRb;
22220          pdcch->dci.u.format0Info.mcs          = alloc->grnt.iMcsCrnt;
22221          pdcch->dci.u.format0Info.ndi          = alloc->hqProc->ndi;
22222          pdcch->dci.u.format0Info.nDmrs        = alloc->grnt.nDmrs;
22223          pdcch->dci.u.format0Info.tpcCmd       = alloc->grnt.tpc;
22224
22225 #ifdef LTE_TDD
22226 #ifdef TFU_TDD
22227          /* ulIdx setting for cfg 0 shall be appropriately fixed thru ccpu00109015 */
22228          pdcch->dci.u.format0Info.ulIdx = RG_SCH_ULIDX_MSB;
22229          pdcch->dci.u.format0Info.dai = RG_SCH_MAX_DAI_IDX;
22230 #endif
22231 #endif
22232          pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_0];
22233       }
22234       else
22235       {
22236          RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(alloc->ue,cell);
22237 #ifdef TFU_UPGRADE
22238          alloc->ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
22239 #endif
22240 #ifdef LTE_L2_MEAS
22241          ue->ul.nPrb = alloc->grnt.numRb;
22242 #endif
22243          ueUl->alloc.alloc = alloc;
22244          /* FIx: Removed the call to rgSCHCmnUlAdapRetx */
22245          rgSCHCmnUlUeFillAllocInfo(cell, alloc->ue);
22246          /* Setting csireq as false for Adaptive Retx*/
22247          ueUl->alloc.alloc->pdcch->dci.u.format0Info.cqiReq = RG_SCH_APCQI_NO;
22248          pdcch->dciNumOfBits = alloc->ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
22249       }
22250       /* Reset as retransmission is done */
22251       proc->isRetx = FALSE;
22252    }
22253    else /* Intg fix */
22254    {
22255       rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
22256       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
22257                "Num SB not suffiecient for adap retx for rnti: %d", 
22258                proc->reTxAlloc.rnti);
22259       RETVALUE(FALSE);
22260    }
22261    RETVALUE(TRUE);
22262 }
22263
22264 /* Fix: syed Adaptive Msg3 Retx crash. */
22265 /**
22266  * @brief Releases all Adaptive Retx HqProcs which failed for
22267  *        allocations in this scheduling occassion.
22268  *
22269  * @details
22270  *
22271  *     Function : rgSCHCmnUlSfRlsRetxProcs
22272  *
22273  *
22274  *  @param[in]  RgSchCellCb *cell
22275  *  @param[in]  RgSchUlSf   *sf
22276  *  @return  U8
22277  **/
22278 #ifdef ANSI
22279 PRIVATE Void rgSCHCmnUlSfRlsRetxProcs
22280 (
22281 RgSchCellCb *cell,
22282 RgSchUlSf   *sf
22283 )
22284 #else
22285 PRIVATE Void rgSCHCmnUlSfRlsRetxProcs(cell, sf)
22286 RgSchCellCb *cell;
22287 RgSchUlSf   *sf;
22288 #endif
22289 {
22290    CmLListCp         *cp;
22291    CmLList           *node;
22292    RgSchUlHqProcCb   *proc;
22293    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22294
22295    TRC2(rgSCHCmnUlSfRlsRetxProcs);
22296
22297    cp = &(cellUl->reTxLst);
22298    node = cp->first;
22299    while (node)
22300    {
22301       proc  = (RgSchUlHqProcCb *)node->node;
22302       node = node->next;
22303       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
22304       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
22305       proc->reTxLnk.node = (PTR)NULLP;
22306    }
22307    RETVOID;
22308 }
22309    
22310
22311 /**
22312  * @brief Attempts allocation for UEs for which retransmissions
22313  *     are required.
22314  *
22315  * @details
22316  *
22317  *     Function : rgSCHCmnUlSfReTxAllocs
22318  *
22319  *     Attempts allocation for UEs for which retransmissions
22320  *     are required.
22321  *
22322  *  @param[in]  RgSchCellCb *cell
22323  *  @param[in]  RgSchUlSf   *sf
22324  *  @return  U8
22325  **/
22326 #ifdef ANSI
22327 PRIVATE Void rgSCHCmnUlSfReTxAllocs
22328 (
22329 RgSchCellCb *cell,
22330 RgSchUlSf   *sf
22331 )
22332 #else
22333 PRIVATE Void rgSCHCmnUlSfReTxAllocs(cell, sf)
22334 RgSchCellCb *cell;
22335 RgSchUlSf   *sf;
22336 #endif
22337 {
22338    CmLListCp         *cp;
22339    CmLList           *node;
22340    RgSchUlHqProcCb   *proc;
22341    RgSchUlHole       *hole;
22342    RgSchUeCb         *ue;
22343    RgSchCmnCell      *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
22344    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22345    TRC2(rgSCHCmnUlSfReTxAllocs);
22346
22347    cp = &(cellUl->reTxLst);
22348    node = cp->first;
22349    while ((node))
22350    {
22351       proc  = (RgSchUlHqProcCb *)node->node;
22352       ue = proc->reTxAlloc.ue;
22353       node = node->next;
22354       /*ccpu00106104 MOD added check for AckNackRep */
22355       /*added check for acknack so that adaptive retx considers ue
22356        inactivity due to ack nack repetition*/
22357       if((ue != NULLP) &&
22358             ((ue->measGapCb.isMeasuring == TRUE)||
22359                (ue->ackNakRepCb.isAckNakRep == TRUE)))
22360       {
22361          continue;
22362       }
22363       /* Fix for ccpu00123917: Check if maximum allocs per UL sf have been exhausted */
22364       if (((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
22365             || (sf->allocDb->count == schCmnCell->ul.maxAllocPerUlSf))
22366       {
22367          /* No more UL BW then return */
22368          break;
22369       }
22370       /* perform adaptive retx for UE's */
22371       if (rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) == FALSE)
22372       {
22373          continue;
22374       }
22375       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
22376       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
22377       /* Fix: syed Adaptive Msg3 Retx crash. */
22378       proc->reTxLnk.node = (PTR)NULLP;
22379    }
22380    RETVOID;
22381 }
22382
22383 /**
22384  * @brief Handles RB allocation for downlink.
22385  *
22386  * @details
22387  *
22388  *     Function : rgSCHCmnDlRbAlloc
22389  *
22390  *     Invoking Module Processing:
22391  *     - This function is invoked for DL RB allocation
22392  *
22393  *     Processing Steps:
22394  *     - If cell is frequency selecive,
22395  *       - Call rgSCHDlfsAllocRb().
22396  *     - else,
22397  *       - Call rgSCHCmnNonDlfsRbAlloc().
22398  *
22399  *  @param[in]  RgSchCellCb        *cell
22400  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
22401  *  @return  Void
22402  **/
22403
22404 #ifdef ANSI
22405 PRIVATE Void rgSCHCmnDlRbAlloc
22406 (
22407 RgSchCellCb           *cell,
22408 RgSchCmnDlRbAllocInfo *allocInfo
22409 )
22410 #else
22411 PRIVATE Void rgSCHCmnDlRbAlloc(cell, allocInfo)
22412 RgSchCellCb           *cell;
22413 RgSchCmnDlRbAllocInfo *allocInfo;
22414 #endif
22415 {
22416    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
22417    TRC2(rgSCHCmnDlRbAlloc);
22418
22419    if (cellSch->dl.isDlFreqSel)
22420    {
22421       printf("5GTF_ERROR DLFS SCH Enabled\n");
22422       cellSch->apisDlfs->rgSCHDlfsAllocRb(cell, allocInfo);
22423    }
22424    else
22425    {
22426       rgSCHCmnNonDlfsRbAlloc(cell, allocInfo);
22427    }
22428    RETVOID;
22429 }
22430
22431 #ifdef LTEMAC_SPS
22432
22433 /**
22434  * @brief Determines number of RBGs and RBG subset sizes for the given DL
22435  * bandwidth and rbgSize
22436  *
22437  * @details
22438  *     Function : rgSCHCmnDlGetRbgInfo
22439  *
22440  *
22441  *     Processing Steps:
22442  *     - Fill-up rbgInfo data structure for given DL bandwidth and rbgSize
22443  *
22444  *   @param[in]  U8             dlTotalBw
22445  *   @param[in]  U8             dlSubsetBw
22446  *   @param[in]  U8             maxRaType1SubsetBw
22447  *   @param[in]  U8             rbgSize
22448  *   @param[out] RgSchBwRbgInfo *rbgInfo
22449  *  @return Void
22450  **/
22451 #ifdef ANSI
22452 PUBLIC Void rgSCHCmnDlGetRbgInfo
22453 (
22454 U8             dlTotalBw,
22455 U8             dlSubsetBw,
22456 U8             maxRaType1SubsetBw,
22457 U8             rbgSize,
22458 RgSchBwRbgInfo *rbgInfo
22459 )
22460 #else
22461 PUBLIC Void rgSCHCmnDlGetRbgInfo(dlTotalBw, dlSubsetBw, maxRaType1SubsetBw,
22462       rbgSize, rbgInfo)
22463 U8             dlTotalBw;
22464 U8             dlSubsetBw;
22465 U8             maxRaType1SubsetBw;
22466 U8             rbgSize;
22467 RgSchBwRbgInfo *rbgInfo;
22468 #endif
22469 {
22470 #ifdef RGSCH_SPS_UNUSED
22471    U8    idx           = 0;
22472    U8    lastRbgIdx    = ((dlTotalBw + rbgSize - 1)/rbgSize) - 1;
22473    U8    currRbgSize   = rbgSize;
22474    U8    subsetSizeIdx = 0;
22475    U8    subsetSize[RG_SCH_NUM_RATYPE1_SUBSETS] = {0};
22476    U8    lastRbgSize = rbgSize - (dlTotalBw - ((dlTotalBw/rbgSize) * rbgSize));
22477    U8    numRaType1Rbgs = (maxRaType1SubsetBw + rbgSize - 1)/rbgSize;
22478 #endif
22479
22480    /* Compute maximum number of SPS RBGs for the cell */
22481    rbgInfo->numRbgs =  ((dlSubsetBw + rbgSize - 1)/rbgSize);
22482
22483 #ifdef RGSCH_SPS_UNUSED
22484    /* Distribute RBGs across subsets except last RBG */
22485    for (;idx < numRaType1Rbgs - 1; ++idx)
22486    {
22487       subsetSize[subsetSizeIdx] += currRbgSize;
22488       subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
22489    }
22490
22491    /* Computation for last RBG */
22492    if (idx == lastRbgIdx)
22493    {
22494       currRbgSize = lastRbgSize;
22495    }
22496    subsetSize[subsetSizeIdx] += currRbgSize;
22497    subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
22498 #endif
22499
22500    /* Update the computed sizes */
22501 #ifdef RGSCH_SPS_UNUSED
22502    rbgInfo->lastRbgSize = currRbgSize;
22503 #endif
22504    rbgInfo->lastRbgSize = rbgSize - 
22505             (dlSubsetBw - ((dlSubsetBw/rbgSize) * rbgSize));
22506 #ifdef RGSCH_SPS_UNUSED
22507    cmMemcpy((U8 *)rbgInfo->rbgSubsetSize, (U8 *) subsetSize, 4 * sizeof(U8));
22508 #endif
22509    rbgInfo->numRbs = (rbgInfo->numRbgs * rbgSize > dlTotalBw) ?
22510       dlTotalBw:(rbgInfo->numRbgs * rbgSize);
22511    rbgInfo->rbgSize = rbgSize;
22512 }
22513
22514 /**
22515  * @brief Handles RB allocation for Resource allocation type 0
22516  *
22517  * @details
22518  *
22519  *     Function : rgSCHCmnDlRaType0Alloc
22520  *
22521  *     Invoking Module Processing:
22522  *     - This function is invoked for DL RB allocation for resource allocation
22523  *     type 0
22524  *
22525  *     Processing Steps:
22526  *     - Determine the available positions in the rbgMask.
22527  *     - Allocate RBGs in the available positions.
22528  *     - Update RA Type 0, RA Type 1 and RA type 2 masks.
22529  *
22530  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22531  *  @param[in]   U8             rbsReq
22532  *  @param[in]   RgSchBwRbgInfo *rbgInfo
22533  *  @param[out]  U8             *numAllocRbs
22534  *  @param[out]  RgSchDlSfAllocInfo *resAllocInfo
22535  *  @param[in]   Bool           isPartialAlloc
22536  *
22537  *  @return  Void
22538  **/
22539
22540 #ifdef ANSI
22541 PUBLIC U8 rgSCHCmnDlRaType0Alloc
22542 (
22543 RgSchDlSfAllocInfo *allocedInfo,
22544 U8                 rbsReq,
22545 RgSchBwRbgInfo     *rbgInfo,
22546 U8                 *numAllocRbs,
22547 RgSchDlSfAllocInfo *resAllocInfo,
22548 Bool               isPartialAlloc
22549 )
22550 #else
22551 PUBLIC U8 rgSCHCmnDlRaType0Alloc(allocedInfo, rbsReq, rbgInfo,
22552       numAllocRbs, resAllocInfo, isPartialAlloc)
22553 RgSchDlSfAllocInfo *allocedInfo;
22554 U8                 rbsReq;
22555 RgSchBwRbgInfo     *rbgInfo;
22556 U8                 *numAllocRbs;
22557 RgSchDlSfAllocInfo *resAllocInfo;
22558 Bool               isPartialAlloc;
22559 #endif
22560 {
22561    /* Note: This function atttempts allocation only full allocation */
22562    U32      remNumRbs, rbgPosInRbgMask, ueRaType2Mask;
22563    U8       type2MaskIdx, cnt, rbIdx;
22564    U8       maskSize, rbg;
22565    U8       bestNumAvailRbs = 0;
22566    U8       usedRbs = 0;
22567    U8       numAllocRbgs = 0;
22568    U8       rbgSize = rbgInfo->rbgSize;
22569    U32      *rbgMask = &(resAllocInfo->raType0Mask);
22570 #ifdef RGSCH_SPS_UNUSED
22571    U8       rbgSubset;
22572    U32      ueRaType1Mask;
22573    U32      *raType1Mask = resAllocInfo->raType1Mask;
22574    U32      *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22575 #endif
22576    U32      *raType2Mask = resAllocInfo->raType2Mask;
22577
22578    U32      allocedMask = allocedInfo->raType0Mask;
22579
22580    maskSize = rbgInfo->numRbgs;
22581
22582    *numAllocRbs = 0;
22583    RG_SCH_CMN_DL_COUNT_ONES(allocedMask, maskSize, &usedRbs);
22584    if (maskSize == usedRbs)
22585    {
22586       /* All RBGs are allocated, including the last one */
22587       remNumRbs = 0;
22588    }
22589    else
22590    {
22591       remNumRbs = (maskSize - usedRbs - 1) * rbgSize; /* vamsee: removed minus 1 */
22592
22593       /* If last RBG is available, add last RBG size */
22594       if (!(allocedMask & (1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(maskSize - 1))))
22595       {
22596          remNumRbs += rbgInfo->lastRbgSize;
22597       }
22598    }
22599
22600    /* If complete allocation is needed, check if total requested RBs are available else
22601     * check the best available RBs */
22602    if (!isPartialAlloc)
22603    {
22604       if (remNumRbs >= rbsReq)
22605       {
22606          bestNumAvailRbs = rbsReq;
22607       }
22608    }
22609    else
22610    {
22611       bestNumAvailRbs = remNumRbs > rbsReq ? rbsReq : remNumRbs;
22612    }
22613
22614    /* Allocate for bestNumAvailRbs */
22615    if (bestNumAvailRbs)
22616    {
22617       for (rbg = 0; rbg < maskSize - 1; ++rbg)
22618       {
22619          rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22620          if (!(allocedMask & rbgPosInRbgMask))
22621          {
22622             /* Update RBG mask */
22623             *rbgMask |= rbgPosInRbgMask;
22624
22625             /* Compute RB index of the first RB of the RBG allocated */
22626             rbIdx = rbg * rbgSize;
22627
22628             for (cnt = 0; cnt < rbgSize; ++cnt)
22629             {
22630 #ifdef RGSCH_SPS_UNUSED
22631                ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22632 #endif
22633                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22634 #ifdef RGSCH_SPS_UNUSED
22635                /* Update RBG mask for RA type 1 */
22636                raType1Mask[rbgSubset] |= ueRaType1Mask;
22637                raType1UsedRbs[rbgSubset]++;
22638 #endif
22639                /* Update RA type 2 mask */
22640                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22641                rbIdx++;
22642             }
22643             *numAllocRbs += rbgSize;
22644             remNumRbs -= rbgSize;
22645             ++numAllocRbgs;
22646             if (*numAllocRbs >= bestNumAvailRbs)
22647             {
22648                break;
22649             }
22650          }
22651       }
22652       /* If last RBG available and allocation is not completed, allocate
22653        * last RBG */
22654       if (*numAllocRbs < bestNumAvailRbs)
22655       {
22656          rbgPosInRbgMask =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22657          *rbgMask |= rbgPosInRbgMask;
22658          *numAllocRbs += rbgInfo->lastRbgSize;
22659
22660          /* Compute RB index of the first RB of the last RBG */
22661          rbIdx = ((rbgInfo->numRbgs - 1 ) * rbgSize ); /* removed minus 1  vamsee */
22662
22663          for (cnt = 0; cnt < rbgInfo->lastRbgSize; ++cnt)
22664          {
22665 #ifdef RGSCH_SPS_UNUSED
22666             ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22667 #endif
22668             ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22669 #ifdef RGSCH_SPS_UNUSED
22670             /* Update RBG mask for RA type 1 */
22671             raType1Mask[rbgSubset] |=  ueRaType1Mask;
22672             raType1UsedRbs[rbgSubset]++;
22673 #endif
22674             /* Update RA type 2 mask */
22675             raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22676             rbIdx++;
22677          }
22678          remNumRbs -= rbgInfo->lastRbgSize;
22679          ++numAllocRbgs;
22680       }
22681       /* Note: this should complete allocation, not checking for the
22682        * same */
22683    }
22684
22685    RETVALUE(numAllocRbgs);
22686 }
22687
22688 #ifdef RGSCH_SPS_UNUSED
22689 /**
22690  * @brief Handles RB allocation for Resource allocation type 1
22691  *
22692  * @details
22693  *
22694  *     Function : rgSCHCmnDlRaType1Alloc
22695  *
22696  *     Invoking Module Processing:
22697  *     - This function is invoked for DL RB allocation for resource allocation
22698  *     type 1
22699  *
22700  *     Processing Steps:
22701  *     - Determine the available positions in the subsets.
22702  *     - Allocate RB in the available subset.
22703  *     - Update RA Type1, RA type 0 and RA type 2 masks.
22704  *
22705  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22706  *  @param[in]   U8                 rbsReq
22707  *  @param[in]   RgSchBwRbgInfo     *rbgInfo
22708  *  @param[in]   U8                 startRbgSubset
22709  *  @param[in]   U8                 *allocRbgSubset
22710  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
22711  *  @param[in]   Bool               isPartialAlloc
22712  *
22713  *  @return  U8
22714  *  Number of allocated RBs
22715  **/
22716
22717 #ifdef ANSI
22718 PUBLIC U8 rgSCHCmnDlRaType1Alloc
22719 (
22720 RgSchDlSfAllocInfo *allocedInfo,
22721 U8                 rbsReq,
22722 RgSchBwRbgInfo     *rbgInfo,
22723 U8                 startRbgSubset,
22724 U8                 *allocRbgSubset,
22725 RgSchDlSfAllocInfo *resAllocInfo,
22726 Bool               isPartialAlloc
22727 )
22728 #else
22729 PUBLIC U8 rgSCHCmnDlRaType1Alloc(allocedInfo, rbsReq,rbgInfo,startRbgSubset,
22730       allocRbgSubset, resAllocInfo, isPartialAlloc)
22731 RgSchDlSfAllocInfo *allocedInfo;
22732 U8                 rbsReq;
22733 RgSchBwRbgInfo     *rbgInfo;
22734 U8                 startRbgSubset;
22735 U8                 *allocRbgSubset;
22736 RgSchDlSfAllocInfo *resAllocInfo;
22737 Bool               isPartialAlloc;
22738 #endif
22739 {
22740    /* Note: This function atttempts only full allocation */
22741    U8          *rbgSubsetSzArr;
22742    U8          type2MaskIdx, subsetIdx, rbIdx, rbInSubset, rbgInSubset;
22743    U8          offset, rbg, maskSize, bestSubsetIdx;
22744    U8          startPos = 0;
22745    U8          bestNumAvailRbs = 0;
22746    U8          numAllocRbs = 0;
22747    U32         ueRaType2Mask, ueRaType0Mask, rbPosInSubset;
22748    U32         remNumRbs, allocedMask;
22749    U8          usedRbs = 0;
22750    U8          rbgSize = rbgInfo->rbgSize;
22751    U8          rbgSubset = startRbgSubset;
22752    U32         *rbgMask = &resAllocInfo->raType0Mask;
22753    U32         *raType1Mask = resAllocInfo->raType1Mask;
22754    U32         *raType2Mask = resAllocInfo->raType2Mask;
22755    U32         *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22756    U32         *allocMask = allocedInfo->raType1Mask;
22757
22758    /* Initialize the subset size Array */
22759    rbgSubsetSzArr = rbgInfo->rbgSubsetSize;
22760
22761    /* Perform allocation for RA type 1 */
22762    for (subsetIdx = 0;subsetIdx < rbgSize; ++subsetIdx)
22763    {
22764       allocedMask = allocMask[rbgSubset];
22765       maskSize = rbgSubsetSzArr[rbgSubset];
22766
22767       /* Determine number of available RBs in the subset */
22768       usedRbs = allocedInfo->raType1UsedRbs[subsetIdx];
22769       remNumRbs = maskSize - usedRbs;
22770
22771       if (remNumRbs >= rbsReq)
22772       {
22773          bestNumAvailRbs = rbsReq;
22774          bestSubsetIdx = rbgSubset;
22775          break;
22776       }
22777       else if (isPartialAlloc && (remNumRbs > bestNumAvailRbs))
22778       {
22779          bestNumAvailRbs = remNumRbs;
22780          bestSubsetIdx = rbgSubset;
22781       }
22782
22783       rbgSubset = (rbgSubset + 1) % rbgSize;
22784    } /* End of for (each rbgsubset) */
22785
22786    if (bestNumAvailRbs)
22787    {
22788       /* Initialize alloced mask and subsetSize depending on the RBG
22789        * subset of allocation */
22790       U8        startIdx = 0;
22791       maskSize = rbgSubsetSzArr[bestSubsetIdx];
22792       allocedMask = allocMask[bestSubsetIdx];
22793       RG_SCH_CMN_DL_GET_START_POS(allocedMask, maskSize,
22794             &startPos);
22795       for (; startIdx < rbgSize; ++startIdx, ++startPos)
22796       {
22797          for (rbInSubset = startPos; rbInSubset < maskSize;
22798                rbInSubset = rbInSubset + rbgSize)
22799          {
22800             rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
22801             if (!(allocedMask & rbPosInSubset))
22802             {
22803                raType1Mask[bestSubsetIdx] |= rbPosInSubset;
22804                raType1UsedRbs[bestSubsetIdx]++;
22805
22806                /* Compute RB index value for the RB being allocated */
22807                rbgInSubset = rbInSubset /rbgSize;
22808                offset = rbInSubset % rbgSize;
22809                rbg = (rbgInSubset * rbgSize) + bestSubsetIdx;
22810                rbIdx = (rbg * rbgSize) + offset;
22811
22812                /* Update RBG mask for RA type 0 allocation */
22813                ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
22814                *rbgMask |= ueRaType0Mask;
22815
22816                /* Update RA type 2 mask */
22817                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22818                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22819
22820                /* Update the counters */
22821                numAllocRbs++;
22822                remNumRbs--;
22823                if (numAllocRbs == bestNumAvailRbs)
22824                {
22825                   break;
22826                }
22827             }
22828          } /* End of for (each position in the subset mask) */
22829          if (numAllocRbs == bestNumAvailRbs)
22830          {
22831             break;
22832          }
22833       } /* End of for startIdx = 0 to rbgSize */
22834
22835       *allocRbgSubset = bestSubsetIdx;
22836    } /* End of if (bestNumAvailRbs) */
22837
22838    RETVALUE(numAllocRbs);
22839 }
22840 #endif
22841 /**
22842  * @brief Handles RB allocation for Resource allocation type 2
22843  *
22844  * @details
22845  *
22846  *     Function : rgSCHCmnDlRaType2Alloc
22847  *
22848  *     Invoking Module Processing:
22849  *     - This function is invoked for DL RB allocation for resource allocation
22850  *     type 2
22851  *
22852  *     Processing Steps:
22853  *     - Determine the available positions in the mask
22854  *     - Allocate best fit cosecutive RBs.
22855  *     - Update RA Type2, RA type 1 and RA type 0 masks.
22856  *
22857  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22858  *  @param[in]   U8             rbsReq
22859  *  @param[in]   RgSchBwRbgInfo *rbgInfo
22860  *  @param[out]  U8             *rbStart
22861  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
22862  *  @param[in]   Bool           isPartialAlloc
22863  *
22864  *  @return  U8
22865  *  Number of allocated RBs
22866  **/
22867
22868 #ifdef ANSI
22869 PUBLIC U8 rgSCHCmnDlRaType2Alloc
22870 (
22871 RgSchDlSfAllocInfo *allocedInfo,
22872 U8                 rbsReq,
22873 RgSchBwRbgInfo     *rbgInfo,
22874 U8                 *rbStart,
22875 RgSchDlSfAllocInfo *resAllocInfo,
22876 Bool               isPartialAlloc
22877 )
22878 #else
22879 PUBLIC U8 rgSCHCmnDlRaType2Alloc(allocedInfo, rbsReq, rbgInfo, rbStart,
22880       resAllocInfo, isPartialAlloc)
22881 RgSchDlSfAllocInfo *allocedInfo;
22882 U8                 rbsReq;
22883 RgSchBwRbgInfo     *rbgInfo;
22884 U8                 *rbStart;
22885 RgSchDlSfAllocInfo *resAllocInfo;
22886 Bool               isPartialAlloc;
22887 #endif
22888 {
22889    U8          numAllocRbs = 0;
22890    U8          rbIdx;
22891    U8          rbgSize = rbgInfo->rbgSize;
22892    U32         *rbgMask = &resAllocInfo->raType0Mask;
22893 #ifdef RGSCH_SPS_UNUSED
22894    U32         *raType1Mask = resAllocInfo->raType1Mask;
22895 #endif
22896    U32         *raType2Mask = resAllocInfo->raType2Mask;
22897 #ifdef RGSCH_SPS_UNUSED
22898    U32         *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22899 #endif
22900    U32         *allocedMask = allocedInfo->raType2Mask;
22901
22902    /* Note: This function atttempts only full allocation */
22903    rgSCHCmnDlGetBestFitHole(allocedMask, rbgInfo->numRbs,
22904          raType2Mask, rbsReq, rbStart, &numAllocRbs, isPartialAlloc);
22905    if (numAllocRbs)
22906    {
22907       /* Update the allocation in RA type 0 and RA type 1 masks */
22908       U8 rbCnt = numAllocRbs;
22909 #ifdef RGSCH_SPS_UNUSED
22910       U8 rbgSubset;
22911       U32 ueRaType1Mask;
22912 #endif
22913       U32 ueRaType0Mask;
22914       rbIdx = *rbStart;
22915
22916       while(rbCnt)
22917       {
22918          /* Update RBG mask for RA type 0 allocation */
22919          ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
22920          *rbgMask |= ueRaType0Mask;
22921
22922 #ifdef RGSCH_SPS_UNUSED
22923          /* Update RBG mask for RA type 1 */
22924          ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22925          raType1Mask[rbgSubset] |= ueRaType1Mask;
22926          raType1UsedRbs[rbgSubset]++;
22927 #endif
22928          /* Update the counters */
22929          --rbCnt;
22930          rbIdx++;
22931       }
22932    }
22933
22934    RETVALUE(numAllocRbs);
22935 }
22936
22937 /**
22938  * @brief Determines RA type 0 mask from given RB index.
22939  *
22940  * @details
22941  *
22942  *     Function : rgSCHCmnGetRaType0Mask
22943  *
22944  *
22945  *     Processing Steps:
22946  *     - Determine RA Type 0 mask for given rbIdex and rbg size.
22947  *
22948  *  @param[in]  U8          rbIdx
22949  *  @param[in]  U8          rbgSize
22950  *  @return  U32 RA type 0 mask
22951  **/
22952 #ifdef ANSI
22953 PRIVATE U32 rgSCHCmnGetRaType0Mask
22954 (
22955 U8                rbIdx,
22956 U8                rbgSize
22957 )
22958 #else
22959 PRIVATE U32 rgSCHCmnGetRaType0Mask(rbIdx, rbgSize)
22960 U8                rbIdx;
22961 U8                rbgSize;
22962 #endif
22963 {
22964    U8 rbg;
22965    U32 rbgPosInRbgMask = 0;
22966
22967    rbg = rbIdx/rbgSize;
22968    rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22969
22970    RETVALUE(rbgPosInRbgMask);
22971 }
22972
22973 #ifdef RGSCH_SPS_UNUSED
22974 /**
22975  * @brief Determines RA type 1 mask from given RB index.
22976  *
22977  * @details
22978  *
22979  *     Function : rgSCHCmnGetRaType1Mask
22980  *
22981  *
22982  *     Processing Steps:
22983  *     - Determine RA Type 1 mask for given rbIdex and rbg size.
22984  *
22985  *  @param[in]  U8          rbIdx
22986  *  @param[in]  U8          rbgSize
22987  *  @param[out] U8          *type1Subset
22988  *  @return  U32 RA type 1 mask
22989  **/
22990 #ifdef ANSI
22991 PRIVATE U32 rgSCHCmnGetRaType1Mask
22992 (
22993 U8                rbIdx,
22994 U8                rbgSize,
22995 U8                *type1Subset
22996 )
22997 #else
22998 PRIVATE U32 rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, type1Subset)
22999 U8                rbIdx;
23000 U8                rbgSize;
23001 U8                *type1Subset;
23002 #endif
23003 {
23004    U8 rbg, rbgSubset, rbgInSubset, offset, rbInSubset;
23005    U32 rbPosInSubset;
23006
23007    rbg = rbIdx/rbgSize;
23008    rbgSubset = rbg % rbgSize;
23009    rbgInSubset = rbg/rbgSize;
23010    offset = rbIdx % rbgSize;
23011    rbInSubset = rbgInSubset * rbgSize + offset;
23012    rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
23013
23014    *type1Subset = rbgSubset;
23015    RETVALUE(rbPosInSubset);
23016
23017 #endif /* RGSCH_SPS_UNUSED */
23018 /**
23019  * @brief Determines RA type 2 mask from given RB index.
23020  *
23021  * @details
23022  *
23023  *     Function : rgSCHCmnGetRaType2Mask
23024  *
23025  *
23026  *     Processing Steps:
23027  *     - Determine RA Type 2 mask for given rbIdx and rbg size.
23028  *
23029  *  @param[in]  U8          rbIdx
23030  *  @param[out] U8          *maskIdx
23031  *  @return  U32 RA type 2 mask
23032  **/
23033 #ifdef ANSI
23034 PRIVATE U32 rgSCHCmnGetRaType2Mask
23035 (
23036 U8                rbIdx,
23037 U8                *maskIdx
23038 )
23039 #else
23040 PRIVATE U32 rgSCHCmnGetRaType2Mask(rbIdx, maskIdx)
23041 U8                rbIdx;
23042 U8                *maskIdx;
23043 #endif
23044 {
23045    U32 rbPosInType2;
23046
23047    *maskIdx = rbIdx / 32;
23048    rbPosInType2 =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbIdx % 32);
23049
23050    RETVALUE(rbPosInType2);
23051 }
23052
23053 /**
23054  * @brief Performs resource allocation for a non-SPS UE in SPS bandwidth
23055  *
23056  * @details
23057  *
23058  *     Function : rgSCHCmnAllocUeInSpsBw
23059  *
23060  *
23061  *     Processing Steps:
23062  *       - Determine allocation for the UE.
23063  *       - Use resource allocation type 0, 1 and 2 for allocation
23064  *         within maximum SPS bandwidth.
23065  *
23066  *  @param[in]  RgSchDlSf       *dlSf
23067  *  @param[in]  RgSchCellCb     *cell
23068  *  @param[in]  RgSchUeCb       *ue
23069  *  @param[in]  RgSchDlRbAlloc  *rbAllocInfo
23070  *  @param[in]  Bool            isPartialAlloc
23071  *  @return  Bool
23072  *             ROK      success
23073  *             RFAILED  failed
23074  **/
23075 #ifdef ANSI
23076 PUBLIC Bool rgSCHCmnAllocUeInSpsBw
23077 (
23078 RgSchDlSf           *dlSf,
23079 RgSchCellCb         *cell,
23080 RgSchUeCb           *ue,
23081 RgSchDlRbAlloc      *rbAllocInfo,
23082 Bool                isPartialAlloc
23083 )
23084 #else
23085 PUBLIC Bool rgSCHCmnAllocUeInSpsBw(dlSf, cell, ue, rbAllocInfo, isPartialAlloc)
23086 RgSchDlSf           *dlSf;
23087 RgSchCellCb         *cell;
23088 RgSchUeCb           *ue;
23089 RgSchDlRbAlloc      *rbAllocInfo;
23090 Bool                isPartialAlloc;
23091 #endif
23092 {
23093    U8                  rbgSize = cell->rbgSize;
23094    U8                  numAllocRbs = 0;
23095    U8                  numAllocRbgs = 0;
23096    U8                  rbStart = 0;
23097    U8                  idx, noLyr, iTbs;
23098    RgSchCmnDlUe        *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
23099    RgSchDlSfAllocInfo  *dlSfAlloc = &rbAllocInfo->dlSf->dlSfAllocInfo;
23100    RgSchBwRbgInfo      *spsRbgInfo = &cell->spsBwRbgInfo;
23101
23102    /* SPS_FIX : Check if this Hq proc is scheduled */
23103    if ((0 == rbAllocInfo->tbInfo[0].schdlngForTb) &&
23104          (0 == rbAllocInfo->tbInfo[1].schdlngForTb))
23105    {
23106       RETVALUE(TRUE);
23107    }
23108
23109    /* Check if the requirement can be accomodated in SPS BW */
23110    if (dlSf->spsAllocdBw == spsRbgInfo->numRbs)
23111    {
23112       /* SPS Bandwidth has been exhausted: no further allocations possible */
23113       RETVALUE(FALSE);
23114    }
23115    if (!isPartialAlloc)
23116    {
23117       if((dlSf->spsAllocdBw + rbAllocInfo->rbsReq) > spsRbgInfo->numRbs)
23118       {
23119          RETVALUE(TRUE);
23120       }
23121    }
23122
23123    /* Perform allocation for RA type 0 if rbsReq is multiple of RBG size (also
23124     * if RBG size = 1) */
23125    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
23126    {
23127       rbAllocInfo->rbsReq += (rbgSize - rbAllocInfo->rbsReq % rbgSize);
23128       numAllocRbgs = rgSCHCmnDlRaType0Alloc(dlSfAlloc,
23129             rbAllocInfo->rbsReq, spsRbgInfo, &numAllocRbs,
23130             &rbAllocInfo->resAllocInfo, isPartialAlloc);
23131    }
23132 #ifdef RGSCH_SPS_UNUSED
23133    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
23134    {
23135       /* If no RBS could be allocated, attempt RA TYPE 1 */
23136
23137       numAllocRbs = rgSCHCmnDlRaType1Alloc(dlSfAlloc,
23138             rbAllocInfo->rbsReq, spsRbgInfo, (U8)dlSfAlloc->nxtRbgSubset,
23139             &rbAllocInfo->allocInfo.raType1.rbgSubset,
23140             &rbAllocInfo->resAllocInfo, isPartialAlloc);
23141
23142       if(numAllocRbs)
23143       {
23144          dlSfAlloc->nxtRbgSubset =
23145             (rbAllocInfo->allocInfo.raType1.rbgSubset + 1 ) % rbgSize;
23146       }
23147    }
23148 #endif
23149    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
23150    {
23151       numAllocRbs = rgSCHCmnDlRaType2Alloc(dlSfAlloc,
23152             rbAllocInfo->rbsReq, spsRbgInfo,
23153             &rbStart, &rbAllocInfo->resAllocInfo, isPartialAlloc);
23154    }
23155    if (!numAllocRbs)
23156    {
23157       RETVALUE(TRUE);
23158    }
23159
23160    if (!(rbAllocInfo->pdcch =
23161             rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi,\
23162                rbAllocInfo->dciFormat, FALSE)))
23163    {
23164       /* Note: Returning TRUE since PDCCH might be available for another UE */
23165       RETVALUE(TRUE);
23166    }
23167
23168    /* Update Tb info for each scheduled TB */
23169    iTbs = rbAllocInfo->tbInfo[0].iTbs;
23170    noLyr = rbAllocInfo->tbInfo[0].noLyr;
23171    rbAllocInfo->tbInfo[0].bytesAlloc =
23172       rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
23173
23174    if (rbAllocInfo->tbInfo[1].schdlngForTb)
23175    {
23176       iTbs = rbAllocInfo->tbInfo[1].iTbs;
23177       noLyr = rbAllocInfo->tbInfo[1].noLyr;
23178       rbAllocInfo->tbInfo[1].bytesAlloc =
23179          rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;;
23180    }
23181
23182    /* Update rbAllocInfo with the allocation information */
23183    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
23184    {
23185       rbAllocInfo->allocInfo.raType0.dlAllocBitMask =
23186          rbAllocInfo->resAllocInfo.raType0Mask;
23187       rbAllocInfo->allocInfo.raType0.numDlAlloc = numAllocRbgs;
23188    }
23189 #ifdef RGSCH_SPS_UNUSED
23190    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
23191    {
23192       rbAllocInfo->allocInfo.raType1.dlAllocBitMask =
23193          rbAllocInfo->resAllocInfo.raType1Mask[rbAllocInfo->allocInfo.raType1.rbgSubset];
23194       rbAllocInfo->allocInfo.raType1.numDlAlloc = numAllocRbs;
23195       rbAllocInfo->allocInfo.raType1.shift = 0;
23196    }
23197 #endif
23198    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
23199    {
23200       rbAllocInfo->allocInfo.raType2.isLocal = TRUE;
23201       rbAllocInfo->allocInfo.raType2.rbStart = rbStart;
23202       rbAllocInfo->allocInfo.raType2.numRb = numAllocRbs;
23203    }
23204
23205    rbAllocInfo->rbsAlloc = numAllocRbs;
23206    rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
23207
23208    /* Update allocation masks for RA types 0, 1 and 2 in DL SF */
23209
23210    /* Update type 0 allocation mask */
23211    dlSfAlloc->raType0Mask |= rbAllocInfo->resAllocInfo.raType0Mask;
23212 #ifdef RGSCH_SPS_UNUSED
23213    /* Update type 1 allocation masks */
23214    for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
23215    {
23216       dlSfAlloc->raType1Mask[idx] |= rbAllocInfo->resAllocInfo.raType1Mask[idx];
23217       dlSfAlloc->raType1UsedRbs[idx] +=
23218          rbAllocInfo->resAllocInfo.raType1UsedRbs[idx];
23219    }
23220 #endif
23221    /* Update type 2 allocation masks */
23222    for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
23223    {
23224       dlSfAlloc->raType2Mask[idx] |= rbAllocInfo->resAllocInfo.raType2Mask[idx];
23225    }
23226
23227    dlSf->spsAllocdBw += numAllocRbs;
23228    RETVALUE(TRUE);
23229 }
23230
23231 /***********************************************************
23232  *
23233  *     Func : rgSCHCmnDlGetBestFitHole
23234  *
23235  *
23236  *     Desc : Converts the best fit hole into allocation and returns the
23237  *     allocation information.
23238  *
23239  *
23240  *     Ret  : Void
23241  *
23242  *
23243  *     Notes:
23244  *
23245  *     File :
23246  *
23247  **********************************************************/
23248 #ifdef ANSI
23249 PRIVATE Void rgSCHCmnDlGetBestFitHole
23250 (
23251 U32         *allocMask,
23252 U8          numMaskRbs,
23253 U32         *crntAllocMask,
23254 U8          rbsReq,
23255 U8          *allocStart,
23256 U8          *allocNumRbs,
23257 Bool        isPartialAlloc
23258 )
23259 #else
23260 PRIVATE  Void rgSCHCmnDlGetBestFitHole (allocMask, numMaskRbs,
23261         crntAllocMask, rbsReq, allocStart, allocNumRbs, isPartialAlloc)
23262 U32         *allocMask;
23263 U8          numMaskRbs;
23264 U32         *crntAllocMask;
23265 U8          rbsReq;
23266 U8          *allocStart;
23267 U8          *allocNumRbs;
23268 Bool        isPartialAlloc;
23269 #endif
23270 {
23271    U8 maskSz = (numMaskRbs + 31)/32;
23272    U8 maxMaskPos = (numMaskRbs % 32);
23273    U8 maskIdx, maskPos;
23274    U8 numAvailRbs = 0;
23275    U8 bestAvailNumRbs = 0;
23276    S8 bestStartPos = -1;
23277    S8 startPos = -1;
23278    U32 tmpMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
23279    U32 bestMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
23280
23281    *allocNumRbs = numAvailRbs;
23282    *allocStart = 0;
23283
23284    for (maskIdx = 0; maskIdx < maskSz; ++maskIdx)
23285    {
23286       maxMaskPos = 31;
23287       if (maskIdx == (maskSz - 1))
23288       {
23289          if (numMaskRbs % 32)
23290          {
23291             maxMaskPos = numMaskRbs % 32;
23292          }
23293       }
23294       for (maskPos = 0; maskPos < maxMaskPos; ++maskPos)
23295       {
23296          if (!(allocMask[maskIdx] & (1 << (31 - maskPos))))
23297          {
23298             tmpMask[maskIdx] |= (1 << (31 - maskPos));
23299             if (startPos == -1)
23300             {
23301                startPos = maskIdx * 32 + maskPos;
23302             }
23303             ++numAvailRbs;
23304             if (numAvailRbs == rbsReq)
23305             {
23306                *allocStart = (U8)startPos;
23307                *allocNumRbs = rbsReq;
23308                break;
23309             }
23310          }
23311          else
23312          {
23313             if (numAvailRbs > bestAvailNumRbs)
23314             {
23315                bestAvailNumRbs = numAvailRbs;
23316                bestStartPos = startPos;
23317                cmMemcpy((U8 *)bestMask, (U8 *) tmpMask, 4 * sizeof(U32));
23318             }
23319             numAvailRbs = 0;
23320             startPos = -1;
23321             cmMemset((U8 *)tmpMask, 0, 4 * sizeof(U32));
23322          }
23323       }
23324       if (*allocNumRbs == rbsReq)
23325       {
23326          break;
23327       }
23328    }
23329
23330    if (*allocNumRbs == rbsReq)
23331    {
23332       /* Convert the hole into allocation */
23333       cmMemcpy((U8 *)crntAllocMask, (U8 *) tmpMask, 4 * sizeof(U32));
23334       RETVOID;
23335    }
23336    else
23337    {
23338       if (bestAvailNumRbs && isPartialAlloc)
23339       {
23340          /* Partial allocation could have been done */
23341          *allocStart = (U8)bestStartPos;
23342          *allocNumRbs = bestAvailNumRbs;
23343          /* Convert the hole into allocation */
23344          cmMemcpy((U8 *)crntAllocMask, (U8 *) bestMask, 4 * sizeof(U32));
23345       }
23346    }
23347
23348    RETVOID;
23349 }
23350 #endif /* LTEMAC_SPS */
23351
23352 /***************************************************************************
23353  *
23354  * NON-DLFS Allocation functions
23355  *
23356  * *************************************************************************/
23357 #ifndef LTE_TDD
23358 #ifdef DEBUGP
23359 /**
23360  * @brief Function to find out code rate
23361  *
23362  * @details
23363  *
23364  *     Function : rgSCHCmnFindCodeRate
23365  *
23366  *     Processing Steps:
23367  *
23368  *  @param[in]      RgSchCellCb     *cell
23369  *  @param[in]      RgSchDlSf       *dlSf
23370  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23371  *  @return  void
23372  **/
23373 #ifdef ANSI
23374 PRIVATE Void rgSCHCmnFindCodeRate
23375 (
23376 RgSchCellCb           *cell,
23377 RgSchDlSf             *dlSf,
23378 RgSchDlRbAlloc        *allocInfo,
23379 U8                    idx
23380 )
23381 #else
23382 PRIVATE Void rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,idx)
23383 RgSchCellCb           *cell;
23384 RgSchDlSf             *dlSf;
23385 RgSchDlRbAlloc        *allocInfo;
23386 U8                    idx;
23387 #endif
23388 {
23389     RETVOID;
23390
23391 }
23392 #endif
23393
23394 /* Adjust the Imcs and bytes allocated also with respect to the adjusted
23395    RBs - Here we will find out the Imcs by identifying first Highest
23396    number of bits compared to the original bytes allocated.  */
23397 /**
23398  * @brief Adjust IMCS according to tbSize and ITBS
23399  *
23400  * @details
23401  *
23402  *     Function : rgSCHCmnNonDlfsPbchTbImcsAdj
23403  *
23404  *     Processing Steps:
23405  *      - Adjust Imcs according to tbSize and ITBS.
23406  *
23407  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23408  *  @param[in]      U8              *idx
23409  *  @return  void
23410  **/
23411 #ifdef ANSI
23412 PRIVATE Void rgSCHCmnNonDlfsPbchTbImcsAdj
23413 (
23414 RgSchCellCb      *cell,
23415 RgSchDlRbAlloc   *allocInfo,
23416 U8               idx,
23417 U8               rbsReq
23418 )
23419 #else
23420 PRIVATE Void rgSCHCmnNonDlfsPbchTbImcsAdj(cell,allocInfo, idx, rbsReq)
23421 RgSchCellCb      *cell;
23422 RgSchDlRbAlloc   *allocInfo;
23423 U8               idx;
23424 U8               rbsReq;
23425 #endif
23426 {
23427    U8             noLyrs = 0;
23428    U8             tbs = 0;
23429    U32            origBytesReq;
23430    U8             noRbgs = 0;
23431    U8             noRbs = 0;
23432    RgSchDlSf     *dlSf = allocInfo->dlSf;
23433
23434    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
23435    noLyrs = allocInfo->tbInfo[idx].noLyr;
23436
23437    if((allocInfo->raType == RG_SCH_CMN_RA_TYPE0))
23438    {
23439       noRbgs = RGSCH_CEIL((allocInfo->rbsReq + dlSf->lstRbgDfct), cell->rbgSize);
23440       noRbs = (noRbgs * cell->rbgSize) - dlSf->lstRbgDfct;
23441    }
23442    else
23443    {
23444        noRbs = allocInfo->rbsReq;
23445    }
23446
23447    /* This line will help in case if tbs is zero and reduction in MCS is not possible */
23448    if (allocInfo->rbsReq == 0 )
23449    {
23450       RETVOID;
23451    }
23452    origBytesReq = rgTbSzTbl[noLyrs - 1][tbs][rbsReq - 1]/8;
23453
23454    /* Find out the ITbs & Imcs by identifying first Highest
23455       number of bits compared to the original bytes allocated.*/
23456    if(tbs > 0)
23457    {
23458       if(((rgTbSzTbl[noLyrs - 1][0][noRbs - 1])/8) < origBytesReq)
23459       {
23460           RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyrs - 1], tbs);
23461           while(((rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1])/8) > origBytesReq)
23462           {
23463               tbs--;
23464           }
23465       }
23466       else
23467       {
23468           tbs = 0;
23469       }
23470       allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1]/8;
23471       allocInfo->tbInfo[idx].iTbs = tbs;
23472       RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
23473    }
23474
23475    RETVOID;
23476 }
23477 /* Added funcion to adjust TBSize*/
23478 /**
23479  * @brief Function to adjust the tbsize in case of subframe 0 & 5 when
23480  * we were not able to do RB alloc adjustment by adding extra required Rbs
23481  *
23482  * @details
23483  *
23484  *     Function : rgSCHCmnNonDlfsPbchTbSizeAdj
23485  *
23486  *     Processing Steps:
23487  *
23488  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23489  *  @param[in]      U8            numOvrlapgPbchRb
23490  *  @param[in]      U8            idx
23491  *  @param[in]      U8            pbchSsRsSym
23492  *  @return  void
23493  **/
23494 #ifdef ANSI
23495 PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj
23496 (
23497 RgSchDlRbAlloc        *allocInfo,
23498 U8                    numOvrlapgPbchRb,
23499 U8                    pbchSsRsSym,
23500 U8                    idx,
23501 U32                   bytesReq
23502 )
23503 #else
23504 PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,idx,bytesReq)
23505 RgSchDlRbAlloc        *allocInfo;
23506 U8                    numOvrlapgPbchRb;
23507 U8                    pbchSsRsSym;
23508 U8                    idx;
23509 U32                   bytesReq;
23510 #endif
23511 {
23512    U32             reducedTbs = 0;
23513    U8              noLyrs = 0;
23514    U8              tbs = 0;
23515
23516    noLyrs = allocInfo->tbInfo[idx].noLyr;
23517
23518    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
23519
23520    reducedTbs = bytesReq - (((U32)numOvrlapgPbchRb * (U32)pbchSsRsSym * 6)/8);
23521
23522    /* find out the ITbs & Imcs by identifying first Highest
23523     number of bits compared with reduced bits considering the bits that are
23524     reserved for PBCH/PSS/SSS */
23525    if(((rgTbSzTbl[noLyrs - 1][0][allocInfo->rbsReq - 1])/8) < reducedTbs)
23526    {
23527        while(((rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1])/8) > reducedTbs)
23528        {
23529            tbs--;
23530        }
23531    }
23532    else
23533    {
23534        tbs = 0;
23535    }
23536    allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1]/8;
23537    allocInfo->tbInfo[idx].iTbs = tbs;
23538    RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
23539
23540    RETVOID;
23541 }
23542
23543 /* Added this function to find num of ovrlapping PBCH rb*/
23544 /**
23545  * @brief Function to find out how many additional rbs are available
23546  *    in the entire bw which can be allocated to a UE
23547  * @details
23548  *
23549  *     Function : rgSCHCmnFindNumAddtlRbsAvl
23550  *
23551  *     Processing Steps:
23552  *      - Calculates number of additinal rbs available
23553  *
23554  *  @param[in]      RgSchCellCb     *cell
23555  *  @param[in]      RgSchDlSf       *dlSf
23556  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23557  *  @param[out]      U8            addtlRbsAvl
23558  *  @return  void
23559  **/
23560 #ifdef ANSI
23561 PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl
23562 (
23563 RgSchCellCb           *cell,
23564 RgSchDlSf             *dlSf,
23565 RgSchDlRbAlloc        *allocInfo
23566 )
23567 #else
23568 PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl(cell,dlSf,allocInfo)
23569 RgSchCellCb           *cell;
23570 RgSchDlSf             *dlSf;
23571 RgSchDlRbAlloc        *allocInfo;
23572 #endif
23573 {
23574     U8 addtlRbsAvl = 0;
23575
23576     TRC2(rgSCHCmnFindNumAddtlRbsAvl)
23577
23578     if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
23579     {
23580          addtlRbsAvl = (((dlSf->type0End - dlSf->type2End + 1)*\
23581                         cell->rbgSize) - dlSf->lstRbgDfct) - allocInfo->rbsReq;
23582     }
23583     else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
23584     {
23585        addtlRbsAvl = (dlSf->bw - dlSf->bwAlloced) - allocInfo->rbsReq;
23586     }
23587
23588     RETVALUE(addtlRbsAvl);
23589
23590 }
23591 /* Added this function to find num of ovrlapping PBCH rb*/
23592 /**
23593  * @brief Function to find out how many of the requested RBs are
23594  *        falling in the center 6 RBs of the downlink bandwidth.
23595  * @details
23596  *
23597  *     Function : rgSCHCmnFindNumPbchOvrlapRbs
23598  *
23599  *     Processing Steps:
23600  *      - Calculates number of overlapping rbs
23601  *
23602  *  @param[in]      RgSchCellCb     *cell
23603  *  @param[in]      RgSchDlSf       *dlSf
23604  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23605  *  @param[out]      U8*            numOvrlapgPbchRb
23606  *  @return  void
23607  **/
23608 #ifdef ANSI
23609 PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs
23610 (
23611 RgSchCellCb           *cell,
23612 RgSchDlSf             *dlSf,
23613 RgSchDlRbAlloc        *allocInfo,
23614 U8                    *numOvrlapgPbchRb
23615 )
23616 #else
23617 PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,numOvrlapgPbchRb)
23618 RgSchCellCb           *cell;
23619 RgSchDlSf             *dlSf;
23620 RgSchDlRbAlloc        *allocInfo;
23621 U8                    *numOvrlapgPbchRb;
23622 #endif
23623 {
23624     *numOvrlapgPbchRb = 0;
23625     TRC2(rgSCHCmnFindNumPbchOvrlapRbs)
23626    /*Find if we have already crossed the start boundary for PBCH 6 RBs,
23627     * if yes then lets find the number of RBs which are getting overlapped
23628     * with this allocation.*/
23629    if(dlSf->bwAlloced <= (cell->pbchRbStart))
23630    {
23631       /*We have not crossed the start boundary of PBCH RBs. Now we need
23632        * to know that if take this allocation then how much PBCH RBs
23633        * are overlapping with this allocation.*/
23634       /* Find out the overlapping RBs in the centre 6 RBs */
23635        if((dlSf->bwAlloced + allocInfo->rbsReq) > cell->pbchRbStart)
23636        {
23637            *numOvrlapgPbchRb = (dlSf->bwAlloced + allocInfo->rbsReq) - (cell->pbchRbStart);
23638            if(*numOvrlapgPbchRb > 6)
23639                 *numOvrlapgPbchRb = 6;
23640        }
23641    }
23642    else if ((dlSf->bwAlloced > (cell->pbchRbStart)) &&
23643          (dlSf->bwAlloced < (cell->pbchRbEnd)))
23644    {
23645       /*We have already crossed the start boundary of PBCH RBs.We need to
23646        * find that if we take this allocation then how much of the RBs for
23647        * this allocation will overlap with PBCH RBs.*/
23648       /* Find out the overlapping RBs in the centre 6 RBs */
23649       if(dlSf->bwAlloced + allocInfo->rbsReq < (cell->pbchRbEnd))
23650       {
23651          /*If we take this allocation then also we are not crossing the
23652           * end boundary of PBCH 6 RBs.*/
23653          *numOvrlapgPbchRb = allocInfo->rbsReq;
23654       }
23655       else
23656       {
23657          /*If we take this allocation then we are crossing the
23658           * end boundary of PBCH 6 RBs.*/
23659          *numOvrlapgPbchRb = (cell->pbchRbEnd) - dlSf->bwAlloced;
23660       }
23661    }
23662     RETVOID;
23663
23664 }
23665 /**
23666  * @brief Performs RB allocation adjustment if the requested RBs are
23667  *        falling in the center 6 RBs of the downlink bandwidth.
23668  * @details
23669  *
23670  *     Function : rgSCHCmnNonDlfsPbchRbAllocAdj
23671  *
23672  *     Processing Steps:
23673  *      - Allocate consecutively available RBs.
23674  *
23675  *  @param[in]      RgSchCellCb     *cell
23676  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23677  *  @param[in]      U8               pbchSsRsSym
23678  *  @return  void
23679  **/
23680 #ifdef ANSI
23681 PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj
23682 (
23683 RgSchCellCb      *cell,
23684 RgSchDlRbAlloc   *allocInfo,
23685 U8               pbchSsRsSym,
23686 Bool             isBcchPcch
23687 )
23688 #else
23689 PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo,pbchSsRsSym)
23690 RgSchCellCb      *cell;
23691 RgSchDlRbAlloc   *allocInfo;
23692 U8               pbchSsRsSym;
23693 Bool             isBcchPcch;
23694 #endif
23695 {
23696    RgSchDlSf     *dlSf = allocInfo->dlSf;
23697    U8             numOvrlapgPbchRb = 0;
23698    U8             numOvrlapgAdtlPbchRb = 0;
23699    U8             totSym;
23700    U8             addtlRbsReq = 0;
23701    U8             moreAddtlRbsReq = 0;
23702    U8             addtlRbsAdd = 0;
23703    U8             moreAddtlRbsAdd = 0;
23704    U8             tbs;
23705    U8             origRbsReq = 0;
23706    U32            bytesReq;
23707    U8             noLyr;
23708    U8             divResult;
23709
23710
23711    TRC2(rgSCHCmnNonDlfsPbchRbAllocAdj);
23712
23713
23714    origRbsReq = allocInfo->rbsReq;
23715    rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23716
23717   totSym =  (cell->isCpDlExtend) ? RGSCH_TOT_NUM_SYM_EXTCP : RGSCH_TOT_NUM_SYM_NORCP;
23718
23719    /* Additional RBs are allocated by considering the loss due to
23720       the reserved symbols for CFICH, PBCH, PSS, SSS and cell specific RS */
23721
23722    divResult = (numOvrlapgPbchRb * pbchSsRsSym)/totSym;
23723    if((numOvrlapgPbchRb * pbchSsRsSym) % totSym)
23724    {
23725       divResult++;
23726    }
23727    addtlRbsReq = divResult;
23728
23729    RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, addtlRbsReq, addtlRbsAdd)
23730
23731    /*Now RBs requires is original requested RBs + these additional RBs to make
23732     * up for PSS/SSS/BCCH.*/
23733    allocInfo->rbsReq = allocInfo->rbsReq + addtlRbsAdd;
23734
23735    /*Check if with these additional RBs we have taken up, these are also falling
23736     * under PBCH RBs range, if yes then we would need to account for
23737     * PSS/BSS/BCCH for these additional RBs too.*/
23738    if(addtlRbsAdd && ((dlSf->bwAlloced + allocInfo->rbsReq - addtlRbsAdd) < (cell->pbchRbEnd)))
23739    {
23740       if((dlSf->bwAlloced + allocInfo->rbsReq) <= (cell->pbchRbEnd))
23741       {
23742       /*With additional RBs taken into account, we are not crossing the
23743        * PBCH RB end boundary.Thus here we need to account just for
23744        * overlapping PBCH RBs for these additonal RBs.*/
23745           divResult = (addtlRbsAdd * pbchSsRsSym)/totSym;
23746           if((addtlRbsAdd * pbchSsRsSym) % totSym)
23747           {
23748             divResult++;
23749           }
23750
23751           moreAddtlRbsReq = divResult;
23752
23753           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
23754
23755           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
23756       }
23757       else
23758       {
23759
23760          /*Here we have crossed the PBCH RB end boundary, thus we need to take
23761           * into account the overlapping RBs for additional RBs which will be
23762           * subset of addtlRbs.*/
23763           numOvrlapgAdtlPbchRb = (cell->pbchRbEnd) - ((dlSf->bwAlloced + allocInfo->rbsReq) -  addtlRbsAdd);
23764
23765           divResult = (numOvrlapgAdtlPbchRb * pbchSsRsSym)/totSym;
23766           if((numOvrlapgAdtlPbchRb * pbchSsRsSym) % totSym)
23767           {
23768              divResult++;
23769           }
23770
23771           moreAddtlRbsReq =  divResult;
23772
23773           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
23774
23775           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
23776       }
23777    }
23778    if (isBcchPcch == TRUE)
23779    {
23780       RETVOID;
23781    }
23782
23783    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
23784    if(tbs == 6)
23785    {
23786       /* This case might be for Imcs value 6 and NPrb = 1 case  - Not
23787          Adjusting either RBs or Imcs or Bytes Allocated */
23788       allocInfo->rbsReq = allocInfo->rbsReq - addtlRbsAdd - moreAddtlRbsAdd;
23789    }
23790    else if(tbs && ((0 == addtlRbsAdd) && (moreAddtlRbsAdd == 0)))
23791    {
23792        /*In case of a situation where we the entire bandwidth is already occupied
23793         * and we dont have room to add additional Rbs then in order to decrease the
23794         * code rate we reduce the tbsize such that we reduce the present calculated
23795         * tbsize by number of bytes that would be occupied by PBCH/PSS/SSS in overlapping
23796         * rbs and find the nearest tbsize which would be less than this deduced value*/
23797
23798       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23799
23800       noLyr = allocInfo->tbInfo[0].noLyr;
23801       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyr - 1], tbs);
23802       bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
23803
23804       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,bytesReq);
23805
23806       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23807       {
23808           noLyr = allocInfo->tbInfo[1].noLyr;
23809           bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
23810           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,bytesReq);
23811       }
23812
23813    }
23814    else if(tbs && ((addtlRbsAdd != addtlRbsReq) ||
23815           (addtlRbsAdd && (moreAddtlRbsReq != moreAddtlRbsAdd))))
23816    {
23817        /*In case of a situation where we were not able to add required number of
23818         * additional RBs then we adjust the Imcs based on original RBs requested.
23819         * Doing this would comensate for the few extra Rbs we have added but inorder
23820         * to comensate for number of RBS we couldnt add we again do the TBSize adjustment*/
23821
23822       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
23823
23824       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23825       {
23826           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
23827       }
23828
23829       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23830       numOvrlapgPbchRb = numOvrlapgPbchRb - (addtlRbsAdd + moreAddtlRbsAdd);
23831
23832       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,allocInfo->tbInfo[0].bytesReq);
23833
23834       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23835       {
23836           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,allocInfo->tbInfo[1].bytesReq);
23837       }
23838
23839    }
23840    else
23841    {
23842        /*We hit this code when we were able to add the required additional RBS
23843         * hence we should adjust the IMcs based on orignals RBs requested*/
23844
23845       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
23846
23847       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23848       {
23849           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
23850       }
23851    }
23852
23853    RETVOID;
23854 } /* end of rgSCHCmnNonDlfsPbchRbAllocAdj */
23855 #endif
23856
23857 /**
23858  * @brief Performs RB allocation for frequency non-selective cell.
23859  *
23860  * @details
23861  *
23862  *     Function : rgSCHCmnNonDlfsCmnRbAlloc
23863  *
23864  *     Processing Steps:
23865  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
23866  *
23867  *  @param[in]      RgSchCellCb     *cell
23868  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
23869  *  @return  S16
23870  *      -# ROK
23871  *      -# RFAILED
23872  **/
23873 #ifdef ANSI
23874 PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc
23875 (
23876 RgSchCellCb      *cell,
23877 RgSchDlRbAlloc   *allocInfo
23878 )
23879 #else
23880 PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo)
23881 RgSchCellCb      *cell;
23882 RgSchDlRbAlloc   *allocInfo;
23883 #endif
23884 {
23885 #ifndef LTE_TDD
23886 #ifdef LTEMAC_SPS
23887 #endif
23888    U8 pbchSsRsSym = 0;
23889    U8 pbchFrame = 0;
23890    U8  tbs = 0;
23891    RgSchCmnDlCell   *cellDl    = RG_SCH_CMN_GET_DL_CELL(cell); 
23892 #endif
23893    RgSchDlSf     *dlSf   = allocInfo->dlSf;
23894 #ifdef LTEMAC_SPS
23895    U8                  rbStart = 0;
23896    U8                  spsRbsAlloc = 0;
23897    RgSchDlSfAllocInfo  *dlSfAlloc = &allocInfo->dlSf->dlSfAllocInfo;
23898 #endif
23899    TRC2(rgSCHCmnNonDlfsCmnRbAlloc);
23900
23901    allocInfo->tbInfo[0].noLyr = 1;
23902
23903 #ifdef LTEMAC_SPS
23904    /* Note: Initialize the masks to 0, this might not be needed since alloInfo
23905     * is initialized to 0 at the beginning of allcoation */
23906    allocInfo->resAllocInfo.raType0Mask = 0;
23907    cmMemset((U8*)allocInfo->resAllocInfo.raType1Mask, 0,
23908          RG_SCH_NUM_RATYPE1_32BIT_MASK * sizeof (U32));
23909    cmMemset((U8*)allocInfo->resAllocInfo.raType2Mask, 0,
23910          RG_SCH_NUM_RATYPE2_32BIT_MASK * sizeof (U32));
23911
23912    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
23913          (dlSf->bwAlloced == dlSf->bw))
23914 #else
23915    if(dlSf->bwAlloced == dlSf->bw)
23916 #endif
23917    {
23918       RETVALUE(RFAILED);
23919    }
23920 #ifndef LTE_TDD
23921    if (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))
23922    {
23923 #ifdef LTEMAC_SPS
23924       if ((allocInfo->tbInfo[0].imcs < 29) && (dlSf->bwAlloced < dlSf->bw))
23925 #else
23926       if(allocInfo->tbInfo[0].imcs < 29)
23927 #endif
23928       {
23929          /* set the remaining RBs for the requested UE */
23930          allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
23931          RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
23932          allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[0][tbs][allocInfo->rbsReq - 1]/8;
23933       }
23934       else
23935       {
23936 #ifdef LTEMAC_SPS
23937          /* Attempt RA Type 2 allocation in SPS Bandwidth */
23938          if (dlSf->spsAllocdBw < cell->spsBwRbgInfo.numRbs) 
23939          {
23940             spsRbsAlloc =
23941                rgSCHCmnDlRaType2Alloc(dlSfAlloc,
23942                      allocInfo->rbsReq, &cell->spsBwRbgInfo, &rbStart,
23943                      &allocInfo->resAllocInfo, FALSE);
23944             /* rbsAlloc assignment moved from line 16671 to here to avoid
23945              * compilation error. Recheck */
23946             dlSf->spsAllocdBw += spsRbsAlloc;
23947          }
23948          if (!spsRbsAlloc)
23949 #endif /* LTEMAC_SPS */
23950          {
23951             RETVALUE(RFAILED);
23952          }
23953       }
23954    }
23955 #endif
23956
23957    /* Update allocation information */
23958    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
23959    if (allocInfo->pdcch == NULLP)
23960    {
23961       RETVALUE(RFAILED);
23962    }
23963    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
23964    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
23965    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
23966    allocInfo->allocInfo.raType2.isLocal = TRUE;
23967 #ifdef LTEMAC_SPS
23968    if (spsRbsAlloc) 
23969    {
23970       allocInfo->allocInfo.raType2.rbStart = rbStart;
23971       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
23972       allocInfo->rbsAlloc = allocInfo->rbsReq;
23973    }
23974 #endif
23975
23976 #ifdef LTEMAC_SPS
23977    if (!spsRbsAlloc)
23978    {
23979 #endif
23980 #ifndef LTE_TDD
23981       if(dlSf->sfNum)
23982       {
23983          if(!(dlSf->sfNum == 5))
23984          {
23985             /* case for subframes 1 to 9 except 5 */
23986 #ifdef LTEMAC_SPS
23987             allocInfo->allocInfo.raType2.rbStart = rbStart;
23988 #else
23989             /*Fix for ccpu00123918*/
23990             allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start;
23991 #endif
23992          }
23993          else
23994          {
23995             pbchFrame = 1; /* case for subframe 5 */
23996             /* In subframe 5, symbols are reserved for PSS and SSS and CFICH
23997                and Cell Specific Reference Signals */
23998             pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PSS_SSS_SYM) *
23999                   RGSCH_NUM_SC_IN_RB + cell->numCellRSPerSf);
24000          }
24001       }
24002       else
24003       {
24004          pbchFrame = 1;
24005          /* In subframe 0, symbols are reserved for PSS, SSS, PBCH, CFICH and
24006             and Cell Specific Reference signals */
24007          pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PBCH_SYM +
24008                   RGSCH_NUM_PSS_SSS_SYM) * RGSCH_NUM_SC_IN_RB +
24009                cell->numCellRSPerSf);
24010       } /* end of outer else */
24011
24012       if((pbchFrame) &&
24013             (((dlSf->bwAlloced + allocInfo->rbsReq) - cell->pbchRbStart) > 0)&&
24014             (dlSf->bwAlloced < cell->pbchRbEnd))
24015       {
24016          if(allocInfo->tbInfo[0].imcs < 29)
24017          {
24018             rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo, pbchSsRsSym, TRUE);
24019          }
24020       }
24021 #endif
24022 #ifdef LTEMAC_SPS
24023    }
24024 #endif
24025
24026 #ifdef LTEMAC_SPS
24027    if (!spsRbsAlloc)
24028    {  
24029 #endif
24030       /*Fix for ccpu00123918*/
24031       allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start;
24032       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
24033       allocInfo->rbsAlloc = allocInfo->rbsReq;
24034
24035       /* LTE_ADV_FLAG_REMOVED_START */
24036 #ifndef LTE_TDD
24037       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
24038       {
24039          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
24040                allocInfo->allocInfo.raType2.rbStart, \
24041                allocInfo->allocInfo.raType2.numRb);
24042       }
24043       else
24044 #endif
24045       {
24046          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
24047                allocInfo->allocInfo.raType2.rbStart, \
24048                allocInfo->allocInfo.raType2.numRb);
24049       }
24050
24051 #ifdef LTEMAC_SPS
24052    }
24053 #endif
24054    /* LTE_ADV_FLAG_REMOVED_END */
24055    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
24056
24057
24058 #ifdef LTEMAC_SPS
24059    if (spsRbsAlloc)
24060    {
24061       U8    idx;
24062       /* Update type 0, 1 and 2 masks */
24063       dlSfAlloc->raType0Mask    |= allocInfo->resAllocInfo.raType0Mask;
24064 #ifdef RGSCH_SPS_UNUSED
24065       for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
24066       {
24067          dlSfAlloc->raType1Mask[idx] |=
24068             allocInfo->resAllocInfo.raType1Mask[idx];
24069          dlSfAlloc->raType1UsedRbs[idx] +=
24070             allocInfo->resAllocInfo.raType1UsedRbs[idx];
24071       }
24072 #endif
24073       for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
24074       {
24075          dlSfAlloc->raType2Mask[idx] |=
24076             allocInfo->resAllocInfo.raType2Mask[idx];
24077       }
24078    }
24079 #endif
24080
24081    RETVALUE(ROK);
24082 }
24083
24084
24085 /**
24086  * @brief Performs RB allocation for frequency non-selective cell.
24087  *
24088  * @details
24089  *
24090  *     Function : rgSCHCmnNonDlfsCmnRbAllocRar
24091  *
24092  *     Processing Steps:
24093  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
24094  *
24095  *  @param[in]      RgSchCellCb     *cell
24096  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
24097  *  @return  S16
24098  *      -# ROK
24099  *      -# RFAILED
24100  **/
24101 #ifdef ANSI
24102 PRIVATE S16 rgSCHCmnNonDlfsCmnRbAllocRar
24103 (
24104  RgSchCellCb      *cell,
24105  RgSchDlRbAlloc   *allocInfo
24106  )
24107 #else
24108 PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo)
24109    RgSchCellCb      *cell;
24110    RgSchDlRbAlloc   *allocInfo;
24111 #endif
24112 {
24113    U8  tbs = 0;
24114    RgSchCmnDlCell   *cellDl    = RG_SCH_CMN_GET_DL_CELL(cell); 
24115    RgSchDlSf     *dlSf   = allocInfo->dlSf;
24116    TRC2(rgSCHCmnNonDlfsCmnRbAllocRar);
24117
24118
24119    if(dlSf->bwAlloced == dlSf->bw)
24120    {
24121       RETVALUE(RFAILED);
24122    }
24123
24124    allocInfo->tbInfo[0].noLyr = 1;
24125 #ifndef RG_5GTF
24126    /* Update allocation information */
24127    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
24128    if (allocInfo->pdcch == NULLP)
24129    {
24130       RETVALUE(RFAILED);
24131    }
24132    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
24133    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
24134    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
24135    allocInfo->allocInfo.raType2.isLocal = TRUE;
24136
24137    /*Fix for ccpu00123918*/
24138    allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start;
24139    allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
24140    allocInfo->rbsAlloc = allocInfo->rbsReq;
24141
24142    /* LTE_ADV_FLAG_REMOVED_END */
24143    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
24144
24145 #else
24146    allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, NULLP, dlSf, 13, TFU_DCI_FORMAT_B1, FALSE);
24147    if (allocInfo->pdcch == NULLP)
24148    {
24149       RETVALUE(RFAILED);
24150    }
24151    RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
24152    if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
24153    {
24154       printf("5GTF_ERROR vrbg allocated > 25\n");
24155       RETVALUE(RFAILED);
24156    }
24157
24158    allocInfo->tbInfo[0].cmnGrnt.vrbgStart = beamInfo->vrbgStart;
24159    allocInfo->tbInfo[0].cmnGrnt.numVrbg = allocInfo->vrbgReq;
24160
24161    /* Update allocation information */
24162    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
24163
24164    allocInfo->tbInfo[0].cmnGrnt.xPDSCHRange = 1;  
24165    allocInfo->tbInfo[0].cmnGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
24166          allocInfo->tbInfo[0].cmnGrnt.vrbgStart, allocInfo->tbInfo[0].cmnGrnt.numVrbg);
24167
24168    allocInfo->tbInfo[0].cmnGrnt.rbStrt = (allocInfo->tbInfo[0].cmnGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
24169    allocInfo->tbInfo[0].cmnGrnt.numRb = (allocInfo->tbInfo[0].cmnGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
24170
24171    beamInfo->vrbgStart += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
24172    beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
24173    allocInfo->tbInfo[0].cmnGrnt.rv = 0;
24174    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
24175
24176 #endif
24177    printf("\n[%s],allocInfo->tbInfo[0].bytesAlloc:%u,vrbgReq:%u\n",
24178          __func__,allocInfo->tbInfo[0].bytesAlloc,allocInfo->vrbgReq);
24179
24180    RETVALUE(ROK);
24181 }
24182
24183
24184 /* LTE_ADV_FLAG_REMOVED_START */
24185 #ifndef LTE_TDD
24186 /**
24187  * @brief To check if DL BW available for non-DLFS allocation.
24188  *
24189  * @details
24190  *
24191  *     Function : rgSCHCmnNonDlfsBwAvlbl
24192  *
24193  *     Processing Steps:
24194  *      - Determine availability based on RA Type.
24195  *
24196  *  @param[in]  RgSchCellCb     *cell
24197  *  @param[in]  RgSchDlSf       *dlSf
24198  *  @param[in]  RgSchDlRbAlloc  *allocInfo
24199  *
24200  *  @return Bool
24201  *      -# TRUE
24202  *      -# FALSE
24203  **/
24204 #ifdef ANSI
24205 PRIVATE Bool rgSCHCmnNonDlfsSFRBwAvlbl
24206 (
24207 RgSchCellCb        *cell,
24208 RgSchSFRPoolInfo   **sfrpoolInfo,
24209 RgSchDlSf          *dlSf,
24210 RgSchDlRbAlloc     *allocInfo,
24211 Bool               isUeCellEdge
24212 )
24213 #else
24214 PRIVATE Bool rgSCHCmnNonDlfsSFRBwAvlbl(cell, sfrpoolInfo, dlSf, allocInfo, isUeCellEdge)
24215 RgSchCellCb        *cell;
24216 RgSchSFRPoolInfo   **sfrpoolInfo;
24217 RgSchDlSf          *dlSf;
24218 RgSchDlRbAlloc     *allocInfo;
24219 Bool               isUeCellEdge;
24220 #endif
24221 {
24222    CmLListCp   *l;
24223    CmLListCp   *l1;
24224    CmLList     *n;
24225    CmLList     *n1;
24226    RgSchSFRPoolInfo  *sfrPool;
24227    RgSchSFRPoolInfo  *sfrCEPool;
24228
24229    U8 tbs;
24230    U8 noLyrs;
24231    RgSchSFRPoolInfo *poolWithMaxAvlblBw = NULLP;
24232    U32 bwAvlbl = 0;
24233    U32 addtnlPRBs = 0;
24234
24235    if (dlSf->bw <= dlSf->bwAlloced)
24236    {
24237       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
24238             "BW is fully allocated for subframe (%d) CRNTI:%d", dlSf->sfNum,allocInfo->rnti);
24239       return FALSE;
24240    }
24241
24242    if (dlSf->sfrTotalPoolInfo.ccBwFull == TRUE)
24243    {
24244       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
24245             "BW is fully allocated for CC Pool CRNTI:%d",allocInfo->rnti);
24246       return FALSE;
24247    }
24248
24249    if ((dlSf->sfrTotalPoolInfo.ceBwFull == TRUE) && (isUeCellEdge))
24250    {
24251       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
24252             "BW is fully allocated for CE Pool CRNTI:%d",allocInfo->rnti);
24253       return FALSE;
24254    }  
24255
24256    /* We first check if the ue scheduled is a cell edge or cell centre and accordingly check the avaialble
24257       memory in their pool. If the cell centre UE doesnt have Bw available in its pool, then it will check
24258       Bw availability in cell edge pool but the other way around is NOT possible.   */
24259    if(isUeCellEdge)
24260    {   
24261       l = &dlSf->sfrTotalPoolInfo.cePool;
24262    }
24263    else
24264    {
24265       l = &dlSf->sfrTotalPoolInfo.ccPool; 
24266    }     
24267
24268    n = cmLListFirst(l);
24269
24270    while(n)       
24271    {
24272       if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
24273       {
24274          sfrPool = (RgSchSFRPoolInfo*)(n->node);
24275
24276          /* MS_FIX for ccpu00123919 : Number of RBs in case of RETX should be same as that of initial transmission. */
24277          if(allocInfo->tbInfo[0].tbCb->txCntr)
24278          {
24279             /* If RB assignment is being done for RETX. Then if reqRbs are   a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
24280              * not a multiple of rbgSize then check if lsgRbgDfct exists */
24281             if (allocInfo->rbsReq % cell->rbgSize == 0)
24282             {
24283                if ((sfrPool->type2End == dlSf->type2End) && dlSf->lstRbgDfct)
24284                {
24285                   /* In this scenario we are wasting the last RBG for this dlSf */
24286                   sfrPool->type0End--;
24287                   sfrPool->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24288
24289                   dlSf->lstRbgDfct = 0;
24290
24291                   /*ABHINAV To check if these variables need to be taken care of*/
24292                   dlSf->type0End--;
24293                   dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24294                }
24295             }
24296             else
24297             {
24298                if (dlSf->lstRbgDfct)
24299                {
24300                   /* Check if type0 allocation can cater to this RETX requirement */
24301                   if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
24302                   {
24303                      RETVALUE(FALSE);
24304                   }
24305                   else
24306                   {
24307                      if (sfrPool->type2End != dlSf->type2End)   /*Search again for some pool which has the END RBG of the BandWidth*/
24308                      {
24309                         continue;                                       
24310                      }  
24311                   }
24312                }
24313                else
24314                {
24315                   /* cannot allocate same number of required RBs */
24316                   RETVALUE(FALSE);                   
24317                }
24318             }
24319          }
24320
24321          /*rg002.301 ccpu00120391 MOD condition is modified approprialtely to find if rbsReq is less than available RBS*/
24322          if(allocInfo->rbsReq <= (((sfrPool->type0End - sfrPool->type2End + 1)*\
24323                      cell->rbgSize) - dlSf->lstRbgDfct))
24324          {
24325             *sfrpoolInfo = sfrPool;
24326             RETVALUE(TRUE);
24327          }
24328          else
24329          {
24330             if (sfrPool->bw <= sfrPool->bwAlloced + cell->rbgSize)
24331             {
24332                n = cmLListNext(l);
24333                /* If the ue is cell centre then it will simply check the memory available in next pool.
24334                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
24335
24336                if((!isUeCellEdge) && (!n->node))
24337                {
24338                   l = &dlSf->sfrTotalPoolInfo.cePool;
24339                   n = cmLListFirst(l);
24340                }
24341
24342                continue; 
24343             }    
24344
24345             /* MS_FIX: Number of RBs in case of RETX should be same as that of initial transmission */
24346             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24347             {
24348                /*rg002.301 ccpu00120391 MOD setting the remaining RBs  for the requested UE*/
24349                allocInfo->rbsReq = (((sfrPool->type0End - sfrPool->type2End + 1)*\
24350                         cell->rbgSize) - dlSf->lstRbgDfct);
24351                RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24352                noLyrs = allocInfo->tbInfo[0].noLyr;
24353                allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24354                *sfrpoolInfo = sfrPool;
24355                RETVALUE(TRUE);
24356             }
24357             else
24358             {
24359                n = cmLListNext(l);
24360
24361                /* If the ue is cell centre then it will simply check the memory available in next pool.
24362                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
24363                if((!isUeCellEdge) && (!n->node))
24364                {
24365                   l = &dlSf->sfrTotalPoolInfo.cePool;
24366                   n = cmLListFirst(l);
24367                }
24368
24369                continue;
24370             }
24371
24372          //   RETVALUE(FALSE);
24373          }
24374       }
24375       else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
24376       {
24377          sfrPool = (RgSchSFRPoolInfo*)(n->node);
24378          /* This is a Case where a UE was CC and had more RBs allocated than present in CE pool.
24379             In case this UE whn become CE with retx going on, then BW is not sufficient for Retx */
24380          if ((isUeCellEdge) &&
24381             (allocInfo->tbInfo[0].tbCb->txCntr != 0))
24382          {
24383             if(allocInfo->rbsReq > (sfrPool->bw - sfrPool->bwAlloced))
24384             {
24385                /* Adjust CE BW such that Retx alloc is successful */
24386                /* Check if merging CE with adjacent CC pool will be sufficient to process Retx */
24387
24388                /* If no Type 0 allocations are made from this pool */
24389                if (sfrPool->type0End == (((sfrPool->poolendRB + 1) / cell->rbgSize) - 1))
24390                {
24391                   if (sfrPool->adjCCPool &&
24392                         (sfrPool->adjCCPool->type2Start == sfrPool->poolendRB + 1) &&
24393                         (allocInfo->rbsReq <= ((sfrPool->bw - sfrPool->bwAlloced) + 
24394                                                ((sfrPool->adjCCPool->bw - sfrPool->adjCCPool->bwAlloced)))))
24395                   {
24396                      addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
24397
24398                      /* Adjusting CE Pool Info */
24399                      sfrPool->bw += addtnlPRBs;
24400                      sfrPool->type0End = ((sfrPool->poolendRB + addtnlPRBs + 1) /
24401                            cell->rbgSize) - 1;
24402
24403                      /* Adjusting CC Pool Info */
24404                      sfrPool->adjCCPool->type2Start += addtnlPRBs;
24405                      sfrPool->adjCCPool->type2End = RGSCH_CEIL(sfrPool->adjCCPool->type2Start, 
24406                            cell->rbgSize);
24407                      sfrPool->adjCCPool->bw -= addtnlPRBs;
24408                      *sfrpoolInfo = sfrPool;
24409                      RETVALUE(TRUE);
24410                   }
24411                }
24412             }
24413          }
24414
24415          /* Check if CC pool is one of the following:
24416           * 1. |CE| + |CC "CCPool2Exists" = TRUE|
24417           * 2. |CC "CCPool2Exists" = FALSE| + |CE| + |CC "CCPool2Exists" = TRUE|
24418           */ 
24419          if(TRUE == sfrPool->CCPool2Exists)
24420          {
24421             l1 = &dlSf->sfrTotalPoolInfo.cePool;
24422             n1 = cmLListFirst(l1); 
24423             sfrCEPool = (RgSchSFRPoolInfo*)(n1->node);
24424             if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced))
24425             {
24426                *sfrpoolInfo = sfrCEPool;
24427                RETVALUE(TRUE);
24428             }
24429             else if(allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))  
24430             {
24431                *sfrpoolInfo = sfrPool;
24432                RETVALUE(TRUE);
24433             }
24434             /* Check if CE and CC boundary has unallocated prbs */
24435             else if ((sfrPool->poolstartRB == sfrPool->type2Start) &&
24436                   (sfrCEPool->type0End  == ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1))
24437             {
24438                if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced) + 
24439                      (sfrPool->bw - sfrPool->bwAlloced))
24440                {
24441                   /* Checking if BW can be allocated partly from CE pool and partly
24442                    * from CC pool
24443                    */
24444                   addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
24445                   /* Updating CE and CC  type2 parametrs based on the RBs allocated
24446                    * from these pools*/
24447                   sfrPool->type2Start -= addtnlPRBs;
24448                   sfrPool->type2End = RGSCH_CEIL(sfrPool->type2Start, cell->rbgSize);
24449                   sfrPool->bw += addtnlPRBs;
24450                   if (addtnlPRBs == (sfrCEPool->bw - sfrCEPool->bwAlloced))
24451                   {
24452                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
24453                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
24454                   }
24455                   else
24456                   {
24457                      sfrCEPool->bw -= addtnlPRBs;
24458                      sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1 - addtnlPRBs) / cell->rbgSize) - 1;
24459                   }
24460                   *sfrpoolInfo = sfrPool;
24461                   RETVALUE(TRUE);
24462                }
24463                else if ( bwAvlbl < 
24464                      ((sfrCEPool->bw - sfrCEPool->bwAlloced) +
24465                       (sfrPool->bw - sfrPool->bwAlloced)))
24466                {
24467                   /* All the Prbs from CE BW shall be allocated */
24468                   if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24469                   {
24470                      sfrPool->type2Start   = sfrCEPool->type2Start;
24471                      sfrPool->bw          += sfrCEPool->bw - sfrCEPool->bwAlloced;
24472                      sfrCEPool->type2Start = sfrCEPool->poolendRB + 1;
24473                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
24474                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
24475
24476                      /* set the remaining RBs for the requested UE */
24477                      allocInfo->rbsReq = (sfrPool->bw - sfrPool->bwAlloced);
24478                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24479                      noLyrs = allocInfo->tbInfo[0].noLyr;
24480                      allocInfo->tbInfo[0].bytesReq = 
24481                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24482                      *sfrpoolInfo = sfrPool;               
24483                      RETVALUE(TRUE);
24484                   }
24485                   else
24486                   {
24487                      RETVALUE(FALSE);
24488                   }
24489                }
24490             }
24491          } 
24492
24493          /* Checking if no. of RBs required can be allocated from
24494           * SFR pool. 
24495           * 1. If available return the SFR pool.
24496           * 2. Else update the RBs required parameter based on the 
24497           *    BW available in the pool 
24498           * 3. Return FALSE if no B/W is available. 
24499           */
24500          if (allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))
24501          {
24502             *sfrpoolInfo = sfrPool;
24503             RETVALUE(TRUE);
24504          }
24505          else
24506          {
24507             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24508             {
24509                if (bwAvlbl < sfrPool->bw - sfrPool->bwAlloced)
24510                {
24511                   if (isUeCellEdge)
24512                   {
24513                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
24514                   }
24515                   bwAvlbl = sfrPool->bw - sfrPool->bwAlloced;
24516                   poolWithMaxAvlblBw = sfrPool;
24517                }
24518                n = cmLListNext(l);
24519
24520                if ((isUeCellEdge == FALSE) && (n == NULLP))
24521                {
24522                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
24523                   {
24524                      l = &dlSf->sfrTotalPoolInfo.cePool;
24525                      n = cmLListFirst(l);                          
24526                   }
24527                }
24528
24529                if (n == NULLP)
24530                {
24531                   if (bwAvlbl == 0)
24532                   {                                                             
24533                      if (isUeCellEdge)
24534                      {
24535                         dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
24536                      }
24537                      else
24538                      {
24539                         dlSf->sfrTotalPoolInfo.ccBwFull = TRUE;  
24540                      }
24541                      RETVALUE(FALSE);
24542                   }
24543                   else
24544                   {
24545                      /* set the remaining RBs for the requested UE */
24546                      allocInfo->rbsReq = poolWithMaxAvlblBw->bw - 
24547                         poolWithMaxAvlblBw->bwAlloced;
24548                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24549                      noLyrs = allocInfo->tbInfo[0].noLyr;
24550                      allocInfo->tbInfo[0].bytesReq = 
24551                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24552                      *sfrpoolInfo = poolWithMaxAvlblBw;            
24553                      RETVALUE(TRUE);
24554                   }
24555                }                          
24556             }
24557             else
24558             {                   
24559                n = cmLListNext(l);
24560
24561                if ((isUeCellEdge == FALSE) && (n == NULLP))
24562                {
24563                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
24564                   {
24565                      l = &dlSf->sfrTotalPoolInfo.cePool;
24566                      n = cmLListFirst(l);                          
24567                   }
24568                }
24569
24570                if (n == NULLP)
24571                {
24572                   RETVALUE(FALSE);
24573                }
24574             }
24575
24576          }
24577       }   
24578    } 
24579    RETVALUE(FALSE);
24580 }
24581 #endif /* end of ifndef LTE_TDD*/
24582 /* LTE_ADV_FLAG_REMOVED_END */
24583
24584 /**
24585  * @brief To check if DL BW available for non-DLFS allocation.
24586  *
24587  * @details
24588  *
24589  *     Function : rgSCHCmnNonDlfsUeRbAlloc
24590  *
24591  *     Processing Steps:
24592  *      - Determine availability based on RA Type.
24593  *
24594  *  @param[in]  RgSchCellCb     *cell
24595  *  @param[in]  RgSchDlSf       *dlSf
24596  *  @param[in]  RgSchDlRbAlloc  *allocInfo
24597  *
24598  *  @return Bool
24599  *      -# TRUE
24600  *      -# FALSE
24601  **/
24602 #ifdef ANSI
24603 PRIVATE Bool rgSCHCmnNonDlfsBwAvlbl
24604 (
24605 RgSchCellCb        *cell,
24606 RgSchDlSf          *dlSf,
24607 RgSchDlRbAlloc     *allocInfo
24608 )
24609 #else
24610 PRIVATE Bool rgSCHCmnNonDlfsBwAvlbl(cell, dlSf, allocInfo)
24611 RgSchCellCb        *cell;
24612 RgSchDlSf          *dlSf;
24613 RgSchDlRbAlloc     *allocInfo;
24614 #endif
24615 {
24616    U8 tbs;
24617    U8 noLyrs;
24618    U8 ignoredDfctRbg = FALSE;
24619
24620    TRC2(rgSCHCmnNonDlfsBwAvlbl);
24621    if (dlSf->bw <= dlSf->bwAlloced)
24622    {
24623       RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, "(%d:%d)FAILED CRNTI:%d",
24624          dlSf->bw, dlSf->bwAlloced,allocInfo->rnti);
24625       RETVALUE(FALSE);
24626    }
24627    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
24628    {
24629        /* Fix for ccpu00123919 : Number of RBs in case of RETX should be same as 
24630         * that of initial transmission. */
24631        if(allocInfo->tbInfo[0].tbCb->txCntr)
24632        {
24633           /* If RB assignment is being done for RETX. Then if reqRbs are 
24634            * a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
24635            * not a multiple of rbgSize then check if lsgRbgDfct exists */
24636           if (allocInfo->rbsReq % cell->rbgSize == 0)
24637           {
24638              if (dlSf->lstRbgDfct)
24639              {
24640                 /* In this scenario we are wasting the last RBG for this dlSf */
24641                 
24642                 dlSf->type0End--;
24643                 dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24644                 /* Fix: MUE_PERTTI_DL */
24645                 dlSf->lstRbgDfct = 0;
24646                 ignoredDfctRbg = TRUE;
24647                 
24648              }
24649           }
24650           else
24651           {
24652              if (dlSf->lstRbgDfct)
24653              {
24654                 /* Check if type0 allocation can cater to this RETX requirement */
24655                 if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
24656                 {
24657                    RETVALUE(FALSE);
24658                 }
24659              }
24660              else
24661              {
24662                 /* cannot allocate same number of required RBs */
24663                 RETVALUE(FALSE);                     
24664              }
24665           }
24666        }
24667
24668        /* Condition is modified approprialtely to find
24669         * if rbsReq is less than available RBS*/
24670       if(allocInfo->rbsReq <= (((dlSf->type0End - dlSf->type2End + 1)*\
24671                cell->rbgSize) - dlSf->lstRbgDfct))
24672       {
24673          RETVALUE(TRUE);
24674       }
24675       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
24676        * allocation in TDD when requested RBs are more than available RBs*/
24677       else
24678       {
24679           /* MS_WORKAROUND for ccpu00122022 */
24680          if (dlSf->bw < dlSf->bwAlloced + cell->rbgSize)
24681          {
24682             /* ccpu00132358- Re-assigning the values which were updated above 
24683              * if it is RETX and Last  RBG available*/
24684             if(ignoredDfctRbg == TRUE)
24685             {
24686                dlSf->type0End++;
24687                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
24688                dlSf->lstRbgDfct = 1;
24689             }
24690
24691
24692             RETVALUE(FALSE);
24693          }
24694          /* Fix: Number of RBs in case of RETX should be same as 
24695           * that of initial transmission. */
24696          if(allocInfo->tbInfo[0].tbCb->txCntr == 0 
24697 #ifdef LTE_ADV
24698             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
24699 #endif
24700             )
24701          {
24702             /* Setting the remaining RBs for the requested UE*/
24703             allocInfo->rbsReq = (((dlSf->type0End - dlSf->type2End + 1)*\
24704                         cell->rbgSize) - dlSf->lstRbgDfct);
24705             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24706             noLyrs = allocInfo->tbInfo[0].noLyr;
24707             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24708             /* DwPts Scheduling Changes Start */
24709 #if LTE_TDD
24710             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24711             {   
24712                allocInfo->tbInfo[0].bytesReq = 
24713                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
24714             }
24715 #endif            
24716             /* DwPts Scheduling Changes End */
24717          }
24718          else
24719          {
24720                     /* ccpu00132358- Re-assigning the values which were updated above 
24721              * if it is RETX and Last  RBG available*/
24722             if(ignoredDfctRbg == TRUE)
24723             {
24724                dlSf->type0End++;
24725                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
24726                dlSf->lstRbgDfct = 1;
24727             }
24728
24729             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "FAILED for CRNTI:%d",
24730                   allocInfo->rnti);
24731             printf ("RB Alloc failed for LAA TB type 0\n");
24732             RETVALUE(FALSE);
24733          }
24734          RETVALUE(TRUE);
24735       }
24736    }
24737    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
24738    {
24739       if (allocInfo->rbsReq <= (dlSf->bw - dlSf->bwAlloced))
24740       {
24741          RETVALUE(TRUE);
24742       }
24743       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
24744        * allocation in TDD when requested RBs are more than available RBs*/
24745       else
24746       {
24747          /* Fix: Number of RBs in case of RETX should be same as 
24748           * that of initial transmission. */
24749          if((allocInfo->tbInfo[0].tbCb->txCntr == 0) 
24750 #ifdef LTE_ADV
24751             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
24752 #endif
24753             )
24754          {
24755             /* set the remaining RBs for the requested UE */
24756             allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
24757             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24758             noLyrs = allocInfo->tbInfo[0].noLyr;
24759             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24760             /* DwPts Scheduling Changes Start */
24761 #ifdef LTE_TDD
24762             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24763             {   
24764                allocInfo->tbInfo[0].bytesReq = 
24765                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
24766             }
24767 #endif            
24768             /* DwPts Scheduling Changes End */
24769          }
24770          else
24771          {
24772             printf ("RB Alloc failed for LAA TB type 2\n");
24773             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti);
24774             RETVALUE(FALSE);
24775          }
24776          /* Fix: Number of RBs in case of RETX should be same as 
24777           * that of initial transmission. */
24778          RETVALUE(TRUE);
24779       }
24780    }
24781    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti);
24782    RETVALUE(FALSE);
24783 }
24784 /* LTE_ADV_FLAG_REMOVED_START */
24785 #ifndef LTE_TDD
24786 /**
24787  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24788  *
24789  * @details
24790  *
24791  *     Function : rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
24792  *
24793  *     Processing Steps:
24794  *
24795  *  @param[in]  RgSchCellCb     *cell
24796  *  @param[in]  RgSchDlSf       *dlSf
24797  *  @param[in]  U8              rbStrt
24798  *  @param[in]  U8              numRb
24799  *
24800  *  @return Void
24801  **/
24802 #ifdef ANSI
24803 PUBLIC Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
24804 (
24805 RgSchCellCb        *cell,
24806 RgSchDlSf          *dlSf,
24807 U8                 rbStrt,
24808 U8                 numRb
24809 )
24810 #else
24811 PUBLIC Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, rbStrt, numRb)
24812 RgSchCellCb        *cell;
24813 RgSchDlSf          *dlSf;
24814 U8                 rbStrt;
24815 U8                 numRb;
24816 #endif
24817
24818    CmLListCp   *l;
24819    CmLList     *n;
24820    RgSchSFRPoolInfo  *sfrPool;
24821    TRC2(rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc);
24822    
24823    l = &dlSf->sfrTotalPoolInfo.ccPool;
24824      
24825    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
24826    dlSf->bwAlloced += numRb;
24827    dlSf->type2Start += numRb;
24828    n = cmLListFirst(l);
24829         
24830    while(n->node)
24831    {
24832         sfrPool = (RgSchSFRPoolInfo*)(n->node);
24833         n = cmLListNext(l);
24834          
24835          /* If the pool contains some RBs allocated in this allocation, e.g: Pool is [30.50]. Pool->type2Start is 40 , dlSf->type2Start is 45. then update the variables in pool   */
24836         if((sfrPool->poolendRB >= dlSf->type2Start) && (sfrPool->type2Start < dlSf->type2Start))
24837         {
24838                 sfrPool->type2End   =  dlSf->type2End;
24839                 sfrPool->bwAlloced  =  dlSf->type2Start - sfrPool->poolstartRB; 
24840                 sfrPool->type2Start =  dlSf->type2Start;
24841         }          
24842         else 
24843         { 
24844                 /* If the pool contains all RBs allocated in this allocation*/
24845                 if(dlSf->type2Start > sfrPool->poolendRB)
24846                 {                
24847                         sfrPool->type2End   =  sfrPool->type0End + 1;
24848                         sfrPool->bwAlloced  =  sfrPool->bw; 
24849                         sfrPool->type2Start =  sfrPool->poolendRB + 1;             
24850                 }  
24851         }
24852       if (!n)
24853       { 
24854          if (l != &dlSf->sfrTotalPoolInfo.cePool)
24855          {
24856             l = &dlSf->sfrTotalPoolInfo.cePool;   
24857             n = cmLListFirst(l);
24858          }
24859          else
24860             RETVOID;
24861       }
24862    }
24863    RETVOID;
24864 }
24865
24866 /**
24867  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24868  *
24869  * @details
24870  *
24871  *     Function : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
24872  *
24873  *     Processing Steps:
24874  *
24875  *  @param[in]  RgSchCellCb     *cell
24876  *  @param[in]  RgSchDlSf       *dlSf
24877  *  @param[in]  U8              rbStrt
24878  *  @param[in]  U8              numRb
24879  *
24880  *  @return Void
24881  **/
24882 #ifdef ANSI
24883 PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
24884 (
24885 RgSchCellCb        *cell,
24886 RgSchUeCb          *ue,
24887 RgSchDlSf          *dlSf,
24888 U8                 rbStrt,
24889 U8                 numRb
24890 )
24891 #else
24892 PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc(cell, ue, dlSf, rbStrt, numRb)
24893 RgSchCellCb        *cell;
24894 RgSchUeCb          *ue;
24895 RgSchDlSf          *dlSf;
24896 U8                 rbStrt;
24897 U8                 numRb;
24898 #endif
24899 {
24900    CmLListCp   *l;
24901    CmLList     *n;
24902    RgSchSFRPoolInfo  *sfrCCPool1 = NULL;
24903    RgSchSFRPoolInfo  *sfrCCPool2 = NULL;
24904    S16 ret = RFAILED;
24905
24906    TRC2(rgSCHCmnNonDlfsUpdDSFRTyp2Alloc);
24907    /* Move the type2End pivot forward */
24908    
24909    
24910    l = &dlSf->sfrTotalPoolInfo.ccPool;
24911    n = cmLListFirst(l);
24912    while(n)
24913    {
24914       sfrCCPool1 = (RgSchSFRPoolInfo*)(n->node);
24915       /* KWork fix */
24916       if (sfrCCPool1 ==  NULLP)
24917             {
24918                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,  "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
24919                         "sfrCCPool1 is NULL for CRNTI:%d",ue->ueId);
24920                RETVALUE(RFAILED);
24921             }
24922       n = cmLListNext(l);
24923       if(n)
24924       {
24925           sfrCCPool2 = (RgSchSFRPoolInfo*)(n->node);
24926           n = cmLListNext(l);
24927       }
24928       if((sfrCCPool1) && (sfrCCPool2))
24929       { 
24930           /* Based on RNTP info, the CC user is assigned high power per subframe basis */
24931           if(((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
24932               (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) || 
24933              ((dlSf->type2Start >= sfrCCPool2->pwrHiCCRange.startRb) &&
24934               (dlSf->type2Start + numRb < sfrCCPool2->pwrHiCCRange.endRb)))
24935           {
24936                ue->lteAdvUeCb.isCCUePHigh = TRUE;
24937
24938                /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
24939                ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
24940                if (ret != ROK)
24941                {
24942                     RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
24943                       "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
24944                     RETVALUE(RFAILED);
24945                }
24946            }
24947       }
24948       else
24949       {
24950          if((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
24951                (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb))
24952          {
24953             ue->lteAdvUeCb.isCCUePHigh = TRUE;
24954
24955             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
24956             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
24957             if (ret != ROK)
24958             {
24959                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,   "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" 
24960                         "rgSCHCmnBuildRntpInfo() function returned RFAILED CRNTI:%d",ue->ueId);
24961                RETVALUE(RFAILED);
24962             }
24963          }
24964       }
24965    }
24966    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
24967 #ifndef LTEMAC_SPS
24968    dlSf->bwAlloced += numRb;
24969    /*MS_FIX for ccpu00123918*/
24970    dlSf->type2Start += numRb;
24971 #endif
24972    RETVALUE(ROK);
24973 }
24974 #endif /* end of ifndef LTE_TDD*/
24975 /* LTE_ADV_FLAG_REMOVED_END */
24976 /**
24977  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24978  *
24979  * @details
24980  *
24981  *     Function : rgSCHCmnNonDlfsUpdTyp2Alloc
24982  *
24983  *     Processing Steps:
24984  *
24985  *  @param[in]  RgSchCellCb     *cell
24986  *  @param[in]  RgSchDlSf       *dlSf
24987  *  @param[in]  U8              rbStrt
24988  *  @param[in]  U8              numRb
24989  *
24990  *  @return Void
24991  **/
24992 #ifdef ANSI
24993 PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc
24994 (
24995 RgSchCellCb        *cell,
24996 RgSchDlSf          *dlSf,
24997 U8                 rbStrt,
24998 U8                 numRb
24999 )
25000 #else
25001 PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, rbStrt, numRb)
25002 RgSchCellCb        *cell;
25003 RgSchDlSf          *dlSf;
25004 U8                 rbStrt;
25005 U8                 numRb;
25006 #endif
25007 {
25008    TRC2(rgSCHCmnNonDlfsUpdTyp2Alloc);
25009    /* Move the type2End pivot forward */
25010    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
25011 //#ifndef LTEMAC_SPS
25012    dlSf->bwAlloced += numRb;
25013    /*Fix for ccpu00123918*/
25014    dlSf->type2Start += numRb;
25015 //#endif
25016    RETVOID;
25017 }
25018
25019 /**
25020  * @brief To do DL allocation using TYPE0 RA.
25021  *
25022  * @details
25023  *
25024  *     Function : rgSCHCmnNonDlfsType0Alloc
25025  *
25026  *     Processing Steps:
25027  *      - Perform TYPE0 allocation using the RBGs between
25028  *        type0End and type2End.
25029  *      - Build the allocation mask as per RBG positioning.
25030  *      - Update the allocation parameters.
25031  *
25032  *  @param[in]  RgSchCellCb     *cell
25033  *  @param[in]  RgSchDlSf       *dlSf
25034  *  @param[in]  RgSchDlRbAlloc  *allocInfo
25035  *
25036  *  @return Void
25037  **/
25038 #ifdef ANSI
25039 PRIVATE Void rgSCHCmnNonDlfsType0Alloc
25040 (
25041 RgSchCellCb        *cell,
25042 RgSchDlSf          *dlSf,
25043 RgSchDlRbAlloc     *allocInfo,
25044 RgSchUeCb          *ue
25045 )
25046 #else
25047 PRIVATE Void rgSCHCmnNonDlfsType0Alloc(cell, dlSf, allocInfo, dlUe)
25048 RgSchCellCb        *cell;
25049 RgSchDlSf          *dlSf;
25050 RgSchDlRbAlloc     *allocInfo;
25051 RgSchUeCb          *ue;
25052 #endif
25053 {
25054    U32 dlAllocMsk = 0;
25055    U8  rbgFiller = dlSf->lstRbgDfct;
25056    U8  noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
25057    //U8  noRbgs = (allocInfo->rbsReq + rbgFiller)/ cell->rbgSize;
25058    U8  noRbs;
25059    U8  noLyr;
25060    U8  iTbs;
25061    U32          tb1BytesAlloc = 0;
25062    U32          tb2BytesAlloc = 0;
25063    RgSchCmnDlUe *dlUe         = RG_SCH_CMN_GET_DL_UE(ue,cell);
25064
25065    TRC2(rgSCHCmnNonDlfsType0Alloc);
25066    //if(noRbgs == 0) noRbgs = 1; /* Not required as ceilling is used above*/
25067
25068    /* Fix for ccpu00123919*/
25069    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25070    if (dlSf->bwAlloced + noRbs > dlSf->bw)
25071    {
25072       if (--noRbgs == 0)
25073       {
25074          RETVOID;
25075       }
25076       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25077    }
25078
25079    /* Fix for ccpu00138701: Ceilling is using to derive num of RBGs, Therefore, 
25080    *  after this operation,checking Max TB size and Max RBs are not crossed
25081    * if it is crossed then decrement num of RBGs. */
25082    //if((noRbs + rbgFiller) % cell->rbgSize)
25083    if((noRbs > allocInfo->rbsReq) &&
25084          (allocInfo->rbsReq + rbgFiller) % cell->rbgSize)
25085    {/* considering ue category limitation
25086      * due to ceiling */
25087
25088 #ifdef LTE_ADV
25089       if (rgSCHLaaIsLaaTB(allocInfo)== FALSE)
25090 #endif
25091       {
25092          if ((allocInfo->tbInfo[0].schdlngForTb) && (!allocInfo->tbInfo[0].tbCb->txCntr))
25093          {
25094             iTbs = allocInfo->tbInfo[0].iTbs;
25095             noLyr = allocInfo->tbInfo[0].noLyr;
25096             tb1BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25097          }
25098
25099          if ((allocInfo->tbInfo[1].schdlngForTb) && (!allocInfo->tbInfo[1].tbCb->txCntr))
25100          {
25101             iTbs = allocInfo->tbInfo[1].iTbs;
25102             noLyr = allocInfo->tbInfo[1].noLyr;
25103             tb2BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25104          }
25105       }
25106       
25107       /* Only Check for New Tx No need for Retx */
25108       if (tb1BytesAlloc || tb2BytesAlloc)
25109       {
25110          if (( ue->dl.aggTbBits >= dlUe->maxTbBits) ||
25111                (tb1BytesAlloc >= dlUe->maxTbSz/8) ||
25112                (tb2BytesAlloc >= dlUe->maxTbSz/8) ||
25113                (noRbs >= dlUe->maxRb))
25114          {
25115             if (--noRbgs == 0)
25116             {
25117                RETVOID;
25118             }
25119             noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25120          }
25121       }
25122    }
25123    /* type0End would have been initially (during subfrm Init) at the bit position
25124     * (cell->noOfRbgs - 1), 0 being the most significant.
25125     * Getting DlAllocMsk for noRbgs and at the appropriate position */
25126    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - dlSf->type0End));
25127    /* Move backwards the type0End pivot */
25128    dlSf->type0End -= noRbgs;
25129    /*Fix for ccpu00123919*/
25130    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
25131    /* Update the bwAlloced field accordingly */
25132 //#ifndef LTEMAC_SPS    /* ccpu00129474*/
25133    dlSf->bwAlloced += noRbs;
25134 //#endif
25135    /* Update Type0 Alloc Info */
25136    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
25137    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
25138    allocInfo->rbsAlloc = noRbs;
25139
25140    /* Update Tb info for each scheduled TB */
25141    iTbs = allocInfo->tbInfo[0].iTbs;
25142    noLyr = allocInfo->tbInfo[0].noLyr;
25143    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
25144     * RETX TB Size is same as Init TX TB Size */
25145    if (allocInfo->tbInfo[0].tbCb->txCntr)
25146    {
25147       allocInfo->tbInfo[0].bytesAlloc =
25148          allocInfo->tbInfo[0].bytesReq;
25149    }
25150    else
25151    {
25152       allocInfo->tbInfo[0].bytesAlloc =
25153          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25154       /* DwPts Scheduling Changes Start */
25155 #ifdef LTE_TDD
25156       if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
25157       {
25158          allocInfo->tbInfo[0].bytesAlloc =
25159             rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
25160       }
25161 #endif      
25162       /* DwPts Scheduling Changes End */
25163    }
25164
25165    if (allocInfo->tbInfo[1].schdlngForTb)
25166    {
25167       iTbs = allocInfo->tbInfo[1].iTbs;
25168       noLyr = allocInfo->tbInfo[1].noLyr;
25169       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
25170        * RETX TB Size is same as Init TX TB Size */
25171       if (allocInfo->tbInfo[1].tbCb->txCntr)
25172       {
25173          allocInfo->tbInfo[1].bytesAlloc =
25174             allocInfo->tbInfo[1].bytesReq;
25175       }
25176       else
25177       {
25178          allocInfo->tbInfo[1].bytesAlloc =
25179             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;;
25180          /* DwPts Scheduling Changes Start */
25181 #ifdef LTE_TDD
25182          if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
25183          {
25184             allocInfo->tbInfo[1].bytesAlloc =
25185                rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
25186          }
25187 #endif      
25188          /* DwPts Scheduling Changes End */
25189       }
25190    }
25191
25192    /* The last RBG which can be smaller than the RBG size is consedered
25193     * only for the first time allocation of TYPE0 UE */
25194    dlSf->lstRbgDfct = 0;
25195    RETVOID;
25196 }
25197 #ifndef LTE_TDD
25198
25199 /**
25200  * @brief To prepare RNTP value from the PRB allocation (P-High -> 1 and P-Low -> 0)
25201  *
25202  * @details
25203  *
25204  *     Function : rgSCHCmnBuildRntpInfo
25205  *
25206  *     Processing Steps:
25207  *
25208  *  @param[in]  U8                 *rntpPtr
25209  *  @param[in]  U8                 startRb
25210  *  @param[in]  U8                 numRb
25211  *
25212  *  @return Void
25213  **/
25214 #ifdef ANSI
25215 PRIVATE S16 rgSCHCmnBuildRntpInfo
25216 (
25217 RgSchCellCb        *cell,
25218 U8                 *rntpPtr,
25219 U8                            startRb,
25220 U8                  nmbRb,
25221 U16                 bw
25222 )
25223 #else
25224 PRIVATE S16 rgSCHCmnBuildRntpInfo(cell, rntpPtr, startRb, nmbRb, bw)
25225 RgSchCellCb        *cell;
25226 U8                 *rntpPtr;
25227 U8                            startRb;
25228 U8                  nmbRb;
25229 U16                 bw;
25230 #endif
25231 {
25232    U16 rbPtrStartIdx;              /* Start Index of Octete Buffer to be filled */
25233    U16 rbPtrEndIdx;                /* End Index of Octete Buffer to be filled */
25234    U16 rbBitLoc;                   /* Bit Location to be set as 1 in the current Byte */
25235    U16 nmbRbPerByte;               /* PRB's to be set in the current Byte (in case of multiple Bytes) */
25236
25237    TRC2(rgSCHCmnBuildRntpInfo);
25238
25239    rbPtrStartIdx = (startRb)/8;
25240    rbPtrEndIdx   = (startRb + nmbRb)/8;
25241
25242    if (rntpPtr == NULLP)
25243    {
25244       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
25245                "rgSCHCmnBuildRntpInfo():"
25246                "rntpPtr can't be NULLP (Memory Allocation Failed)");
25247       RETVALUE(RFAILED);
25248    }
25249
25250    while(rbPtrStartIdx <= rbPtrEndIdx)
25251    {
25252       rbBitLoc = (startRb)%8;
25253
25254       /* case 1: startRb and endRb lies in same Byte */
25255       if (rbPtrStartIdx == rbPtrEndIdx)
25256       {
25257          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
25258                                      | (((1<<nmbRb)-1)<<rbBitLoc);
25259       }
25260
25261       /* case 2: startRb and endRb lies in different Byte */
25262       if (rbPtrStartIdx != rbPtrEndIdx)
25263       {
25264          nmbRbPerByte = 8 - rbBitLoc;
25265          nmbRb        = nmbRb - nmbRbPerByte;
25266          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
25267                                      | (((1<<nmbRbPerByte)-1)<<rbBitLoc);
25268          startRb = startRb + nmbRbPerByte;
25269       }
25270
25271       rbPtrStartIdx++;
25272    }
25273
25274    /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** Adding Debug logs */
25275
25276    /* dsfr_pal_fixes ** 25-March-2013 ** SKS ** Adding Debug logs to print RNTP */
25277
25278    RETVALUE(ROK);
25279 }
25280
25281
25282 /**
25283  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
25284  *
25285  * @details
25286  *
25287  *     Function : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
25288  *
25289  *     Processing Steps:
25290  *
25291  *  @param[in]  RgSchCellCb     *cell
25292  *  @param[in]  RgSchDlSf       *dlSf
25293  *  @param[in]  U8              rbStrt
25294  *  @param[in]  U8              numRb
25295  *
25296  *  @return Void
25297  **/
25298 #ifdef ANSI
25299 PRIVATE S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
25300 (
25301 RgSchCellCb        *cell,
25302 RgSchUeCb                  *ue,
25303 RgSchDlSf          *dlSf,
25304 RgSchSFRPoolInfo   *sfrPool,
25305 U8                 rbStrt,
25306 U8                 numRb
25307 )
25308 #else
25309 PRIVATE S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrPool, rbStrt, numRb)
25310 RgSchCellCb        *cell;
25311 RgSchUeCb          *ue;
25312 RgSchDlSf          *dlSf;
25313 RgSchSFRPoolInfo   *sfrPool;
25314 U8                 rbStrt;
25315 U8                 numRb;
25316 #endif
25317 {
25318 #ifndef LTEMAC_SPS
25319    S16 ret;
25320 #endif
25321
25322    TRC2(rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc);
25323    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
25324    sfrPool->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
25325    
25326 #ifndef LTEMAC_SPS
25327    dlSf->type2Start += numRb;
25328    dlSf->bwAlloced += numRb;
25329    
25330    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
25331    {
25332       /* Based on RNTP info, the CC user is assigned high power per subframe basis */
25333       if(FALSE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge)
25334       {
25335          if((sfrPool->type2Start >= sfrPool->pwrHiCCRange.startRb) &&
25336                (sfrPool->type2Start + numRb < sfrPool->pwrHiCCRange.endRb))
25337          {
25338             ue->lteAdvUeCb.isCCUePHigh = TRUE;
25339
25340             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
25341             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
25342             if (ret != ROK)
25343             {
25344                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
25345                         "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
25346                RETVALUE(RFAILED);
25347             }
25348          }
25349       }
25350       else
25351       {
25352          /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
25353          ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
25354          if (ret != ROK)
25355          {
25356             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
25357                      "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
25358             RETVALUE(RFAILED);
25359          }
25360       }
25361    }
25362    sfrPool->type2Start += numRb;
25363    sfrPool->bwAlloced += numRb;
25364 #endif 
25365
25366    RETVALUE(ROK);
25367 }
25368
25369 /**
25370  * @brief To do DL allocation using TYPE0 RA.
25371  *
25372  * @details
25373  *
25374  *     Function : rgSCHCmnNonDlfsSFRPoolType0Alloc
25375  *
25376  *     Processing Steps:
25377  *      - Perform TYPE0 allocation using the RBGs between type0End and type2End.
25378  *      - Build the allocation mask as per RBG positioning.
25379  *      - Update the allocation parameters.
25380  *
25381  *  @param[in]  RgSchCellCb     *cell
25382  *  @param[in]  RgSchDlSf       *dlSf
25383  *  @param[in]  RgSchDlRbAlloc  *allocInfo
25384  *
25385  *  @return Void
25386  **/
25387 #ifdef ANSI
25388 PRIVATE Void rgSCHCmnNonDlfsSFRPoolType0Alloc
25389 (
25390 RgSchCellCb        *cell,
25391 RgSchDlSf          *dlSf,
25392 RgSchSFRPoolInfo   *poolInfo,
25393 RgSchDlRbAlloc     *allocInfo
25394 )
25395 #else
25396 PRIVATE Void rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, poolInfo, allocInfo)
25397 RgSchCellCb        *cell;
25398 RgSchDlSf          *dlSf;
25399 RgSchSFRPoolInfo   *poolInfo;
25400 RgSchDlRbAlloc     *allocInfo;
25401 #endif
25402 {
25403    U32 dlAllocMsk = 0;
25404    U8  rbgFiller = 0;
25405    U8  noRbgs = 0;
25406    U8  noRbs;
25407    U8  noLyr;
25408    U8  iTbs;
25409
25410    TRC2(rgSCHCmnNonDlfsSFRPoolType0Alloc);
25411
25412    if (poolInfo->poolstartRB + poolInfo->bw == dlSf->bw)
25413    {
25414                 if (poolInfo->type0End == dlSf->bw/4)
25415                 {
25416                         rbgFiller = dlSf->lstRbgDfct;
25417                         /* The last RBG which can be smaller than the RBG size is consedered
25418                         * only for the first time allocation of TYPE0 UE */
25419                         dlSf->lstRbgDfct = 0;
25420                 }
25421    }
25422
25423    noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
25424
25425    /* Abhinav to-do start */
25426    /* MS_FIX for ccpu00123919*/
25427    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25428    if (dlSf->bwAlloced + noRbs > dlSf->bw)
25429    {
25430       if (--noRbgs == 0)
25431       {
25432          RETVOID;
25433       }
25434       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25435    }
25436    /* Abhinav to-do end */
25437
25438
25439    
25440    /* type0End would have been initially (during subfrm Init) at the bit position
25441     * (cell->noOfRbgs - 1), 0 being the most significant.
25442     * Getting DlAllocMsk for noRbgs and at the appropriate position */
25443    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - poolInfo->type0End));
25444    /* Move backwards the type0End pivot */
25445    poolInfo->type0End -= noRbgs;
25446    /*MS_FIX for ccpu00123919*/
25447    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
25448    /* Update the bwAlloced field accordingly */
25449    poolInfo->bwAlloced += noRbs + dlSf->lstRbgDfct;
25450    dlSf->bwAlloced += noRbs + dlSf->lstRbgDfct;
25451    
25452    /* Update Type0 Alloc Info */
25453    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
25454    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
25455    allocInfo->rbsAlloc = noRbs;
25456
25457    /* Update Tb info for each scheduled TB */
25458    iTbs = allocInfo->tbInfo[0].iTbs;
25459    noLyr = allocInfo->tbInfo[0].noLyr;
25460    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
25461     * RETX TB Size is same as Init TX TB Size */
25462    if (allocInfo->tbInfo[0].tbCb->txCntr)
25463    {
25464       allocInfo->tbInfo[0].bytesAlloc =
25465          allocInfo->tbInfo[0].bytesReq;
25466    }
25467    else
25468    {
25469       allocInfo->tbInfo[0].bytesAlloc =
25470          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25471    }
25472
25473    if (allocInfo->tbInfo[1].schdlngForTb)
25474    {
25475       iTbs = allocInfo->tbInfo[1].iTbs;
25476       noLyr = allocInfo->tbInfo[1].noLyr;
25477       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
25478        * RETX TB Size is same as Init TX TB Size */
25479       if (allocInfo->tbInfo[1].tbCb->txCntr)
25480       {
25481          allocInfo->tbInfo[1].bytesAlloc =
25482             allocInfo->tbInfo[1].bytesReq;
25483       }
25484       else
25485       {
25486          allocInfo->tbInfo[1].bytesAlloc =
25487             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;;
25488       }
25489    }
25490
25491    /* The last RBG which can be smaller than the RBG size is consedered
25492     * only for the first time allocation of TYPE0 UE */
25493    dlSf->lstRbgDfct = 0;
25494    RETVOID;
25495 }
25496
25497 /**
25498  * @brief Computes RNTP Info for a subframe.
25499  *
25500  * @details
25501  *
25502  *     Function :  rgSCHCmnNonDlfsDsfrRntpComp 
25503  *
25504  *     Processing Steps:
25505  *      - Computes RNTP info from individual pools.
25506  *
25507  *  @param[in]  RgSchDlSf       *dlSf
25508  *
25509  *  @return  void
25510  
25511  **/
25512 #ifdef ANSI
25513 PRIVATE void rgSCHCmnNonDlfsDsfrRntpComp
25514 (
25515 RgSchCellCb         *cell,
25516 RgSchDlSf          *dlSf
25517 )
25518 #else
25519 PRIVATE void rgSCHCmnNonDlfsDsfrRntpComp(cell, dlSf)
25520 RgSchCellCb         *cell;
25521 RgSchDlSf          *dlSf;
25522 #endif
25523 {
25524    PRIVATE U16 samples = 0;
25525    U16 i;
25526    U16 bwBytes = (dlSf->bw-1)/8;
25527    RgrLoadInfIndInfo *rgrLoadInf;
25528    U16 len;
25529    U16 ret     = ROK;
25530
25531    TRC2(rgSCHCmnNonDlfsDsfrRntpComp);
25532
25533    len = (dlSf->bw % 8 == 0) ? dlSf->bw/8 : dlSf->bw/8 + 1;
25534
25535    /* RNTP info is ORed every TTI and the sample is stored in cell control block */ 
25536    for(i = 0; i <= bwBytes; i++)
25537    {
25538      cell->rntpAggrInfo.val[i] |= dlSf->rntpInfo.val[i];
25539    }
25540    samples = samples + 1;
25541    /* After every 1000 ms, the RNTP info will be sent to application to be further sent to all neighbouring eNB
25542          informing them about the load indication for cell edge users */
25543    if(RG_SCH_MAX_RNTP_SAMPLES == samples)
25544    {
25545       /* ccpu00134492 */
25546       ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf,
25547                sizeof(RgrLoadInfIndInfo));
25548       if (ret != ROK)
25549       {
25550          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Could not "
25551             "allocate memory for sending LoadInfo");
25552          RETVOID;  
25553       }
25554      
25555       rgrLoadInf->u.rntpInfo.pres = cell->rntpAggrInfo.pres;
25556       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
25557       rgrLoadInf->u.rntpInfo.len  = len;
25558
25559       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
25560       rgrLoadInf->u.rntpInfo.val = cell->rntpAggrInfo.val; 
25561       rgrLoadInf->cellId = cell->cellId;
25562
25563       /* dsfr_pal_fixes ** 22-March-2013 ** SKS */
25564       rgrLoadInf->bw = dlSf->bw;
25565       rgrLoadInf->type = RGR_SFR;
25566
25567       ret = rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf);
25568       if(ret == RFAILED)
25569       {
25570          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsDsfrRntpComp():"
25571                   "rgSCHUtlRgrLoadInfInd() returned RFAILED");
25572       }
25573
25574       cmMemset(cell->rntpAggrInfo.val,0,len);
25575       samples = 0;
25576    }
25577  } 
25578 /* LTE_ADV_FLAG_REMOVED_END */
25579
25580 /* LTE_ADV_FLAG_REMOVED_START */
25581 /**
25582  * @brief Performs RB allocation per UE from a pool.
25583  *
25584  * @details
25585  *
25586  *     Function : rgSCHCmnSFRNonDlfsUeRbAlloc
25587  *
25588  *     Processing Steps:
25589  *      - Allocate consecutively available RBs.
25590  *
25591  *  @param[in]  RgSchCellCb     *cell
25592  *  @param[in]  RgSchUeCb       *ue
25593  *  @param[in]  RgSchDlSf       *dlSf
25594  *  @param[out] U8              *isDlBwAvail
25595  *
25596  *  @return  S16
25597  *      -# ROK
25598  *      -# RFAILED
25599  **/
25600 #ifdef ANSI
25601 PRIVATE S16 rgSCHCmnSFRNonDlfsUeRbAlloc
25602 (
25603 RgSchCellCb        *cell,
25604 RgSchUeCb          *ue,
25605 RgSchDlSf          *dlSf,
25606 U8                 *isDlBwAvail
25607 )
25608 #else
25609 PRIVATE S16 rgSCHCmnSFRNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail)
25610 RgSchCellCb        *cell;
25611 RgSchUeCb          *ue;
25612 RgSchDlSf          *dlSf;
25613 U8                 *isDlBwAvail;
25614 #endif
25615 {
25616    U32             y;
25617    RgSchDlRbAlloc  *allocInfo;
25618    RgSchCmnDlUe    *dlUe;
25619    Bool isUECellEdge;
25620    RgSchSFRPoolInfo *sfrpoolInfo = NULLP;
25621
25622    TRC2(rgSCHCmnSFRNonDlfsUeRbAlloc);
25623
25624    isUECellEdge = RG_SCH_CMN_IS_UE_CELL_EDGE(ue);
25625
25626    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
25627    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25628    *isDlBwAvail = TRUE;
25629
25630    /*Find which pool is available for this UE*/
25631    if (rgSCHCmnNonDlfsSFRBwAvlbl(cell,  &sfrpoolInfo, dlSf, allocInfo, isUECellEdge) != TRUE)
25632    {
25633       /* SFR_FIX - If this is CE UE there may be BW available in CC Pool
25634          So CC UEs will be scheduled */
25635       if (isUECellEdge)
25636       {
25637          *isDlBwAvail = TRUE;
25638       }
25639       else
25640       {
25641          *isDlBwAvail = FALSE;
25642       }
25643       RETVALUE(RFAILED);
25644    }
25645
25646    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX || dlUe->proc->tbInfo[1].isAckNackDtx)
25647    {
25648       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
25649    }
25650    else
25651    {
25652       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
25653    }
25654    
25655    if (!(allocInfo->pdcch))
25656    {
25657       /* Returning ROK since PDCCH might be available for another UE and further allocations could be done */
25658       RETVALUE(RFAILED);
25659    }
25660    
25661 #ifdef LTEMAC_SPS
25662    allocInfo->rnti = ue->ueId;
25663 #endif
25664
25665    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
25666    {
25667       allocInfo->allocInfo.raType2.isLocal = TRUE;
25668       /* rg004.201 patch - ccpu00109921 fix end */
25669       /* MS_FIX for ccpu00123918*/
25670       allocInfo->allocInfo.raType2.rbStart = (U8)sfrpoolInfo->type2Start;
25671       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
25672       /* rg007.201 - Changes for MIMO feature addition */
25673       /* rg008.201 - Removed dependency on MIMO compile-time flag */
25674       rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrpoolInfo, \
25675             allocInfo->allocInfo.raType2.rbStart, \
25676             allocInfo->allocInfo.raType2.numRb);
25677       allocInfo->rbsAlloc = allocInfo->rbsReq;
25678       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25679    }
25680    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
25681    {
25682       rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, sfrpoolInfo, allocInfo);
25683    }
25684 #ifndef LTE_TDD
25685 #ifdef DEBUGP
25686    rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,0);
25687    if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
25688    {
25689       rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,1);
25690    }
25691 #endif
25692 #endif
25693
25694 #if defined(LTEMAC_SPS)
25695    /* Update the sub-frame with new allocation */
25696    dlSf->bwAlloced += allocInfo->rbsReq;
25697 #endif
25698
25699    RETVALUE(ROK);
25700 }
25701 /* LTE_ADV_FLAG_REMOVED_END */
25702 #endif /* LTE_TDD */
25703
25704 /**
25705  * @brief Performs RB allocation per UE for frequency non-selective cell.
25706  *
25707  * @details
25708  *
25709  *     Function : rgSCHCmnNonDlfsUeRbAlloc
25710  *
25711  *     Processing Steps:
25712  *      - Allocate consecutively available RBs.
25713  *
25714  *  @param[in]  RgSchCellCb     *cell
25715  *  @param[in]  RgSchUeCb       *ue
25716  *  @param[in]  RgSchDlSf       *dlSf
25717  *  @param[out] U8              *isDlBwAvail
25718  *
25719  *  @return  S16
25720  *      -# ROK
25721  *      -# RFAILED
25722  **/
25723 #ifdef ANSI
25724 PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc
25725 (
25726 RgSchCellCb        *cell,
25727 RgSchUeCb          *ue,
25728 RgSchDlSf          *dlSf,
25729 U8                 *isDlBwAvail
25730 )
25731 #else
25732 PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail)
25733 RgSchCellCb        *cell;
25734 RgSchUeCb          *ue;
25735 RgSchDlSf          *dlSf;
25736 U8                 *isDlBwAvail;
25737 #endif
25738 {
25739    RgSchDlRbAlloc  *allocInfo;
25740    RgSchCmnDlUe    *dlUe;
25741 #ifdef LAA_DBG
25742    U32            dbgRbsReq = 0;
25743 #endif
25744    TRC2(rgSCHCmnNonDlfsUeRbAlloc);
25745
25746 #ifdef RG_5GTF
25747    RgSch5gtfUeCb  *ue5gtfCb = &(ue->ue5gtfCb);
25748         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[ue5gtfCb->BeamId]);
25749 #endif
25750    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
25751    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25752    *isDlBwAvail = TRUE;
25753
25754         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
25755         {
25756            RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
25757          "5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
25758          ue->ueId);
25759            printf("5GTF_ERROR vrbg allocated > 25\n");
25760                 RETVALUE(RFAILED);
25761         }
25762
25763    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX 
25764        || dlUe->proc->tbInfo[1].isAckNackDtx)
25765    {
25766       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
25767    }
25768    else
25769    {
25770       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
25771    }
25772    if (!(allocInfo->pdcch))
25773    {
25774       /* Returning ROK since PDCCH might be available for another UE and
25775        * further allocations could be done */
25776       RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
25777          "5GTF_ERROR : PDCCH allocation failed :ue (%u)",
25778          ue->ueId);
25779            printf("5GTF_ERROR PDCCH allocation failed\n");
25780       RETVALUE(RFAILED);
25781    }
25782 #ifdef RG_5GTF
25783         //maxPrb = RGSCH_MIN((allocInfo->vrbgReq * MAX_5GTF_VRBG_SIZE), ue5gtfCb->maxPrb);
25784    //maxPrb = RGSCH_MIN(maxPrb, 
25785                 //((beamInfo->totVrbgAvail - beamInfo->vrbgStart)* MAX_5GTF_VRBG_SIZE)));
25786         //TODO_SID Need to check for vrbg available after scheduling for same beam.
25787         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
25788         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
25789         //TODO_SID: Setting for max TP
25790         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
25791         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
25792          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
25793         allocInfo->tbInfo[0].tbCb->dlGrnt.SCID = 0;
25794         allocInfo->tbInfo[0].tbCb->dlGrnt.dciFormat = allocInfo->dciFormat;
25795    //Filling temporarily
25796    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
25797    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
25798
25799         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
25800         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
25801         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25802 #endif
25803
25804    RETVALUE(ROK);
25805 }
25806
25807 #ifdef RGR_V1
25808 /**
25809  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
25810  *
25811  * @details
25812  *
25813  *     Function : rgSCHCmnNonDlfsCcchSduAlloc
25814  *
25815  *     Processing Steps:
25816  *     - For each element in the list, Call rgSCHCmnNonDlfsCcchSduRbAlloc().
25817  *        - If allocation is successful, add the ueCb to scheduled list of CCCH
25818  *        SDU.
25819  *        - else, add UeCb to non-scheduled list.
25820  *
25821  *  @param[in]      RgSchCellCb         *cell
25822  *  @param[in, out] RgSchCmnCcchSduRbAlloc *allocInfo
25823  *  @param[in]      U8                  isRetx
25824  *
25825  *  @return  Void
25826  **/
25827 #ifdef ANSI
25828 PRIVATE Void rgSCHCmnNonDlfsCcchSduAlloc
25829 (
25830 RgSchCellCb         *cell,
25831 RgSchCmnCcchSduRbAlloc *allocInfo,
25832 U8                  isRetx
25833 )
25834 #else
25835 PRIVATE Void rgSCHCmnNonDlfsCcchSduAlloc(cell, allocInfo, isRetx)
25836 RgSchCellCb         *cell;
25837 RgSchCmnCcchSduRbAlloc *allocInfo;
25838 U8                  isRetx;
25839 #endif
25840 {
25841    S16             ret;
25842    CmLListCp       *ccchSduLst        = NULLP;
25843    CmLListCp       *schdCcchSduLst    = NULLP;
25844    CmLListCp       *nonSchdCcchSduLst = NULLP;
25845    CmLList         *schdLnkNode    = NULLP;
25846    CmLList         *toBeSchdLnk    = NULLP;
25847    RgSchDlSf       *dlSf           = allocInfo->ccchSduDlSf;
25848    RgSchUeCb       *ueCb           = NULLP;
25849    RgSchDlHqProcCb *hqP            = NULLP;
25850    TRC2(rgSCHCmnNonDlfsCcchSduAlloc);
25851
25852    if (isRetx)
25853    {
25854       /* Initialize re-transmitting lists */
25855       ccchSduLst = &(allocInfo->ccchSduRetxLst);
25856       schdCcchSduLst = &(allocInfo->schdCcchSduRetxLst);
25857       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduRetxLst);
25858    }
25859    else
25860    {
25861       /* Initialize transmitting lists */
25862       ccchSduLst = &(allocInfo->ccchSduTxLst);
25863       schdCcchSduLst = &(allocInfo->schdCcchSduTxLst);
25864       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduTxLst);
25865    }
25866
25867    /* Perform allocaations  for the list */
25868    toBeSchdLnk = cmLListFirst(ccchSduLst);
25869    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
25870    {
25871       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25872       ueCb = hqP->hqE->ue;
25873       schdLnkNode = &hqP->schdLstLnk;
25874       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25875       ret = rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf);
25876       if (ret != ROK)
25877       {
25878          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
25879           * list and return */
25880          do
25881          {
25882             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25883             ueCb = hqP->hqE->ue;
25884             schdLnkNode = &hqP->schdLstLnk;
25885             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25886             cmLListAdd2Tail(nonSchdCcchSduLst, schdLnkNode);
25887             toBeSchdLnk = toBeSchdLnk->next;
25888          } while(toBeSchdLnk);
25889          RETVOID;
25890       }
25891
25892       /* Allocation successful: Add UE to the scheduled list */
25893       cmLListAdd2Tail(schdCcchSduLst, schdLnkNode);
25894    }
25895
25896
25897    RETVOID;
25898 }
25899
25900 /**
25901  * @brief Performs RB allocation for CcchSdu for frequency non-selective cell.
25902  *
25903  * @details
25904  *
25905  *     Function : rgSCHCmnNonDlfsCcchSduRbAlloc
25906  *
25907  *     Processing Steps:
25908  *     - Fetch PDCCH
25909  *     - Allocate consecutively available RBs
25910  *
25911  *  @param[in] RgSchCellCb     *cell
25912  *  @param[in] RgSchUeCb       *ueCb
25913  *  @param[in] RgSchDlSf       *dlSf
25914  *  @return  S16
25915  *      -# ROK
25916  *      -# RFAILED
25917  **/
25918 #ifdef ANSI
25919 PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc
25920 (
25921 RgSchCellCb        *cell,
25922 RgSchUeCb          *ueCb,
25923 RgSchDlSf          *dlSf
25924 )
25925 #else
25926 PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf)
25927 RgSchCellCb        *cell;
25928 RgSchUeCb          *ueCb;
25929 RgSchDlSf          *dlSf;
25930 #endif
25931 {
25932    RgSchDlRbAlloc  *allocInfo;
25933    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
25934
25935    TRC2(rgSCHCmnNonDlfsCcchSduRbAlloc);
25936
25937
25938    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb,cell);
25939
25940    /* [ccpu00138802]-MOD-If Bw is less than required, return fail
25941       It will be allocated in next TTI */
25942 #ifdef LTEMAC_SPS
25943    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
25944          (dlSf->bwAlloced == dlSf->bw))
25945 #else
25946    if((dlSf->bwAlloced == dlSf->bw) ||
25947       (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
25948 #endif
25949    {
25950       RETVALUE(RFAILED);
25951    }
25952    /* Retrieve PDCCH */
25953    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
25954    if (ueDl->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
25955    {
25956       /*      allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, dlSf, y, ueDl->cqi,
25957        *      TFU_DCI_FORMAT_1A, TRUE);*/
25958       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, TRUE);
25959    }
25960    else
25961    {
25962       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE);
25963    }
25964    if (!(allocInfo->pdcch))
25965    {
25966       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
25967       RETVALUE(RFAILED);
25968    }
25969
25970    /* Update allocation information */
25971    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25972    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
25973    allocInfo->allocInfo.raType2.isLocal = TRUE;
25974
25975       /*Fix for ccpu00123918*/
25976       /* Push this harq process back to the free queue */
25977       allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start;
25978       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
25979       allocInfo->rbsAlloc = allocInfo->rbsReq;
25980       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25981       /* Update the sub-frame with new allocation */
25982       /* ccpu00129469 */
25983       /* LTE_ADV_FLAG_REMOVED_START */
25984 #ifndef LTE_TDD
25985       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
25986       {
25987          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf,
25988                allocInfo->allocInfo.raType2.rbStart,
25989                allocInfo->allocInfo.raType2.numRb);
25990       }
25991       else
25992 #endif /* end of ifndef LTE_TDD*/
25993       {
25994          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, 
25995                allocInfo->allocInfo.raType2.rbStart, 
25996                allocInfo->allocInfo.raType2.numRb);
25997       }
25998
25999    /* LTE_ADV_FLAG_REMOVED_END */
26000    /* ccpu00131941 - bwAlloced is updated from SPS bandwidth */  
26001
26002
26003    RETVALUE(ROK);
26004 }
26005 #endif
26006
26007 /**
26008  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
26009  *
26010  * @details
26011  *
26012  *     Function : rgSCHCmnNonDlfsMsg4RbAlloc
26013  *
26014  *     Processing Steps:
26015  *     - Fetch PDCCH
26016  *     - Allocate consecutively available RBs
26017  *
26018  *  @param[in] RgSchCellCb     *cell
26019  *  @param[in] RgSchRaCb       *raCb
26020  *  @param[in] RgSchDlSf       *dlSf
26021  *  @return  S16
26022  *      -# ROK
26023  *      -# RFAILED
26024  **/
26025 #ifdef ANSI
26026 PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc
26027 (
26028 RgSchCellCb        *cell,
26029 RgSchRaCb          *raCb,
26030 RgSchDlSf          *dlSf
26031 )
26032 #else
26033 PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf)
26034 RgSchCellCb        *cell;
26035 RgSchRaCb          *raCb;
26036 RgSchDlSf          *dlSf;
26037 #endif
26038 {
26039    RgSchDlRbAlloc  *allocInfo;
26040    TRC2(rgSCHCmnNonDlfsMsg4RbAlloc);
26041
26042
26043    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(raCb);
26044
26045 #ifdef RG_5GTF
26046         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
26047         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
26048         {
26049            RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
26050          "5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
26051          raCb->ue->ueId);
26052            printf("5GTF_ERROR vrbg allocated > 25\n");
26053                 RETVALUE(RFAILED);
26054         }
26055 #endif
26056 #ifdef LTEMAC_SPS
26057    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
26058          (dlSf->bwAlloced == dlSf->bw))
26059 #else
26060    if((dlSf->bwAlloced == dlSf->bw) ||
26061             (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
26062 #endif
26063    {
26064
26065       RETVALUE(RFAILED);
26066    }
26067
26068    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
26069    if (raCb->dlHqE->msg4Proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
26070    {
26071       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, TRUE);
26072    }
26073    else
26074    {
26075       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, FALSE);
26076    }
26077    if (!(allocInfo->pdcch))
26078    {
26079       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
26080       RETVALUE(RFAILED);
26081    }
26082    
26083 #ifndef RG_5GTF
26084  /* SR_RACH_STATS : MSG4 TX Failed */
26085    allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
26086
26087    /* Update allocation information */
26088    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
26089    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
26090    allocInfo->allocInfo.raType2.isLocal = TRUE;
26091
26092
26093         /*Fix for ccpu00123918*/
26094         allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start;
26095         allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
26096         /* LTE_ADV_FLAG_REMOVED_START */
26097 #ifndef LTE_TDD
26098         if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
26099         {
26100           rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
26101                 allocInfo->allocInfo.raType2.rbStart, \
26102                 allocInfo->allocInfo.raType2.numRb);
26103         }
26104         else
26105 #endif /* end of ifndef LTE_TDD */
26106         {
26107           rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
26108                 allocInfo->allocInfo.raType2.rbStart, \
26109                 allocInfo->allocInfo.raType2.numRb);
26110         }
26111         /* LTE_ADV_FLAG_REMOVED_END */
26112
26113    allocInfo->rbsAlloc = allocInfo->rbsReq;
26114    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
26115
26116 #else
26117
26118   allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
26119
26120         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
26121         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
26122
26123    /* Update allocation information */
26124    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
26125
26126         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
26127         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
26128          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
26129
26130    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
26131    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
26132
26133
26134         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
26135         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
26136         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
26137
26138 #endif
26139
26140    RETVALUE(ROK);
26141 }
26142
26143 /**
26144  * @brief Performs RB allocation for Msg4 lists of frequency non-selective cell.
26145  *
26146  * @details
26147  *
26148  *     Function : rgSCHCmnNonDlfsMsg4Alloc
26149  *
26150  *     Processing Steps:
26151  *     - For each element in the list, Call rgSCHCmnNonDlfsMsg4RbAlloc().
26152  *        - If allocation is successful, add the raCb to scheduled list of MSG4.
26153  *        - else, add RaCb to non-scheduled list.
26154  *
26155  *  @param[in]      RgSchCellCb         *cell
26156  *  @param[in, out] RgSchCmnMsg4RbAlloc *allocInfo
26157  *  @param[in]      U8                  isRetx
26158  *
26159  *  @return  Void
26160  **/
26161 #ifdef ANSI
26162 PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc
26163 (
26164 RgSchCellCb         *cell,
26165 RgSchCmnMsg4RbAlloc *allocInfo,
26166 U8                  isRetx
26167 )
26168 #else
26169 PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc(cell, allocInfo, isRetx)
26170 RgSchCellCb         *cell;
26171 RgSchCmnMsg4RbAlloc *allocInfo;
26172 U8                  isRetx;
26173 #endif
26174 {
26175    S16             ret;
26176    CmLListCp       *msg4Lst        = NULLP;
26177    CmLListCp       *schdMsg4Lst    = NULLP;
26178    CmLListCp       *nonSchdMsg4Lst = NULLP;
26179    CmLList         *schdLnkNode    = NULLP;
26180    CmLList         *toBeSchdLnk    = NULLP;
26181    RgSchDlSf       *dlSf           = allocInfo->msg4DlSf;
26182    RgSchRaCb       *raCb           = NULLP;
26183    RgSchDlHqProcCb *hqP            = NULLP;
26184    TRC2(rgSCHCmnNonDlfsMsg4Alloc);
26185
26186    if (isRetx)
26187    {
26188       /* Initialize re-transmitting lists */
26189       msg4Lst = &(allocInfo->msg4RetxLst);
26190       schdMsg4Lst = &(allocInfo->schdMsg4RetxLst);
26191       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4RetxLst);
26192    }
26193    else
26194    {
26195       /* Initialize transmitting lists */
26196       msg4Lst = &(allocInfo->msg4TxLst);
26197       schdMsg4Lst = &(allocInfo->schdMsg4TxLst);
26198       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4TxLst);
26199    }
26200
26201    /* Perform allocaations  for the list */
26202    toBeSchdLnk = cmLListFirst(msg4Lst);
26203    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
26204    {
26205       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26206       raCb = hqP->hqE->raCb;
26207       schdLnkNode = &hqP->schdLstLnk;
26208       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26209       ret = rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf);
26210       if (ret != ROK)
26211       {
26212          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
26213           * list and return */
26214          do
26215          {
26216             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26217             raCb = hqP->hqE->raCb;
26218             schdLnkNode = &hqP->schdLstLnk;
26219             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26220             cmLListAdd2Tail(nonSchdMsg4Lst, schdLnkNode);
26221             toBeSchdLnk = toBeSchdLnk->next;
26222          } while(toBeSchdLnk);
26223          RETVOID;
26224       }
26225
26226       /* Allocation successful: Add UE to the scheduled list */
26227       cmLListAdd2Tail(schdMsg4Lst, schdLnkNode);
26228       if (isRetx)
26229       {
26230       }
26231    }
26232
26233
26234    RETVOID;
26235 }
26236
26237 /**
26238  * @brief Performs RB allocation for the list of UEs of a frequency
26239  * non-selective cell.
26240  *
26241  * @details
26242  *
26243  *     Function : rgSCHCmnNonDlfsDedRbAlloc
26244  *
26245  *     Processing Steps:
26246  *     - For each element in the list, Call rgSCHCmnNonDlfsUeRbAlloc().
26247  *        - If allocation is successful, add the ueCb to scheduled list of UEs.
26248  *        - else, add ueCb to non-scheduled list of UEs.
26249  *
26250  *  @param[in]      RgSchCellCb        *cell
26251  *  @param[in, out] RgSchCmnUeRbAlloc  *allocInfo
26252  *  @param[in]      CmLListCp          *ueLst,
26253  *  @param[in, out] CmLListCp          *schdHqPLst,
26254  *  @param[in, out] CmLListCp          *nonSchdHqPLst
26255  *
26256  *  @return  Void
26257  **/
26258 #ifdef ANSI
26259 PUBLIC Void rgSCHCmnNonDlfsDedRbAlloc
26260 (
26261 RgSchCellCb        *cell,
26262 RgSchCmnUeRbAlloc  *allocInfo,
26263 CmLListCp          *ueLst,
26264 CmLListCp          *schdHqPLst,
26265 CmLListCp          *nonSchdHqPLst
26266 )
26267 #else
26268 PUBLIC Void rgSCHCmnNonDlfsDedRbAlloc(cell, allocInfo, ueLst,
26269         schdHqPLst, nonSchdHqPLst)
26270 RgSchCellCb        *cell;
26271 RgSchCmnUeRbAlloc  *allocInfo;
26272 CmLListCp          *ueLst;
26273 CmLListCp          *schdHqPLst;
26274 CmLListCp          *nonSchdHqPLst;
26275 #endif
26276 {
26277    S16             ret;
26278    CmLList         *schdLnkNode  = NULLP;
26279    CmLList         *toBeSchdLnk  = NULLP;
26280    RgSchDlSf       *dlSf         = allocInfo->dedDlSf;
26281    RgSchUeCb       *ue           = NULLP;
26282    RgSchDlHqProcCb *hqP          = NULLP;
26283    U8              isDlBwAvail;
26284    TRC2(rgSCHCmnNonDlfsDedRbAlloc);
26285
26286
26287    /* Perform allocaations  for the list */
26288    toBeSchdLnk = cmLListFirst(ueLst);
26289    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
26290    {
26291       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26292       ue = hqP->hqE->ue;
26293       schdLnkNode = &hqP->schdLstLnk;
26294       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26295
26296       ret = rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, &isDlBwAvail);
26297       if (!isDlBwAvail)
26298       {
26299          /* Allocation failed: Add remaining UEs to non-scheduled
26300           * list and return */
26301          do
26302          {
26303             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26304             ue = hqP->hqE->ue;
26305             schdLnkNode = &hqP->schdLstLnk;
26306             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26307             cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
26308             toBeSchdLnk = toBeSchdLnk->next;
26309          } while(toBeSchdLnk);
26310          break; 
26311       }
26312
26313       if (ret == ROK)
26314       {
26315 #if defined (TENB_STATS) && defined (RG_5GTF)
26316          cell->tenbStats->sch.dl5gtfRbAllocPass++;
26317 #endif
26318          /* Allocation successful: Add UE to the scheduled list */
26319          cmLListAdd2Tail(schdHqPLst, schdLnkNode);
26320       }
26321       else
26322       {
26323 #if defined (TENB_STATS) && defined (RG_5GTF)
26324          cell->tenbStats->sch.dl5gtfRbAllocFail++;
26325 #endif
26326          /* Allocation failed : Add UE to the non-scheduled list */
26327                         printf("5GTF_ERROR Dl rb alloc failed adding nonSchdHqPLst\n");
26328          cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
26329       }
26330    }
26331
26332    RETVOID;
26333 }
26334
26335 /**
26336  * @brief Handles RB allocation for frequency non-selective cell.
26337  *
26338  * @details
26339  *
26340  *     Function : rgSCHCmnNonDlfsRbAlloc
26341  *
26342  *     Invoking Module Processing:
26343  *      - SCH shall invoke this if downlink frequency selective is disabled for
26344  *        the cell for RB allocation.
26345  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
26346  *        estimate and subframe for each allocation to be made to SCH.
26347  *
26348  *     Processing Steps:
26349  *     - Allocate sequentially for common channels.
26350  *     - For transmitting and re-transmitting UE list.
26351  *      - For each UE:
26352  *       - Perform wide-band allocations for UE in increasing order of
26353  *         frequency.
26354  *       - Determine Imcs for the allocation.
26355  *       - Determine RA type.
26356  *       - Determine DCI format.
26357  *
26358  *  @param[in]  RgSchCellCb        *cell
26359  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
26360  *  @return  Void
26361  **/
26362
26363 #ifdef ANSI
26364 PUBLIC Void rgSCHCmnNonDlfsRbAlloc
26365 (
26366 RgSchCellCb           *cell,
26367 RgSchCmnDlRbAllocInfo *allocInfo
26368 )
26369 #else
26370 PUBLIC Void rgSCHCmnNonDlfsRbAlloc(cell, allocInfo)
26371 RgSchCellCb           *cell;
26372 RgSchCmnDlRbAllocInfo *allocInfo;
26373 #endif
26374 {
26375    U8                 raRspCnt = 0;
26376    RgSchDlRbAlloc     *reqAllocInfo;
26377    TRC2(rgSCHCmnNonDlfsRbAlloc);
26378
26379    /* Allocate for MSG4 retransmissions */
26380    if (allocInfo->msg4Alloc.msg4RetxLst.count)
26381    {
26382       printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc RetxLst\n");
26383       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), TRUE);
26384    }
26385
26386    /* Allocate for MSG4 transmissions */
26387    /* Assuming all the nodes in the list need allocations: rbsReq is valid */
26388    if (allocInfo->msg4Alloc.msg4TxLst.count)
26389    {
26390       printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc txLst\n");
26391       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), FALSE);
26392    }
26393 #ifdef RGR_V1
26394    /* Allocate for CCCH SDU (received after guard timer expiry)
26395     * retransmissions */
26396    if (allocInfo->ccchSduAlloc.ccchSduRetxLst.count)
26397    {
26398       printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
26399       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), TRUE);
26400    }
26401
26402    /* Allocate for CCCD SDU transmissions */
26403    /* Allocate for CCCH SDU (received after guard timer expiry) transmissions */
26404    if (allocInfo->ccchSduAlloc.ccchSduTxLst.count)
26405    {
26406       printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
26407       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), FALSE);
26408    }
26409 #endif
26410
26411    /* Allocate for Random access response */
26412    for (raRspCnt = 0; raRspCnt < RG_SCH_CMN_MAX_CMN_PDCCH; ++raRspCnt)
26413    {
26414       /* Assuming that the requests will be filled in sequentially */
26415       reqAllocInfo = &(allocInfo->raRspAlloc[raRspCnt]);
26416       if (!reqAllocInfo->rbsReq)
26417       {
26418          break;
26419       }
26420       printf("5GTF_ERROR calling RAR rgSCHCmnNonDlfsCmnRbAlloc\n");
26421    //   if ((rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo)) != ROK)
26422       if ((rgSCHCmnNonDlfsCmnRbAllocRar(cell, reqAllocInfo)) != ROK)
26423       {
26424          break;
26425       }
26426    }
26427
26428    /* Allocate for RETX+TX UEs */
26429    if(allocInfo->dedAlloc.txRetxHqPLst.count)
26430    {
26431       printf("5GTF_ERROR TX RETX rgSCHCmnNonDlfsDedRbAlloc\n");
26432       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26433             &(allocInfo->dedAlloc.txRetxHqPLst),
26434             &(allocInfo->dedAlloc.schdTxRetxHqPLst),
26435             &(allocInfo->dedAlloc.nonSchdTxRetxHqPLst));
26436    }
26437
26438    if((allocInfo->dedAlloc.retxHqPLst.count))
26439    {
26440       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26441             &(allocInfo->dedAlloc.retxHqPLst),
26442             &(allocInfo->dedAlloc.schdRetxHqPLst),
26443             &(allocInfo->dedAlloc.nonSchdRetxHqPLst));
26444    }
26445
26446    /* Allocate for transmitting UEs */
26447    if((allocInfo->dedAlloc.txHqPLst.count))
26448    {
26449       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26450             &(allocInfo->dedAlloc.txHqPLst),
26451             &(allocInfo->dedAlloc.schdTxHqPLst),
26452             &(allocInfo->dedAlloc.nonSchdTxHqPLst));
26453    }
26454    {
26455       RgSchCmnCell  *cmnCell = RG_SCH_CMN_GET_CELL(cell);
26456       if ((allocInfo->dedAlloc.txRetxHqPLst.count + 
26457                allocInfo->dedAlloc.retxHqPLst.count + 
26458                allocInfo->dedAlloc.txHqPLst.count) > 
26459             cmnCell->dl.maxUePerDlSf)
26460       {
26461 #ifndef ALIGN_64BIT
26462          RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by"
26463                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %ld retx %ld tx %ld\n",
26464                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
26465                   allocInfo->dedAlloc.retxHqPLst.count,
26466                   allocInfo->dedAlloc.txHqPLst.count));
26467 #else
26468          RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by"
26469                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %d retx %d tx %d\n",
26470                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
26471                   allocInfo->dedAlloc.retxHqPLst.count,
26472                   allocInfo->dedAlloc.txHqPLst.count));
26473 #endif
26474       }
26475    }
26476 #ifndef LTE_TDD
26477    /* LTE_ADV_FLAG_REMOVED_START */
26478    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
26479    {    
26480       printf("5GTF_ERROR RETX rgSCHCmnNonDlfsDsfrRntpComp\n");
26481       rgSCHCmnNonDlfsDsfrRntpComp(cell, allocInfo->dedAlloc.dedDlSf); 
26482    }  
26483    /* LTE_ADV_FLAG_REMOVED_END */
26484 #endif /* LTE_TDD */
26485    RETVOID;
26486 }
26487
26488 /***********************************************************
26489  *
26490  *     Func : rgSCHCmnCalcRiv
26491  *
26492  *     Desc : This function calculates RIV.
26493  *
26494  *     Ret  : None.
26495  *
26496  *     Notes: None.
26497  *
26498  *     File : rg_sch_utl.c
26499  *
26500  **********************************************************/
26501 #ifdef LTEMAC_SPS
26502 #ifdef ANSI
26503 PUBLIC U32 rgSCHCmnCalcRiv
26504 (
26505 U8           bw,
26506 U8           rbStart,
26507 U8           numRb
26508 )
26509 #else
26510 PUBLIC U32 rgSCHCmnCalcRiv(bw, rbStart, numRb)
26511 U8           bw;
26512 U8           rbStart;
26513 U8           numRb;
26514 #endif
26515 #else
26516 #ifdef ANSI
26517 PUBLIC U32 rgSCHCmnCalcRiv
26518 (
26519 U8           bw,
26520 U8           rbStart,
26521 U8           numRb
26522 )
26523 #else
26524 PUBLIC U32 rgSCHCmnCalcRiv(bw, rbStart, numRb)
26525 U8           bw;
26526 U8           rbStart;
26527 U8           numRb;
26528 #endif
26529 #endif
26530 {
26531    U8           numRbMinus1 = numRb - 1;
26532    U32          riv;
26533
26534    TRC2(rgSCHCmnCalcRiv);
26535
26536    if (numRbMinus1 <= bw/2)
26537    {
26538       riv = bw * numRbMinus1 + rbStart;
26539    }
26540    else
26541    {
26542       riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
26543    }
26544    RETVALUE(riv);
26545 } /* rgSCHCmnCalcRiv */
26546
26547 #ifdef LTE_TDD
26548 /**
26549  * @brief This function allocates and copies the RACH response scheduling
26550  *        related information into cell control block.
26551  *
26552  * @details
26553  *
26554  *     Function: rgSCHCmnDlCpyRachInfo
26555  *     Purpose:  This function allocates and copies the RACH response
26556  *               scheduling related information into cell control block
26557  *               for each DL subframe.
26558  *
26559  *
26560  *     Invoked by: Scheduler
26561  *
26562  *  @param[in]  RgSchCellCb*           cell
26563  *  @param[in]  RgSchTddRachRspLst     rachRspLst[][RGSCH_NUM_SUB_FRAMES]
26564  *  @param[in]  U8                     raArrSz
26565  *  @return     S16
26566  *
26567  **/
26568 #ifdef ANSI
26569 PRIVATE S16 rgSCHCmnDlCpyRachInfo
26570 (
26571 RgSchCellCb                *cell,
26572 RgSchTddRachRspLst         rachRspLst[][RGSCH_NUM_SUB_FRAMES],
26573 U8                         raArrSz
26574 )
26575 #else
26576 PRIVATE S16 rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz)
26577 RgSchCellCb                *cell;
26578 RgSchTddRachRspLst         rachRspLst[][RGSCH_NUM_SUB_FRAMES];
26579 U8                         raArrSz;
26580 #endif
26581 {
26582    U8                   ulDlCfgIdx = cell->ulDlCfgIdx;
26583    U8                   sfNum;
26584    S16                  sfnIdx;
26585    U16                  subfrmIdx;
26586    U8                   numRfs;
26587    U8                   numSubfrms;
26588    U8                   sfcount;
26589    S16                   ret;
26590
26591    TRC2(rgSCHCmnDlCpyRachInfo);
26592
26593    /* Allocate RACH response information for each DL
26594     * subframe in a radio frame */
26595    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cell->rachRspLst,
26596          rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1] *
26597          sizeof(RgSchTddRachRspLst));
26598    if (ret != ROK)
26599    {
26600       RETVALUE(ret);
26601    }
26602
26603    for(sfnIdx=raArrSz-1; sfnIdx>=0; sfnIdx--)
26604    {
26605       for(subfrmIdx=0; subfrmIdx < RGSCH_NUM_SUB_FRAMES; subfrmIdx++)
26606       {
26607          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
26608          if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
26609          {
26610             break;
26611          }
26612
26613          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx],subfrmIdx);
26614          numSubfrms =
26615             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
26616
26617          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddNumDlSubfrmTbl[ulDlCfgIdx],subfrmIdx);
26618          sfNum = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][subfrmIdx]-1;
26619          numRfs = cell->rachRspLst[sfNum].numRadiofrms;
26620          /* For each DL subframe in which RACH response can
26621           * be sent is updated */
26622          if(numSubfrms > 0)
26623          {
26624             cell->rachRspLst[sfNum].rachRsp[numRfs].sfnOffset =
26625                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset;
26626             for(sfcount=0; sfcount < numSubfrms; sfcount++)
26627             {
26628                cell->rachRspLst[sfNum].rachRsp[numRfs].\
26629                   subframe[sfcount] =
26630                   rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].\
26631                   subframe[sfcount];
26632             }
26633             cell->rachRspLst[sfNum].rachRsp[numRfs].numSubfrms =
26634                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
26635             cell->rachRspLst[sfNum].numRadiofrms++;
26636          }
26637
26638          /* Copy the subframes to be deleted at ths subframe */
26639          numSubfrms =
26640             rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
26641          if(numSubfrms > 0)
26642          {
26643             cell->rachRspLst[sfNum].delInfo.sfnOffset =
26644                rachRspLst[sfnIdx][subfrmIdx].delInfo.sfnOffset;
26645             for(sfcount=0; sfcount < numSubfrms; sfcount++)
26646             {
26647                cell->rachRspLst[sfNum].delInfo.subframe[sfcount] =
26648                   rachRspLst[sfnIdx][subfrmIdx].delInfo.subframe[sfcount];
26649             }
26650             cell->rachRspLst[sfNum].delInfo.numSubfrms =
26651                rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
26652          }
26653       }
26654    }
26655    RETVALUE(ROK);
26656 }
26657 #endif
26658 /**
26659  * @brief This function determines the iTbs based on the new CFI, 
26660  *        CQI and BLER based delta iTbs 
26661  *
26662  * @details
26663  *
26664  *     Function: rgSchCmnFetchItbs
26665  *     Purpose:  Fetch the new iTbs when CFI changes.
26666  *
26667  *  @param[in]  RgSchCellCb           *cell
26668  *  @param[in]  RgSchCmnDlUe          *ueDl
26669  *  @param[in]  U8                    cqi
26670  *
26671  *  @return S32 iTbs
26672  *
26673  **/
26674 #ifdef LTE_TDD
26675 #ifdef ANSI
26676 PRIVATE S32 rgSchCmnFetchItbs 
26677 (
26678 RgSchCellCb        *cell,
26679 RgSchCmnDlUe       *ueDl,
26680 RgSchDlSf          *subFrm,
26681 U8                 cqi,
26682 U8                 cfi,
26683 U8                 cwIdx,
26684 U8                 noLyr
26685 )
26686 #else
26687 PRIVATE S32 rgSchCmnFetchItbs (cell, ueDl, subFrm, cqi, cfi, cwIdx, noLyr)
26688 RgSchCellCb        *cell;
26689 RgSchCmnDlUe       *ueDl; 
26690 RgSchDlSf          *subFrm;
26691 U8                 cqi;
26692 U8                 cfi;
26693 U8                 cwIdx;
26694 U8                 noLyr;
26695 #endif
26696 #else
26697 #ifdef ANSI
26698 PRIVATE S32 rgSchCmnFetchItbs 
26699 (
26700 RgSchCellCb        *cell,
26701 RgSchCmnDlUe       *ueDl,
26702 U8                 cqi,
26703 U8                 cfi,
26704 U8                 cwIdx,
26705 U8                 noLyr
26706 )
26707 #else
26708 PRIVATE S32 rgSchCmnFetchItbs (cell, ueDl, cqi, cfi, cwIdx, noLyr)
26709 RgSchCellCb        *cell;
26710 RgSchCmnDlUe       *ueDl; 
26711 U8                 cqi;
26712 U8                 cfi;
26713 U8                 cwIdx;
26714 U8                 noLyr;
26715 #endif 
26716 #endif
26717 {
26718
26719    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
26720    S32 iTbs = 0;
26721
26722    TRC2(rgSchCmnFetchItbs);
26723
26724 #ifdef LTE_TDD      
26725    /* Special Handling for Spl Sf when CFI is 3 as 
26726     * CFI in Spl Sf will be max 2 */
26727    if(subFrm->sfType == RG_SCH_SPL_SF_DATA) 
26728    {
26729       if((cellDl->currCfi == 3) || 
26730             ((cell->bwCfg.dlTotalBw <= 10) && (cellDl->currCfi == 1)))
26731       {    
26732          /* Use CFI 2 in this case */
26733          iTbs = (ueDl->laCb[cwIdx].deltaiTbs + 
26734                ((*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][2]))[cqi])* 100)/100;
26735
26736          RG_SCH_CHK_ITBS_RANGE(iTbs, RGSCH_NUM_ITBS - 1);
26737       }
26738       else
26739       {
26740          iTbs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1];
26741       }
26742       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
26743    }   
26744    else /* CFI Changed. Update with new iTbs Reset the BLER*/
26745 #endif         
26746    {
26747       S32 tmpiTbs  = (*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][cfi]))[cqi];
26748       
26749       iTbs = (ueDl->laCb[cwIdx].deltaiTbs + tmpiTbs*100)/100;
26750
26751       RG_SCH_CHK_ITBS_RANGE(iTbs, tmpiTbs);     
26752
26753       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
26754
26755       ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1] = iTbs;
26756
26757       ueDl->lastCfi = cfi;
26758       ueDl->laCb[cwIdx].deltaiTbs = 0;
26759    }
26760
26761    RETVALUE(iTbs);
26762
26763 \f
26764 /**
26765  * @brief This function determines the RBs and Bytes required for BO
26766  *        transmission for UEs configured with TM 1/2/6/7.
26767  *
26768  * @details
26769  *
26770  *     Function: rgSCHCmnDlAllocTxRb1Tb1Cw
26771  *     Purpose:  Allocate TB1 on CW1.
26772  *
26773  *               Reference Parameter effBo is filled with alloced bytes.
26774  *               Returns RFAILED if BO not satisfied at all.
26775  *
26776  *     Invoked by: rgSCHCmnDlAllocTxRbTM1/2/6/7
26777  *
26778  *  @param[in]  RgSchCellCb           *cell
26779  *  @param[in]  RgSchDlSf             *subFrm
26780  *  @param[in]  RgSchUeCb             *ue
26781  *  @param[in]  U32                   bo
26782  *  @param[out] U32                   *effBo
26783  *  @param[in]  RgSchDlHqProcCb       *proc
26784  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26785  *  @return  Void
26786  *
26787  **/
26788 #ifdef ANSI
26789 PRIVATE Void rgSCHCmnDlAllocTxRb1Tb1Cw
26790 (
26791 RgSchCellCb                *cell,
26792 RgSchDlSf                  *subFrm,
26793 RgSchUeCb                  *ue,
26794 U32                        bo,
26795 U32                        *effBo,
26796 RgSchDlHqProcCb            *proc,
26797 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26798 )
26799 #else
26800 PRIVATE Void rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26801 RgSchCellCb                *cell;
26802 RgSchDlSf                  *subFrm;
26803 RgSchUeCb                  *ue;
26804 U32                        bo;
26805 U32                        *effBo;
26806 RgSchDlHqProcCb            *proc;
26807 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26808 #endif
26809 {
26810    RgSchDlRbAlloc   *allocInfo;
26811    S16              ret;
26812    U8               numRb;
26813    TRC2(rgSCHCmnDlAllocTxRb1Tb1Cw);
26814
26815    ret = ROK;
26816    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26817 #ifdef RG_5GTF
26818    if (ue->ue5gtfCb.rank == 2)
26819    {
26820       allocInfo->dciFormat = TFU_DCI_FORMAT_B2;
26821    }
26822    else
26823    {
26824       allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
26825    }
26826 #else
26827    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
26828          allocInfo->raType);
26829 #endif
26830    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
26831          bo, &numRb, effBo);
26832    if (ret == RFAILED)
26833    {
26834       /* If allocation couldn't be made then return */
26835       RETVOID;
26836    }
26837    /* Adding UE to RbAllocInfo TX Lst */
26838    rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
26839    /* Fill UE alloc Info */
26840    allocInfo->rbsReq = numRb;
26841    allocInfo->dlSf   = subFrm;
26842 #ifdef RG_5GTF
26843    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
26844 #endif
26845
26846    RETVOID;
26847 }
26848
26849 \f
26850 /**
26851  * @brief This function determines the RBs and Bytes required for BO
26852  *        retransmission for UEs configured with TM 1/2/6/7.
26853  *
26854  * @details
26855  *
26856  *     Function: rgSCHCmnDlAllocRetxRb1Tb1Cw
26857  *     Purpose:  Allocate TB1 on CW1.
26858  *
26859  *               Reference Parameter effBo is filled with alloced bytes.
26860  *               Returns RFAILED if BO not satisfied at all.
26861  *
26862  *     Invoked by: rgSCHCmnDlAllocRetxRbTM1/2/6/7
26863  *
26864  *  @param[in]  RgSchCellCb           *cell
26865  *  @param[in]  RgSchDlSf             *subFrm
26866  *  @param[in]  RgSchUeCb             *ue
26867  *  @param[in]  U32                   bo
26868  *  @param[out] U32                   *effBo
26869  *  @param[in]  RgSchDlHqProcCb       *proc
26870  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26871  *  @return  Void
26872  *
26873  **/
26874 #ifdef ANSI
26875 PRIVATE Void rgSCHCmnDlAllocRetxRb1Tb1Cw
26876 (
26877 RgSchCellCb                *cell,
26878 RgSchDlSf                  *subFrm,
26879 RgSchUeCb                  *ue,
26880 U32                        bo,
26881 U32                        *effBo,
26882 RgSchDlHqProcCb            *proc,
26883 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26884 )
26885 #else
26886 PRIVATE Void rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26887 RgSchCellCb                *cell;
26888 RgSchDlSf                  *subFrm;
26889 RgSchUeCb                  *ue;
26890 U32                        bo;
26891 U32                        *effBo;
26892 RgSchDlHqProcCb            *proc;
26893 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26894 #endif
26895 {
26896    RgSchDlRbAlloc   *allocInfo;
26897    S16              ret;
26898    U8               numRb;
26899    TRC2(rgSCHCmnDlAllocRetxRb1Tb1Cw);
26900
26901    ret = ROK;
26902    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26903
26904 #ifndef RG_5GTF
26905    /* 5GTF: RETX DCI format same as TX */
26906    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
26907       &allocInfo->raType);
26908 #endif
26909
26910    /* Get the Allocation in terms of RBs that are required for
26911     * this retx of TB1 */
26912    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
26913          1, &numRb, effBo);
26914    if (ret == RFAILED)
26915    {
26916       /* Allocation couldn't be made for Retx */
26917       /* Fix : syed If TxRetx allocation failed then add the UE along with the proc
26918        * to the nonSchdTxRetxUeLst and let spfc scheduler take care of it during
26919        * finalization. */        
26920       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
26921       RETVOID;
26922    }
26923    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
26924    /* Fill UE alloc Info */
26925    allocInfo->rbsReq = numRb;
26926    allocInfo->dlSf   = subFrm;
26927 #ifdef RG_5GTF
26928    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
26929 #endif
26930
26931    RETVOID;
26932 }
26933
26934 \f
26935 /**
26936  * @brief This function determines the RBs and Bytes required for BO
26937  *        transmission for UEs configured with TM 2.
26938  *
26939  * @details
26940  *
26941  *     Function: rgSCHCmnDlAllocTxRbTM1
26942  *     Purpose:
26943  *
26944  *               Reference Parameter effBo is filled with alloced bytes.
26945  *               Returns RFAILED if BO not satisfied at all.
26946  *
26947  *     Invoked by: rgSCHCmnDlAllocTxRb
26948  *
26949  *  @param[in]  RgSchCellCb           *cell
26950  *  @param[in]  RgSchDlSf             *subFrm
26951  *  @param[in]  RgSchUeCb             *ue
26952  *  @param[in]  U32                   bo
26953  *  @param[out] U32                   *effBo
26954  *  @param[in]  RgSchDlHqProcCb       *proc
26955  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26956  *  @return Void
26957  *
26958  **/
26959 #ifdef ANSI
26960 PRIVATE Void rgSCHCmnDlAllocTxRbTM1
26961 (
26962 RgSchCellCb                *cell,
26963 RgSchDlSf                  *subFrm,
26964 RgSchUeCb                  *ue,
26965 U32                        bo,
26966 U32                        *effBo,
26967 RgSchDlHqProcCb            *proc,
26968 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26969 )
26970 #else
26971 PRIVATE Void rgSCHCmnDlAllocTxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26972 RgSchCellCb                *cell;
26973 RgSchDlSf                  *subFrm;
26974 RgSchUeCb                  *ue;
26975 U32                        bo;
26976 U32                        *effBo;
26977 RgSchDlHqProcCb            *proc;
26978 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26979 #endif
26980 {
26981    TRC2(rgSCHCmnDlAllocTxRbTM1);
26982    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
26983    RETVOID;
26984 }
26985
26986 \f
26987 /**
26988  * @brief This function determines the RBs and Bytes required for BO
26989  *        retransmission for UEs configured with TM 2.
26990  *
26991  * @details
26992  *
26993  *     Function: rgSCHCmnDlAllocRetxRbTM1
26994  *     Purpose:
26995  *
26996  *               Reference Parameter effBo is filled with alloced bytes.
26997  *               Returns RFAILED if BO not satisfied at all.
26998  *
26999  *     Invoked by: rgSCHCmnDlAllocRetxRb
27000  *
27001  *  @param[in]  RgSchCellCb           *cell
27002  *  @param[in]  RgSchDlSf             *subFrm
27003  *  @param[in]  RgSchUeCb             *ue
27004  *  @param[in]  U32                   bo
27005  *  @param[out] U32                   *effBo
27006  *  @param[in]  RgSchDlHqProcCb       *proc
27007  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27008  *  @return Void
27009  *
27010  **/
27011 #ifdef ANSI
27012 PRIVATE Void rgSCHCmnDlAllocRetxRbTM1
27013 (
27014 RgSchCellCb                *cell,
27015 RgSchDlSf                  *subFrm,
27016 RgSchUeCb                  *ue,
27017 U32                        bo,
27018 U32                        *effBo,
27019 RgSchDlHqProcCb            *proc,
27020 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27021 )
27022 #else
27023 PRIVATE Void rgSCHCmnDlAllocRetxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27024 RgSchCellCb                *cell;
27025 RgSchDlSf                  *subFrm;
27026 RgSchUeCb                  *ue;
27027 U32                        bo;
27028 U32                        *effBo;
27029 RgSchDlHqProcCb            *proc;
27030 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27031 #endif
27032 {
27033    TRC2(rgSCHCmnDlAllocRetxRbTM1);
27034    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
27035    RETVOID;
27036 }
27037
27038 \f
27039 /**
27040  * @brief This function determines the RBs and Bytes required for BO
27041  *        transmission for UEs configured with TM 2.
27042  *
27043  * @details
27044  *
27045  *     Function: rgSCHCmnDlAllocTxRbTM2
27046  *     Purpose:
27047  *
27048  *               Reference Parameter effBo is filled with alloced bytes.
27049  *               Returns RFAILED if BO not satisfied at all.
27050  *
27051  *     Invoked by: rgSCHCmnDlAllocTxRb
27052  *
27053  *  @param[in]  RgSchCellCb           *cell
27054  *  @param[in]  RgSchDlSf             *subFrm
27055  *  @param[in]  RgSchUeCb             *ue
27056  *  @param[in]  U32                   bo
27057  *  @param[out] U32                   *effBo
27058  *  @param[in]  RgSchDlHqProcCb       *proc
27059  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27060  *  @return Void
27061  *
27062  **/
27063 #ifdef ANSI
27064 PRIVATE Void rgSCHCmnDlAllocTxRbTM2
27065 (
27066 RgSchCellCb                *cell,
27067 RgSchDlSf                  *subFrm,
27068 RgSchUeCb                  *ue,
27069 U32                        bo,
27070 U32                        *effBo,
27071 RgSchDlHqProcCb            *proc,
27072 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27073 )
27074 #else
27075 PRIVATE Void rgSCHCmnDlAllocTxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27076 RgSchCellCb                *cell;
27077 RgSchDlSf                  *subFrm;
27078 RgSchUeCb                  *ue;
27079 U32                        bo;
27080 U32                        *effBo;
27081 RgSchDlHqProcCb            *proc;
27082 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27083 #endif
27084 {
27085    TRC2(rgSCHCmnDlAllocTxRbTM2);
27086    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
27087    RETVOID;
27088 }
27089
27090 \f
27091 /**
27092  * @brief This function determines the RBs and Bytes required for BO
27093  *        retransmission for UEs configured with TM 2.
27094  *
27095  * @details
27096  *
27097  *     Function: rgSCHCmnDlAllocRetxRbTM2
27098  *     Purpose:
27099  *
27100  *               Reference Parameter effBo is filled with alloced bytes.
27101  *               Returns RFAILED if BO not satisfied at all.
27102  *
27103  *     Invoked by: rgSCHCmnDlAllocRetxRb
27104  *
27105  *  @param[in]  RgSchCellCb           *cell
27106  *  @param[in]  RgSchDlSf             *subFrm
27107  *  @param[in]  RgSchUeCb             *ue
27108  *  @param[in]  U32                   bo
27109  *  @param[out] U32                   *effBo
27110  *  @param[in]  RgSchDlHqProcCb       *proc
27111  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27112  *  @return Void
27113  *
27114  **/
27115 #ifdef ANSI
27116 PRIVATE Void rgSCHCmnDlAllocRetxRbTM2
27117 (
27118 RgSchCellCb                *cell,
27119 RgSchDlSf                  *subFrm,
27120 RgSchUeCb                  *ue,
27121 U32                        bo,
27122 U32                        *effBo,
27123 RgSchDlHqProcCb            *proc,
27124 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27125 )
27126 #else
27127 PRIVATE Void rgSCHCmnDlAllocRetxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27128 RgSchCellCb                *cell;
27129 RgSchDlSf                  *subFrm;
27130 RgSchUeCb                  *ue;
27131 U32                        bo;
27132 U32                        *effBo;
27133 RgSchDlHqProcCb            *proc;
27134 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27135 #endif
27136 {
27137    TRC2(rgSCHCmnDlAllocRetxRbTM2);
27138    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
27139    RETVOID;
27140 }
27141
27142 \f
27143 /**
27144  * @brief This function determines the RBs and Bytes required for BO
27145  *        transmission for UEs configured with TM 3.
27146  *
27147  * @details
27148  *
27149  *     Function: rgSCHCmnDlAllocTxRbTM3
27150  *     Purpose:
27151  *
27152  *               Reference Parameter effBo is filled with alloced bytes.
27153  *               Returns RFAILED if BO not satisfied at all.
27154  *
27155  *     Invoked by: rgSCHCmnDlAllocTxRb
27156  *
27157  *  @param[in]  RgSchCellCb           *cell
27158  *  @param[in]  RgSchDlSf             *subFrm
27159  *  @param[in]  RgSchUeCb             *ue
27160  *  @param[in]  U32                   bo
27161  *  @param[out] U32                   *effBo
27162  *  @param[in]  RgSchDlHqProcCb       *proc
27163  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27164  *  @return Void
27165  *
27166  **/
27167 #ifdef ANSI
27168 PRIVATE Void rgSCHCmnDlAllocTxRbTM3
27169 (
27170 RgSchCellCb                *cell,
27171 RgSchDlSf                  *subFrm,
27172 RgSchUeCb                  *ue,
27173 U32                        bo,
27174 U32                        *effBo,
27175 RgSchDlHqProcCb            *proc,
27176 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27177 )
27178 #else
27179 PRIVATE Void rgSCHCmnDlAllocTxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27180 RgSchCellCb                *cell;
27181 RgSchDlSf                  *subFrm;
27182 RgSchUeCb                  *ue;
27183 U32                        bo;
27184 U32                        *effBo;
27185 RgSchDlHqProcCb            *proc;
27186 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27187 #endif
27188 {
27189
27190    TRC2(rgSCHCmnDlAllocTxRbTM3);
27191
27192    /* Both TBs free for TX allocation */
27193    rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo,\
27194          proc, cellWdAllocInfo);
27195
27196    RETVOID;
27197 }
27198
27199 \f
27200 /**
27201  * @brief This function determines the RBs and Bytes required for BO
27202  *        retransmission for UEs configured with TM 3.
27203  *
27204  * @details
27205  *
27206  *     Function: rgSCHCmnDlAllocRetxRbTM3
27207  *     Purpose:
27208  *
27209  *               Reference Parameter effBo is filled with alloced bytes.
27210  *               Returns RFAILED if BO not satisfied at all.
27211  *
27212  *     Invoked by: rgSCHCmnDlAllocRetxRb
27213  *
27214  *  @param[in]  RgSchCellCb           *cell
27215  *  @param[in]  RgSchDlSf             *subFrm
27216  *  @param[in]  RgSchUeCb             *ue
27217  *  @param[in]  U32                   bo
27218  *  @param[out] U32                   *effBo
27219  *  @param[in]  RgSchDlHqProcCb       *proc
27220  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27221  *  @return Void
27222  *
27223  **/
27224 #ifdef ANSI
27225 PRIVATE Void rgSCHCmnDlAllocRetxRbTM3
27226 (
27227 RgSchCellCb                *cell,
27228 RgSchDlSf                  *subFrm,
27229 RgSchUeCb                  *ue,
27230 U32                        bo,
27231 U32                        *effBo,
27232 RgSchDlHqProcCb            *proc,
27233 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27234 )
27235 #else
27236 PRIVATE Void rgSCHCmnDlAllocRetxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27237 RgSchCellCb                *cell;
27238 RgSchDlSf                  *subFrm;
27239 RgSchUeCb                  *ue;
27240 U32                        bo;
27241 U32                        *effBo;
27242 RgSchDlHqProcCb            *proc;
27243 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27244 #endif
27245 {
27246
27247    TRC2(rgSCHCmnDlAllocRetxRbTM3);
27248
27249    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
27250          (proc->tbInfo[1].state == HQ_TB_NACKED))
27251    {
27252 #ifdef LAA_DBG_LOG
27253       printf ("RETX RB TM3 nack for both hqp %d cell %d \n", proc->procId, proc->hqE->cell->cellId);
27254 #endif
27255       /* Both TBs require RETX allocation */
27256       rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo,\
27257             proc, cellWdAllocInfo);
27258    }
27259    else
27260    {
27261       /* One of the TBs need RETX allocation. Other TB may/maynot
27262        * be available for new TX allocation. */
27263       rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo,\
27264             proc, cellWdAllocInfo);
27265    }
27266
27267    RETVOID;
27268 }
27269
27270 \f
27271 /**
27272  * @brief This function performs the DCI format selection in case of
27273  *        Transmit Diversity scheme where there can be more
27274  *        than 1 option for DCI format selection.
27275  *
27276  * @details
27277  *
27278  *     Function: rgSCHCmnSlctPdcchFrmt
27279  *     Purpose:  1. If DLFS is enabled, then choose TM specific
27280  *                  DCI format for Transmit diversity. All the
27281  *                  TM Specific DCI Formats support Type0 and/or
27282  *                  Type1 resource allocation scheme. DLFS
27283  *                  supports only Type-0&1 Resource allocation.
27284  *               2. If DLFS is not enabled, select a DCI format
27285  *                  which is of smaller size. Since Non-DLFS
27286  *                  scheduler supports all Resource allocation
27287  *                  schemes, selection is based on efficiency.
27288  *
27289  *     Invoked by: DL UE Allocation by Common Scheduler.
27290  *
27291  *  @param[in]  RgSchCellCb      *cell
27292  *  @param[in]  RgSchUeCb        *ue
27293  *  @param[out] U8               *raType
27294  *  @return  TfuDciFormat
27295  *
27296  **/
27297 #ifdef ANSI
27298 PUBLIC TfuDciFormat rgSCHCmnSlctPdcchFrmt
27299 (
27300 RgSchCellCb                *cell,
27301 RgSchUeCb                  *ue,
27302 U8                         *raType
27303 )
27304 #else
27305 PUBLIC TfuDciFormat rgSCHCmnSlctPdcchFrmt(cell, ue, raType)
27306 RgSchCellCb                *cell;
27307 RgSchUeCb                  *ue;
27308 U8                         *raType;
27309 #endif
27310 {
27311    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
27312
27313    TRC2(rgSCHCmnSlctPdcchFrmt);
27314
27315    /* ccpu00140894- Selective DCI Format and RA type should be selected only 
27316     * after TX Mode transition is completed*/
27317    if ((cellSch->dl.isDlFreqSel) && (ue->txModeTransCmplt))
27318    {
27319       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciRAType;
27320       RETVALUE(rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciFrmt);
27321    }
27322    else
27323    {
27324       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciRAType;
27325       RETVALUE(rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciFrmt);
27326    }
27327 }
27328
27329 \f
27330 /**
27331  * @brief This function handles Retx allocation in case of TM3 UEs
27332  *        where both the TBs were NACKED previously.
27333  *
27334  * @details
27335  *
27336  *     Function: rgSCHCmnDlTM3RetxRetx
27337  *     Purpose:  If forceTD flag enabled
27338  *                  TD for TB1 on CW1.
27339  *               Else
27340  *                  DCI Frmt 2A and RA Type 0
27341  *                  RI layered SM of both TBs on 2 CWs
27342  *               Add UE to cell Alloc Info.
27343  *               Fill UE alloc Info.
27344  *
27345  *
27346  *               Successful allocation is indicated by non-zero effBo value.
27347  *
27348  *     Invoked by: rgSCHCmnDlAllocRbTM3
27349  *
27350  *  @param[in]  RgSchCellCb           *cell
27351  *  @param[in]  RgSchDlSf             *subFrm
27352  *  @param[in]  RgSchUeCb             *ue
27353  *  @param[in]  U32                   bo
27354  *  @param[out] U32                   *effBo
27355  *  @param[in]  RgSchDlHqProcCb       *proc
27356  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27357  *  @return  Void
27358  *
27359  **/
27360 #ifdef ANSI
27361 PRIVATE Void rgSCHCmnDlTM3RetxRetx
27362 (
27363 RgSchCellCb                *cell,
27364 RgSchDlSf                  *subFrm,
27365 RgSchUeCb                  *ue,
27366 U32                        bo,
27367 U32                        *effBo,
27368 RgSchDlHqProcCb            *proc,
27369 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27370 )
27371 #else
27372 PRIVATE Void rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27373 RgSchCellCb                *cell;
27374 RgSchDlSf                  *subFrm;
27375 RgSchUeCb                  *ue;
27376 U32                        bo;
27377 U32                        *effBo;
27378 RgSchDlHqProcCb            *proc;
27379 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27380 #endif
27381 {
27382    S16           ret;
27383    RgSchDlRbAlloc *allocInfo;
27384    U8            numRb;
27385    Bool          swpFlg;
27386    U8            precInfo;
27387    U8            noTxLyrs;
27388    U8            precInfoAntIdx;
27389
27390    TRC2(rgSCHCmnDlTM3RetxRetx);
27391
27392    ret = ROK;
27393    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
27394    swpFlg = FALSE;
27395 /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
27396    {
27397       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
27398       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
27399
27400       ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
27401             effBo);
27402       if (ret == RFAILED)
27403       {
27404          /* Allocation couldn't be made for Retx */
27405          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
27406          RETVOID;
27407       }
27408       /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
27409       noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
27410 #ifdef FOUR_TX_ANTENNA
27411       /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 should
27412        * have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
27413       if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
27414       {
27415          swpFlg = TRUE;
27416          proc->cwSwpEnabled = TRUE;
27417       }
27418 #endif
27419       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27420       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
27421    }
27422
27423 #ifdef LTEMAC_SPS
27424    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
27425 #endif
27426    {
27427       /* Adding UE to allocInfo RETX Lst */
27428       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
27429    }
27430    /* Fill UE alloc Info scratch pad */
27431    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
27432          precInfo, noTxLyrs, subFrm);
27433
27434    RETVOID;
27435 }
27436
27437 \f
27438 /**
27439  * @brief This function handles Retx allocation in case of TM4 UEs
27440  *        where both the TBs were NACKED previously.
27441  *
27442  * @details
27443  *
27444  *     Function: rgSCHCmnDlTM4RetxRetx
27445  *     Purpose:  If forceTD flag enabled
27446  *                  TD for TB1 on CW1.
27447  *               Else
27448  *                  DCI Frmt 2 and RA Type 0
27449  *                  If RI == 1
27450  *                     1 layer SM of TB1 on CW1.
27451  *                  Else
27452  *                     RI layered SM of both TBs on 2 CWs
27453  *               Add UE to cell Alloc Info.
27454  *               Fill UE alloc Info.
27455  *
27456  *
27457  *               Successful allocation is indicated by non-zero effBo value.
27458  *
27459  *     Invoked by: rgSCHCmnDlAllocRbTM4
27460  *
27461  *  @param[in]  RgSchCellCb           *cell
27462  *  @param[in]  RgSchDlSf             *subFrm
27463  *  @param[in]  RgSchUeCb             *ue
27464  *  @param[in]  U32                   bo
27465  *  @param[out] U32                   *effBo
27466  *  @param[in]  RgSchDlHqProcCb       *proc
27467  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27468  *  @return  Void
27469  *
27470  **/
27471 #ifdef ANSI
27472 PRIVATE Void rgSCHCmnDlTM4RetxRetx
27473 (
27474 RgSchCellCb                *cell,
27475 RgSchDlSf                  *subFrm,
27476 RgSchUeCb                  *ue,
27477 U32                        bo,
27478 U32                        *effBo,
27479 RgSchDlHqProcCb            *proc,
27480 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27481 )
27482 #else
27483 PRIVATE Void rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27484 RgSchCellCb                *cell;
27485 RgSchDlSf                  *subFrm;
27486 RgSchUeCb                  *ue;
27487 U32                        bo;
27488 U32                        *effBo;
27489 RgSchDlHqProcCb            *proc;
27490 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27491 #endif
27492 {
27493    S16            ret;
27494    RgSchDlRbAlloc *allocInfo;
27495    U8             numRb;
27496    Bool           swpFlg = FALSE;
27497    U8             precInfo;
27498 #ifdef FOUR_TX_ANTENNA
27499    U8             precInfoAntIdx;
27500 #endif
27501    U8             noTxLyrs;
27502
27503    TRC2(rgSCHCmnDlTM4RetxRetx);
27504
27505    ret = ROK;
27506    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
27507                        
27508    /* Irrespective of RI Schedule both CWs */
27509    allocInfo->dciFormat = TFU_DCI_FORMAT_2;
27510    allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
27511
27512    ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
27513          effBo);
27514    if (ret == RFAILED)
27515    {
27516       /* Allocation couldn't be made for Retx */
27517       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
27518       RETVOID;
27519    }
27520    noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
27521    precInfo = 0; 
27522 #ifdef FOUR_TX_ANTENNA
27523    /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1
27524     * should have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
27525    if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
27526    {
27527       swpFlg = TRUE;
27528       proc->cwSwpEnabled = TRUE;
27529 }
27530 precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27531 precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
27532 #endif
27533
27534 #ifdef LTEMAC_SPS
27535    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
27536 #endif
27537    {
27538       /* Adding UE to allocInfo RETX Lst */
27539       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
27540    }
27541    /* Fill UE alloc Info scratch pad */
27542    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
27543          precInfo, noTxLyrs, subFrm);
27544
27545    RETVOID;
27546 }
27547
27548
27549 \f
27550 /**
27551  * @brief This function determines Transmission attributes
27552  *        incase of Spatial multiplexing for TX and RETX TBs.
27553  *
27554  * @details
27555  *
27556  *     Function: rgSCHCmnDlSMGetAttrForTxRetx
27557  *     Purpose:  1. Reached here for a TM3/4 UE's HqP whose one of the TBs is
27558  *                  NACKED and the other TB is either NACKED or WAITING.
27559  *               2. Select the NACKED TB for RETX allocation.
27560  *               3. Allocation preference for RETX TB by mapping it to a better
27561  *                  CW (better in terms of efficiency).
27562  *               4. Determine the state of the other TB.
27563  *                  Determine if swapFlag were to be set.
27564  *                  Swap flag would be set if Retx TB is cross
27565  *                  mapped to a CW.
27566  *               5. If UE has new data available for TX and if the other TB's state
27567  *                  is ACKED then set furtherScope as TRUE.
27568  *
27569  *     Invoked by: rgSCHCmnDlTM3[4]TxRetx
27570  *
27571  *  @param[in]  RgSchUeCb        *ue
27572  *  @param[in]  RgSchDlHqProcCb  *proc
27573  *  @param[out] RgSchDlHqTbCb    **retxTb
27574  *  @param[out] RgSchDlHqTbCb    **txTb
27575  *  @param[out] Bool             *frthrScp
27576  *  @param[out] Bool             *swpFlg
27577  *  @return  Void
27578  *
27579  **/
27580 #ifdef ANSI
27581 PRIVATE Void rgSCHCmnDlSMGetAttrForTxRetx
27582 (
27583 RgSchUeCb                  *ue,
27584 RgSchDlHqProcCb            *proc,
27585 RgSchDlHqTbCb              **retxTb,
27586 RgSchDlHqTbCb              **txTb,
27587 Bool                       *frthrScp,
27588 Bool                       *swpFlg
27589 )
27590 #else
27591 PRIVATE Void rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, frthrScp,\
27592         swpFlg)
27593 RgSchUeCb                  *ue;
27594 RgSchDlHqProcCb            *proc;
27595 RgSchDlHqTbCb              **retxTb;
27596 RgSchDlHqTbCb              **txTb;
27597 Bool                       *frthrScp;
27598 Bool                       *swpFlg;
27599 #endif
27600 {
27601    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,proc->hqE->cell);
27602    RgSchDlRbAlloc  *allocInfo;
27603
27604    TRC2(rgSCHCmnDlSMGetAttrForTxRetx);
27605
27606    if (proc->tbInfo[0].state == HQ_TB_NACKED)
27607    {
27608       *retxTb = &proc->tbInfo[0];
27609       *txTb = &proc->tbInfo[1];
27610       /* TENB_BRDCM_TM4- Currently disabling swapflag for TM3/TM4, since 
27611        * HqFeedback processing does not consider a swapped hq feedback */
27612       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 1))
27613       {
27614          *swpFlg = TRUE;
27615          proc->cwSwpEnabled = TRUE;
27616       }
27617       if (proc->tbInfo[1].state == HQ_TB_ACKED)
27618       {
27619          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
27620          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
27621       }
27622    }
27623    else
27624    {
27625       *retxTb = &proc->tbInfo[1];
27626       *txTb = &proc->tbInfo[0];
27627       /* TENB_BRDCM_TM4 - Currently disabling swapflag for TM3/TM4, since 
27628        * HqFeedback processing does not consider a swapped hq feedback */
27629       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 0))
27630       {
27631          *swpFlg = TRUE;
27632          proc->cwSwpEnabled = TRUE;
27633       }
27634       if (proc->tbInfo[0].state == HQ_TB_ACKED)
27635       {
27636          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
27637          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
27638       }
27639    }
27640    RETVOID;
27641 }
27642
27643 \f
27644 /**
27645  * @brief Determine Precoding information for TM3 2 TX Antenna.
27646  *
27647  * @details
27648  *
27649  *     Function: rgSCHCmnDlTM3PrecInf2
27650  *     Purpose:
27651  *
27652  *     Invoked by: rgSCHCmnDlGetAttrForTM3
27653  *
27654  *  @param[in]  RgSchUeCb        *ue
27655  *  @param[in]  U8               numTxLyrs
27656  *  @param[in]  Bool             bothCwEnbld
27657  *  @return  U8
27658  *
27659  **/
27660 #ifdef ANSI
27661 PRIVATE U8 rgSCHCmnDlTM3PrecInf2
27662 (
27663 RgSchCellCb                *cell,
27664 RgSchUeCb                  *ue,
27665 U8                         numTxLyrs,
27666 Bool                       bothCwEnbld
27667 )
27668 #else
27669 PRIVATE U8 rgSCHCmnDlTM3PrecInf2(ue, numTxLyrs, bothCwEnbld)
27670 RgSchCellCb                *cell;
27671 RgSchUeCb                  *ue;
27672 U8                         numTxLyrs;
27673 Bool                       bothCwEnbld;
27674 #endif
27675 {
27676    TRC2(rgSCHCmnDlTM3PrecInf2);
27677
27678    RETVALUE(0);
27679 }
27680
27681 \f
27682 /**
27683  * @brief Determine Precoding information for TM4 2 TX Antenna.
27684  *
27685  * @details
27686  *
27687  *     Function: rgSCHCmnDlTM4PrecInf2
27688  *     Purpose:  To determine a logic of deriving precoding index
27689  *               information from 36.212 table 5.3.3.1.5-4
27690  *
27691  *     Invoked by: rgSCHCmnDlGetAttrForTM4
27692  *
27693  *  @param[in]  RgSchUeCb        *ue
27694  *  @param[in]  U8               numTxLyrs
27695  *  @param[in]  Bool             bothCwEnbld
27696  *  @return  U8
27697  *
27698  **/
27699 #ifdef ANSI
27700 PRIVATE U8 rgSCHCmnDlTM4PrecInf2
27701 (
27702 RgSchCellCb                *cell,
27703 RgSchUeCb                  *ue,
27704 U8                         numTxLyrs,
27705 Bool                       bothCwEnbld
27706 )
27707 #else
27708 PRIVATE U8 rgSCHCmnDlTM4PrecInf2(ue, numTxLyrs, bothCwEnbld)
27709 RgSchCellCb                *cell;
27710 RgSchUeCb                  *ue;
27711 U8                         numTxLyrs;
27712 Bool                       bothCwEnbld;
27713 #endif
27714 {
27715    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27716    U8            precIdx;
27717
27718    TRC2(rgSCHCmnDlTM4PrecInf2);
27719
27720    if (ueDl->mimoInfo.ri == numTxLyrs)
27721    {
27722       if (ueDl->mimoInfo.ri == 2)
27723       {
27724          /* PrecInfo corresponding to 2 CW
27725            Transmission */
27726          if (ue->mimoInfo.puschFdbkVld)
27727          {
27728             precIdx = 2;
27729          }
27730          else 
27731          {
27732             precIdx = ueDl->mimoInfo.pmi - 1;
27733          }
27734       }
27735       else
27736       {
27737          /* PrecInfo corresponding to 1 CW
27738           * Transmission */
27739          if (ue->mimoInfo.puschFdbkVld)
27740          {
27741             precIdx =  5;
27742          }
27743          else
27744          {
27745             precIdx =  ueDl->mimoInfo.pmi + 1;
27746          }
27747       }
27748    }
27749    else if (ueDl->mimoInfo.ri > numTxLyrs)
27750    {
27751       /* In case of choosing among the columns of a
27752        * precoding matrix, choose the column corresponding
27753        * to the MAX-CQI */
27754       if (ue->mimoInfo.puschFdbkVld)
27755       {
27756          precIdx = 5;
27757       }
27758       else
27759       {
27760          precIdx = (ueDl->mimoInfo.pmi- 1)* 2  + 1;
27761       }
27762    }
27763    else /* if RI < numTxLyrs */
27764    {
27765       precIdx = (ueDl->mimoInfo.pmi < 2)? 0:1;
27766    }
27767    RETVALUE(precIdx);
27768 }
27769
27770 \f
27771 /**
27772  * @brief Determine Precoding information for TM3 4 TX Antenna.
27773  *
27774  * @details
27775  *
27776  *     Function: rgSCHCmnDlTM3PrecInf4
27777  *     Purpose:  To determine a logic of deriving precoding index
27778  *               information from 36.212 table 5.3.3.1.5A-2
27779  *
27780  *     Invoked by: rgSCHCmnDlGetAttrForTM3
27781  *
27782  *  @param[in]  RgSchUeCb        *ue
27783  *  @param[in]  U8               numTxLyrs
27784  *  @param[in]  Bool             bothCwEnbld
27785  *  @return  U8
27786  *
27787  **/
27788 #ifdef ANSI
27789 PRIVATE U8 rgSCHCmnDlTM3PrecInf4
27790 (
27791 RgSchCellCb                *cell,
27792 RgSchUeCb                  *ue,
27793 U8                         numTxLyrs,
27794 Bool                       bothCwEnbld
27795 )
27796 #else
27797 PRIVATE U8 rgSCHCmnDlTM3PrecInf4(ue, numTxLyrs, bothCwEnbld)
27798 RgSchCellCb                *cell;
27799 RgSchUeCb                  *ue;
27800 U8                         numTxLyrs;
27801 Bool                       bothCwEnbld;
27802 #endif
27803 {
27804    U8            precIdx;
27805
27806    TRC2(rgSCHCmnDlTM3PrecInf4);
27807
27808    if (bothCwEnbld)
27809    {
27810       precIdx = numTxLyrs - 2;
27811    }
27812    else /* one 1 CW transmission */
27813    {
27814       precIdx = 1;
27815    }
27816    RETVALUE(precIdx);
27817 }
27818
27819 \f
27820 /**
27821  * @brief Determine Precoding information for TM4 4 TX Antenna.
27822  *
27823  * @details
27824  *
27825  *     Function: rgSCHCmnDlTM4PrecInf4
27826  *     Purpose:  To determine a logic of deriving precoding index
27827  *               information from 36.212 table 5.3.3.1.5-5
27828  *
27829  *     Invoked by: rgSCHCmnDlGetAttrForTM4
27830  *
27831  *  @param[in]  RgSchUeCb        *ue
27832  *  @param[in]  U8               numTxLyrs
27833  *  @param[in]  Bool             bothCwEnbld
27834  *  @return  U8
27835  *
27836  **/
27837 #ifdef ANSI
27838 PRIVATE U8 rgSCHCmnDlTM4PrecInf4
27839 (
27840 RgSchCellCb                *cell,
27841 RgSchUeCb                  *ue,
27842 U8                         numTxLyrs,
27843 Bool                       bothCwEnbld
27844 )
27845 #else
27846 PRIVATE U8 rgSCHCmnDlTM4PrecInf4(cell, ue, numTxLyrs, bothCwEnbld)
27847 RgSchCellCb                *cell;
27848 RgSchUeCb                  *ue;
27849 U8                         numTxLyrs;
27850 Bool                       bothCwEnbld;
27851 #endif
27852 {
27853    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27854    U8            precInfoBaseIdx, precIdx;
27855
27856    TRC2(rgSCHCmnDlTM4PrecInf4);
27857
27858    precInfoBaseIdx  = (ue->mimoInfo.puschFdbkVld)? (16):
27859       (ueDl->mimoInfo.pmi);
27860    if (bothCwEnbld)
27861    {
27862       precIdx = precInfoBaseIdx + (numTxLyrs-2)*17;
27863    }
27864    else /* one 1 CW transmission */
27865    {
27866       precInfoBaseIdx += 1;
27867       precIdx = precInfoBaseIdx + (numTxLyrs-1)*17;
27868    }
27869    RETVALUE(precIdx);
27870 }
27871
27872 \f
27873 /**
27874  * @brief This function determines Transmission attributes
27875  *        incase of TM3 scheduling.
27876  *
27877  * @details
27878  *
27879  *     Function: rgSCHCmnDlGetAttrForTM3
27880  *     Purpose:  Determine retx TB and tx TB based on TB states.
27881  *               If forceTD enabled
27882  *                  perform only retx TB allocation.
27883  *                  If retxTB == TB2 then DCI Frmt = 2A, RA Type = 0.
27884  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
27885  *               If RI == 1
27886  *                  perform retxTB allocation on CW1.
27887  *               Else if RI > 1
27888  *                  Determine further Scope and Swap Flag attributes
27889  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
27890  *                  If no further scope for new TX allocation
27891  *                     Allocate only retx TB using 2 layers if
27892  *                     this TB was previously transmitted using 2 layers AND
27893  *                     number of Tx antenna ports == 4.
27894  *                     otherwise do single layer precoding.
27895  *
27896  *     Invoked by: rgSCHCmnDlTM3TxRetx
27897  *
27898  *  @param[in]  RgSchUeCb        *ue
27899  *  @param[in]  RgSchDlHqProcCb  *proc
27900  *  @param[out] U8               *numTxLyrs
27901  *  @param[out] Bool             *isTraDiv
27902  *  @param[out] U8               *prcdngInf
27903  *  @param[out] U8               *raType
27904  *  @return  Void
27905  *
27906  **/
27907 #ifdef ANSI
27908 PRIVATE Void rgSCHCmnDlGetAttrForTM3
27909 (
27910 RgSchCellCb                *cell,
27911 RgSchUeCb                  *ue,
27912 RgSchDlHqProcCb            *proc,
27913 U8                         *numTxLyrs,
27914 TfuDciFormat               *dciFrmt,
27915 U8                         *prcdngInf,
27916 RgSchDlHqTbCb              **retxTb,
27917 RgSchDlHqTbCb              **txTb,
27918 Bool                       *frthrScp,
27919 Bool                       *swpFlg,
27920 U8                         *raType
27921 )
27922 #else
27923 PRIVATE Void rgSCHCmnDlGetAttrForTM3(cell, ue, proc, numTxLyrs, dciFrmt,\
27924         prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType)
27925 RgSchCellCb                *cell;
27926 RgSchUeCb                  *ue;
27927 RgSchDlHqProcCb            *proc;
27928 U8                         *numTxLyrs;
27929 TfuDciFormat               *dciFrmt;
27930 U8                         *prcdngInf;
27931 RgSchDlHqTbCb              **retxTb;
27932 RgSchDlHqTbCb              **txTb;
27933 Bool                       *frthrScp;
27934 Bool                       *swpFlg;
27935 U8                         *raType;
27936 #endif
27937 {
27938    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27939    U8            precInfoAntIdx;
27940
27941    TRC2(rgSCHCmnDlGetAttrForTM3);
27942
27943    /* Avoiding Tx-Retx for LAA cell as firstSchedTime is associated with 
27944       HQP */
27945    /* Integration_fix: SPS Proc shall always have only one Cw */
27946 #ifdef LTEMAC_SPS
27947    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
27948          (ueDl->mimoInfo.forceTD)) 
27949 #ifdef LTE_ADV
27950      ||(TRUE == rgSCHLaaSCellEnabled(cell))
27951 #endif
27952       )
27953 #else
27954    if ((ueDl->mimoInfo.forceTD) 
27955 #ifdef LTE_ADV
27956        || (TRUE == rgSCHLaaSCellEnabled(cell))
27957 #endif
27958       )
27959 #endif
27960    {
27961       /* Transmit Diversity. Format based on dlfsEnabled
27962        * No further scope */
27963       if (proc->tbInfo[0].state == HQ_TB_NACKED)
27964       {
27965          *retxTb = &proc->tbInfo[0];
27966          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
27967       }
27968       else
27969       {
27970          *retxTb = &proc->tbInfo[1];
27971          *dciFrmt = TFU_DCI_FORMAT_2A;
27972          *raType = RG_SCH_CMN_RA_TYPE0;
27973       }
27974       *numTxLyrs = 1;
27975       *frthrScp = FALSE;
27976       *prcdngInf = 0;
27977       RETVOID;
27978    }
27979
27980    /* Determine the 2 TB transmission attributes */
27981    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
27982          frthrScp, swpFlg);
27983    if (*frthrScp)
27984    {
27985       /* Prefer allocation of RETX TB over 2 layers rather than combining
27986        * it with a new TX. */
27987       if ((ueDl->mimoInfo.ri == 2)
27988             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
27989       {
27990          /* Allocate TB on CW1, using 2 Lyrs,
27991           * Format 2, precoding accordingly */
27992          *numTxLyrs = 2;
27993          *frthrScp = FALSE;
27994       }
27995       else
27996       {
27997          *numTxLyrs=  ((*retxTb)->numLyrs + ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)].noLyr);
27998
27999          if((*retxTb)->tbIdx == 0 && ((*retxTb)->numLyrs == 2 ) && *numTxLyrs ==3)
28000          {
28001             *swpFlg = TRUE;
28002             proc->cwSwpEnabled = TRUE;
28003          }
28004          else if((*retxTb)->tbIdx == 1 && ((*retxTb)->numLyrs == 1) && *numTxLyrs ==3)
28005          {
28006             *swpFlg = TRUE;
28007             proc->cwSwpEnabled = TRUE;
28008          }
28009       }
28010
28011       precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
28012       *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])\
28013                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
28014       *dciFrmt = TFU_DCI_FORMAT_2A;
28015       *raType = RG_SCH_CMN_RA_TYPE0;
28016    }
28017    else /* frthrScp == FALSE */
28018    {
28019       if (cell->numTxAntPorts == 2)
28020       {
28021          /*  Transmit Diversity  */
28022          *numTxLyrs = 1;
28023          if ((*retxTb)->tbIdx == 0)
28024          {
28025             *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
28026          }
28027          else
28028          {
28029             /* If retxTB is TB2 then use format 2A */
28030             *dciFrmt = TFU_DCI_FORMAT_2A;
28031             *raType = RG_SCH_CMN_RA_TYPE0;
28032          }
28033          *prcdngInf = 0;
28034          RETVOID;
28035       }
28036       else /* NumAntPorts == 4 */
28037       {
28038          if ((*retxTb)->numLyrs == 2)
28039          {
28040             /* Allocate TB on CW1, using 2 Lyrs,
28041              * Format 2A, precoding accordingly */
28042             *numTxLyrs = 2;
28043             *dciFrmt = TFU_DCI_FORMAT_2A;
28044             *raType = RG_SCH_CMN_RA_TYPE0;
28045             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28046             *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, *numTxLyrs, *frthrScp);
28047             RETVOID;
28048          }
28049          else
28050          {
28051             /*  Transmit Diversity  */
28052             *numTxLyrs = 1;
28053             if ((*retxTb)->tbIdx == 0)
28054             {
28055                *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
28056             }
28057             else
28058             {
28059                /* If retxTB is TB2 then use format 2A */
28060                *dciFrmt = TFU_DCI_FORMAT_2A;
28061                *raType = RG_SCH_CMN_RA_TYPE0;
28062             }
28063             *prcdngInf = 0;
28064             RETVOID;
28065          }
28066       }
28067    }
28068
28069    RETVOID;
28070 }
28071
28072
28073 \f
28074 /**
28075  * @brief This function determines Transmission attributes
28076  *        incase of TM4 scheduling.
28077  *
28078  * @details
28079  *
28080  *     Function: rgSCHCmnDlGetAttrForTM4
28081  *     Purpose:  Determine retx TB and tx TB based on TB states.
28082  *               If forceTD enabled
28083  *                  perform only retx TB allocation.
28084  *                  If retxTB == TB2 then DCI Frmt = 2, RA Type = 0.
28085  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
28086  *               If RI == 1
28087  *                  perform retxTB allocation on CW1.
28088  *               Else if RI > 1
28089  *                  Determine further Scope and Swap Flag attributes
28090  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
28091  *                  If no further scope for new TX allocation
28092  *                     Allocate only retx TB using 2 layers if
28093  *                     this TB was previously transmitted using 2 layers AND
28094  *                     number of Tx antenna ports == 4.
28095  *                     otherwise do single layer precoding.
28096  *
28097  *     Invoked by: rgSCHCmnDlTM4TxRetx
28098  *
28099  *  @param[in]  RgSchUeCb        *ue
28100  *  @param[in]  RgSchDlHqProcCb  *proc
28101  *  @param[out] U8               *numTxLyrs
28102  *  @param[out] Bool             *isTraDiv
28103  *  @param[out] U8               *prcdngInf
28104  *  @param[out] U8               *raType
28105  *  @return  Void
28106  *
28107  **/
28108 #ifdef ANSI
28109 PRIVATE Void rgSCHCmnDlGetAttrForTM4
28110 (
28111 RgSchCellCb                *cell,
28112 RgSchUeCb                  *ue,
28113 RgSchDlHqProcCb            *proc,
28114 U8                         *numTxLyrs,
28115 TfuDciFormat               *dciFrmt,
28116 U8                         *prcdngInf,
28117 RgSchDlHqTbCb              **retxTb,
28118 RgSchDlHqTbCb              **txTb,
28119 Bool                       *frthrScp,
28120 Bool                       *swpFlg,
28121 U8                         *raType
28122 )
28123 #else
28124 PRIVATE Void rgSCHCmnDlGetAttrForTM4(cell, ue, proc, numTxLyrs, dciFrmt,\
28125         prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType)
28126 RgSchCellCb                *cell;
28127 RgSchUeCb                  *ue;
28128 RgSchDlHqProcCb            *proc;
28129 U8                         *numTxLyrs;
28130 TfuDciFormat               *dciFrmt;
28131 U8                         *prcdngInf;
28132 RgSchDlHqTbCb              **retxTb;
28133 RgSchDlHqTbCb              **txTb;
28134 Bool                       *frthrScp;
28135 Bool                       *swpFlg;
28136 U8                         *raType;
28137 #endif
28138 {
28139    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
28140    U8 precInfoAntIdx;
28141
28142    TRC2(rgSCHCmnDlGetAttrForTM4);
28143
28144    *frthrScp = FALSE;
28145    /* Integration_fix: SPS Proc shall always have only one Cw */
28146 #ifdef LTEMAC_SPS
28147    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28148          (ueDl->mimoInfo.forceTD)) 
28149 #ifdef LTE_ADV
28150      ||(TRUE == rgSCHLaaSCellEnabled(cell))
28151 #endif
28152       )
28153 #else
28154    if ((ueDl->mimoInfo.forceTD) 
28155 #ifdef LTE_ADV
28156        || (TRUE == rgSCHLaaSCellEnabled(cell))
28157 #endif
28158       )
28159 #endif
28160    {
28161       /* Transmit Diversity. Format based on dlfsEnabled
28162        * No further scope */
28163       if (proc->tbInfo[0].state == HQ_TB_NACKED)
28164       {
28165          *retxTb = &proc->tbInfo[0];
28166          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
28167       }
28168       else
28169       {
28170          *retxTb = &proc->tbInfo[1];
28171          *dciFrmt = TFU_DCI_FORMAT_2;
28172          *raType = RG_SCH_CMN_RA_TYPE0;
28173       }
28174       *numTxLyrs = 1;
28175       *frthrScp = FALSE;
28176       *prcdngInf = 0;
28177       RETVOID;
28178    }
28179
28180    if (ueDl->mimoInfo.ri == 1)
28181    {
28182       /* single layer precoding. Format 2.
28183        * No further scope */
28184       if (proc->tbInfo[0].state == HQ_TB_NACKED)
28185       {
28186          *retxTb = &proc->tbInfo[0];
28187       }
28188       else
28189       {
28190          *retxTb = &proc->tbInfo[1];
28191       }
28192       *numTxLyrs = 1;
28193       *dciFrmt = TFU_DCI_FORMAT_2;
28194       *raType = RG_SCH_CMN_RA_TYPE0;
28195       *frthrScp = FALSE;
28196       *prcdngInf = 0; /*When RI= 1*/
28197       RETVOID;
28198    }
28199
28200    /* Determine the 2 TB transmission attributes */
28201    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
28202          frthrScp, swpFlg);
28203    *dciFrmt = TFU_DCI_FORMAT_2;
28204    *raType = RG_SCH_CMN_RA_TYPE0;
28205    if (*frthrScp)
28206    {
28207       /* Prefer allocation of RETX TB over 2 layers rather than combining
28208        * it with a new TX. */
28209       if ((ueDl->mimoInfo.ri == 2)
28210             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
28211       {
28212          /* Allocate TB on CW1, using 2 Lyrs,
28213           * Format 2, precoding accordingly */
28214          *numTxLyrs = 2;
28215          *frthrScp = FALSE;
28216       }
28217       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28218       *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])
28219                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
28220    }
28221    else /* frthrScp == FALSE */
28222    {
28223       if (cell->numTxAntPorts == 2)
28224       {
28225          /* single layer precoding. Format 2. */
28226          *numTxLyrs = 1;
28227          *prcdngInf = (getPrecInfoFunc[1][cell->numTxAntPorts/2 - 1])\
28228                       (cell, ue, *numTxLyrs, *frthrScp);
28229          RETVOID;
28230       }
28231       else /* NumAntPorts == 4 */
28232       {
28233          if ((*retxTb)->numLyrs == 2)
28234          {
28235             /* Allocate TB on CW1, using 2 Lyrs,
28236              * Format 2, precoding accordingly */
28237             *numTxLyrs = 2;
28238             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28239             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
28240                          (cell, ue, *numTxLyrs, *frthrScp);
28241             RETVOID;
28242          }
28243          else
28244          {
28245             /* Allocate TB with 1 lyr precoding,
28246              * Format 2, precoding info accordingly */
28247             *numTxLyrs = 1;
28248             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28249             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
28250                          (cell, ue, *numTxLyrs, *frthrScp);
28251             RETVOID;
28252          }
28253       }
28254    }
28255
28256    RETVOID;
28257 }
28258
28259 \f
28260 /**
28261  * @brief This function handles Retx allocation in case of TM3 UEs
28262  *        where previously one of the TBs was NACKED and the other
28263  *        TB is either ACKED/WAITING.
28264  *
28265  * @details
28266  *
28267  *     Function: rgSCHCmnDlTM3TxRetx
28268  *     Purpose:  Determine the TX attributes for TM3 TxRetx Allocation.
28269  *               If futher Scope for New Tx Allocation on other TB
28270  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
28271  *                  Add UE to cell wide RetxTx List.
28272  *               Else
28273  *                  Perform only RETX alloc'n on CW1.
28274  *                  Add UE to cell wide Retx List.
28275  *
28276  *               effBo is set to a non-zero value if allocation is
28277  *               successful.
28278  *
28279  *     Invoked by: rgSCHCmnDlAllocRbTM3
28280  *
28281  *  @param[in]  RgSchCellCb           *cell
28282  *  @param[in]  RgSchDlSf             *subFrm
28283  *  @param[in]  RgSchUeCb             *ue
28284  *  @param[in]  U32                   bo
28285  *  @param[out] U32                   *effBo
28286  *  @param[in]  RgSchDlHqProcCb       *proc
28287  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28288  *  @return  Void
28289  *
28290  **/
28291 #ifdef ANSI
28292 PRIVATE Void rgSCHCmnDlTM3TxRetx
28293 (
28294 RgSchCellCb                *cell,
28295 RgSchDlSf                  *subFrm,
28296 RgSchUeCb                  *ue,
28297 U32                        bo,
28298 U32                        *effBo,
28299 RgSchDlHqProcCb            *proc,
28300 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28301 )
28302 #else
28303 PRIVATE Void rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28304 RgSchCellCb                *cell;
28305 RgSchDlSf                  *subFrm;
28306 RgSchUeCb                  *ue;
28307 U32                        bo;
28308 U32                        *effBo;
28309 RgSchDlHqProcCb            *proc;
28310 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28311 #endif
28312 {
28313    S16              ret;
28314    RgSchDlRbAlloc   *allocInfo;
28315    U8               numRb;
28316    RgSchDlHqTbCb    *retxTb, *txTb;
28317    Bool             frthrScp;
28318    Bool             swpFlg;
28319    U8               prcdngInf;
28320    U8               numTxLyrs;
28321
28322    TRC2(rgSCHCmnDlTM3TxRetx);
28323    frthrScp = FALSE;
28324
28325    ret = ROK;
28326    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28327    swpFlg = FALSE;
28328
28329    /* Determine the transmission attributes */
28330    rgSCHCmnDlGetAttrForTM3(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
28331          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
28332          &allocInfo->raType);
28333
28334    if (frthrScp)
28335    {
28336 #ifdef LAA_DBG_LOG
28337       printf ("TX RETX called from proc %d cell %d \n",proc->procId, cell->cellId);
28338 #endif
28339       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
28340             &numRb, effBo);
28341       if (ret == RFAILED)
28342       {
28343          /* Allocation couldn't be made for Retx */
28344          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28345          RETVOID;
28346       }
28347       /* Adding UE to RbAllocInfo RETX-TX Lst */
28348       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
28349    }
28350    else
28351    {
28352       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
28353             numTxLyrs, &numRb, effBo);
28354       if (ret == RFAILED)
28355       {
28356          /* Allocation couldn't be made for Retx */
28357          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28358          RETVOID;
28359       }
28360 #ifdef LTEMAC_SPS
28361       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28362 #endif
28363       {
28364          /* Adding UE to allocInfo RETX Lst */
28365          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
28366       }
28367    }
28368    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
28369          prcdngInf, numTxLyrs, subFrm);
28370
28371    RETVOID;
28372 }
28373
28374 \f
28375 /**
28376  * @brief This function handles Retx allocation in case of TM4 UEs
28377  *        where previously one of the TBs was NACKED and the other
28378  *        TB is either ACKED/WAITING.
28379  *
28380  * @details
28381  *
28382  *     Function: rgSCHCmnDlTM4TxRetx
28383  *     Purpose:  Determine the TX attributes for TM4 TxRetx Allocation.
28384  *               If futher Scope for New Tx Allocation on other TB
28385  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
28386  *                  Add UE to cell wide RetxTx List.
28387  *               Else
28388  *                  Perform only RETX alloc'n on CW1.
28389  *                  Add UE to cell wide Retx List.
28390  *
28391  *               effBo is set to a non-zero value if allocation is
28392  *               successful.
28393  *
28394  *     Invoked by: rgSCHCmnDlAllocRbTM4
28395  *
28396  *  @param[in]  RgSchCellCb           *cell
28397  *  @param[in]  RgSchDlSf             *subFrm
28398  *  @param[in]  RgSchUeCb             *ue
28399  *  @param[in]  U32                   bo
28400  *  @param[out] U32                   *effBo
28401  *  @param[in]  RgSchDlHqProcCb       *proc
28402  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28403  *  @return  Void
28404  *
28405  **/
28406 #ifdef ANSI
28407 PRIVATE Void rgSCHCmnDlTM4TxRetx
28408 (
28409 RgSchCellCb                *cell,
28410 RgSchDlSf                  *subFrm,
28411 RgSchUeCb                  *ue,
28412 U32                        bo,
28413 U32                        *effBo,
28414 RgSchDlHqProcCb            *proc,
28415 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28416 )
28417 #else
28418 PRIVATE Void rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28419 RgSchCellCb                *cell;
28420 RgSchDlSf                  *subFrm;
28421 RgSchUeCb                  *ue;
28422 U32                        bo;
28423 U32                        *effBo;
28424 RgSchDlHqProcCb            *proc;
28425 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28426 #endif
28427 {
28428    S16              ret;
28429    RgSchDlRbAlloc   *allocInfo;
28430    U8               numRb;
28431    RgSchDlHqTbCb    *retxTb, *txTb;
28432    Bool             frthrScp;
28433    Bool             swpFlg;
28434    U8               prcdngInf;
28435    U8               numTxLyrs;
28436
28437    TRC2(rgSCHCmnDlTM4TxRetx);
28438
28439    ret = ROK;
28440    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28441    swpFlg = FALSE;
28442
28443    /* Determine the transmission attributes */
28444    rgSCHCmnDlGetAttrForTM4(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
28445          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
28446          &allocInfo->raType);
28447
28448    if (frthrScp)
28449    {
28450       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
28451             &numRb, effBo);
28452       if (ret == RFAILED)
28453       {
28454          /* Fix : syed If TxRetx allocation failed then add the UE along 
28455           * with the proc to the nonSchdTxRetxUeLst and let spfc scheduler
28456           *  take care of it during finalization. */       
28457          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28458          RETVOID;
28459       }
28460       /* Adding UE to RbAllocInfo RETX-TX Lst */
28461       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
28462    }
28463    else
28464    {
28465       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
28466             numTxLyrs, &numRb, effBo);
28467       if (ret == RFAILED)
28468       {
28469          /* Allocation couldn't be made for Retx */
28470          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28471          RETVOID;
28472       }
28473 #ifdef LTEMAC_SPS
28474       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28475 #endif
28476       {
28477          /* Adding UE to allocInfo RETX Lst */
28478          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
28479       }
28480    }
28481    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
28482          prcdngInf, numTxLyrs, subFrm)
28483
28484       RETVOID;
28485 }
28486
28487 \f
28488 /**
28489  * @brief This function handles Retx allocation in case of TM4 UEs
28490  *        where previously both the TBs were ACKED and ACKED
28491  *        respectively.
28492  *
28493  * @details
28494  *
28495  *     Function: rgSCHCmnDlTM3TxTx
28496  *     Purpose:  Reached here for a TM3 UE's HqP's fresh allocation
28497  *                  where both the TBs are free for TX scheduling.
28498  *               If forceTD flag is set
28499  *                  perform TD on CW1 with TB1.
28500  *                  precInfo = 0
28501  *               else
28502  *                  DCI Format = 2A.
28503  *                  RA Type = Type0.
28504  *                  RI layered precoding 2 TB on 2 CW.
28505  *                  Set precoding info.
28506  *               Add UE to cellAllocInfo.
28507  *               Fill ueAllocInfo.
28508  *
28509  *              effBo is set to a non-zero value if allocation is
28510  *              successful.
28511  *
28512  *     Invoked by: rgSCHCmnDlAllocRbTM3
28513  *
28514  *  @param[in]  RgSchCellCb           *cell
28515  *  @param[in]  RgSchDlSf             *subFrm
28516  *  @param[in]  RgSchUeCb             *ue
28517  *  @param[in]  U32                   bo
28518  *  @param[out] U32                   *effBo
28519  *  @param[in]  RgSchDlHqProcCb       *proc
28520  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28521  *  @return  Void
28522  *
28523  **/
28524 #ifdef ANSI
28525 PRIVATE Void rgSCHCmnDlTM3TxTx
28526 (
28527 RgSchCellCb                *cell,
28528 RgSchDlSf                  *subFrm,
28529 RgSchUeCb                  *ue,
28530 U32                        bo,
28531 U32                        *effBo,
28532 RgSchDlHqProcCb            *proc,
28533 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28534 )
28535 #else
28536 PRIVATE Void rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28537 RgSchCellCb                *cell;
28538 RgSchDlSf                  *subFrm;
28539 RgSchUeCb                  *ue;
28540 U32                        bo;
28541 U32                        *effBo;
28542 RgSchDlHqProcCb            *proc;
28543 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28544 #endif
28545 {
28546    RgSchCmnDlUe     *ueDl;
28547    RgSchDlRbAlloc   *allocInfo;
28548    U8               numRb;
28549    U8               noTxLyrs;
28550    U8               precInfo;
28551    S16              ret;
28552    U8               precInfoAntIdx;
28553
28554    TRC2(rgSCHCmnDlTM3TxTx);
28555
28556    ret = ROK;
28557    ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
28558    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28559
28560    /* Integration_fix: SPS Proc shall always have only one Cw */
28561 #ifdef LTEMAC_SPS
28562 #ifdef FOUR_TX_ANTENNA
28563       if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28564                      (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
28565 #else
28566    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28567          (ueDl->mimoInfo.forceTD))
28568 #endif
28569 #else
28570    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
28571 #endif
28572    {
28573       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
28574             &allocInfo->raType);
28575       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28576             bo, &numRb, effBo);
28577       if (ret == RFAILED)
28578       {
28579          /* If allocation couldn't be made then return */
28580          RETVOID;
28581       }
28582       noTxLyrs = 1;
28583       precInfo = 0; /* TD */
28584    }
28585    else /* Precoding */
28586    {
28587       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
28588       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
28589
28590       /* Spatial Multiplexing using 2 CWs */
28591       ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
28592       if (ret == RFAILED)
28593       {
28594          /* If allocation couldn't be made then return */
28595          RETVOID;
28596       }
28597       noTxLyrs = ueDl->mimoInfo.ri;
28598       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28599       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, getPrecInfoFunc[0], precInfoAntIdx);
28600       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
28601    }
28602
28603 #ifdef LTEMAC_SPS
28604    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28605 #endif
28606    {
28607       /* Adding UE to RbAllocInfo TX Lst */
28608       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
28609    }
28610    /* Fill UE allocInfo scrath pad */
28611    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
28612          precInfo, noTxLyrs, subFrm);
28613
28614    RETVOID;
28615 }
28616
28617 \f
28618 /**
28619  * @brief This function handles Retx allocation in case of TM4 UEs
28620  *        where previously both the TBs were ACKED and ACKED
28621  *        respectively.
28622  *
28623  * @details
28624  *
28625  *     Function: rgSCHCmnDlTM4TxTx
28626  *     Purpose:  Reached here for a TM4 UE's HqP's fresh allocation
28627  *                  where both the TBs are free for TX scheduling.
28628  *               If forceTD flag is set
28629  *                  perform TD on CW1 with TB1.
28630  *                  precInfo = 0
28631  *               else
28632  *                  DCI Format = 2.
28633  *                  RA Type = Type0.
28634  *                  If Rank == 1
28635  *                     Single layer precoding of TB1 on CW1.
28636  *                     Set precoding info.
28637  *                  else
28638  *                     RI layered precoding 2 TB on 2 CW.
28639  *                     Set precoding info.
28640  *               Add UE to cellAllocInfo.
28641  *               Fill ueAllocInfo.
28642  *
28643  *              effBo is set to a non-zero value if allocation is
28644  *              successful.
28645  *
28646  *     Invoked by: rgSCHCmnDlAllocRbTM4
28647  *
28648  *  @param[in]  RgSchCellCb           *cell
28649  *  @param[in]  RgSchDlSf             *subFrm
28650  *  @param[in]  RgSchUeCb             *ue
28651  *  @param[in]  U32                   bo
28652  *  @param[out] U32                   *effBo
28653  *  @param[in]  RgSchDlHqProcCb       *proc
28654  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28655  *  @return  Void
28656  *
28657  **/
28658 #ifdef ANSI
28659 PRIVATE Void rgSCHCmnDlTM4TxTx
28660 (
28661 RgSchCellCb                *cell,
28662 RgSchDlSf                  *subFrm,
28663 RgSchUeCb                  *ue,
28664 U32                        bo,
28665 U32                        *effBo,
28666 RgSchDlHqProcCb            *proc,
28667 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28668 )
28669 #else
28670 PRIVATE Void rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28671 RgSchCellCb                *cell;
28672 RgSchDlSf                  *subFrm;
28673 RgSchUeCb                  *ue;
28674 U32                        bo;
28675 U32                        *effBo;
28676 RgSchDlHqProcCb            *proc;
28677 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28678 #endif
28679 {
28680    RgSchCmnDlUe     *ueDl;
28681    RgSchDlRbAlloc   *allocInfo;
28682    U8               numRb;
28683    U8               precInfo;
28684    U8               noTxLyrs;
28685    U8               precInfoAntIdx;
28686    S16              ret;
28687
28688    TRC2(rgSCHCmnDlTM4TxTx);
28689
28690    ret       = ROK;
28691    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
28692    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28693
28694    /* Integration_fix: SPS Proc shall always have only one Cw */
28695 #ifdef LTEMAC_SPS
28696 #ifdef FOUR_TX_ANTENNA
28697    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28698                   (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
28699 #else
28700    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28701          (ueDl->mimoInfo.forceTD))
28702 #endif
28703 #else
28704    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
28705 #endif
28706    {
28707       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
28708             &allocInfo->raType);
28709
28710       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28711             bo, &numRb, effBo);
28712       if (ret == RFAILED)
28713       {
28714          /* If allocation couldn't be made then return */
28715          RETVOID;
28716       }
28717       noTxLyrs = 1;
28718       precInfo = 0; /* TD */
28719    }
28720    else /* Precoding */
28721    {
28722       allocInfo->dciFormat = TFU_DCI_FORMAT_2;
28723       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
28724
28725       if (ueDl->mimoInfo.ri == 1)
28726       {
28727          /* Single Layer SM using FORMAT 2 */
28728          ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28729                bo, &numRb, effBo);
28730          if (ret == RFAILED)
28731          {
28732             /* If allocation couldn't be made then return */
28733             RETVOID;
28734          }
28735          noTxLyrs = 1;
28736          precInfo = 0; /* PrecInfo as 0 for RI=1*/
28737       }
28738       else
28739       {
28740          /* Spatial Multiplexing using 2 CWs */
28741          ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
28742          if (ret == RFAILED)
28743          {
28744             /* If allocation couldn't be made then return */
28745             RETVOID;
28746          }
28747          noTxLyrs = ueDl->mimoInfo.ri;
28748          precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
28749          precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
28750       }
28751    }
28752
28753    
28754 #ifdef LTEMAC_SPS
28755    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28756 #endif
28757    {
28758       /* Adding UE to RbAllocInfo TX Lst */
28759       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
28760    }
28761
28762    /* Fill UE allocInfo scrath pad */
28763    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
28764          precInfo, noTxLyrs, subFrm);
28765
28766    RETVOID;
28767 }
28768
28769 \f
28770 /**
28771  * @brief This function determines the RBs and Bytes required for BO
28772  *        transmission for UEs configured with TM 4.
28773  *
28774  * @details
28775  *
28776  *     Function: rgSCHCmnDlAllocTxRbTM4
28777  *     Purpose:  Invokes the functionality particular to the
28778  *               current state of the TBs of the "proc".
28779  *
28780  *               Reference Parameter effBo is filled with alloced bytes.
28781  *               Returns RFAILED if BO not satisfied at all.
28782  *
28783  *     Invoked by: rgSCHCmnDlAllocTxRb
28784  *
28785  *  @param[in]  RgSchCellCb           *cell
28786  *  @param[in]  RgSchDlSf             *subFrm
28787  *  @param[in]  RgSchUeCb             *ue
28788  *  @param[in]  U32                   bo
28789  *  @param[out] U32                   *effBo
28790  *  @param[in]  RgSchDlHqProcCb       *proc
28791  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28792  *  @return  Void
28793  *
28794  **/
28795 #ifdef ANSI
28796 PRIVATE Void rgSCHCmnDlAllocTxRbTM4
28797 (
28798 RgSchCellCb                *cell,
28799 RgSchDlSf                  *subFrm,
28800 RgSchUeCb                  *ue,
28801 U32                        bo,
28802 U32                        *effBo,
28803 RgSchDlHqProcCb            *proc,
28804 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28805 )
28806 #else
28807 PRIVATE Void rgSCHCmnDlAllocTxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28808 RgSchCellCb                *cell;
28809 RgSchDlSf                  *subFrm;
28810 RgSchUeCb                  *ue;
28811 U32                        bo;
28812 U32                        *effBo;
28813 RgSchDlHqProcCb            *proc;
28814 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28815 #endif
28816 {
28817    TRC2(rgSCHCmnDlAllocTxRbTM4);
28818
28819    /* Both TBs free for TX allocation */
28820    rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo,\
28821          proc, cellWdAllocInfo);
28822
28823    RETVOID;
28824 }
28825
28826 \f
28827 /**
28828  * @brief This function determines the RBs and Bytes required for BO
28829  *        retransmission for UEs configured with TM 4.
28830  *
28831  * @details
28832  *
28833  *     Function: rgSCHCmnDlAllocRetxRbTM4
28834  *     Purpose:  Invokes the functionality particular to the
28835  *               current state of the TBs of the "proc".
28836  *
28837  *               Reference Parameter effBo is filled with alloced bytes.
28838  *               Returns RFAILED if BO not satisfied at all.
28839  *
28840  *     Invoked by: rgSCHCmnDlAllocRetxRb
28841  *
28842  *  @param[in]  RgSchCellCb           *cell
28843  *  @param[in]  RgSchDlSf             *subFrm
28844  *  @param[in]  RgSchUeCb             *ue
28845  *  @param[in]  U32                   bo
28846  *  @param[out] U32                   *effBo
28847  *  @param[in]  RgSchDlHqProcCb       *proc
28848  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28849  *  @return  Void
28850  *
28851  **/
28852 #ifdef ANSI
28853 PRIVATE Void rgSCHCmnDlAllocRetxRbTM4
28854 (
28855 RgSchCellCb                *cell,
28856 RgSchDlSf                  *subFrm,
28857 RgSchUeCb                  *ue,
28858 U32                        bo,
28859 U32                        *effBo,
28860 RgSchDlHqProcCb            *proc,
28861 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28862 )
28863 #else
28864 PRIVATE Void rgSCHCmnDlAllocRetxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28865 RgSchCellCb                *cell;
28866 RgSchDlSf                  *subFrm;
28867 RgSchUeCb                  *ue;
28868 U32                        bo;
28869 U32                        *effBo;
28870 RgSchDlHqProcCb            *proc;
28871 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28872 #endif
28873 {
28874    TRC2(rgSCHCmnDlAllocRetxRbTM4);
28875
28876    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
28877          (proc->tbInfo[1].state == HQ_TB_NACKED))
28878    {
28879       /* Both TBs require RETX allocation */
28880       rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo,\
28881             proc, cellWdAllocInfo);
28882    }
28883    else
28884    {
28885       /* One of the TBs need RETX allocation. Other TB may/maynot
28886        * be available for new TX allocation. */
28887       rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo,\
28888             proc, cellWdAllocInfo);
28889    }
28890
28891    RETVOID;
28892 }
28893
28894 #ifdef RG_UNUSED
28895 \f
28896 /**
28897  * @brief This function determines the RBs and Bytes required for BO
28898  *        transmission for UEs configured with TM 5.
28899  *
28900  * @details
28901  *
28902  *     Function: rgSCHCmnDlAllocTxRbTM5
28903  *     Purpose:
28904  *
28905  *               Reference Parameter effBo is filled with alloced bytes.
28906  *               Returns RFAILED if BO not satisfied at all.
28907  *
28908  *     Invoked by: rgSCHCmnDlAllocTxRb
28909  *
28910  *  @param[in]  RgSchCellCb           *cell
28911  *  @param[in]  RgSchDlSf             *subFrm
28912  *  @param[in]  RgSchUeCb             *ue
28913  *  @param[in]  U32                   bo
28914  *  @param[out] U32                   *effBo
28915  *  @param[in]  RgSchDlHqProcCb       *proc
28916  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28917  *  @return Void
28918  *
28919  **/
28920 #ifdef ANSI
28921 PRIVATE Void rgSCHCmnDlAllocTxRbTM5
28922 (
28923 RgSchCellCb                *cell,
28924 RgSchDlSf                  *subFrm,
28925 RgSchUeCb                  *ue,
28926 U32                        bo,
28927 U32                        *effBo,
28928 RgSchDlHqProcCb            *proc,
28929 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28930 )
28931 #else
28932 PRIVATE Void rgSCHCmnDlAllocTxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28933 RgSchCellCb                *cell;
28934 RgSchDlSf                  *subFrm;
28935 RgSchUeCb                  *ue;
28936 U32                        bo;
28937 U32                        *effBo;
28938 RgSchDlHqProcCb            *proc;
28939 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28940 #endif
28941 {
28942    TRC2(rgSCHCmnDlAllocTxRbTM5);
28943 #if (ERRCLASS & ERRCLS_DEBUG)
28944    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId);
28945 #endif
28946    RETVOID;
28947 }
28948
28949 \f
28950 /**
28951  * @brief This function determines the RBs and Bytes required for BO
28952  *        retransmission for UEs configured with TM 5.
28953  *
28954  * @details
28955  *
28956  *     Function: rgSCHCmnDlAllocRetxRbTM5
28957  *     Purpose:
28958  *
28959  *               Reference Parameter effBo is filled with alloced bytes.
28960  *               Returns RFAILED if BO not satisfied at all.
28961  *
28962  *     Invoked by: rgSCHCmnDlAllocRetxRb
28963  *
28964  *  @param[in]  RgSchCellCb           *cell
28965  *  @param[in]  RgSchDlSf             *subFrm
28966  *  @param[in]  RgSchUeCb             *ue
28967  *  @param[in]  U32                   bo
28968  *  @param[out] U32                   *effBo
28969  *  @param[in]  RgSchDlHqProcCb       *proc
28970  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28971  *  @return Void
28972  *
28973  **/
28974 #ifdef ANSI
28975 PRIVATE Void rgSCHCmnDlAllocRetxRbTM5
28976 (
28977 RgSchCellCb                *cell,
28978 RgSchDlSf                  *subFrm,
28979 RgSchUeCb                  *ue,
28980 U32                        bo,
28981 U32                        *effBo,
28982 RgSchDlHqProcCb            *proc,
28983 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28984 )
28985 #else
28986 PRIVATE Void rgSCHCmnDlAllocRetxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28987 RgSchCellCb                *cell;
28988 RgSchDlSf                  *subFrm;
28989 RgSchUeCb                  *ue;
28990 U32                        bo;
28991 U32                        *effBo;
28992 RgSchDlHqProcCb            *proc;
28993 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28994 #endif
28995 {
28996    TRC2(rgSCHCmnDlAllocRetxRbTM5);
28997 #if (ERRCLASS & ERRCLS_DEBUG)
28998    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId);
28999 #endif
29000    RETVOID;
29001 }
29002 #endif
29003
29004 \f
29005 /**
29006  * @brief This function determines the RBs and Bytes required for BO
29007  *        transmission for UEs configured with TM 6.
29008  *
29009  * @details
29010  *
29011  *     Function: rgSCHCmnDlAllocTxRbTM6
29012  *     Purpose:
29013  *
29014  *               Reference Parameter effBo is filled with alloced bytes.
29015  *               Returns RFAILED if BO not satisfied at all.
29016  *
29017  *     Invoked by: rgSCHCmnDlAllocTxRb
29018  *
29019  *  @param[in]  RgSchCellCb           *cell
29020  *  @param[in]  RgSchDlSf             *subFrm
29021  *  @param[in]  RgSchUeCb             *ue
29022  *  @param[in]  U32                   bo
29023  *  @param[out] U32                   *effBo
29024  *  @param[in]  RgSchDlHqProcCb       *proc
29025  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29026  *  @return Void
29027  *
29028  **/
29029 #ifdef ANSI
29030 PRIVATE Void rgSCHCmnDlAllocTxRbTM6
29031 (
29032 RgSchCellCb                *cell,
29033 RgSchDlSf                  *subFrm,
29034 RgSchUeCb                  *ue,
29035 U32                        bo,
29036 U32                        *effBo,
29037 RgSchDlHqProcCb            *proc,
29038 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29039 )
29040 #else
29041 PRIVATE Void rgSCHCmnDlAllocTxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29042 RgSchCellCb                *cell;
29043 RgSchDlSf                  *subFrm;
29044 RgSchUeCb                  *ue;
29045 U32                        bo;
29046 U32                        *effBo;
29047 RgSchDlHqProcCb            *proc;
29048 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29049 #endif
29050 {
29051    RgSchDlRbAlloc *allocInfo;
29052    RgSchCmnDlUe   *ueDl;
29053    S16            ret;
29054    U8             numRb;
29055
29056    TRC2(rgSCHCmnDlAllocTxRbTM6);
29057
29058    ret       = ROK;
29059    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29060    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29061
29062    if (ueDl->mimoInfo.forceTD)
29063    {
29064       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
29065       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
29066    }
29067    else
29068    {
29069       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
29070       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
29071       /* Fill precoding information for FORMAT 1B */
29072       /* First 4 least significant bits to indicate PMI.
29073        * 4th most significant corresponds to pmi Confirmation.
29074        */
29075       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
29076       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
29077    }
29078    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
29079          bo, &numRb, effBo);
29080    if (ret == RFAILED)
29081    {
29082       /* If allocation couldn't be made then return */
29083       RETVOID;
29084    }
29085    
29086 #ifdef LTEMAC_SPS
29087    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
29088 #endif
29089    {
29090       /* Adding UE to RbAllocInfo TX Lst */
29091       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
29092    }
29093    /* Fill UE alloc Info */
29094    allocInfo->rbsReq = numRb;
29095    allocInfo->dlSf   = subFrm;
29096    RETVOID;
29097 }
29098
29099 \f
29100 /**
29101  * @brief This function determines the RBs and Bytes required for BO
29102  *        retransmission for UEs configured with TM 6.
29103  *
29104  * @details
29105  *
29106  *     Function: rgSCHCmnDlAllocRetxRbTM6
29107  *     Purpose:
29108  *
29109  *               Reference Parameter effBo is filled with alloced bytes.
29110  *               Returns RFAILED if BO not satisfied at all.
29111  *
29112  *     Invoked by: rgSCHCmnDlAllocRetxRb
29113  *
29114  *  @param[in]  RgSchCellCb           *cell
29115  *  @param[in]  RgSchDlSf             *subFrm
29116  *  @param[in]  RgSchUeCb             *ue
29117  *  @param[in]  U32                   bo
29118  *  @param[out] U32                   *effBo
29119  *  @param[in]  RgSchDlHqProcCb       *proc
29120  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29121  *  @return Void
29122  *
29123  **/
29124 #ifdef ANSI
29125 PRIVATE Void rgSCHCmnDlAllocRetxRbTM6
29126 (
29127 RgSchCellCb                *cell,
29128 RgSchDlSf                  *subFrm,
29129 RgSchUeCb                  *ue,
29130 U32                        bo,
29131 U32                        *effBo,
29132 RgSchDlHqProcCb            *proc,
29133 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29134 )
29135 #else
29136 PRIVATE Void rgSCHCmnDlAllocRetxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29137 RgSchCellCb                *cell;
29138 RgSchDlSf                  *subFrm;
29139 RgSchUeCb                  *ue;
29140 U32                        bo;
29141 U32                        *effBo;
29142 RgSchDlHqProcCb            *proc;
29143 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29144 #endif
29145 {
29146    RgSchDlRbAlloc *allocInfo;
29147    RgSchCmnDlUe   *ueDl;
29148    S16            ret;
29149    U8             numRb;
29150
29151    TRC2(rgSCHCmnDlAllocRetxRbTM6);
29152
29153    ret       = ROK;
29154    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29155    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29156
29157    if (ueDl->mimoInfo.forceTD)
29158    {
29159       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
29160       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
29161    }
29162    else
29163    {
29164       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
29165       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
29166       /* Fill precoding information for FORMAT 1B */
29167       /* First 4 least significant bits to indicate PMI.
29168        * 4th most significant corresponds to pmi Confirmation.
29169        */
29170       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
29171       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
29172    }
29173
29174    /* Get the Allocation in terms of RBs that are required for
29175     * this retx of TB1 */
29176    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
29177          1, &numRb, effBo);
29178    if (ret == RFAILED)
29179    {
29180       /* Allocation couldn't be made for Retx */
29181       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
29182       RETVOID;
29183    }
29184    /* Adding UE to allocInfo RETX Lst */
29185    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
29186    /* Fill UE alloc Info */
29187    allocInfo->rbsReq = numRb;
29188    allocInfo->dlSf   = subFrm;
29189    RETVOID;
29190 }
29191
29192 \f
29193 /**
29194  * @brief This function determines the RBs and Bytes required for BO
29195  *        transmission for UEs configured with TM 7.
29196  *
29197  * @details
29198  *
29199  *     Function: rgSCHCmnDlAllocTxRbTM7
29200  *     Purpose:
29201  *
29202  *               Reference Parameter effBo is filled with alloced bytes.
29203  *               Returns RFAILED if BO not satisfied at all.
29204  *
29205  *     Invoked by: rgSCHCmnDlAllocTxRb
29206  *
29207  *  @param[in]  RgSchCellCb           *cell
29208  *  @param[in]  RgSchDlSf             *subFrm
29209  *  @param[in]  RgSchUeCb             *ue
29210  *  @param[in]  U32                   bo
29211  *  @param[out] U32                   *effBo
29212  *  @param[in]  RgSchDlHqProcCb       *proc
29213  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29214  *  @return Void
29215  *
29216  **/
29217 #ifdef ANSI
29218 PRIVATE Void rgSCHCmnDlAllocTxRbTM7
29219 (
29220 RgSchCellCb                *cell,
29221 RgSchDlSf                  *subFrm,
29222 RgSchUeCb                  *ue,
29223 U32                        bo,
29224 U32                        *effBo,
29225 RgSchDlHqProcCb            *proc,
29226 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29227 )
29228 #else
29229 PRIVATE Void rgSCHCmnDlAllocTxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29230 RgSchCellCb                *cell;
29231 RgSchDlSf                  *subFrm;
29232 RgSchUeCb                  *ue;
29233 U32                        bo;
29234 U32                        *effBo;
29235 RgSchDlHqProcCb            *proc;
29236 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29237 #endif
29238 {
29239    TRC2(rgSCHCmnDlAllocTxRbTM7);
29240    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
29241    RETVOID;
29242 }
29243
29244 \f
29245 /**
29246  * @brief This function determines the RBs and Bytes required for BO
29247  *        retransmission for UEs configured with TM 7.
29248  *
29249  * @details
29250  *
29251  *     Function: rgSCHCmnDlAllocRetxRbTM7
29252  *     Purpose:
29253  *
29254  *               Reference Parameter effBo is filled with alloced bytes.
29255  *               Returns RFAILED if BO not satisfied at all.
29256  *
29257  *     Invoked by: rgSCHCmnDlAllocRetxRb
29258  *
29259  *  @param[in]  RgSchCellCb           *cell
29260  *  @param[in]  RgSchDlSf             *subFrm
29261  *  @param[in]  RgSchUeCb             *ue
29262  *  @param[in]  U32                   bo
29263  *  @param[out] U32                   *effBo
29264  *  @param[in]  RgSchDlHqProcCb       *proc
29265  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29266  *  @return Void
29267  *
29268  **/
29269 #ifdef ANSI
29270 PRIVATE Void rgSCHCmnDlAllocRetxRbTM7
29271 (
29272 RgSchCellCb                *cell,
29273 RgSchDlSf                  *subFrm,
29274 RgSchUeCb                  *ue,
29275 U32                        bo,
29276 U32                        *effBo,
29277 RgSchDlHqProcCb            *proc,
29278 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29279 )
29280 #else
29281 PRIVATE Void rgSCHCmnDlAllocRetxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29282 RgSchCellCb                *cell;
29283 RgSchDlSf                  *subFrm;
29284 RgSchUeCb                  *ue;
29285 U32                        bo;
29286 U32                        *effBo;
29287 RgSchDlHqProcCb            *proc;
29288 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29289 #endif
29290 {
29291    TRC2(rgSCHCmnDlAllocRetxRbTM7);
29292    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
29293    RETVOID;
29294 }
29295
29296 \f
29297 /**
29298  * @brief This function invokes the TM specific DL TX RB Allocation routine.
29299  *
29300  * @details
29301  *
29302  *     Function: rgSCHCmnDlAllocTxRb
29303  *     Purpose:  This function invokes the TM specific
29304  *               DL TX RB Allocation routine.
29305  *
29306  *     Invoked by: Specific Schedulers
29307  *
29308  *  @param[in]  RgSchCellCb           *cell
29309  *  @param[in]  RgSchDlSf             *subFrm
29310  *  @param[in]  RgSchUeCb             *ue
29311  *  @param[in]  U32                   bo
29312  *  @param[out] U32                   *effBo
29313  *  @param[in]  RgSchDlHqProcCb       *proc
29314  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29315  *  @return  S16
29316  *
29317  **/
29318 #ifdef ANSI
29319 PUBLIC S16 rgSCHCmnDlAllocTxRb
29320 (
29321 RgSchCellCb                *cell,
29322 RgSchDlSf                  *subFrm,
29323 RgSchUeCb                  *ue,
29324 U32                        bo,
29325 U32                        *effBo,
29326 RgSchDlHqProcCb            *proc,
29327 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29328 )
29329 #else
29330 PUBLIC S16 rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29331 RgSchCellCb                *cell;
29332 RgSchDlSf                  *subFrm;
29333 RgSchUeCb                  *ue;
29334 U32                        bo;
29335 U32                        *effBo;
29336 RgSchDlHqProcCb            *proc;
29337 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29338 #endif
29339 {
29340    U32                     newSchBits = 0;
29341    U32                     prevSchBits = 0;
29342    RgSchDlRbAlloc          *allocInfo;
29343
29344    TRC2(rgSCHCmnDlAllocTxRb);
29345
29346    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
29347    {
29348       ue->dl.aggTbBits = 0;
29349    }
29350    *effBo = 0;
29351
29352    /* Calculate totals bits previously allocated */
29353    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29354    if (allocInfo->tbInfo[0].schdlngForTb)
29355    {
29356       prevSchBits += allocInfo->tbInfo[0].bytesReq;
29357    }
29358    if (allocInfo->tbInfo[1].schdlngForTb)
29359    {
29360       prevSchBits += allocInfo->tbInfo[1].bytesReq;
29361    }
29362
29363    /* Call TM specific RB allocation routine */
29364    (dlAllocTxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
29365          proc, cellWdAllocInfo);
29366
29367    if (*effBo)
29368    {
29369       /* Calculate totals bits newly allocated */
29370       if (allocInfo->tbInfo[0].schdlngForTb)
29371       {
29372          newSchBits += allocInfo->tbInfo[0].bytesReq;
29373       }
29374       if (allocInfo->tbInfo[1].schdlngForTb)
29375       {
29376          newSchBits += allocInfo->tbInfo[1].bytesReq;
29377       }
29378       if (newSchBits > prevSchBits)
29379       {
29380          ue->dl.aggTbBits += ((newSchBits - prevSchBits) * 8);
29381          RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
29382       }
29383    }
29384
29385    RETVALUE(ROK);
29386 }
29387
29388 /* DwPTS Scheduling Changes Start */
29389 #ifdef LTE_TDD
29390 /**
29391  * @brief Retransmit decision for TDD. Retx is avoided in below cases
29392  *        1) DL Sf       -> Spl Sf
29393  *        2) DL SF       -> DL SF 0 
29394  *
29395  * @details
29396  *
29397  *     Function: rgSCHCmnRetxAvoidTdd 
29398  *     Purpose: Avoid allocating RETX for cases 1, 2 
29399  * 
29400  *     Invoked by: rgSCHCmnRetxAvoidTdd 
29401  *
29402  *  @param[in]  RgSchDlSf             *curSf
29403  *  @param[in]  RgSchCellCb           *cell
29404  *  @param[in]  RgSchDlHqProcCb       *proc
29405  *  @return  Bool 
29406  *
29407  **/
29408 #ifdef ANSI
29409 PUBLIC Bool rgSCHCmnRetxAvoidTdd 
29410 (
29411 RgSchDlSf                  *curSf,
29412 RgSchCellCb                *cell,
29413 RgSchDlHqProcCb            *proc
29414 )
29415 #else
29416 PUBLIC Bool rgSCHCmnRetxAvoidTdd(curSf, cell, proc)
29417 RgSchDlSf                  *curSf;
29418 RgSchCellCb                *cell;
29419 RgSchDlHqProcCb            *proc;
29420 #endif
29421 {
29422    RgSchTddSfType   txSfType = 0;
29423
29424    TRC2(rgSCHCmnRetxAvoidTdd);
29425
29426    /* Get the RBs of TB that will be retransmitted */
29427    if (proc->tbInfo[0].state == HQ_TB_NACKED)
29428    {
29429       txSfType = proc->tbInfo[0].sfType;
29430
29431 #ifdef XEON_SPECIFIC_CHANGES
29432 #ifndef XEON_TDD_SPCL
29433       /* Avoid re-transmission on Normal SF when the corresponding TB wss transmitted on SPCL SF */
29434       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
29435       {
29436          RETVALUE(TRUE);
29437       }
29438 #endif
29439 #endif
29440    }
29441    if (proc->tbInfo[1].state == HQ_TB_NACKED) 
29442    {
29443       /* Select the TxSf with the highest num of possible REs 
29444        * In ascending order -> 1) SPL SF 2) DL_SF_0 3) DL_SF */
29445       txSfType = RGSCH_MAX(txSfType, proc->tbInfo[1].sfType);
29446
29447 #ifdef XEON_SPECIFIC_CHANGES
29448 #ifndef XEON_TDD_SPCL
29449       /* Avoid re-transmission on Normal SF when the corresponding TB wss tranmitted on SPCL SF */
29450       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
29451       {
29452          RETVALUE(TRUE);
29453       }
29454 #endif
29455 #endif
29456    }
29457
29458    if (txSfType > curSf->sfType)
29459    {
29460       /* Avoid retx */
29461       RETVALUE(TRUE);
29462    }
29463    
29464    /* Allow Retx */
29465    RETVALUE(FALSE);
29466 }
29467
29468 #else
29469 /* DwPTS Scheduling Changes End */
29470 \f
29471 /**
29472  * @brief Avoid allocating RETX incase of collision
29473  * with reserved resources for BCH/PSS/SSS occassions.
29474  *
29475  * @details
29476  *
29477  *     Function: rgSCHCmnRetxAllocAvoid 
29478  *     Purpose: Avoid allocating RETX incase of collision
29479  * with reserved resources for BCH/PSS/SSS occassions 
29480  *
29481  *     Invoked by: rgSCHCmnDlAllocRetxRb 
29482  *
29483  *  @param[in]  RgSchDlSf             *subFrm
29484  *  @param[in]  RgSchUeCb             *ue
29485  *  @param[in]  RgSchDlHqProcCb       *proc
29486  *  @return  Bool 
29487  *
29488  **/
29489 #ifdef ANSI
29490 PUBLIC Bool rgSCHCmnRetxAllocAvoid 
29491 (
29492 RgSchDlSf                  *subFrm,
29493 RgSchCellCb                *cell,
29494 RgSchDlHqProcCb            *proc
29495 )
29496 #else
29497 PUBLIC Bool rgSCHCmnRetxAllocAvoid(subFrm, cell, proc)
29498 RgSchDlSf                  *subFrm;
29499 RgSchCellCb                *cell;
29500 RgSchDlHqProcCb            *proc;
29501 #endif
29502 {
29503    U8          reqRbs;
29504
29505    TRC2(rgSCHCmnRetxAllocAvoid);
29506
29507    if (proc->tbInfo[0].state == HQ_TB_NACKED)
29508    {
29509       reqRbs = proc->tbInfo[0].dlGrnt.numRb;    
29510    }
29511    else
29512    {
29513       reqRbs = proc->tbInfo[1].dlGrnt.numRb;    
29514    }
29515    /* Consider the dlGrnt.numRb of the Retransmitting proc->tbInfo
29516     * and current available RBs to determine if this RETX TB
29517     * will collide with the BCH/PSS/SSS occassion */
29518    if (subFrm->sfNum % 5 == 0)
29519    {
29520       if ((subFrm->bwAssigned < cell->pbchRbEnd) &&
29521           (((subFrm->bwAssigned + reqRbs) - cell->pbchRbStart) > 0))
29522       {
29523          RETVALUE(TRUE);
29524       }
29525    }
29526    RETVALUE(FALSE);
29527 }
29528
29529 #endif
29530
29531 \f
29532 /**
29533  * @brief This function invokes the TM specific DL RETX RB Allocation routine.
29534  *
29535  * @details
29536  *
29537  *     Function: rgSCHCmnDlAllocRetxRb
29538  *     Purpose:  This function invokes the TM specific
29539  *               DL RETX RB Allocation routine.
29540  *
29541  *     Invoked by: Specific Schedulers
29542  *
29543  *  @param[in]  RgSchCellCb           *cell
29544  *  @param[in]  RgSchDlSf             *subFrm
29545  *  @param[in]  RgSchUeCb             *ue
29546  *  @param[in]  U32                   bo
29547  *  @param[out] U32                   *effBo
29548  *  @param[in]  RgSchDlHqProcCb       *proc
29549  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29550  *  @return  S16
29551  *
29552  **/
29553 #ifdef ANSI
29554 PUBLIC S16 rgSCHCmnDlAllocRetxRb
29555 (
29556 RgSchCellCb                *cell,
29557 RgSchDlSf                  *subFrm,
29558 RgSchUeCb                  *ue,
29559 U32                        bo,
29560 U32                        *effBo,
29561 RgSchDlHqProcCb            *proc,
29562 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29563 )
29564 #else
29565 PUBLIC S16 rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29566 RgSchCellCb                *cell;
29567 RgSchDlSf                  *subFrm;
29568 RgSchUeCb                  *ue;
29569 U32                        bo;
29570 U32                        *effBo;
29571 RgSchDlHqProcCb            *proc;
29572 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29573 #endif
29574 {
29575    U32                     newSchBits = 0;
29576    RgSchDlRbAlloc          *allocInfo;
29577
29578    TRC2(rgSCHCmnDlAllocRetxRb);
29579
29580    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
29581    {
29582       ue->dl.aggTbBits = 0;
29583    }
29584  
29585    *effBo = 0;
29586    /* Check for DL BW exhaustion */
29587    if (subFrm->bw <= subFrm->bwAssigned)
29588    {
29589       RETVALUE(RFAILED);
29590    }
29591    /* Call TM specific RB allocation routine */
29592    (dlAllocRetxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
29593          proc, cellWdAllocInfo);
29594
29595    if (*effBo)
29596    {
29597       allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29598       /* Calculate totals bits newly allocated */
29599       if (allocInfo->tbInfo[0].schdlngForTb)
29600       {
29601          newSchBits += allocInfo->tbInfo[0].bytesReq;
29602       }
29603       if (allocInfo->tbInfo[1].schdlngForTb)
29604       {
29605          newSchBits += allocInfo->tbInfo[1].bytesReq;
29606       }
29607       ue->dl.aggTbBits += (newSchBits * 8);
29608       RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
29609    }
29610    
29611    RETVALUE(ROK);
29612 }
29613
29614 \f
29615 /**
29616  * @brief This function determines the RBs and Bytes required for
29617  *        Transmission on 1 CW.
29618  *
29619  * @details
29620  *
29621  *     Function: rgSCHCmnDlAlloc1CwTxRb
29622  *     Purpose:  This function determines the RBs and Bytes required
29623  *               for Transmission of DL SVC BO on 1 CW.
29624  *               Also, takes care of SVC by SVC allocation by tracking
29625  *               previous SVCs allocations.
29626  *               Returns RFAILED if BO not satisfied at all.
29627  *
29628  *     Invoked by: DL UE Allocation
29629  *
29630  *  @param[in]  RgSchCellCb      *cell
29631  *  @param[in]  RgSchDlSf        *subFrm
29632  *  @param[in]  RgSchUeCb        *ue
29633  *  @param[in]  RgSchDlHqTbCb    *tbInfo
29634  *  @param[in]  U32              bo
29635  *  @param[out] U8               *numRb
29636  *  @param[out] U32              *effBo
29637  *  @return  S16
29638  *
29639  **/
29640 #ifdef ANSI
29641 PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb
29642 (
29643 RgSchCellCb                *cell,
29644 RgSchDlSf                  *subFrm,
29645 RgSchUeCb                  *ue,
29646 RgSchDlHqTbCb              *tbInfo,
29647 U32                        bo,
29648 U8                         *numRb,
29649 U32                        *effBo
29650 )
29651 #else
29652 PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, tbInfo, bo, numRb, effBo)
29653 RgSchCellCb                *cell;
29654 RgSchDlSf                  *subFrm;
29655 RgSchUeCb                  *ue;
29656 RgSchDlHqTbCb              *tbInfo;
29657 U32                        bo;
29658 U8                         *numRb;
29659 U32                        *effBo;
29660 #endif
29661 {
29662    U32                tbSz;
29663    U8                 imcs;
29664    U8                 iTbs;
29665    RgSchCmnDlUe       *ueDl;
29666    RgSchDlRbAlloc     *allocInfo;
29667    U32                oldReq;
29668    U32                reqBytes;
29669    /* Correcting wrap around issue.
29670     * This change has been done at mutliple places in this function.*/
29671    U32                tempNumRb;
29672    TRC2(rgSCHCmnDlAlloc1CwTxRb);
29673
29674    reqBytes  = bo;
29675    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29676    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29677    oldReq    = ueDl->outStndAlloc;
29678
29679 #ifdef RG_5GTF
29680    //TODO_SID: Currently setting max Tb size wrt to 5GTF TM3
29681    iTbs = ue->ue5gtfCb.mcs;
29682    ueDl->maxTbSz = MAX_5GTF_TB_SIZE * ue->ue5gtfCb.rank;
29683    ueDl->maxRb = MAX_5GTF_PRBS;
29684 #endif
29685    ueDl->outStndAlloc += bo;
29686    /* consider Cumulative amount of this BO and bytes so far allocated */
29687    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbSz/8);
29688    /* Get the number of REs needed for this bo. */
29689    //noRes = ((bo * 8 * 1024) / eff);
29690
29691    /* Get the number of RBs needed for this transmission */
29692    /* Number of RBs = No of REs / No of REs per RB       */
29693    //tempNumRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
29694    tempNumRb = MAX_5GTF_PRBS;
29695    tbSz = RGSCH_MIN(bo, (rgSch5gtfTbSzTbl[iTbs]/8) * ue->ue5gtfCb.rank);
29696
29697    /* DwPts Scheduling Changes End */
29698    *effBo = RGSCH_MIN(tbSz - oldReq, reqBytes);
29699
29700 #ifdef RG_5GTF
29701    //RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs);
29702    imcs = iTbs;
29703 #endif
29704
29705
29706    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbSz, \
29707          iTbs, imcs, tbInfo, ue->ue5gtfCb.rank);
29708    *numRb = (U8) tempNumRb;
29709    
29710    /* Update the subframe Allocated BW field */
29711    subFrm->bwAssigned = subFrm->bwAssigned + tempNumRb - allocInfo->rbsReq;
29712    
29713    RETVALUE(ROK);
29714 }
29715
29716 \f
29717 /**
29718  * @brief This function is invoked in the event of any TB's allocation
29719  *  being underutilized by the specific scheduler. Here we reduce iMcs
29720  *  to increase redundancy and hence increase reception quality at UE.
29721  *
29722  * @details
29723  *
29724  *     Function: rgSCHCmnRdcImcsTxTb
29725  *     Purpose:  This function shall reduce the iMcs in accordance with
29726  *               the total consumed bytes by the UE at allocation
29727  *               finalization.
29728  *
29729  *     Invoked by: UE DL Allocation finalization routine
29730  *                 of specific scheduler.
29731  *
29732  *  @param[in]  RgSchDlRbAlloc   *allocInfo
29733  *  @param[in]  U8               tbInfoIdx
29734  *  @param[in]  U32              cnsmdBytes
29735  *  @return  Void
29736  *
29737  **/
29738 #ifdef ANSI
29739 PUBLIC Void rgSCHCmnRdcImcsTxTb
29740 (
29741 RgSchDlRbAlloc   *allocInfo,
29742 U8               tbInfoIdx,
29743 U32              cnsmdBytes
29744 )
29745 #else
29746 PUBLIC Void rgSCHCmnRdcImcsTxTb(allocInfo, tbInfoIdx, cnsmdBytes)
29747 RgSchDlRbAlloc   *allocInfo;
29748 U8               tbInfoIdx;
29749 U32              cnsmdBytes;
29750 #endif
29751 {
29752    RETVOID;
29753    /*The below functionality is not needed.*/
29754    U8                 noLyr;
29755    U8                 iTbs;
29756    U16                numRb;
29757
29758    TRC2(rgSCHCmnRdcImcsTxTb);
29759
29760    iTbs = allocInfo->tbInfo[tbInfoIdx].iTbs;
29761    noLyr = allocInfo->tbInfo[tbInfoIdx].noLyr;
29762    numRb = allocInfo->rbsAlloc;
29763    if ( numRb > 0)
29764    {
29765       if ((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) == cnsmdBytes)
29766       {
29767          RETVOID;
29768       }
29769    }
29770    /* Get iTbs as suitable for the consumed bytes */
29771    while((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) > cnsmdBytes)
29772    {
29773       if (iTbs == 0)
29774       {
29775          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].\
29776                tbCb->dlGrnt.iMcs);
29777          RETVOID;
29778       }
29779       iTbs--;
29780    }
29781    iTbs++;
29782    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].tbCb->dlGrnt.iMcs);
29783
29784    RETVOID;
29785 }
29786
29787 \f
29788 /**
29789  * @brief This function determines the RBs and Bytes required for
29790  *        Transmission on 2 CWs.
29791  *
29792  * @details
29793  *
29794  *     Function: rgSCHCmnDlAlloc2CwTxRb
29795  *     Purpose:  This function determines the RBs and Bytes required
29796  *               for Transmission of DL SVC BO on 2 CWs.
29797  *               Also, takes care of SVC by SVC allocation by tracking
29798  *               previous SVCs allocations.
29799  *               Returns RFAILED if BO not satisfied at all.
29800  *
29801  *     Invoked by: TM3 and TM4 DL UE Allocation
29802  *
29803  *  @param[in]  RgSchCellCb      *cell
29804  *  @param[in]  RgSchDlSf        *subFrm
29805  *  @param[in]  RgSchUeCb        *ue
29806  *  @param[in]  RgSchDlHqProcCb  *proc
29807  *  @param[in]  RgSchDlHqProcCb  bo
29808  *  @param[out] U8               *numRb
29809  *  @param[out] U32              *effBo
29810  *  @return  Void
29811  *
29812  **/
29813 #ifdef ANSI
29814 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb
29815 (
29816 RgSchCellCb                *cell,
29817 RgSchDlSf                  *subFrm,
29818 RgSchUeCb                  *ue,
29819 RgSchDlHqProcCb            *proc,
29820 U32                        bo,
29821 U8                         *numRbRef,
29822 U32                        *effBo
29823 )
29824 #else
29825 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, numRbRef, effBo)
29826 RgSchCellCb                *cell;
29827 RgSchDlSf                  *subFrm;
29828 RgSchUeCb                  *ue;
29829 RgSchDlHqProcCb            *proc;
29830 U32                        bo;
29831 U8                         *numRbRef;
29832 U32                        *effBo;
29833 #endif
29834 {
29835    U32                noRes;
29836    U32                eff1, eff2;
29837    U32                tb1Sz, tb2Sz;
29838    U8                 imcs1, imcs2;
29839    U8                 noLyr1, noLyr2;
29840    U8                 iTbs1, iTbs2;
29841    RgSchCmnDlCell     *cellDl;
29842    RgSchCmnDlUe       *ueDl;
29843    RgSchDlRbAlloc     *allocInfo;
29844    U32                oldReq;
29845    U32                reqBytes;
29846    /* Fix: MUE_PERTTI_DL */
29847    U32                numRb;
29848    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
29849    U8                 cfi = cellSch->dl.currCfi;
29850    S16                availBw; 
29851    U32                availBits = 0;
29852 #ifdef LTE_ADV
29853    U32                boTmp = bo;
29854 #endif
29855
29856    TRC2(rgSCHCmnDlAlloc2CwTxRb);
29857
29858    reqBytes  = bo;
29859    cellDl    = RG_SCH_CMN_GET_DL_CELL(cell);
29860    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29861    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29862    oldReq    = ueDl->outStndAlloc;
29863
29864    
29865    if (ueDl->maxTbBits > ue->dl.aggTbBits)
29866    {
29867       availBits = ueDl->maxTbBits - ue->dl.aggTbBits;
29868    }
29869    /* check if we can further allocate to this UE */
29870    if ((ue->dl.aggTbBits >= ueDl->maxTbBits) ||
29871          (allocInfo->tbInfo[0].bytesReq >= ueDl->maxTbSz/8) ||
29872          (allocInfo->tbInfo[1].bytesReq >= ueDl->maxTbSz/8) ||
29873          (allocInfo->rbsReq >= ueDl->maxRb))
29874    {
29875       RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
29876             "rgSCHCmnDlAllocRb(): UEs max allocation exceed");
29877       RETVALUE(RFAILED);
29878    }
29879
29880    noLyr1 = ueDl->mimoInfo.cwInfo[0].noLyr;
29881    noLyr2 = ueDl->mimoInfo.cwInfo[1].noLyr;
29882
29883    /* If there is no CFI change, continue to use the BLER based
29884     * iTBS value */
29885    if (ueDl->lastCfi == cfi)
29886    {   
29887       iTbs1  = ueDl->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
29888       iTbs2  = ueDl->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
29889    }
29890    else
29891    {  
29892       U8 cqi = ueDl->mimoInfo.cwInfo[0].cqi;
29893 #ifdef LTE_TDD      
29894       iTbs1 = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 0, noLyr1);
29895 #else      
29896       iTbs1 = (U8) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 0, noLyr1);
29897 #endif         
29898
29899       cqi = ueDl->mimoInfo.cwInfo[1].cqi;
29900 #ifdef LTE_TDD      
29901       iTbs2 = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 1, noLyr2);
29902 #else      
29903       iTbs2 = (U8) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 1, noLyr2);
29904 #endif         
29905    } 
29906
29907    /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure
29908     * issue for VoLTE call */
29909    //if ((proc->hasDcch)  || (TRUE == rgSCHLaaSCellEnabled(cell)))
29910    if (proc->hasDcch)
29911    {
29912       if (iTbs1 > 5)
29913       {
29914          iTbs1  = iTbs1 - 5;
29915       }
29916       else
29917       {
29918          iTbs1  = 0; 
29919       }
29920       if (iTbs2 > 5)
29921       {
29922          iTbs2  = iTbs2 - 5;
29923       }
29924       else
29925       {
29926          iTbs2  = 0; 
29927       }
29928    }
29929    else if(!cellSch->dl.isDlFreqSel)
29930    {
29931 #ifdef LTE_TDD
29932       /* for Tdd reduce iTbs only for SF0. SF5 contains only 
29933        * SSS and can be ignored */
29934       if (subFrm->sfNum == 0)
29935       {
29936          (iTbs1 > 1)? (iTbs1 -= 1) : (iTbs1 = 0);
29937          (iTbs2 > 1)? (iTbs2 -= 1) : (iTbs2 = 0);
29938       }
29939       /* For SF 3 and 8 CRC is getting failed in DL.
29940          Need to do proper fix after the replay from 
29941          BRCM PHY team*/
29942 #ifdef CA_PHY_BRDCM_61765      
29943       if ((subFrm->sfNum == 3) || (subFrm->sfNum == 8))
29944       {
29945          (iTbs1 > 2)? (iTbs1 -= 2) : (iTbs1 = 0);
29946          (iTbs2 > 2)? (iTbs2 -= 2) : (iTbs2 = 0);
29947       }
29948 #endif
29949 #else
29950 #endif
29951    }
29952
29953 #ifdef LTE_TDD
29954    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
29955    {
29956       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
29957    }
29958 #endif 
29959
29960    eff1 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
29961    eff2 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
29962
29963
29964    bo = RGSCH_MIN(bo,availBits/8);
29965    ueDl->outStndAlloc += bo;
29966    /* consider Cumulative amount of this BO and bytes so far allocated */
29967    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbBits/8);
29968    bo = RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff1)/(eff1+eff2)), 
29969                   ueDl->maxTbSz/8) +
29970         RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff2)/(eff1+eff2)), 
29971                   (ueDl->maxTbSz)/8) +
29972         1; /* Add 1 to adjust the truncation at weighted averaging */
29973    /* Get the number of REs needed for this bo. */
29974    noRes = ((bo * 8 * 1024) / (eff1 + eff2));
29975
29976    /* Get the number of RBs needed for this transmission */
29977    /* Number of RBs = No of REs / No of REs per RB       */
29978    numRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
29979    /* Cannot exceed the maximum number of RBs per UE */
29980    if (numRb > ueDl->maxRb)
29981    {
29982       numRb = ueDl->maxRb;
29983    }
29984    else
29985    {
29986 #ifdef LTE_ADV
29987       if(RFAILED == rgSCHLaaCmn2CwAdjustPrb(allocInfo,  boTmp, &numRb, ueDl, noLyr1, noLyr2, iTbs1, iTbs2))
29988 #endif
29989       {
29990          while ((numRb <= ueDl->maxRb) &&
29991                (rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1] <= ueDl->maxTbSz) &&
29992                (rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1] <= ueDl->maxTbSz) &&
29993                ((rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8 +
29994                  rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8) <= bo))
29995          {
29996             (numRb)++;
29997          }
29998       }
29999    }
30000    availBw = subFrm->bw - subFrm->bwAssigned;
30001    /* Cannot exceed the total number of RBs in the cell */
30002    if ((S16)(numRb - allocInfo->rbsReq) > availBw)
30003    {
30004       numRb = availBw + allocInfo->rbsReq;
30005    }
30006    tb1Sz = rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8;
30007    tb2Sz = rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8;
30008    /* DwPts Scheduling Changes Start */
30009 #ifdef LTE_TDD
30010    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
30011    { 
30012       /* Max Rb for Special Sf is approximated as 4/3 of maxRb */
30013       rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, (U8*)&numRb,  ueDl->maxRb*4/3, 
30014                                 &iTbs1, &iTbs2, noLyr1, 
30015                                 noLyr2, &tb1Sz, &tb2Sz, cfi);   
30016       /* Check for available Bw */
30017       if ((S16)numRb - allocInfo->rbsReq > availBw)
30018       {
30019          numRb = availBw + allocInfo->rbsReq;
30020          tb1Sz = rgTbSzTbl[noLyr1-1][iTbs1][RGSCH_MAX(numRb*3/4,1)-1]/8;
30021          tb2Sz = rgTbSzTbl[noLyr2-1][iTbs2][RGSCH_MAX(numRb*3/4,1)-1]/8;
30022       }
30023    }
30024 #endif
30025    /* DwPts Scheduling Changes End */
30026    /* Update the subframe Allocated BW field */
30027    subFrm->bwAssigned = subFrm->bwAssigned + numRb - \
30028                         allocInfo->rbsReq;
30029
30030    *effBo = RGSCH_MIN((tb1Sz + tb2Sz) - oldReq, reqBytes);
30031
30032 #ifdef LTE_ADV
30033    if (ROK != rgSCHLaaCmn2TBPrbCheck(allocInfo, tb1Sz, tb2Sz, boTmp, effBo, iTbs1, iTbs2, numRb, proc))
30034    {
30035       RETVALUE(RFAILED);
30036    }
30037 #endif
30038
30039    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs1, imcs1);
30040    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs2, imcs2);
30041    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tb1Sz, \
30042          iTbs1, imcs1, &proc->tbInfo[0], noLyr1);
30043    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
30044          iTbs2, imcs2, &proc->tbInfo[1], noLyr2);
30045    *numRbRef = (U8)numRb;
30046
30047
30048    RETVALUE(ROK);
30049 }
30050
30051 \f
30052 /**
30053  * @brief This function determines the RBs and Bytes required for
30054  *        Transmission & Retransmission on 2 CWs.
30055  *
30056  * @details
30057  *
30058  *     Function: rgSCHCmnDlAlloc2CwTxRetxRb
30059  *     Purpose:  This function determines the RBs and Bytes required
30060  *               for Transmission & Retransmission on 2 CWs. Allocate
30061  *               RETX TB on a better CW and restrict new TX TB by
30062  *               RETX allocation.
30063  *               Returns RFAILED if BO not satisfied at all.
30064  *
30065  *     Invoked by: TM3 and TM4 DL UE Allocation
30066  *
30067  *  @param[in]  RgSchCellCb      *cell
30068  *  @param[in]  RgSchDlSf        *subFrm
30069  *  @param[in]  RgSchUeCb        *ue
30070  *  @param[in]  RgSchDlHqTbCb    *reTxTb
30071  *  @param[in]  RgSchDlHqTbCb    *txTb
30072  *  @param[out] U8               *numRb
30073  *  @param[out] U32              *effBo
30074  *  @return  Void
30075  *
30076  **/
30077 #ifdef ANSI
30078 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb
30079 (
30080 RgSchCellCb                *cell,
30081 RgSchDlSf                  *subFrm,
30082 RgSchUeCb                  *ue,
30083 RgSchDlHqTbCb              *reTxTb,
30084 RgSchDlHqTbCb              *txTb,
30085 U8                         *numRb,
30086 U32                        *effBo
30087 )
30088 #else
30089 PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, reTxTb, txTb, numRb,\
30090         effBo)
30091 RgSchCellCb                *cell;
30092 RgSchDlSf                  *subFrm;
30093 RgSchUeCb                  *ue;
30094 RgSchDlHqTbCb              *reTxTb;
30095 RgSchDlHqTbCb              *txTb;
30096 U8                         *numRb;
30097 U32                        *effBo;
30098 #endif
30099 {
30100    RgSchCmnDlUe       *ueDl;
30101    RgSchDlRbAlloc     *allocInfo;
30102    U8                 imcs1, imcs2;
30103    U8                  noLyr2;
30104    U16                 tb2Sz;
30105    RgSchCmnDlUeCwInfo *otherCw;
30106    S16                 availBw;
30107    RgSchCmnDlCell     *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
30108    U8                 cfi = cellDl->currCfi; 
30109    U8                 iTbs;
30110
30111    TRC2(rgSCHCmnDlAlloc2CwTxRetxRb);
30112
30113    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
30114    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
30115    otherCw   = &ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)];
30116
30117
30118    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
30119     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
30120     * MCS.  */
30121    availBw = subFrm->bw - subFrm->bwAssigned; 
30122    *numRb = reTxTb->dlGrnt.numRb;
30123
30124 #ifdef XEON_TDD_SPCL
30125    *numRb = (reTxTb->initTxNumRbs);
30126    if(reTxTb->sfType == RG_SCH_SPL_SF_DATA && subFrm->sfType != RG_SCH_SPL_SF_DATA)
30127    {
30128       *numRb = (reTxTb->initTxNumRbs*3/4);
30129
30130       if(*numRb <= 3)
30131       {
30132          RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb);
30133          RETVALUE(RFAILED);
30134       }
30135    }
30136 #endif
30137
30138    if ((S16)*numRb > availBw)
30139    {
30140       RETVALUE(RFAILED);
30141    }
30142    /* Update the subframe Allocated BW field */
30143    subFrm->bwAssigned += *numRb;
30144    noLyr2 = otherCw->noLyr;
30145    RG_SCH_CMN_GET_MCS_FOR_RETX(reTxTb, imcs1);
30146
30147    /* If there is no CFI change, continue to use the BLER based
30148     * iTBS value */
30149    if (ueDl->lastCfi == cfi)
30150    {   
30151       iTbs = otherCw->iTbs[noLyr2-1];
30152    }
30153    else
30154    {  
30155 #ifdef LTE_TDD      
30156       iTbs = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, otherCw->cqi, cfi, 
30157                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
30158 #else      
30159       iTbs = (U8) rgSchCmnFetchItbs(cell, ueDl, otherCw->cqi, cfi, 
30160                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
30161 #endif 
30162    } 
30163    tb2Sz = rgTbSzTbl[noLyr2-1][iTbs][*numRb-1]/8;
30164    /* DwPts Scheduling Changes Start */
30165 #ifdef LTE_TDD
30166 #endif
30167    /* DwPts Scheduling Changes End */
30168    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs2);
30169    
30170    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], reTxTb->tbSz, \
30171                               0, imcs1, reTxTb, reTxTb->numLyrs);
30172    
30173    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
30174                               iTbs, imcs2, txTb, noLyr2);
30175    
30176    *effBo = reTxTb->tbSz + tb2Sz;
30177
30178    RETVALUE(ROK);
30179 }
30180
30181 \f
30182 /**
30183  * @brief This function determines the RBs and Bytes required for BO
30184  *        Retransmission on 2 CWs.
30185  *
30186  * @details
30187  *
30188  *     Function: rgSCHCmnDlAlloc2CwRetxRb
30189  *     Purpose:  This function determines the RBs and Bytes required
30190  *               for BO Retransmission on 2 CWs. Allocate larger TB
30191  *               on a better CW and check if the smaller TB can be
30192  *               accomodated on the other CW.
30193  *               Returns RFAILED if BO not satisfied at all.
30194  *
30195  *     Invoked by: Common Scheduler
30196  *
30197  *  @param[in]  RgSchCellCb      *cell
30198  *  @param[in]  RgSchDlSf        *subFrm
30199  *  @param[in]  RgSchUeCb        *ue
30200  *  @param[in]  RgSchDlHqProcCb  *proc
30201  *  @param[out] U8               *numRb
30202  *  @param[out] Bool             *swpFlg
30203  *  @param[out] U32              *effBo
30204  *  @return  Void
30205  *
30206  **/
30207 #ifdef ANSI
30208 PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb
30209 (
30210 RgSchCellCb                *cell,
30211 RgSchDlSf                  *subFrm,
30212 RgSchUeCb                  *ue,
30213 RgSchDlHqProcCb            *proc,
30214 U8                         *numRb,
30215 Bool                       *swpFlg,
30216 U32                        *effBo
30217 )
30218 #else
30219 PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc,\
30220         numRb, swpFlg, effBo)
30221 RgSchCellCb                *cell;
30222 RgSchDlSf                  *subFrm;
30223 RgSchUeCb                  *ue;
30224 RgSchDlHqProcCb            *proc;
30225 U8                         *numRb;
30226 Bool                       *swpFlg;
30227 U32                        *effBo;
30228 #endif
30229 {
30230    RgSchDlRbAlloc     *allocInfo;
30231    U8                 imcs1;
30232    U8                 imcs2;
30233    RgSchDlHqTbCb      *lrgTbInfo, *othrTbInfo;
30234
30235    TRC2(rgSCHCmnDlAlloc2CwRetxRb);
30236
30237    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
30238
30239
30240    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
30241     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
30242     * MCS.  */
30243    lrgTbInfo  = &proc->tbInfo[0];
30244    othrTbInfo = &proc->tbInfo[1];
30245    *numRb = lrgTbInfo->dlGrnt.numRb;
30246 #ifdef XEON_TDD_SPCL
30247    if((lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA || othrTbInfo->sfType == RG_SCH_SPL_SF_DATA))
30248    {
30249       if(lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA)
30250       {       
30251           *numRb = (lrgTbInfo->initTxNumRbs);
30252       }
30253       else
30254       {
30255           *numRb = (othrTbInfo->initTxNumRbs);
30256       }
30257
30258       if(subFrm->sfType != RG_SCH_SPL_SF_DATA)
30259       {
30260          *numRb = (*numRb)*3/4;
30261       }
30262        
30263       if(*numRb <= 3)
30264       {
30265          RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb);
30266          RETVALUE(RFAILED);
30267       }
30268    }
30269 #endif
30270    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
30271    {
30272       RETVALUE(RFAILED);
30273    }
30274    /* Update the subframe Allocated BW field */
30275    subFrm->bwAssigned += *numRb;
30276    RG_SCH_CMN_GET_MCS_FOR_RETX(lrgTbInfo, imcs1);
30277    RG_SCH_CMN_GET_MCS_FOR_RETX(othrTbInfo, imcs2);
30278    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], lrgTbInfo->tbSz, \
30279          0, imcs1, lrgTbInfo, lrgTbInfo->numLyrs);
30280    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], othrTbInfo->tbSz, \
30281          0, imcs2, othrTbInfo, othrTbInfo->numLyrs);
30282    *effBo = lrgTbInfo->tbSz + othrTbInfo->tbSz;
30283
30284
30285
30286    RETVALUE(ROK);
30287 }
30288
30289 \f
30290 /**
30291  * @brief This function determines the RBs and Bytes required for BO
30292  *        Retransmission on 1 CW.
30293  *
30294  * @details
30295  *
30296  *     Function: rgSCHCmnDlAlloc1CwRetxRb
30297  *     Purpose:  This function determines the RBs and Bytes required
30298  *               for BO Retransmission on 1 CW, the first CW.
30299  *               Returns RFAILED if BO not satisfied at all.
30300  *
30301  *     Invoked by: Common Scheduler
30302  *
30303  *  @param[in]  RgSchCellCb      *cell
30304  *  @param[in]  RgSchDlSf        *subFrm
30305  *  @param[in]  RgSchUeCb        *ue
30306  *  @param[in]  RgSchDlHqTbCb    *tbInfo
30307  *  @param[in]  U8               noLyr
30308  *  @param[out] U8               *numRb
30309  *  @param[out] U32              *effBo
30310  *  @return  S16
30311  *
30312  **/
30313 #ifdef ANSI
30314 PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb
30315 (
30316 RgSchCellCb                *cell,
30317 RgSchDlSf                  *subFrm,
30318 RgSchUeCb                  *ue,
30319 RgSchDlHqTbCb              *tbInfo,
30320 U8                         noLyr,
30321 U8                         *numRb,
30322 U32                        *effBo
30323 )
30324 #else
30325 PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, tbInfo, noLyr,\
30326         numRb, effBo)
30327 RgSchCellCb                *cell;
30328 RgSchDlSf                  *subFrm;
30329 RgSchUeCb                  *ue;
30330 RgSchDlHqTbCb              *tbInfo;
30331 U8                         noLyr;
30332 U8                         *numRb;
30333 U32                        *effBo;
30334 #endif
30335 {
30336    RgSchDlRbAlloc  *allocInfo;
30337    U8              imcs;
30338
30339    TRC2(rgSCHCmnDlAlloc1CwRetxRb);
30340
30341    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
30342
30343
30344    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
30345     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
30346     * MCS.  */
30347    *numRb = tbInfo->dlGrnt.numRb;
30348    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
30349    {
30350       RETVALUE(RFAILED);
30351    }
30352    /* Update the subframe Allocated BW field */
30353    subFrm->bwAssigned += *numRb;
30354    imcs = tbInfo->dlGrnt.iMcs;
30355    allocInfo->dciFormat = tbInfo->dlGrnt.dciFormat; 
30356    /* Fix: For a RETX TB the iTbs is irrelevant, hence setting 0 */
30357    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbInfo->tbSz, \
30358          0, imcs, tbInfo, tbInfo->numLyrs);
30359    *effBo = tbInfo->tbSz;
30360
30361    RETVALUE(ROK);
30362 }
30363
30364 #ifdef LTEMAC_SPS
30365
30366 /**
30367  * @brief This function is called to handle Release PDCCH feedback for SPS UE
30368  *
30369  * @details
30370  *
30371  *     Function: rgSCHCmnDlRelPdcchFbk
30372  *     Purpose:  Invokes SPS module to handle release PDCCH feedback
30373  *
30374  *     Invoked by: DHM
30375  *
30376  *  @param[in]   RgSchCellCb     *cell
30377  *  @param[in]   RgSchUeCb       *ue
30378  *  @param[in]   Bool            isAck
30379  *  @return  Void
30380  *
30381  **/
30382 #ifdef ANSI
30383 PUBLIC Void rgSCHCmnDlRelPdcchFbk
30384 (
30385 RgSchCellCb        *cell,
30386 RgSchUeCb          *ue,
30387 Bool               isAck
30388 )
30389 #else
30390 PUBLIC Void rgSCHCmnDlRelPdcchFbk(cell, ue, isAck)
30391 RgSchCellCb        *cell;
30392 RgSchUeCb          *ue;
30393 Bool               isAck;
30394 #endif
30395 {
30396
30397    TRC2(rgSCHCmnDlRelPdcchFbk);
30398    rgSCHCmnSpsDlRelPdcchFbk(cell, ue, isAck);
30399    RETVOID;
30400
30401 }
30402
30403
30404 /**
30405  * @brief This function is invoked to handle Ack processing for a HARQ proc.
30406  *
30407  * @details
30408  *
30409  *     Function: rgSCHCmnDlProcAck
30410  *     Purpose:  DTX processing for HARQ proc
30411  *
30412  *     Invoked by: DHM
30413  *
30414  *  @param[in]   RgSchCellCb     *cell
30415  *  @param[in]   RgSchDlHqProcCb *hqP
30416  *  @return  Void
30417  *
30418  **/
30419 #ifdef ANSI
30420 PUBLIC Void rgSCHCmnDlProcAck
30421 (
30422 RgSchCellCb        *cell,
30423 RgSchDlHqProcCb    *hqP
30424 )
30425 #else
30426 PUBLIC Void rgSCHCmnDlProcAck(cell, hqP)
30427 RgSchCellCb        *cell;
30428 RgSchDlHqProcCb    *hqP;
30429 #endif
30430 {
30431
30432    TRC2(rgSCHCmnDlProcAck);
30433
30434    if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
30435    {
30436       /* Invoke SPS module if SPS service was scheduled for this HARQ proc */
30437       rgSCHCmnSpsDlProcAck(cell, hqP);
30438    }
30439    RETVOID;
30440 }
30441 #ifdef RGSCH_SPS_STATS
30442 extern U32 rgSchStatCrntiCeRcvCnt;
30443 #endif
30444 /**
30445  * @brief This function is invoked to handle CRNTI CE reception for an UE
30446  *
30447  * @details
30448  *
30449  *     Function: rgSCHCmnHdlCrntiCE
30450  *     Purpose:  Handle CRNTI CE reception
30451  *
30452  *     Invoked by: DHM
30453  *
30454  *  @param[in]   RgSchCellCb     *cell
30455  *  @param[in]   RgSchDlHqProcCb *hqP
30456  *  @return  Void
30457  *
30458  **/
30459 #ifdef ANSI
30460 PUBLIC Void rgSCHCmnHdlCrntiCE
30461 (
30462 RgSchCellCb        *cell,
30463 RgSchUeCb          *ue
30464 )
30465 #else
30466 PUBLIC Void rgSCHCmnHdlCrntiCE(cell, ue)
30467 RgSchCellCb        *cell;
30468 RgSchUeCb          *ue;
30469 #endif
30470 {
30471
30472    TRC2(rgSCHCmnHdlCrntiCE);
30473 #ifdef RGSCH_SPS_STATS   
30474    rgSchStatCrntiCeRcvCnt++;
30475 #endif
30476
30477    /* When UL sync lost happened due to TA timer expiry UE is being moved to 
30478       PDCCH order inactivity list.But when CRNTI CE received in msg3 from UE
30479       we are not moving UE into active state due to that RRC Reconfiguration is
30480       not happening.
30481       So here we are moving UE to active list whenever we receive the CRNTI CE and
30482       UE is inactive */
30483    /* CR ccpu00144525 */      
30484    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
30485    {
30486        /* Activate this UE if it was inactive */
30487        RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
30488        RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
30489    }
30490
30491    /* Handling is same as reception of UE RESET for both DL and UL */
30492    if (ue->dl.dlSpsCfg.isDlSpsEnabled)
30493    {
30494       rgSCHCmnSpsDlUeReset(cell, ue);
30495    }
30496    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30497    {
30498       rgSCHCmnSpsUlUeReset(cell, ue);
30499    }
30500    
30501    RETVOID;
30502 }
30503
30504
30505 /**
30506  * @brief This function is called to handle relInd from MAC for a UE
30507  *
30508  * @details
30509  *
30510  *     Function: rgSCHCmnUlSpsRelInd
30511  *     Purpose:  Invokes SPS module to handle UL SPS release for a UE
30512  *
30513  *     Invoked by: SCH_UTL
30514  *
30515  *  @param[in]   RgSchCellCb        *cell
30516  *  @param[in]   RgSchUeCb          *ue
30517  *  @param[in]   Bool               isExplRel
30518  *  @return  Void
30519  *
30520  **/
30521 #ifdef ANSI
30522 PUBLIC Void rgSCHCmnUlSpsRelInd
30523 (
30524 RgSchCellCb        *cell,
30525 RgSchUeCb          *ue,
30526 Bool               isExplRel
30527 )
30528 #else
30529 PUBLIC Void rgSCHCmnUlSpsRelInd(cell, ue, isExplRel)
30530 RgSchCellCb        *cell;
30531 RgSchUeCb          *ue;
30532 Bool               isExplRel;
30533 #endif
30534 {
30535
30536    TRC2(rgSCHCmnUlSpsRelInd);
30537    rgSCHCmnSpsUlProcRelInd(cell, ue, isExplRel);
30538    RETVOID;
30539
30540 } /* end of rgSCHCmnUlSpsRelInd */
30541
30542 /**
30543  * @brief This function is called to handle SPS Activate Ind from MAC for a UE
30544  *
30545  * @details
30546  *
30547  *     Function: rgSCHCmnUlSpsActInd
30548  *     Purpose:  Invokes SPS module to handle UL SPS activate for a UE
30549  *
30550  *     Invoked by: SCH_UTL
30551  *
30552  *  @param[in]   RgSchCellCb        *cell
30553  *  @param[in]   RgSchUeCb          *ue
30554  *  @return  Void
30555  *
30556  **/
30557 #ifdef ANSI
30558 PUBLIC Void rgSCHCmnUlSpsActInd
30559 (
30560 RgSchCellCb        *cell,
30561 RgSchUeCb          *ue,
30562 U16                spsSduSize
30563 )
30564 #else
30565 PUBLIC Void rgSCHCmnUlSpsActInd(cell, ue,spsSduSize)
30566 RgSchCellCb        *cell;
30567 RgSchUeCb          *ue;
30568 U16                spsSduSize;
30569 #endif
30570 {
30571
30572    TRC2(rgSCHCmnUlSpsActInd);
30573
30574    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30575    {
30576       rgSCHCmnSpsUlProcActInd(cell, ue,spsSduSize);
30577    }
30578    RETVOID;
30579
30580 } /* end of rgSCHCmnUlSpsActInd */
30581
30582 /**
30583  * @brief This function is called to handle CRC in UL for UEs
30584  * undergoing SPS release
30585  *
30586  * @details
30587  *
30588  *     Function: rgSCHCmnUlCrcInd
30589  *     Purpose:  Invokes SPS module to handle CRC in UL for SPS UE
30590  *
30591  *     Invoked by: SCH_UTL
30592  *
30593  *  @param[in]   RgSchCellCb        *cell
30594  *  @param[in]   RgSchUeCb          *ue
30595  *  @param[in]   CmLteTimingInfo    crcTime
30596  *  @return  Void
30597  *
30598  **/
30599 #ifdef ANSI
30600 PUBLIC Void rgSCHCmnUlCrcInd
30601 (
30602 RgSchCellCb        *cell,
30603 RgSchUeCb          *ue,
30604 CmLteTimingInfo    crcTime
30605 )
30606 #else
30607 PUBLIC Void rgSCHCmnUlCrcInd(cell, ue, crcTime)
30608 RgSchCellCb        *cell;
30609 RgSchUeCb          *ue;
30610 CmLteTimingInfo    crcTime;
30611 #endif
30612 {
30613
30614    TRC2(rgSCHCmnUlCrcInd);
30615    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30616    {
30617       rgSCHCmnSpsUlProcCrcInd(cell, ue, crcTime);
30618    }
30619    RETVOID;
30620
30621 } /* end of rgSCHCmnUlCrcFailInd */
30622
30623 /**
30624  * @brief This function is called to handle CRC failure in UL
30625  *
30626  * @details
30627  *
30628  *     Function: rgSCHCmnUlCrcFailInd
30629  *     Purpose:  Invokes SPS module to handle CRC failure in UL for SPS UE
30630  *
30631  *     Invoked by: SCH_UTL
30632  *
30633  *  @param[in]   RgSchCellCb        *cell
30634  *  @param[in]   RgSchUeCb          *ue
30635  *  @param[in]   CmLteTimingInfo    crcTime
30636  *  @return  Void
30637  *
30638  **/
30639 #ifdef ANSI
30640 PUBLIC Void rgSCHCmnUlCrcFailInd
30641 (
30642 RgSchCellCb        *cell,
30643 RgSchUeCb          *ue,
30644 CmLteTimingInfo    crcTime
30645 )
30646 #else
30647 PUBLIC Void rgSCHCmnUlCrcFailInd(cell, ue, crcTime)
30648 RgSchCellCb        *cell;
30649 RgSchUeCb          *ue;
30650 CmLteTimingInfo    crcTime;
30651 #endif
30652 {
30653
30654    TRC2(rgSCHCmnUlCrcFailInd);
30655    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30656    {
30657       rgSCHCmnSpsUlProcDtxInd(cell, ue, crcTime);
30658    }
30659    RETVOID;
30660
30661 } /* end of rgSCHCmnUlCrcFailInd */
30662
30663 #endif /* LTEMAC_SPS */
30664
30665 /**
30666  * @brief BCH,BCCH,PCCH Dowlink Scheduling Handler.
30667  *
30668  * @details
30669  *
30670  *     Function: rgSCHCmnDlBcchPcchAlloc
30671  *     Purpose:  This function calls common scheduler APIs to
30672  *     schedule for BCCH/PCCH.
30673  *     It then invokes Allocator for actual RB
30674  *     allocations. It processes on the actual resources allocated
30675  *     against requested to the allocator module.
30676  *
30677  *     Invoked by: Common Scheduler
30678  *
30679  *  @param[in]  RgSchCellCb *cell
30680  *  @return  Void
30681  **/
30682 #ifdef ANSI
30683 PRIVATE Void rgSCHCmnDlBcchPcchAlloc
30684 (
30685 RgSchCellCb  *cell
30686 )
30687 #else
30688 PRIVATE Void rgSCHCmnDlBcchPcchAlloc(cell)
30689 RgSchCellCb  *cell;
30690 #endif
30691 {
30692 #ifdef LTE_TDD
30693    U8           nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
30694 #else
30695 #ifdef LTEMAC_HDFDD
30696    U8           nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
30697 #else
30698    U8           nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
30699 #endif
30700 #endif
30701    RgInfSfAlloc *nextsfAlloc = &(cell->sfAllocArr[nextSfIdx]);
30702    RgSchCmnCell           *cellSch   = RG_SCH_CMN_GET_CELL(cell);
30703    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo;  
30704    
30705    TRC2(rgSCHCmnDlBcchPcchAlloc);
30706
30707
30708    /*Reset the bitmask for BCCH/PCCH*/
30709    rgSCHUtlResetSfAlloc(nextsfAlloc,TRUE,FALSE);
30710 #ifndef DISABLE_MIB_SIB /* Not sending MIB and SIB to CL */
30711 #ifdef RGR_SI_SCH
30712    rgSCHChkNUpdSiCfg(cell);
30713    rgSCHSelectSi(cell);
30714 #endif
30715
30716    /*Perform the scheduling for BCCH,PCCH*/
30717    rgSCHCmnDlBcchPcch(cell, allocInfo, nextsfAlloc);
30718
30719    /* Call common allocator for RB Allocation */
30720    rgSCHBcchPcchDlRbAlloc(cell, allocInfo);
30721
30722    /* Finalize the Allocations for reqested Against alloced */
30723    rgSCHCmnDlBcchPcchFnlz(cell, allocInfo);
30724 #endif /* DISABLE_MIB_SIB */
30725    RETVOID;
30726 }
30727
30728 /**
30729  * @brief Handles RB allocation for BCCH/PCCH for downlink.
30730  *
30731  * @details
30732  *
30733  *     Function : rgSCHBcchPcchDlRbAlloc
30734  *
30735  *     Invoking Module Processing:
30736  *     - This function is invoked for DL RB allocation of BCCH/PCCH
30737  *
30738  *     Processing Steps:
30739  *     - If cell is frequency selecive,
30740  *       - Call rgSCHDlfsBcchPcchAllocRb().
30741  *     - else,
30742  *       - Do the processing
30743  *
30744  *  @param[in]  RgSchCellCb        *cell
30745  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
30746  *  @return  Void
30747  **/
30748
30749 #ifdef ANSI
30750 PRIVATE Void rgSCHBcchPcchDlRbAlloc
30751 (
30752 RgSchCellCb           *cell,
30753 RgSchCmnDlRbAllocInfo *allocInfo
30754 )
30755 #else
30756 PRIVATE Void rgSCHBcchPcchDlRbAlloc(cell, allocInfo)
30757 RgSchCellCb           *cell;
30758 RgSchCmnDlRbAllocInfo *allocInfo;
30759 #endif
30760 {
30761    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
30762
30763    TRC2(rgSCHBcchPcchDlRbAlloc);
30764
30765
30766    if (cellSch->dl.isDlFreqSel)
30767    {
30768       cellSch->apisDlfs->rgSCHDlfsBcchPcchAllocRb(cell, allocInfo);
30769    }
30770    else
30771    {
30772       rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo);
30773    }
30774
30775    RETVOID;
30776 }
30777
30778 /**
30779  * @brief Handles RB allocation for BCCH,PCCH for frequency
30780  *  non-selective cell.
30781  *
30782  * @details
30783  *
30784  *     Function : rgSCHCmnNonDlfsBcchPcchRbAlloc
30785  *
30786  *     Invoking Module Processing:
30787  *      - SCH shall invoke this if downlink frequency selective is disabled for
30788  *        the cell for RB allocation.
30789  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
30790  *        estimate and subframe for each allocation to be made to SCH.
30791  *
30792  *     Processing Steps:
30793  *     - Allocate sequentially for BCCH,PCCH common channels.
30794  *
30795  *  @param[in]  RgSchCellCb        *cell
30796  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
30797  *  @return  Void
30798  **/
30799
30800 #ifdef ANSI
30801 PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc
30802 (
30803 RgSchCellCb           *cell,
30804 RgSchCmnDlRbAllocInfo *allocInfo
30805 )
30806 #else
30807 PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo)
30808 RgSchCellCb           *cell;
30809 RgSchCmnDlRbAllocInfo *allocInfo;
30810 #endif
30811 {
30812    RgSchDlRbAlloc     *reqAllocInfo;
30813
30814    TRC2(rgSCHCmnNonDlfsBcchPcchRbAlloc);
30815
30816    /* 143473 */
30817    /* Allocate for PCCH */
30818    reqAllocInfo = &(allocInfo->pcchAlloc);
30819    if (reqAllocInfo->rbsReq)
30820    {
30821       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
30822    }
30823    /* Allocate for BCCH on DLSCH */
30824    reqAllocInfo = &(allocInfo->bcchAlloc);
30825    if (reqAllocInfo->rbsReq)
30826    {
30827       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
30828    }
30829    RETVOID;
30830 }
30831
30832
30833 #ifdef RGR_SI_SCH
30834 /**
30835  * @brief This function implements the handling to check and
30836  *        update the SI cfg at the start of the modificiation period.
30837  *
30838  * @details
30839  *
30840  *     Function: rgSCHChkNUpdSiCfg
30841  *     Purpose:  This function implements handling for update of SI Cfg
30842  *               at the start of modification period.
30843  *
30844  *     Invoked by: Scheduler
30845  *
30846  *  @param[in]  RgSchCellCb*     cell
30847  *  @return  S16
30848  *      -# ROK
30849  *      -# RFAILED
30850  **/
30851 #ifdef ANSI
30852 PRIVATE Void rgSCHChkNUpdSiCfg
30853 (
30854 RgSchCellCb             *cell
30855 )
30856 #else
30857 PRIVATE Void rgSCHChkNUpdSiCfg(cell)
30858 RgSchCellCb             *cell;
30859 #endif
30860 {
30861    CmLteTimingInfo   pdSchTmInfo;
30862
30863    TRC2(rgSCHChkNUpdSiCfg);
30864
30865
30866    pdSchTmInfo   = cell->crntTime;
30867 #ifdef LTEMAC_HDFDD
30868    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
30869       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
30870    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
30871 #else
30872    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA);
30873 #endif
30874
30875
30876    /* Updating the SIB1 for Warning SI message immediately after it is received 
30877     * from application. No need to wait for next modification period.
30878     */
30879    if((pdSchTmInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
30880          && (RGSCH_SIB1_TX_SF_NUM == (pdSchTmInfo.subframe % RGSCH_NUM_SUB_FRAMES)))
30881    {   
30882       /*Check whether SIB1 with PWS has been updated*/
30883       if(cell->siCb.siBitMask & RGSCH_SI_SIB1_PWS_UPD)
30884       {
30885          RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
30886                cell->siCb.newSiInfo.sib1Info.sib1);
30887          cell->siCb.crntSiInfo.sib1Info.mcs = 
30888             cell->siCb.newSiInfo.sib1Info.mcs;
30889          cell->siCb.crntSiInfo.sib1Info.nPrb = 
30890              cell->siCb.newSiInfo.sib1Info.nPrb;
30891          cell->siCb.crntSiInfo.sib1Info.msgLen = 
30892             cell->siCb.newSiInfo.sib1Info.msgLen;
30893          cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_PWS_UPD;
30894       }
30895    }
30896
30897    /*Check if this SFN and SF No marks the start of next modification
30898      period. If current SFN,SF No doesn't marks the start of next
30899      modification period, then return. */
30900    if(!((pdSchTmInfo.sfn % cell->siCfg.modPrd == 0)
30901             && (0 == pdSchTmInfo.subframe)))
30902    /*if(!((((pdSchTmInfo.hSfn * 1024) + pdSchTmInfo.sfn) % cell->siCfg.modPrd == 0)
30903             && (0 == pdSchTmInfo.subframe)))*/
30904    {
30905       RETVOID;
30906    }
30907
30908    /*Check whether MIB has been updated*/
30909    if(cell->siCb.siBitMask & RGSCH_SI_MIB_UPD)
30910    {
30911       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.mib,
30912             cell->siCb.newSiInfo.mib);
30913       cell->siCb.siBitMask &= ~RGSCH_SI_MIB_UPD;
30914    }
30915
30916    /*Check whether SIB1 has been updated*/
30917    if(cell->siCb.siBitMask & RGSCH_SI_SIB1_UPD)
30918    {
30919       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
30920             cell->siCb.newSiInfo.sib1Info.sib1);
30921       cell->siCb.crntSiInfo.sib1Info.mcs = cell->siCb.newSiInfo.sib1Info.mcs;
30922       cell->siCb.crntSiInfo.sib1Info.nPrb = cell->siCb.newSiInfo.sib1Info.nPrb;
30923       cell->siCb.crntSiInfo.sib1Info.msgLen = 
30924          cell->siCb.newSiInfo.sib1Info.msgLen;
30925       cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_UPD;
30926    }
30927
30928    /*Check whether SIs have been updated*/
30929    if(cell->siCb.siBitMask & RGSCH_SI_SI_UPD)
30930    {
30931       U8  idx;
30932
30933       /*Check if SI cfg have been modified And Check if numSi have
30934         been changed, if yes then we would need to update the
30935         pointers for all the SIs */
30936       if((cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) &&
30937             (cell->siCfg.numSi != cell->siCb.newSiCfg.numSi))
30938       {
30939          for(idx = 0;idx < cell->siCb.newSiCfg.numSi;idx++)
30940          {
30941             RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
30942                   cell->siCb.newSiInfo.siInfo[idx].si);
30943             cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
30944             cell->siCb.siArray[idx].isWarningSi = FALSE;
30945
30946             cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
30947             cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
30948             cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
30949          }
30950
30951          /*If numSi have been reduced then we need to free the
30952            pointers at the indexes in crntSiInfo which haven't
30953            been exercised. If numSi has increased then nothing
30954            additional is requires as above handling has taken
30955            care.*/
30956          if(cell->siCfg.numSi > cell->siCb.newSiCfg.numSi)
30957          {
30958             for(idx = cell->siCb.newSiCfg.numSi;
30959                   idx < cell->siCfg.numSi;idx++)
30960             {
30961                RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si);
30962                cell->siCb.siArray[idx].si = NULLP;
30963             }
30964          }
30965       }
30966       else
30967       {
30968          /*numSi has not been updated, we just need to update the
30969            pointers for the SIs which are set to NON NULLP */
30970          /*ccpu00118260 - Correct Update of SIB2 */
30971          for(idx = 0;idx < cell->siCfg.numSi;idx++)
30972          {
30973             if(NULLP != cell->siCb.newSiInfo.siInfo[idx].si)
30974             {
30975                RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
30976                      cell->siCb.newSiInfo.siInfo[idx].si);
30977
30978                cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
30979                cell->siCb.siArray[idx].isWarningSi = FALSE;
30980                cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
30981                cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
30982                cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
30983             }
30984          }
30985       }
30986       cell->siCb.siBitMask &= ~RGSCH_SI_SI_UPD;
30987    }
30988
30989    /*Check whether SI cfg have been updated*/
30990    if(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD)
30991    {
30992       cell->siCfg = cell->siCb.newSiCfg;
30993       cell->siCb.siBitMask &= ~RGSCH_SI_SICFG_UPD;
30994    }
30995
30996    RETVOID;
30997 }
30998
30999
31000 /**
31001  * @brief This function implements the selection of the SI
31002  *        that is to be scheduled.
31003  *
31004  * @details
31005  *
31006  *     Function: rgSCHSelectSi
31007  *     Purpose:  This function implements the selection of SI
31008  *               that is to be scheduled.
31009  *
31010  *     Invoked by: Scheduler
31011  *
31012  *  @param[in]  RgSchCellCb*     cell
31013  *  @return  S16
31014  *      -# ROK
31015  *      -# RFAILED
31016  **/
31017 #ifdef ANSI
31018 PRIVATE Void rgSCHSelectSi
31019 (
31020 RgSchCellCb             *cell
31021 )
31022 #else
31023 PRIVATE Void rgSCHSelectSi(cell)
31024 RgSchCellCb             *cell;
31025 #endif
31026 {
31027    CmLteTimingInfo        crntTmInfo;
31028    U8                     siWinSize;
31029    U16                    x; 
31030    U16                    windowId; 
31031
31032    TRC2(rgSCHSelectSi);
31033
31034
31035    crntTmInfo  = cell->crntTime;
31036 #ifdef LTEMAC_HDFDD
31037    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
31038       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
31039    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
31040 #else
31041    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA);
31042 #endif
31043
31044    siWinSize    = cell->siCfg.siWinSize;
31045
31046    /* Select SI only once at the starting of the new window */
31047    if(cell->siCb.inWindow)
31048    {
31049       if ((crntTmInfo.sfn % cell->siCfg.minPeriodicity) == 0 && 
31050           crntTmInfo.subframe == 0)
31051       {
31052          /* Reinit inWindow at the beginning of every SI window */
31053          cell->siCb.inWindow = siWinSize - 1;
31054       }
31055       else
31056       {
31057          cell->siCb.inWindow--;
31058          RETVOID;
31059       }
31060    }
31061    else /* New window. Re-init the winSize counter with the window length */
31062    {
31063       if((cell->siCb.siArray[cell->siCb.siCtx.siId - 1].isWarningSi == TRUE)&&
31064             (cell->siCb.siCtx.retxCntRem != 0))   
31065       {
31066          rgSCHUtlFreeWarningSiPdu(cell);
31067          cell->siCb.siCtx.warningSiFlag  = FALSE;
31068       }
31069
31070       cell->siCb.inWindow = siWinSize - 1;
31071    }
31072
31073    x = rgSCHCmnGetSiSetId(crntTmInfo.sfn, crntTmInfo.subframe, 
31074                                   cell->siCfg.minPeriodicity); 
31075
31076    /* Window Id within a SI set. This window Id directly maps to a
31077     * unique SI Id */
31078    windowId = (((crntTmInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + 
31079             crntTmInfo.subframe) - (x * (cell->siCfg.minPeriodicity * 10))) 
31080                                                                / siWinSize;
31081
31082    if(windowId >= RGR_MAX_NUM_SI)
31083       RETVOID;
31084
31085    /* Update the siCtx if there is a valid SI and its periodicity
31086     * has occurred */
31087    if (NULLP != cell->siCb.siArray[windowId].si)
31088    {
31089       /* Warning SI Periodicity is same as SIB2 Periodicity */
31090       if(((cell->siCb.siArray[windowId].isWarningSi == FALSE) && 
31091                (x % (cell->siCfg.siPeriodicity[windowId]
31092                      /cell->siCfg.minPeriodicity) == 0)) || 
31093             ((cell->siCb.siArray[windowId].isWarningSi == TRUE) &&
31094              (x % (cell->siCfg.siPeriodicity[0]
31095                    /cell->siCfg.minPeriodicity) == 0)))
31096       {
31097          cell->siCb.siCtx.siId = windowId+1;
31098          cell->siCb.siCtx.retxCntRem = cell->siCfg.retxCnt;
31099          cell->siCb.siCtx.warningSiFlag = cell->siCb.siArray[windowId].
31100                                                            isWarningSi;
31101          cell->siCb.siCtx.timeToTx.sfn = crntTmInfo.sfn;
31102          cell->siCb.siCtx.timeToTx.subframe = crntTmInfo.subframe;
31103
31104          RG_SCH_ADD_TO_CRNT_TIME(cell->siCb.siCtx.timeToTx,
31105                cell->siCb.siCtx.maxTimeToTx, (siWinSize - 1))
31106       }
31107    }
31108    else
31109    {/* Update the siCtx with invalid si Id */
31110       cell->siCb.siCtx.siId = 0;
31111    }
31112
31113    RETVOID;
31114 }
31115
31116
31117 /**
31118  * @brief This function implements scheduler DL allocation for
31119  *        SI.
31120  *
31121  * @details
31122  *
31123  *     Function: rgSCHDlSiSched
31124  *     Purpose:  This function implements scheduler for DL allocation
31125  *               for SI.
31126  *
31127  *     Invoked by: Scheduler
31128  *
31129  *  @param[in]  RgSchCellCb*     cell
31130  *  @return  S16
31131  *      -# ROK
31132  *      -# RFAILED
31133  **/
31134 #ifdef ANSI
31135 PRIVATE Void rgSCHDlSiSched
31136 (
31137 RgSchCellCb             *cell,
31138 RgSchCmnDlRbAllocInfo   *allocInfo,
31139 RgInfSfAlloc            *subfrmAlloc
31140 )
31141 #else
31142 PRIVATE Void rgSCHDlSiSched(cell, allocInfo, subfrmAlloc)
31143 RgSchCellCb             *cell;
31144 RgSchCmnDlRbAllocInfo   *allocInfo;
31145 RgInfSfAlloc            *subfrmAlloc;
31146 #endif
31147 {
31148    CmLteTimingInfo   crntTimInfo;
31149    RgSchDlSf         *sf;
31150    U8                nPrb = 0;
31151    U8                mcs  = 0;
31152    MsgLen            msgLen = 0;
31153    U32               rb=0;
31154    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
31155    /* DwPTS Scheduling Changes Start */
31156 #ifdef LTE_TDD   
31157    U16                lostRe;  
31158    U8                 cfi = cellDl->currCfi;      
31159 #endif
31160    /* DwPTS Scheduling Changes End */
31161
31162    TRC2(rgSCHDlSiSched);
31163
31164
31165    crntTimInfo   = cell->crntTime;
31166 #ifdef LTEMAC_HDFDD
31167    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
31168       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
31169    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
31170 #else
31171    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA);
31172 #endif
31173
31174    /* Compute the subframe for which allocation is being made.
31175       Essentially, we need pointer to the dl frame for this subframe */
31176    sf = rgSCHUtlSubFrmGet(cell, crntTimInfo);
31177
31178    /*Check if scheduling of MIB is required */
31179 #ifdef EMTC_ENABLE
31180    /* since we are adding the MIB repetition logic for EMTC UEs, checking if
31181     * emtcEnabled or not,  If enabled MIB would be repeted at as part of EMTC
31182     * feature, otherwise scheduling at (n,0) */
31183    if(0 == cell->emtcEnable)
31184    {
31185 #endif
31186    if((crntTimInfo.sfn % RGSCH_MIB_PERIODICITY == 0)
31187          && (RGSCH_MIB_TX_SF_NUM == crntTimInfo.subframe))
31188    {
31189       MsgLen  mibLen = 0;
31190       U8      sfnOctet, mibOct2 = 0;
31191       U8      mibOct1 = 0;
31192       /*If MIB has not been yet setup by Application, return*/
31193       if(NULLP == cell->siCb.crntSiInfo.mib)
31194          RETVOID;
31195
31196       SFndLenMsg(cell->siCb.crntSiInfo.mib, &mibLen);
31197       sf->bch.tbSize = mibLen;
31198       /*Fill the interface information */
31199       rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, NULLD, NULLD);
31200
31201       /*Set the bits of MIB to reflect SFN */
31202       /*First get the Most signficant 8 bits of SFN */
31203       sfnOctet = (U8)(crntTimInfo.sfn >> 2);
31204       /*Get the first two octets of MIB, and then update them
31205         using the SFN octet value obtained above.*/
31206       if(ROK != SExamMsg((Data *)(&mibOct1),
31207                cell->siCb.crntSiInfo.mib, 0))
31208          RETVOID;
31209
31210       if(ROK != SExamMsg((Data *)(&mibOct2),
31211                cell->siCb.crntSiInfo.mib, 1))
31212          RETVOID;
31213
31214       /* ccpu00114572- Fix for improper way of MIB Octet setting for SFN */
31215       mibOct1 = (mibOct1 & 0xFC) | (sfnOctet >> 6);
31216       mibOct2 = (mibOct2 & 0x03) | (sfnOctet << 2);
31217       /* ccpu00114572- Fix ends*/
31218
31219       /*Now, replace the two octets in MIB */
31220       if(ROK != SRepMsg((Data)(mibOct1),
31221                cell->siCb.crntSiInfo.mib, 0))
31222          RETVOID;
31223
31224       if(ROK != SRepMsg((Data)(mibOct2),
31225                cell->siCb.crntSiInfo.mib, 1))
31226          RETVOID;
31227
31228       /*Copy the MIB msg buff into interface buffer */
31229       SCpyMsgMsg(cell->siCb.crntSiInfo.mib,
31230             rgSchCb[cell->instIdx].rgSchInit.region,
31231             rgSchCb[cell->instIdx].rgSchInit.pool,
31232             &subfrmAlloc->cmnLcInfo.bchInfo.pdu);
31233       /* Added Dl TB count for MIB message transmission
31234        * This counter is incremented 4 times to consider 
31235        * the retransmission at the PHY level on PBCH channel*/
31236 #ifdef LTE_L2_MEAS
31237       cell->dlUlTbCnt.tbTransDlTotalCnt += RG_SCH_MIB_CNT;
31238 #endif      
31239    }
31240 #ifdef EMTC_ENABLE
31241    }
31242 #endif
31243
31244    allocInfo->bcchAlloc.schdFirst = FALSE;
31245    /*Check if scheduling of SIB1 is required.
31246      Check of (crntTimInfo.sfn % RGSCH_SIB1_PERIODICITY == 0)
31247      is not required here since the below check takes care
31248      of SFNs applicable for this one too.*/
31249    if((crntTimInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
31250          && (RGSCH_SIB1_TX_SF_NUM == crntTimInfo.subframe))
31251    {
31252       /*If SIB1 has not been yet setup by Application, return*/
31253       if(NULLP == (cell->siCb.crntSiInfo.sib1Info.sib1))
31254       {
31255          RETVOID;
31256       }
31257
31258       allocInfo->bcchAlloc.schdFirst = TRUE;
31259       mcs =  cell->siCb.crntSiInfo.sib1Info.mcs;
31260       nPrb =  cell->siCb.crntSiInfo.sib1Info.nPrb;
31261       msgLen =  cell->siCb.crntSiInfo.sib1Info.msgLen;
31262    }
31263    else
31264    {
31265       /*Check if scheduling of SI can be performed.*/
31266       Bool    invalid = FALSE;
31267
31268       if(cell->siCb.siCtx.siId == 0)
31269          RETVOID;
31270
31271       /*Check if the Si-Window for the current Si-Context is completed*/
31272       invalid = rgSCHCmnChkPastWin(crntTimInfo, cell->siCb.siCtx.maxTimeToTx);
31273       if(invalid)
31274       {
31275          /* LTE_ADV_FLAG_REMOVED_START */
31276          if(cell->siCb.siCtx.retxCntRem)
31277          { 
31278             RGSCHLOGERROR(cell->instIdx,ERRCLS_INT_PAR,ERG011,(ErrVal)cell->siCb.siCtx.siId,
31279                                 "rgSCHDlSiSched(): SI not scheduled and window expired");
31280          }
31281          /* LTE_ADV_FLAG_REMOVED_END */
31282          if(cell->siCb.siCtx.warningSiFlag == TRUE)
31283          {
31284             rgSCHUtlFreeWarningSiPdu(cell);
31285             cell->siCb.siCtx.warningSiFlag  = FALSE;
31286          }
31287          RETVOID;
31288       }
31289
31290       /*Check the timinginfo of the current SI-Context to see if its
31291         transmission can be scheduled. */
31292       if(FALSE == (rgSCHCmnChkInWin(crntTimInfo,
31293                   cell->siCb.siCtx.timeToTx,
31294                   cell->siCb.siCtx.maxTimeToTx)))
31295       {
31296          RETVOID;
31297
31298       }
31299       /*Check if retransmission count has become 0*/
31300       if(0 == cell->siCb.siCtx.retxCntRem)
31301       {
31302          RETVOID;
31303       }
31304
31305       /* LTE_ADV_FLAG_REMOVED_START */
31306       /* Check if ABS is enabled/configured  */
31307       if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
31308       {
31309          /* The pattern type is RGR_ABS_MUTE, then eNB need to blank the subframe */
31310          if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
31311          {
31312             /* Determine next scheduling subframe is ABS or not */
31313             if(RG_SCH_ABS_ENABLED_ABS_SF == (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern
31314                   [((crntTimInfo.sfn*RGSCH_NUM_SUB_FRAMES) + crntTimInfo.subframe) % RGR_ABS_PATTERN_LEN]))
31315             {
31316                /* Skip the SI scheduling to next tti */
31317                RETVOID;
31318             }
31319          }
31320       }
31321       /* LTE_ADV_FLAG_REMOVED_END */
31322
31323       /*Schedule the transmission of the current SI-Context */
31324       /*Find out the messg length for the SI message */
31325       /* warningSiFlag is to differentiate between Warning SI
31326        * and Other SI */
31327         if((rgSCHUtlGetMcsAndNPrb(cell, &nPrb, &mcs, &msgLen)) != ROK)
31328         {
31329            RETVOID; 
31330         }
31331
31332       cell->siCb.siCtx.i = RGSCH_CALC_SF_DIFF(crntTimInfo,
31333             cell->siCb.siCtx.timeToTx);
31334    } 
31335
31336
31337    /*Get the number of rb required */
31338    /*rgSCHCmnClcRbAllocForFxdTb(cell, msgLen, cellDl->ccchCqi, &rb);*/
31339    if(cellDl->bitsPerRb==0)
31340    {
31341       while ((rgTbSzTbl[0][0][rb]) < (U32) (msgLen*8))
31342       {
31343          rb++;
31344       }
31345       rb = rb+1;
31346    }
31347    else
31348    {
31349       rb = RGSCH_CEIL((msgLen*8), cellDl->bitsPerRb);
31350    }
31351    /* DwPTS Scheduling Changes Start */   
31352 #ifdef LTE_TDD
31353    if (sf->sfType == RG_SCH_SPL_SF_DATA) 
31354    {
31355       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
31356
31357       /* Calculate the less RE's because of DwPTS */
31358        lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
31359
31360        /* Increase number of RBs in Spl SF to compensate for lost REs */
31361        rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
31362    }
31363 #endif
31364    /* DwPTS Scheduling Changes End */   
31365    /*ccpu00115595- end*/
31366    /* Additional check to see if required RBs
31367     * exceeds the available */
31368    if (rb > sf->bw - sf->bwAssigned)
31369    {
31370       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,  "rgSCHDlSiSched(): "
31371          "BW allocation failed CRNTI:%d",RGSCH_SI_RNTI);
31372       RETVOID;
31373    }
31374
31375    /* Update the subframe Allocated BW field */
31376    sf->bwAssigned = sf->bwAssigned + rb;
31377
31378    /*Fill the parameters in allocInfo */
31379    allocInfo->bcchAlloc.rnti = RGSCH_SI_RNTI;
31380    allocInfo->bcchAlloc.dlSf = sf;
31381    allocInfo->bcchAlloc.rbsReq = rb;
31382    /*ccpu00116710- MCS is not getting assigned */
31383    allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
31384
31385    /* ccpu00117510 - ADD - Assignment of nPrb and other information */
31386    allocInfo->bcchAlloc.nPrb = nPrb;
31387    allocInfo->bcchAlloc.tbInfo[0].bytesReq = msgLen;
31388    allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
31389    RETVOID;
31390 }
31391 #endif /*RGR_SI_SCH*/
31392
31393 \f
31394 /* ccpu00117452 - MOD - Changed macro name from
31395    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
31396 #ifdef RGR_CQI_REPT
31397 /**
31398  * @brief This function Updates the DL CQI for the UE.
31399  *
31400  * @details
31401  *
31402  *     Function: rgSCHCmnUeDlPwrCtColltCqiRept
31403  *     Purpose:  Manages PUSH N CQI reporting
31404  *         Step 1: Store the CQI in collation array
31405  *         Step 2: Increament the tracking count
31406  *         Step 3: Check is it time to to send the report
31407  *         Step 4: if yes, Send StaInd to RRM
31408  *         Step 4.1: Fill StaInd for sending collated N CQI rpeorts
31409  *         Step 4.2: Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM
31410  *         Step 4.2.1: If sending was not sucessful, return RFAILED
31411  *         Step 4.2.2: If sending was sucessful, return ROK
31412  *         Step 5: If no, return
31413  *     Invoked by: rgSCHCmnDlCqiInd
31414  *
31415  *  @param[in]  RgSchCellCb        *cell
31416  *  @param[in]  RgSchUeCb          *ue
31417  *  @param[in]  RgrUeCqiRept        *ueCqiRpt
31418  *  @return  Void
31419  *
31420  **/
31421 #ifdef ANSI
31422 PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept
31423 (
31424 RgSchCellCb        *cell,
31425 RgSchUeCb          *ue,
31426 RgrUeCqiRept        *ueCqiRpt
31427 )
31428 #else
31429 PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, ueCqiRpt)
31430 RgSchCellCb        *cell;
31431 RgSchUeCb          *ue;
31432 RgrUeCqiRept        *ueCqiRpt;
31433 #endif
31434 {
31435    U8    *cqiCount = NULLP;
31436    S16   retVal;
31437    RgrStaIndInfo *staInfo = NULLP;
31438
31439    TRC2(rgSCHCmnUeDlPwrCtColltCqiRept)
31440
31441    /* Step 1: Store the CQI in collation array */
31442    /* Step 2: Increament the tracking count */
31443    cqiCount = &(ue->schCqiInfo.cqiCount);
31444    ue->schCqiInfo.cqiRept[(*cqiCount)++] =
31445                   *ueCqiRpt;
31446
31447
31448    /* Step 3: Check is it time to to send the report */
31449    if(RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(ue))
31450    {
31451    /* Step 4: if yes, Send StaInd to RRM */
31452       retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo,
31453                sizeof(RgrStaIndInfo));
31454       if (retVal != ROK)
31455       {
31456          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not "
31457             "allocate memory for sending StaInd CRNTI:%d",ue->ueId);
31458          RETVALUE(retVal);
31459       }
31460
31461    /* Step 4.1: Fill StaInd for sending collated N CQI rpeorts */
31462 #ifdef CA_DBG
31463       {
31464          extern U32 gCqiReptToAppCount;
31465          gCqiReptToAppCount++;
31466       
31467       }
31468
31469 #endif
31470       retVal = rgSCHUtlFillSndStaInd(cell, ue, staInfo,
31471             ue->cqiReptCfgInfo.numColltdCqiRept);
31472       RETVALUE(retVal);
31473
31474    }
31475
31476    RETVALUE(ROK);
31477 } /* End of rgSCHCmnUeDlPwrCtColltCqiRept */
31478
31479 #endif /* End of RGR_CQI_REPT */
31480
31481 /**
31482  * @brief This function checks for the retransmisson
31483  *        for a DTX scenario.
31484  * @details
31485  *
31486  *     Function:
31487  *     Purpose:
31488  *     Invoked by:
31489  *
31490  *  @param[in]  RgSchCellCb        *cell
31491  *  @param[in]  RgSchUeCb          *ue
31492  *  @param[in]
31493  *  @return  Void
31494  *
31495  **/
31496 #ifdef ANSI
31497 PUBLIC Void rgSCHCmnChkRetxAllowDtx
31498 (
31499 RgSchCellCb        *cell,
31500 RgSchUeCb          *ueCb,
31501 RgSchDlHqProcCb    *proc,
31502 Bool               *reTxAllwd
31503 )
31504 #else
31505 PUBLIC Void rgSCHCmnChkRetxAllowDtx(cell, ueCb, proc, reTxAllwd)
31506 RgSchCellCb        *cell;
31507 RgSchUeCb          *ueCb;
31508 RgSchDlHqProcCb    *proc;
31509 Bool               *reTxAllwd;
31510 #endif
31511 {
31512    TRC3(rgSCHCmnChkRetxAllowDtx)
31513
31514
31515    *reTxAllwd = TRUE;
31516    /* Fix */
31517    if ((proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX))
31518    {
31519        *reTxAllwd = FALSE;
31520    }
31521
31522    RETVOID;
31523 }
31524
31525 /**
31526  * @brief API for calculating the SI Set Id 
31527  *
31528  * @details
31529  *
31530  *     Function: rgSCHCmnGetSiSetId
31531  *
31532  *     This API is used for calculating the SI Set Id, as shown below
31533  *     
31534  *          siSetId = 0        siSetId = 1
31535  *     |******************|******************|---------------->
31536  *   (0,0)              (8,0)              (16,0)          (SFN, SF)
31537  *    
31538  *
31539  *  @param[in]  U16     sfn                   
31540  *  @param[in]  U8      sf
31541  *  @return     U16     siSetId
31542  **/
31543 #ifdef ANSI
31544 PUBLIC U16 rgSCHCmnGetSiSetId
31545 (
31546 U16    sfn,
31547 U8     sf,
31548 U16    minPeriodicity
31549 )
31550 #else
31551 PUBLIC U16 rgSCHCmnGetSiSetId(sfn, sf, minPeriodicity)
31552 U16    sfn;
31553 U8     sf
31554 U16    minPeriodicity;
31555 #endif
31556 {
31557    /* 80 is the minimum SI periodicity in sf. Also
31558     * all other SI periodicities are multiples of 80 */
31559     RETVALUE (((sfn * RGSCH_NUM_SUB_FRAMES_5G) + sf) / (minPeriodicity * 10));
31560 }
31561 #ifdef LTE_TDD
31562 /**
31563  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
31564  *
31565  * @details
31566  *
31567  *     Function: rgSCHCmnCalcDwPtsTbSz
31568  *
31569  *  @param[in]     RgSchCellCb    *cell                   
31570  *  @param[in]     U32             bo
31571  *  @param[in/out] U8             *rb
31572  *  @param[in/out] U8             *iTbs
31573  *  @param[in]     U8              lyr
31574  *  @param[in]     U8              cfi
31575  *  @return        U32             tbSz
31576  **/
31577 #ifdef ANSI
31578 PRIVATE U32 rgSCHCmnCalcDwPtsTbSz
31579 (
31580 RgSchCellCb    *cell,
31581 U32             bo,
31582 U8             *rb,
31583 U8             *iTbs,
31584 U8              lyr,
31585 U8              cfi
31586 )
31587 #else
31588 PRIVATE U32 rgSCHCmnCalcDwPtsTbSz(cell, bo, rb, iTbs, lyr, cfi)
31589 RgSchCellCb    *cell;
31590 U32             bo;
31591 U8             *rb;
31592 U8             *iTbs;
31593 U8              lyr;
31594 U8              cfi;
31595 #endif
31596 {
31597     U32             tbSz;
31598     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
31599     U32             numRE      = *rb * cellDl->noResPerRb[cfi];
31600     U32             numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
31601
31602     TRC2(rgSCHCmnCalcDwPtsTbSz);
31603
31604     /* DwPts Rb cannot exceed the cell Bw */
31605     numDwPtsRb = RGSCH_MIN(numDwPtsRb, cellDl->maxDlBwPerUe);
31606     
31607     /* Adjust the iTbs for optimum usage of the DwPts region. 
31608      * Using the same iTbs adjustment will not work for all 
31609      * special subframe configurations and iTbs levels. Hence use the 
31610      * static iTbs Delta table for adjusting the iTbs  */
31611     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs);
31612     
31613     if (bo)
31614     {
31615        while(rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1] < bo*8 &&
31616              numDwPtsRb < cellDl->maxDlBwPerUe) 
31617        {
31618           (numDwPtsRb)++;
31619        }
31620
31621        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
31622     }
31623     else
31624     {
31625        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
31626     }
31627     *rb = numDwPtsRb;
31628
31629     RETVALUE(tbSz/8);
31630 }
31631
31632 /**
31633  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
31634  *
31635  * @details
31636  *
31637  *     Function: rgSCHCmnCalcDwPtsTbSz2Cw
31638  *
31639  *  @param[in]      RgSchCellCb    *cell                   
31640  *  @param[in]      U32             bo
31641  *  @param[in/out]  U8             *rb
31642  *  @param[in]      U8              maxRb
31643  *  @param[in/out]  U8             *iTbs1
31644  *  @param[in/out]  U8             *iTbs2
31645  *  @param[in]      U8              lyr1
31646  *  @param[in]      U8              lyr2
31647  *  @return[in/out] U32            *tb1Sz
31648  *  @return[in/out] U32            *tb2Sz
31649  *  @param[in]      U8              cfi 
31650  **/
31651 #ifdef ANSI
31652 PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw
31653 (
31654 RgSchCellCb    *cell,
31655 U32             bo,
31656 U8             *rb,
31657 U8              maxRb,
31658 U8             *iTbs1,
31659 U8             *iTbs2,
31660 U8              lyr1,
31661 U8              lyr2,
31662 U32            *tb1Sz, 
31663 U32            *tb2Sz,
31664 U8              cfi
31665 )
31666 #else
31667 PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, rb, maxRb, iTbs1, iTbs2, 
31668       lyr1, lyr2, tb1Sz, tb2Sz, cfi)
31669 RgSchCellCb    *cell;
31670 U32             bo;
31671 U8             *rb;
31672 U8              maxRb;
31673 U8             *iTbs1;
31674 U8             *iTbs2;
31675 U8              lyr1;
31676 U8              lyr2;
31677 U32            *tb1Sz; 
31678 U32            *tb2Sz;
31679 U8              cfi;
31680 #endif
31681 {
31682     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
31683     U32             numRE      = *rb * cellDl->noResPerRb[cfi];
31684     U32             numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
31685
31686     TRC2(rgSCHCmnCalcDwPtsTbSz2Cw);
31687
31688     /* DwPts Rb cannot exceed the cell Bw */
31689     numDwPtsRb = RGSCH_MIN(numDwPtsRb, maxRb);
31690     
31691     /* Adjust the iTbs for optimum usage of the DwPts region. 
31692      * Using the same iTbs adjustment will not work for all 
31693      * special subframe configurations and iTbs levels. Hence use the 
31694      * static iTbs Delta table for adjusting the iTbs  */
31695     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs1);
31696     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs2);
31697     
31698     while((rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1] +
31699            rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1])< bo*8 &&
31700           numDwPtsRb < maxRb) 
31701     {
31702        (numDwPtsRb)++;
31703     }
31704
31705     *tb1Sz = rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
31706     *tb2Sz = rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
31707
31708     *rb = numDwPtsRb;
31709
31710     RETVOID;    
31711 }
31712
31713 #endif
31714
31715 /**
31716  * @brief Updates the GBR LCGs when datInd is received from MAC
31717  * 
31718  * @details
31719  *
31720  *     Function: rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
31721  *     Purpose:  This function updates the GBR LCGs 
31722  *               when datInd is received from MAC.
31723  *
31724  *     Invoked by: TOM
31725  *
31726  *  @param[in]  RgSchCellCb      *cell
31727  *  @param[in]  RgSchUeCb        *ue
31728  *  @param[in]  RgInfUeDatInd    *datInd
31729  *  @return Void
31730  **/
31731 #ifdef ANSI
31732 PUBLIC Void rgSCHCmnUpdUeDataIndLcg 
31733 (
31734 RgSchCellCb    *cell,
31735 RgSchUeCb      *ue,
31736 RgInfUeDatInd  *datInd
31737 )
31738 #else
31739 PUBLIC Void rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
31740 RgSchCellCb    *cell;
31741 RgSchUeCb      *ue;
31742 RgInfUeDatInd  *datInd;
31743 #endif
31744 {
31745    U32 idx = 0;
31746    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
31747 #ifdef DEBUGP
31748    Inst                inst = cell->instIdx;
31749 #endif
31750
31751    TRC2(rgSCHCmnUpdUeDataIndLcg);
31752
31753    for (idx = 0; (idx < RGINF_MAX_LCG_PER_UE - 1); idx++)
31754    {
31755       if (datInd->lcgInfo[idx].bytesRcvd != 0)
31756       {
31757          U8  lcgId     = datInd->lcgInfo[idx].lcgId;
31758          U32 bytesRcvd = datInd->lcgInfo[idx].bytesRcvd;
31759
31760          if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
31761          {
31762             RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
31763             if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
31764             {
31765                if(bytesRcvd > cmnLcg->effGbr)
31766                {
31767                   bytesRcvd -= cmnLcg->effGbr;
31768                   cmnLcg->effDeltaMbr = (cmnLcg->effDeltaMbr > bytesRcvd) ? \
31769                                         (cmnLcg->effDeltaMbr - bytesRcvd) : (0);
31770                   cmnLcg->effGbr = 0;
31771                }
31772                else
31773                {
31774                   cmnLcg->effGbr -= bytesRcvd;
31775                }
31776                /* To keep BS updated with the amount of data received for the GBR */
31777                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31778                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31779                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr+cmnLcg->effDeltaMbr);
31780             }
31781             else if(lcgId != 0)
31782             {
31783                ue->ul.effAmbr = (ue->ul.effAmbr > datInd->lcgInfo[idx].bytesRcvd) ? \
31784                                (ue->ul.effAmbr - datInd->lcgInfo[idx].bytesRcvd) : (0);
31785                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31786                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31787                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
31788                ue->ul.nonGbrLcgBs = (ue->ul.nonGbrLcgBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31789                                    (ue->ul.nonGbrLcgBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31790             }
31791             ue->ul.nonLcg0Bs = (ue->ul.nonLcg0Bs > datInd->lcgInfo[idx].bytesRcvd) ? \
31792                               (ue->ul.nonLcg0Bs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31793          }
31794       }
31795       else
31796       {
31797          break;
31798       }
31799    }
31800 #ifdef EMTC_ENABLE
31801    if(TRUE == ue->isEmtcUe)
31802    {
31803       if (cellSch->apisEmtcUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
31804       {
31805          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure"));
31806       }
31807
31808    }
31809    else
31810 #endif
31811    {
31812       if (cellSch->apisUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
31813       {
31814          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure"));
31815       }
31816    }
31817 }
31818
31819
31820 /** @brief This function initializes DL allocation lists and prepares
31821  *         for scheduling  
31822  *
31823  * @details
31824  *
31825  *     Function: rgSCHCmnInitRbAlloc
31826  *
31827  * @param  [in] RgSchCellCb    *cell
31828  *
31829  * Returns: Void
31830  *
31831  */
31832 #ifdef ANSI
31833 PRIVATE Void  rgSCHCmnInitRbAlloc 
31834 (
31835 RgSchCellCb        *cell
31836 )
31837 #else
31838 PRIVATE Void  rgSCHCmnInitRbAlloc (cell)
31839 RgSchCellCb        *cell;
31840 #endif
31841 {
31842    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
31843    CmLteTimingInfo        frm;
31844    RgSchDlSf              *dlSf;
31845         U8                     idx;
31846    
31847    TRC2(rgSCHCmnInitRbAlloc);
31848
31849 /* Initializing RgSchCmnUlRbAllocInfo structure.*/
31850    rgSCHCmnInitDlRbAllocInfo(&cellSch->allocInfo);
31851
31852    frm = cellSch->dl.time;
31853
31854    dlSf = rgSCHUtlSubFrmGet(cell, frm);
31855 #ifdef RG_5GTF
31856    dlSf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
31857    dlSf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
31858         for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
31859    {
31860       dlSf->sfBeamInfo[idx].totVrbgAllocated = 0;
31861       dlSf->sfBeamInfo[idx].totVrbgRequired = 0;
31862       dlSf->sfBeamInfo[idx].vrbgStart = 0;
31863    }
31864 #endif
31865    dlSf->remUeCnt = cellSch->dl.maxUePerDlSf;
31866    /* Updating the Subframe information in RBAllocInfo */
31867    cellSch->allocInfo.dedAlloc.dedDlSf   = dlSf;
31868    cellSch->allocInfo.msg4Alloc.msg4DlSf = dlSf;
31869
31870    /* LTE_ADV_FLAG_REMOVED_START */
31871    /* Determine next scheduling subframe is ABS or not */
31872    if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
31873    {
31874       cell->lteAdvCb.absPatternDlIdx = 
31875          ((frm.sfn*RGSCH_NUM_SUB_FRAMES_5G) + frm.subframe) % RGR_ABS_PATTERN_LEN;
31876       cell->lteAdvCb.absDlSfInfo = (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern[
31877             cell->lteAdvCb.absPatternDlIdx]);
31878
31879    }
31880    else
31881    {
31882       cell->lteAdvCb.absDlSfInfo = RG_SCH_ABS_DISABLED;
31883    }
31884    /* LTE_ADV_FLAG_REMOVED_END */
31885
31886 #ifdef RGR_V1
31887    cellSch->allocInfo.ccchSduAlloc.ccchSduDlSf = dlSf;
31888 #endif
31889 #ifdef LTEMAC_SPS
31890    /* Update subframe-wide allocation information with SPS allocation */
31891    rgSCHCmnSpsDlUpdDlSfAllocWithSps(cell, frm, dlSf);
31892 #endif
31893    RETVOID;
31894 }
31895
31896
31897
31898 #ifdef DL_LA
31899 /**
31900  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
31901  * actual iTbs
31902  * 
31903  * @details
31904  *
31905  *     Function: rgSCHCmnSendTxModeInd(cell, ueUl, newTxMode)
31906  *     Purpose:  This function sends the TX mode Change 
31907  *               indication to RRM
31908  *     change
31909  *
31910  *     Invoked by: CMN
31911  *
31912  *  @param[in]  RgSchCellCb      *cell
31913  *  @param[in]  RgSchUeCb        *ue
31914  *  @param[in]  U8               newTxMode
31915  *  @return Void
31916  **/
31917 #ifdef ANSI
31918 PRIVATE Void rgSCHCmnSendTxModeInd 
31919 (
31920 RgSchCellCb    *cell,
31921 RgSchUeCb      *ue,
31922 U8             newTxMode
31923 )
31924 #else
31925 PRIVATE Void rgSCHCmnSendTxModeInd(cell, ue, newTxMode)
31926 RgSchCellCb    *cell;
31927 RgSchUeCb      *ue;
31928 U8             newTxMode;
31929 #endif
31930
31931    RgmTransModeInd   *txModeChgInd;
31932    RgSchCmnDlUe      *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
31933
31934    TRC2(rgSCHCmnSendTxModeInd);
31935
31936    if(!(ueDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG))
31937    {
31938       /* Mem Alloc */
31939       if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
31940                cell->rgmSap->sapCfg.sapPst.pool, (Data**)&txModeChgInd,
31941                sizeof(RgmTransModeInd)) != ROK)
31942       {
31943          RETVOID;
31944       }
31945       RG_SCH_FILL_RGM_TRANSMODE_IND(ue->ueId, cell->cellId, newTxMode, txModeChgInd);
31946       RgUiRgmChangeTransModeInd(&(cell->rgmSap->sapCfg.sapPst),
31947             cell->rgmSap->sapCfg.suId, txModeChgInd);
31948    }
31949
31950    ue->mimoInfo.txModUpChgFactor = 0;
31951    ue->mimoInfo.txModDownChgFactor = 0;
31952    ueDl->laCb[0].deltaiTbs = 0;
31953
31954    RETVOID;
31955 }
31956
31957 /**
31958  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
31959  * actual iTbs
31960  * 
31961  * @details
31962  *
31963  *     Function: rgSchCheckAndTriggerModeChange(cell, ueUl, iTbsNew)
31964  *     Purpose:  This function update and check for threashold for TM mode
31965  *     change
31966  *
31967  *     Invoked by: CMN
31968  *
31969  *  @param[in]  RgSchCellCb      *cell
31970  *  @param[in]  RgSchUeCb        *ue
31971  *  @param[in]  U8               iTbs
31972  *  @return Void
31973  **/
31974 #ifdef ANSI
31975 PUBLIC Void rgSchCheckAndTriggerModeChange
31976 (
31977 RgSchCellCb    *cell,
31978 RgSchUeCb      *ue,
31979 U8             reportediTbs,
31980 U8             previTbs,
31981 U8             maxiTbs
31982 )
31983 #else
31984 PUBLIC Void rgSchCheckAndTriggerModeChange(cell, ue, reportediTbs, previTbs, maxiTbs)
31985 RgSchCellCb    *cell;
31986 RgSchUeCb      *ue;
31987 U8             reportediTbs;
31988 U8             previTbs;
31989 U8             maxiTbs;
31990 #endif
31991 {
31992    RgrTxMode          txMode;       /*!< UE's Transmission Mode */
31993    RgrTxMode          modTxMode;       /*!< UE's Transmission Mode */
31994
31995    TRC2(rgSchCheckAndTriggerModeChange);
31996
31997    txMode = ue->mimoInfo.txMode;
31998
31999    /* Check for Step down */
32000    /* Step down only when TM4 is configured. */
32001    if(RGR_UE_TM_4 == txMode)
32002    {
32003       if((previTbs <= reportediTbs) && ((reportediTbs - previTbs) >= RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR))
32004       {
32005          ue->mimoInfo.txModDownChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
32006       }
32007       else
32008       {
32009          ue->mimoInfo.txModDownChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
32010       }
32011
32012       ue->mimoInfo.txModDownChgFactor =  
32013          RGSCH_MAX(ue->mimoInfo.txModDownChgFactor, -(RG_SCH_MODE_CHNG_STEPDOWN_THRSHD));
32014
32015       if(ue->mimoInfo.txModDownChgFactor >= RG_SCH_MODE_CHNG_STEPDOWN_THRSHD)
32016       {
32017          /* Trigger Mode step down */
32018          modTxMode = RGR_UE_TM_3;
32019          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
32020       }
32021    }
32022
32023    /* Check for Setup up */
32024    /* Step Up only when TM3 is configured, Max possible Mode is TM4*/
32025    if(RGR_UE_TM_3 == txMode)
32026    {
32027       if((previTbs > reportediTbs) || (maxiTbs == previTbs))
32028       {
32029          ue->mimoInfo.txModUpChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
32030       }
32031       else
32032       {
32033          ue->mimoInfo.txModUpChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
32034       }
32035
32036       ue->mimoInfo.txModUpChgFactor = 
32037          RGSCH_MAX(ue->mimoInfo.txModUpChgFactor, -(RG_SCH_MODE_CHNG_STEPUP_THRSHD));
32038
32039       /* Check if TM step up need to be triggered */
32040       if(ue->mimoInfo.txModUpChgFactor >= RG_SCH_MODE_CHNG_STEPUP_THRSHD)
32041       {
32042          /* Trigger mode chnage */
32043          modTxMode =  RGR_UE_TM_4;
32044          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
32045       }
32046    }
32047
32048    RETVOID;
32049 }
32050 #endif
32051
32052 /**
32053 * @brief Updates the GBR LCGs when datInd is received from MAC
32054  * 
32055  * @details
32056  *
32057  *     Function: rgSCHCmnIsDlCsgPrio (cell)
32058  *     Purpose:  This function returns if csg UEs are
32059  *               having priority at current time
32060  *
32061  *     Invoked by: Scheduler
32062  *
32063  *  @param[in]  RgSchCellCb      *cell
32064  *  @param[in]  RgSchUeCb        *ue
32065  *  @param[in]  RgInfUeDatInd    *datInd
32066  *  @return Void
32067  **/
32068 #ifdef ANSI
32069 PUBLIC Bool rgSCHCmnIsDlCsgPrio
32070 (
32071 RgSchCellCb    *cell
32072 )
32073 #else
32074 PUBLIC Bool rgSCHCmnIsDlCsgPrio(cell)
32075 RgSchCellCb    *cell;
32076 #endif
32077 {
32078   
32079    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
32080  
32081    TRC2(rgSCHCmnIsDlCsgPrio)
32082    /* Calculating the percentage resource allocated */
32083    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
32084    {
32085       RETVALUE(FALSE);
32086    }
32087    else
32088    {
32089       if(((cmnDlCell->ncsgPrbCnt * 100) / cmnDlCell->totPrbCnt) < cell->minDlResNonCsg)
32090       {
32091          RETVALUE(FALSE);
32092       }
32093       else
32094       {
32095          RETVALUE(TRUE);
32096       }
32097    }
32098 }
32099
32100 /**
32101 * @brief Updates the GBR LCGs when datInd is received from MAC
32102  * 
32103  * @details
32104  *
32105  *     Function: rgSCHCmnIsUlCsgPrio (cell)
32106  *     Purpose:  This function returns if csg UEs are
32107  *               having priority at current time
32108  *
32109  *     Invoked by: Scheduler
32110  *
32111  *  @param[in]  RgSchCellCb      *cell
32112  *  @param[in]  RgSchUeCb        *ue
32113  *  @param[in]  RgInfUeDatInd    *datInd
32114  *  @return Void
32115  **/
32116 #ifdef ANSI
32117 PUBLIC Bool rgSCHCmnIsUlCsgPrio
32118 (
32119 RgSchCellCb    *cell
32120 )
32121 #else
32122 PUBLIC Bool rgSCHCmnIsUlCsgPrio(cell)
32123 RgSchCellCb    *cell;
32124 #endif
32125 {
32126    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
32127  
32128    TRC2(rgSCHCmnIsUlCsgPrio)
32129
32130    /* Calculating the percentage resource allocated */
32131    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
32132    {
32133       RETVALUE(FALSE);
32134    }
32135    else
32136    {
32137       if (((cmnUlCell->ncsgPrbCnt * 100) /cmnUlCell->totPrbCnt) < cell->minUlResNonCsg)
32138       {
32139          RETVALUE(FALSE);
32140       }
32141       else
32142       {
32143          RETVALUE(TRUE);
32144       }
32145    }
32146 }
32147 /**********************************************************************
32148
32149   End of file
32150 **********************************************************************/