924c48831ff000c2e3aca5121fb12ca6921aa1ea
[o-du/l2.git] / src / 5gnrsch / 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
36 /* header include files -- defines (.h) */
37 #include "common_def.h"
38 #include "lrg.h"
39 #include "rgr.h"
40 #include "tfu.h"
41 #include "rgm.h"
42 #include "rg_env.h"
43 #include "rg_sch_err.h"
44 #include "rg_sch_inf.h"
45 #include "rg_sch.h"
46 #include "rg_sch_cmn.h"
47 /* header/extern include files (.x) */
48 #include "tfu.x"           /* TFU types */
49 #include "lrg.x"           /* layer management typedefs for MAC */
50 #include "rgr.x"           /* layer management typedefs for MAC */
51 #include "rgm.x"           /* layer management typedefs for MAC */
52 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
53 #include "rg_sch.x"        /* typedefs for Scheduler */
54 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
55 #include "sch_utils.h"
56 #ifdef MAC_SCH_STATS
57 #include "lrg.x"            /* Stats Structures */
58 #endif /* MAC_SCH_STATS */
59 #ifdef __cplusplus
60 extern "C" {
61 #endif /* __cplusplus */
62
63 #ifdef EMTC_ENABLE
64 uint32_t emtcStatsUlTomSrInd;
65 uint32_t emtcStatsUlBsrTmrTxp;
66 #endif
67
68 #define RG_ITBS_DIFF(_x, _y) ((_x) > (_y) ? (_x) - (_y) : (_y) - (_x))
69 Void rgSCHSc1UlInit ARGS((RgUlSchdApis *apis));
70 #ifdef RG_PHASE2_SCHED
71 Void rgSCHRrUlInit ARGS((RgUlSchdApis *apis));
72 #ifdef EMTC_ENABLE
73 Void rgSCHEmtcHqInfoFree ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP));
74 Void rgSCHEmtcRrUlInit ARGS((RgUlSchdApis *apis));
75 Void rgSCHEmtcCmnDlInit ARGS((Void));
76 Void rgSCHEmtcCmnUlInit ARGS((Void));
77 Void rgSCHEmtcCmnUeNbReset ARGS((RgSchUeCb *ueCb));
78 RgSchCmnCqiToTbs *rgSchEmtcCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
79 #endif
80 Void rgSCHMaxciUlInit ARGS((RgUlSchdApis *apis));
81 Void rgSCHPfsUlInit ARGS((RgUlSchdApis *apis));
82 #endif
83 Void rgSCHSc1DlInit ARGS((RgDlSchdApis *apis));
84 #ifdef RG_PHASE2_SCHED
85 Void rgSCHRrDlInit ARGS((RgDlSchdApis *apis));
86 #ifdef EMTC_ENABLE
87 Void rgSCHEmtcRrDlInit ARGS((RgDlEmtcSchdApis *apis));
88 #endif
89 Void rgSCHMaxciDlInit ARGS((RgDlSchdApis *apis));
90 Void rgSCHPfsDlInit ARGS((RgDlSchdApis *apis));
91 #ifdef TFU_UPGRADE
92 Void rgSCHDlfsInit ARGS((RgDlfsSchdApis *apis));
93 #endif
94 #endif
95 #ifdef EMTC_ENABLE
96 Void rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl ARGS((RgSchCellCb *cell));
97 Void rgSCHCmnGetEmtcDciFrmtSizes ARGS((RgSchCellCb *cell));
98 Void rgSCHEmtcRrUlProcRmvFrmRetx ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *proc));
99 S16 rgSCHCmnPrecompEmtcMsg3Vars
100 ARGS((
101 RgSchCmnUlCell *cellUl,
102 uint8_t           ccchCqi,
103 uint16_t          msgSzA,
104 uint8_t           sbSize,
105 Bool         isEcp
106 ));
107 Void rgSCHEmtcCmnUeCcchSduDel
108 (
109 RgSchCellCb  *cell,
110 RgSchUeCb    *ueCb
111 );
112 Void rgSCHEmtcRmvFrmTaLst
113 (
114 RgSchCmnDlCell  *cellDl,
115 RgSchUeCb       *ue
116 );
117 Void rgSCHEmtcInitTaLst
118 (
119 RgSchCmnDlCell  *cellDl
120 );
121 Void rgSCHEmtcAddToTaLst
122 (
123 RgSchCmnDlCell  *cellDl,
124 RgSchUeCb       *ue
125 );
126
127 #endif
128
129 #ifdef RGR_SI_SCH
130 static Void rgSCHDlSiSched ARGS((RgSchCellCb  *cell,
131                       RgSchCmnDlRbAllocInfo *allocInfo,
132                       RgInfSfAlloc  *subfrmAlloc));
133 static Void rgSCHChkNUpdSiCfg ARGS((RgSchCellCb  *cell));
134 static Void rgSCHSelectSi ARGS((RgSchCellCb *cell));
135 #endif /*RGR_SI_SCH*/
136 /* LTE_ADV_FLAG_REMOVED_START */
137 #ifdef UNUSED_FUNC
138 #ifndef LTE_TDD
139 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
140 (
141 RgSchCellCb        *cell,
142 RgSchUeCb          *ue,
143 RgSchDlSf          *dlSf,
144 uint8_t                 rbStrt,
145 uint8_t                 numRb
146 );
147 static S16 rgSCHCmnBuildRntpInfo (
148 RgSchCellCb        *cell,
149 uint8_t                 *rntpPtr,
150 uint8_t                  startRb,
151 uint8_t                  nmbRb,
152 uint16_t                 bw
153 );
154 #endif
155 static Void rgSCHCmnNonDlfsType0Alloc
156 (
157 RgSchCellCb        *cell,
158 RgSchDlSf          *dlSf,
159 RgSchDlRbAlloc     *allocInfo,
160 RgSchUeCb          *ue
161 );
162 static uint8_t rgSchCmnUlRvIdxToIMcsTbl[4] = {32, 30, 31, 29};
163 static Void rgSCHCmnUlNonadapRetx ARGS((
164 RgSchCmnUlCell  *cellUl,
165 RgSchUlAlloc    *alloc,
166 uint8_t               idx
167 ));
168 static Void rgSCHCmnUlSfRlsRetxProcs ARGS((
169 RgSchCellCb *cell,
170 RgSchUlSf   *sf
171 ));
172
173 #ifdef TFU_UPGRADE
174 static S16 rgSCHCmnUlMdfyGrntForCqi ARGS((
175 RgSchCellCb  *cell,
176 RgSchUeCb    *ue,
177 uint32_t          maxRb,
178 uint32_t          *numSb,
179 uint8_t           *iTbs,
180 uint32_t          hqSz,
181 uint32_t          stepDownItbs,
182 uint32_t          effTgt
183 ));
184 #endif
185 static Void rgSCHCmnFillHqPPdcchDciFrmt1 ARGS((
186 RgSchCellCb                *cell,
187 RgSchDlRbAlloc             *rbAllocInfo,
188 RgSchDlHqProcCb            *hqP,
189 RgSchPdcch                 *pdcch,
190 uint8_t                         tpc
191 ));
192 static Void rgSCHCmnFillHqPPdcchDciFrmt1A ARGS((
193 RgSchCellCb                *cell,
194 RgSchDlRbAlloc             *rbAllocInfo,
195 RgSchDlHqProcCb            *hqP,
196 RgSchPdcch                 *pdcch,
197 uint8_t                         tpc
198 ));
199 static Void rgSCHCmnFillHqPPdcchDciFrmt1B ARGS((
200 RgSchCellCb                *cell,
201 RgSchDlRbAlloc             *rbAllocInfo,
202 RgSchDlHqProcCb            *hqP,
203 RgSchPdcch                 *pdcch,
204 uint8_t                         tpc
205 ));
206 static Void rgSCHCmnFillHqPPdcchDciFrmt2 ARGS((
207 RgSchCellCb                *cell,
208 RgSchDlRbAlloc             *rbAllocInfo,
209 RgSchDlHqProcCb            *hqP,
210 RgSchPdcch                 *pdcch,
211 uint8_t                         tpc
212 ));
213 static Void rgSCHCmnFillHqPPdcchDciFrmt2A ARGS((
214 RgSchCellCb                *cell,
215 RgSchDlRbAlloc             *rbAllocInfo,
216 RgSchDlHqProcCb            *hqP,
217 RgSchPdcch                 *pdcch,
218 uint8_t                         tpc
219 ));
220
221 #endif
222
223 Void rgSCHCmnDlSpsSch
224 (
225  RgSchCellCb        *cell
226 );
227 /* LTE_ADV_FLAG_REMOVED_END */
228
229 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc ARGS((
230 RgSchCellCb           *cell,
231 RgSchCmnDlRbAllocInfo *allocInfo
232 ));
233 static Void rgSCHBcchPcchDlRbAlloc ARGS((
234 RgSchCellCb           *cell,
235 RgSchCmnDlRbAllocInfo *allocInfo
236 ));
237 static Void rgSCHCmnDlBcchPcchAlloc ARGS((
238 RgSchCellCb  *cell
239 ));
240 #ifdef RGR_CQI_REPT
241 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
242  RgSchCellCb        *cell,
243  RgSchUeCb          *ue,
244  TfuDlCqiPucch      *pucchCqi,
245  RgrUeCqiRept       *ueCqiRept,
246  Bool               *isCqiAvail,
247  Bool               *is2ndCwCqiAvail
248  ));
249 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
250  RgSchCellCb        *cell,
251  RgSchUeCb          *ue,
252  TfuDlCqiPusch      *puschCqi,
253  RgrUeCqiRept       *ueCqiRept,
254  Bool               *isCqiAvail,
255  Bool               *is2ndCwCqiAvail
256  ));
257 #else
258 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
259  RgSchCellCb        *cell,
260  RgSchUeCb          *ue,
261  TfuDlCqiPucch      *pucchCqi
262  ));
263 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
264  RgSchCellCb        *cell,
265  RgSchUeCb          *ue,
266  TfuDlCqiPusch      *puschCqi
267  ));
268 #endif
269 /* ccpu00117452 - MOD - Changed macro name from
270    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
271 #ifdef RGR_CQI_REPT
272 static S16 rgSCHCmnUeDlPwrCtColltCqiRept ARGS((
273    RgSchCellCb        *cell,
274    RgSchUeCb          *ue,
275    RgrUeCqiRept        *ueCqiRept));
276 #endif /* End of RGR_CQI_REPT */
277 /* Fix: syed align multiple UEs to refresh at same time */
278 static Void rgSCHCmnGetRefreshPer ARGS((
279    RgSchCellCb  *cell,
280    RgSchUeCb    *ue,
281    uint32_t          *waitPer));
282 static S16 rgSCHCmnApplyUeRefresh ARGS((
283 RgSchCellCb     *cell,
284 RgSchUeCb       *ue));
285 #ifdef DL_LA
286 Void rgSCHCmnDlSetUeAllocLmtLa ARGS
287 ((
288 RgSchCellCb   *cell,
289 RgSchUeCb     *ue
290 ));
291 static Void rgSCHCheckAndSetTxScheme ARGS
292 ((
293 RgSchCellCb   *cell,
294 RgSchUeCb     *ue
295 ));
296 #endif
297
298 #ifdef LTE_TDD
299 static uint32_t rgSCHCmnCalcDwPtsTbSz ARGS
300 ((
301 RgSchCellCb    *cell,
302 uint32_t             bo,
303 uint8_t             *rb,
304 uint8_t             *iTbs,
305 uint8_t              lyr,
306 uint8_t              cfi
307 ));
308
309 static Void rgSCHCmnCalcDwPtsTbSz2Cw ARGS
310 ((
311 RgSchCellCb    *cell,
312 uint32_t             bo,
313 uint8_t             *rb,
314 uint8_t              maxRb,
315 uint8_t             *iTbs1,
316 uint8_t             *iTbs2,
317 uint8_t              lyr1,
318 uint8_t              lyr2,
319 uint32_t            *tb1Sz, 
320 uint32_t            *tb2Sz, 
321 uint8_t              cfi
322 ));
323
324 #endif
325 static Void  rgSCHCmnInitRbAlloc ARGS 
326 ((
327 RgSchCellCb        *cell
328 ));
329 #ifdef __cplusplus
330 }
331 #endif /* __cplusplus */
332
333
334 /* local defines */
335  RgSchdApis          rgSchCmnApis;
336 static RgUlSchdApis        rgSchUlSchdTbl[RGSCH_NUM_SCHEDULERS];
337 static RgDlSchdApis        rgSchDlSchdTbl[RGSCH_NUM_SCHEDULERS];
338 #ifdef EMTC_ENABLE
339 static RgUlSchdApis        rgSchEmtcUlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
340 static RgDlEmtcSchdApis        rgSchEmtcDlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
341 #endif
342 #ifdef RG_PHASE2_SCHED
343 static RgDlfsSchdApis      rgSchDlfsSchdTbl[RGSCH_NUM_DLFS_SCHEDULERS];
344 #endif
345 RgUlSchdInits       rgSchUlSchdInits = RGSCH_ULSCHED_INITS;
346 RgDlSchdInits       rgSchDlSchdInits = RGSCH_DLSCHED_INITS;
347 #ifdef EMTC_ENABLE
348 static RgEmtcUlSchdInits       rgSchEmtcUlSchdInits = RGSCH_EMTC_ULSCHED_INITS;
349 static RgEmtcDlSchdInits       rgSchEmtcDlSchdInits = RGSCH_EMTC_DLSCHED_INITS;
350 #endif
351 #if (defined (RG_PHASE2_SCHED) && defined (TFU_UPGRADE))
352 static RgDlfsSchdInits     rgSchDlfsSchdInits = RGSCH_DLFSSCHED_INITS;
353 #endif
354
355 typedef Void (*RgSchCmnDlAllocRbFunc) ARGS((RgSchCellCb *cell, RgSchDlSf *subFrm,
356 RgSchUeCb *ue, uint32_t bo, uint32_t *effBo, RgSchDlHqProcCb *proc,
357 RgSchCmnDlRbAllocInfo *cellWdAllocInfo));
358 typedef uint8_t (*RgSchCmnDlGetPrecInfFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, 
359       uint8_t numLyrs, Bool bothCwEnbld));
360 static Void rgSCHCmnDlAllocTxRbTM1 ARGS((
361 RgSchCellCb                *cell,
362 RgSchDlSf                  *subFrm,
363 RgSchUeCb                  *ue,
364 uint32_t                        bo,
365 uint32_t                        *effBo,
366 RgSchDlHqProcCb            *proc,
367 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
368 ));
369 static Void rgSCHCmnDlAllocTxRbTM2 ARGS((
370 RgSchCellCb                *cell,
371 RgSchDlSf                  *subFrm,
372 RgSchUeCb                  *ue,
373 uint32_t                        bo,
374 uint32_t                        *effBo,
375 RgSchDlHqProcCb            *proc,
376 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
377 ));
378 static Void rgSCHCmnDlAllocTxRbTM3 ARGS((
379 RgSchCellCb                *cell,
380 RgSchDlSf                  *subFrm,
381 RgSchUeCb                  *ue,
382 uint32_t                        bo,
383 uint32_t                        *effBo,
384 RgSchDlHqProcCb            *proc,
385 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
386 ));
387 static Void rgSCHCmnDlAllocTxRbTM4 ARGS((
388 RgSchCellCb                *cell,
389 RgSchDlSf                  *subFrm,
390 RgSchUeCb                  *ue,
391 uint32_t                        bo,
392 uint32_t                        *effBo,
393 RgSchDlHqProcCb            *proc,
394 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
395 ));
396 #ifdef RG_UNUSED
397 static Void rgSCHCmnDlAllocTxRbTM5 ARGS((
398 RgSchCellCb                *cell,
399 RgSchDlSf                  *subFrm,
400 RgSchUeCb                  *ue,
401 uint32_t                        bo,
402 uint32_t                        *effBo,
403 RgSchDlHqProcCb            *proc,
404 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
405 ));
406 #endif
407 static Void rgSCHCmnDlAllocTxRbTM6 ARGS((
408 RgSchCellCb                *cell,
409 RgSchDlSf                  *subFrm,
410 RgSchUeCb                  *ue,
411 uint32_t                        bo,
412 uint32_t                        *effBo,
413 RgSchDlHqProcCb            *proc,
414 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
415 ));
416 static Void rgSCHCmnDlAllocTxRbTM7 ARGS((
417 RgSchCellCb                *cell,
418 RgSchDlSf                  *subFrm,
419 RgSchUeCb                  *ue,
420 uint32_t                        bo,
421 uint32_t                        *effBo,
422 RgSchDlHqProcCb            *proc,
423 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
424 ));
425 static Void rgSCHCmnDlAllocRetxRbTM1 ARGS((
426 RgSchCellCb                *cell,
427 RgSchDlSf                  *subFrm,
428 RgSchUeCb                  *ue,
429 uint32_t                        bo,
430 uint32_t                        *effBo,
431 RgSchDlHqProcCb            *proc,
432 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
433 ));
434 static Void rgSCHCmnDlAllocRetxRbTM2 ARGS((
435 RgSchCellCb                *cell,
436 RgSchDlSf                  *subFrm,
437 RgSchUeCb                  *ue,
438 uint32_t                        bo,
439 uint32_t                        *effBo,
440 RgSchDlHqProcCb            *proc,
441 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
442 ));
443 static Void rgSCHCmnDlAllocRetxRbTM3 ARGS((
444 RgSchCellCb                *cell,
445 RgSchDlSf                  *subFrm,
446 RgSchUeCb                  *ue,
447 uint32_t                        bo,
448 uint32_t                        *effBo,
449 RgSchDlHqProcCb            *proc,
450 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
451 ));
452 static Void rgSCHCmnDlAllocRetxRbTM4 ARGS((
453 RgSchCellCb                *cell,
454 RgSchDlSf                  *subFrm,
455 RgSchUeCb                  *ue,
456 uint32_t                        bo,
457 uint32_t                        *effBo,
458 RgSchDlHqProcCb            *proc,
459 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
460 ));
461 #ifdef RG_UNUSED
462 static Void rgSCHCmnDlAllocRetxRbTM5 ARGS((
463 RgSchCellCb                *cell,
464 RgSchDlSf                  *subFrm,
465 RgSchUeCb                  *ue,
466 uint32_t                        bo,
467 uint32_t                        *effBo,
468 RgSchDlHqProcCb            *proc,
469 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
470 ));
471 #endif
472 static Void rgSCHCmnDlAllocRetxRbTM6 ARGS((
473 RgSchCellCb                *cell,
474 RgSchDlSf                  *subFrm,
475 RgSchUeCb                  *ue,
476 uint32_t                        bo,
477 uint32_t                        *effBo,
478 RgSchDlHqProcCb            *proc,
479 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
480 ));
481 static Void rgSCHCmnDlAllocRetxRbTM7 ARGS((
482 RgSchCellCb                *cell,
483 RgSchDlSf                  *subFrm,
484 RgSchUeCb                  *ue,
485 uint32_t                        bo,
486 uint32_t                        *effBo,
487 RgSchDlHqProcCb            *proc,
488 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
489 ));
490
491 #ifdef LTE_ADV 
492 static uint8_t rgSchGetN1ResCount ARGS ((
493  RgSchUeCb *ue,
494  uint16_t       servCellId 
495 ));
496 Bool rgSchCmnChkDataOnlyOnPcell 
497 (
498  RgSchUeCb         *ue,
499  RgSchDlSf         *dlSf
500 );
501 #endif /*LTE_ADV */
502 uint8_t rgSCHCmnCalcPcqiBitSz
503 (
504  RgSchUeCb    *ueCb, 
505  uint8_t           numTxAnt
506 );
507
508 #ifndef LTE_ADV
509 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
510 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[7] = {rgSCHCmnDlAllocTxRbTM1,
511 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
512 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7};
513
514 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
515 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[7] = {rgSCHCmnDlAllocRetxRbTM1,
516 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
517 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7};
518 #else
519 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
520 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[9] = {rgSCHCmnDlAllocTxRbTM1,
521 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
522 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7, NULLP, NULLP};
523
524 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
525 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[9] = {rgSCHCmnDlAllocRetxRbTM1,
526 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
527 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7, NULLP, NULLP};
528
529 #endif
530
531
532 static uint8_t rgSCHCmnDlTM3PrecInf2 ARGS((
533 RgSchCellCb                *cell,
534 RgSchUeCb                  *ue,
535 uint8_t                         numTxLyrs,
536 Bool                       bothCwEnbld
537 ));
538 static uint8_t rgSCHCmnDlTM3PrecInf4 ARGS((
539 RgSchCellCb                *cell,
540 RgSchUeCb                  *ue,
541 uint8_t                         numTxLyrs,
542 Bool                       bothCwEnbld
543 ));
544 static uint8_t rgSCHCmnDlTM4PrecInf2 ARGS((
545 RgSchCellCb                *cell,
546 RgSchUeCb                  *ue,
547 uint8_t                         numTxLyrs,
548 Bool                       bothCwEnbld
549 ));
550 static uint8_t rgSCHCmnDlTM4PrecInf4 ARGS((
551 RgSchCellCb                *cell,
552 RgSchUeCb                  *ue,
553 uint8_t                         numTxLyrs,
554 Bool                       bothCwEnbld
555 ));
556 /* Functions specific to each transmission mode for DL RB Allocation*/
557 RgSchCmnDlGetPrecInfFunc getPrecInfoFunc[2][2] = {
558 {rgSCHCmnDlTM3PrecInf2, rgSCHCmnDlTM3PrecInf4},
559 {rgSCHCmnDlTM4PrecInf2, rgSCHCmnDlTM4PrecInf4}
560 };
561
562 static S16 rgSCHCmnDlAlloc1CwRetxRb ARGS((
563 RgSchCellCb                *cell,
564 RgSchDlSf                  *subFrm,
565 RgSchUeCb                  *ue,
566 RgSchDlHqTbCb              *tbInfo,
567 uint8_t                         noLyr,
568 uint8_t                         *numRb,
569 uint32_t                        *effBo
570 ));
571 static S16 rgSCHCmnDlAlloc2CwRetxRb ARGS((
572 RgSchCellCb                *cell,
573 RgSchDlSf                  *subFrm,
574 RgSchUeCb                  *ue,
575 RgSchDlHqProcCb            *proc,
576 uint8_t                         *numRb,
577 Bool                       *swpFlg,
578 uint32_t                        *effBo
579 ));
580 static Void rgSCHCmnDlTM3TxTx ARGS((
581 RgSchCellCb                *cell,
582 RgSchDlSf                  *subFrm,
583 RgSchUeCb                  *ue,
584 uint32_t                        bo,
585 uint32_t                        *effBo,
586 RgSchDlHqProcCb            *proc,
587 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
588 ));
589 static Void rgSCHCmnDlTM3TxRetx ARGS((
590 RgSchCellCb                *cell,
591 RgSchDlSf                  *subFrm,
592 RgSchUeCb                  *ue,
593 uint32_t                        bo,
594 uint32_t                        *effBo,
595 RgSchDlHqProcCb            *proc,
596 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
597 ));
598 static Void rgSCHCmnDlTM3RetxRetx ARGS((
599 RgSchCellCb                *cell,
600 RgSchDlSf                  *subFrm,
601 RgSchUeCb                  *ue,
602 uint32_t                        bo,
603 uint32_t                        *effBo,
604 RgSchDlHqProcCb            *proc,
605 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
606 ));
607
608 static Void rgSCHCmnNonDlfsUpdTyp2Alloc ARGS((
609 RgSchCellCb        *cell,
610 RgSchDlSf          *dlSf,
611 uint8_t                 rbStrt,
612 uint8_t                 numRb
613 ));
614 /* LTE_ADV_FLAG_REMOVED_START */
615 #ifndef LTE_TDD
616 static Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc ARGS((
617 RgSchCellCb        *cell,
618 RgSchDlSf          *dlSf,
619 uint8_t                 rbStrt,
620 uint8_t                 numRb
621 ));
622 #endif
623 /* LTE_ADV_FLAG_REMOVED_END */
624 static Void rgSCHCmnDlRbInfoAddUeTx ARGS((
625 RgSchCellCb        *cell,
626 RgSchCmnDlRbAllocInfo *allocInfo,
627 RgSchUeCb             *ue,
628 RgSchDlHqProcCb       *proc
629 ));
630 static Void rgSCHCmnDlRbInfoAddUeRetx ARGS((
631 RgSchCellCb        *cell,
632 RgSchCmnDlRbAllocInfo *allocInfo,
633 RgSchUeCb             *ue,
634 RgSchDlHqProcCb       *hqP
635 ));
636 static Void rgSCHCmnDlAdd2NonSchdRetxLst ARGS((
637 RgSchCmnDlRbAllocInfo *allocInfo,
638 RgSchUeCb             *ue,
639 RgSchDlHqProcCb       *proc
640 ));
641 static S16 rgSCHCmnDlAlloc2CwTxRetxRb ARGS((
642 RgSchCellCb                *cell,
643 RgSchDlSf                  *subFrm,
644 RgSchUeCb                  *ue,
645 RgSchDlHqTbCb              *reTxTb,
646 RgSchDlHqTbCb              *txTb,
647 uint8_t                         *numRb,
648 uint32_t                        *effBo
649 ));
650 static S16 rgSCHCmnDlAlloc2CwTxRb ARGS((
651 RgSchCellCb                *cell,
652 RgSchDlSf                  *subFrm,
653 RgSchUeCb                  *ue,
654 RgSchDlHqProcCb            *proc,
655 uint32_t                        bo,
656 uint8_t                         *numRb,
657 uint32_t                        *effBo
658 ));
659 static S16 rgSCHCmnDlAlloc1CwTxRb ARGS((
660 RgSchCellCb                *cell,
661 RgSchDlSf                  *subFrm,
662 RgSchUeCb                  *ue,
663 RgSchDlHqTbCb              *tbInfo,
664 uint32_t                        bo,
665 uint8_t                         *numRb,
666 uint32_t                        *effBo
667 ));
668 #ifndef LTEMAC_SPS
669 static Void rgSCHCmnFillHqPTb ARGS((
670 RgSchCellCb                *cell,
671 RgSchDlRbAlloc             *rbAllocInfo,
672 uint8_t                         tbAllocIdx,
673 RgSchPdcch                 *pdcch
674 ));
675 #endif
676 #ifdef LTEMAC_SPS
677 static Void rgSCHCmnDlGetBestFitHole ARGS((
678 uint32_t         *allocMask,
679 uint8_t          numMaskRbs,
680 uint32_t         *crntAllocMask,
681 uint8_t          rbsReq,
682 uint8_t          *allocStart,
683 uint8_t          *allocNumRbs,
684 Bool        isPartialAlloc
685 ));
686 #ifdef RGSCH_SPS_UNUSED
687 static uint32_t rgSCHCmnGetRaType1Mask ARGS((
688 uint8_t                rbIdx,
689 uint8_t                rbgSize,
690 uint8_t                *type1Subset
691 ));
692 #endif
693 static uint32_t rgSCHCmnGetRaType0Mask ARGS((
694 uint8_t                rbIdx,
695 uint8_t                rbgSize
696 ));
697 static uint32_t rgSCHCmnGetRaType2Mask ARGS((
698 uint8_t                rbIdx,
699 uint8_t                *maskIdx
700 ));
701 #endif
702
703 Bool rgSCHCmnRetxAllocAvoid ARGS(( 
704 RgSchDlSf                  *subFrm,
705 RgSchCellCb                *cell,
706 RgSchDlHqProcCb            *proc
707 ));
708
709 uint16_t rgSCHCmnGetSiSetId ARGS((
710 uint16_t    sfn,
711 uint8_t     sf,
712 uint16_t    minPeriodicity
713 ));
714
715
716 #ifdef RG_5GTF
717 //TODO_SID: Currenly table is only for 100 Prbs. Need to modify wrt VRBG table 8.1.5.2.1-1 V5G_213
718 uint32_t rgSch5gtfTbSzTbl[MAX_5GTF_MCS] = 
719     {1864, 5256, 8776, 13176, 17576, 21976, 26376, 31656, 35176, 39576, 43976, 47496, 52776, 59376, 66392};
720 uint32_t g5gtfTtiCnt = 0;
721 uint32_t gUl5gtfSrRecv = 0;
722 uint32_t gUl5gtfBsrRecv = 0;
723 uint32_t gUl5gtfUeSchPick = 0;
724 uint32_t gUl5gtfPdcchSchd = 0;
725 uint32_t gUl5gtfAllocAllocated = 0;
726 uint32_t gUl5gtfUeRbAllocDone = 0;
727 uint32_t gUl5gtfUeRmvFnlzZeroBo = 0;
728 uint32_t gUl5gtfUeFnlzReAdd = 0;
729 uint32_t gUl5gtfPdcchSend = 0;
730 uint32_t gUl5gtfRbAllocFail = 0;
731 uint32_t ul5gtfsidUlMarkUl = 0;
732 uint32_t ul5gtfsidDlSchdPass = 0;
733 uint32_t ul5gtfsidDlAlreadyMarkUl = 0;
734 uint32_t ul5gtfTotSchdCnt = 0;
735 #endif
736
737 /* CQI Offset Index to Beta CQI Offset value mapping,
738  * stored as parts per 1000. Reserved is set to 0.
739  * Refer 36.213 sec 8.6.3 Tbl 8.6.3-3 */
740 uint32_t rgSchCmnBetaCqiOffstTbl[16] = {0, 0, 1125,
741    1250, 1375, 1625, 1750, 2000, 2250, 2500, 2875,
742    3125, 3500, 4000, 5000, 6250};
743 uint32_t rgSchCmnBetaHqOffstTbl[16] =  {2000, 2500, 3125, 
744    4000, 5000, 6250, 8000,10000, 12625, 15875, 20000, 
745    31000, 50000,80000,126000,0};
746 uint32_t rgSchCmnBetaRiOffstTbl[16] = {1250, 1625, 2000, 
747    2500, 3125, 4000, 5000, 6250, 8000, 10000,12625,
748    15875,20000,0,0,0};
749 S8 rgSchCmnDlCqiDiffOfst[8] = {0, 1, 2, 3, -4, -3, -2, -1};
750
751 /* Include CRS REs while calculating Efficiency */
752 const static uint8_t rgSchCmnAntIdx[5] = {0,0,1,0,2};
753 const static uint8_t rgSchCmnNumResForCrs[5] = {0,6,12,0,16};
754 uint32_t cfiSwitchCnt ;
755 uint32_t cfiIncr ;
756 uint32_t cfiDecr ;
757
758
759 #ifdef TFU_UPGRADE
760 S8 rgSchCmnApUeSelDiffCqi[4] = {1, 2, 3, 4};
761 S8 rgSchCmnApEnbConfDiffCqi[4] = {0, 1, 2, -1};
762 #endif
763
764 typedef struct rgSchCmnDlUeDciFrmtOptns
765 {
766   TfuDciFormat spfcDciFrmt;   /* TM(Transmission Mode) specific DCI format.
767                                * Search space : UE Specific by C-RNTI only. */
768   uint8_t           spfcDciRAType; /* Resource Alloctn(RA) type for spfcDciFrmt */
769   TfuDciFormat prfrdDciFrmt;  /* Preferred DCI format among the available
770                                * options for TD (Transmit Diversity) */
771   uint8_t           prfrdDciRAType; /* Resource Alloctn(RA) type for prfrdDciFrmt */
772 }RgSchCmnDlUeDciFrmtOptns;
773 #ifndef LTE_ADV
774
775 /* DCI Format options for each Transmission Mode */
776 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[7] = {
777    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
778    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
779    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
780    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
781    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
782    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
783    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
784 };
785
786 #else
787 /* DCI Format options for each Transmission Mode */
788 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[9] = {
789    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
790    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
791    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
792    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
793    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
794    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
795    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
796 };
797 #endif
798
799
800 typedef struct rgSchCmnDlImcsTbl
801 {
802   uint8_t   modOdr; /* Modulation Order */
803   uint8_t   iTbs;   /* ITBS */
804 }RgSchCmnDlImcsTbl[29];
805
806 const struct rgSchCmnMult235Info
807 {
808    uint8_t   match;    /* Closest number satisfying 2^a.3^b.5^c, with a bias
809                   * towards the smaller number */
810    uint8_t   prvMatch; /* Closest number not greater than array index
811                   * satisfying 2^a.3^b.5^c */
812 } rgSchCmnMult235Tbl[110+1] = {
813    {0, 0},  /* dummy */
814    {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {6, 6}, {8, 8},
815    {9, 9}, {10, 10}, {10, 10}, {12, 12}, {12, 12}, {15, 12}, {15, 15},
816    {16, 16}, {16, 16}, {18, 18}, {18, 18}, {20, 20}, {20, 20}, {20, 20},
817    {24, 20}, {24, 24}, {25, 25}, {25, 25}, {27, 27}, {27, 27}, {30, 27},
818    {30, 30}, {30, 30}, {32, 32}, {32, 32}, {32, 32}, {36, 32}, {36, 36},
819    {36, 36}, {36, 36}, {40, 36}, {40, 40}, {40, 40}, {40, 40}, {45, 40},
820    {45, 40}, {45, 45}, {45, 45}, {48, 45}, {48, 48}, {48, 48}, {50, 50},
821    {50, 50}, {50, 50}, {54, 50}, {54, 54}, {54, 54}, {54, 54}, {54, 54},
822    {60, 54}, {60, 54}, {60, 60}, {60, 60}, {60, 60}, {64, 60}, {64, 64},
823    {64, 64}, {64, 64}, {64, 64}, {64, 64}, {72, 64}, {72, 64}, {72, 64},
824    {72, 72}, {72, 72}, {75, 72}, {75, 75}, {75, 75}, {75, 75}, {80, 75},
825    {80, 75}, {80, 80}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, {81, 81},
826    {90, 81}, {90, 81}, {90, 81}, {90, 81}, {90, 90}, {90, 90}, {90, 90},
827    {90, 90}, {96, 90}, {96, 90}, {96, 96}, {96, 96}, {96, 96}, {100, 96},
828    {100, 100}, {100, 100}, {100, 100}, {100, 100}, {100, 100}, {108, 100},
829    {108, 100}, {108, 100}, {108, 108}, {108, 108}, {108, 108}
830 };
831
832 /* R8 Upgrade */
833 /* BI table from 36.321 Table 7.2.1 */
834 const static S16 rgSchCmnBiTbl[RG_SCH_CMN_NUM_BI_VAL] = {
835       0, 10, 20, 30,40,60,80,120,160,240,320,480,960};
836 RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI] = {
837  {     0,                0              },
838  {RGSCH_CMN_QM_CQI_1,RGSCH_CMN_UL_EFF_CQI_1 },
839  {RGSCH_CMN_QM_CQI_2,RGSCH_CMN_UL_EFF_CQI_2 },
840  {RGSCH_CMN_QM_CQI_3,RGSCH_CMN_UL_EFF_CQI_3 },
841  {RGSCH_CMN_QM_CQI_4,RGSCH_CMN_UL_EFF_CQI_4 },
842  {RGSCH_CMN_QM_CQI_5,RGSCH_CMN_UL_EFF_CQI_5 },
843  {RGSCH_CMN_QM_CQI_6,RGSCH_CMN_UL_EFF_CQI_6 },
844  {RGSCH_CMN_QM_CQI_7,RGSCH_CMN_UL_EFF_CQI_7 },
845  {RGSCH_CMN_QM_CQI_8,RGSCH_CMN_UL_EFF_CQI_8 },
846  {RGSCH_CMN_QM_CQI_9,RGSCH_CMN_UL_EFF_CQI_9 },
847  {RGSCH_CMN_QM_CQI_10,RGSCH_CMN_UL_EFF_CQI_10 },
848  {RGSCH_CMN_QM_CQI_11,RGSCH_CMN_UL_EFF_CQI_11 },
849  {RGSCH_CMN_QM_CQI_12,RGSCH_CMN_UL_EFF_CQI_12 },
850  {RGSCH_CMN_QM_CQI_13,RGSCH_CMN_UL_EFF_CQI_13 },
851  {RGSCH_CMN_QM_CQI_14,RGSCH_CMN_UL_EFF_CQI_14 },
852  {RGSCH_CMN_QM_CQI_15,RGSCH_CMN_UL_EFF_CQI_15 },
853 };
854
855 #ifdef RG_UNUSED
856 /* This table maps a (delta_offset * 2 + 2) to a (beta * 8)
857  * where beta is 10^-(delta_offset/10) rounded off to nearest 1/8
858  */
859 static uint16_t rgSchCmnUlBeta8Tbl[29] = {
860    6, RG_SCH_CMN_UL_INVALID_BETA8, 8, 9, 10, 11, 13, 14, 16, 18, 20, 23,
861    25, 28, 32, RG_SCH_CMN_UL_INVALID_BETA8, 40, RG_SCH_CMN_UL_INVALID_BETA8,
862    50, RG_SCH_CMN_UL_INVALID_BETA8, 64, RG_SCH_CMN_UL_INVALID_BETA8, 80,
863    RG_SCH_CMN_UL_INVALID_BETA8, 101, RG_SCH_CMN_UL_INVALID_BETA8, 127,
864    RG_SCH_CMN_UL_INVALID_BETA8, 160
865 };
866 #endif
867
868 /* QCI to SVC priority mapping. Index specifies the Qci*/
869 static uint8_t rgSchCmnDlQciPrio[RG_SCH_CMN_MAX_QCI] = RG_SCH_CMN_QCI_TO_PRIO;
870
871 /* The configuration is efficiency measured per 1024 REs.  */
872 /* The first element stands for when CQI is not known      */
873 /* This table is used to translate CQI to its corrospoding */
874 /* allocation parameters. These are currently from 36.213  */
875 /* Just this talbe needs to be edited for modifying the    */
876 /* the resource allocation behaviour                       */
877
878 /* ADD CQI to MCS mapping correction
879  * single dimensional array is replaced by 2 dimensions for different CFI*/
880 static uint16_t rgSchCmnCqiPdschEff[4][16] = {RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1,
881     RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3};
882
883 static uint16_t rgSchCmn2LyrCqiPdschEff[4][16] = {RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1,
884     RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2, RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3};
885
886 /* This configuration determines the transalation of a UEs CQI to its    */
887 /* PDCCH coding efficiency. This may be edited based on the installation */
888 static uint8_t rgSchCmnDlRvTbl[4] = {0, 2, 3, 1}; /* RVIdx sequence is corrected*/
889
890 /* Indexed by [DciFrmt].
891  * Considering the following definition in determining the dciFrmt index.
892  * typedef enum
893 {
894    TFU_DCI_FORMAT_0,
895    TFU_DCI_FORMAT_1,
896    TFU_DCI_FORMAT_1A,
897    TFU_DCI_FORMAT_1B,
898    TFU_DCI_FORMAT_1C,
899    TFU_DCI_FORMAT_1D,
900    TFU_DCI_FORMAT_2,
901    TFU_DCI_FORMAT_2A,
902    TFU_DCI_FORMAT_3,
903    TFU_DCI_FORMAT_3A
904 } TfuDciFormat;
905 */
906 static uint16_t rgSchCmnDciFrmtSizes[10];
907
908 static uint16_t rgSchCmnCqiPdcchEff[16] = RG_SCH_CMN_CQI_TO_PDCCH_EFF;
909
910 #ifdef LTE_TDD
911
912 RgSchTddUlDlSubfrmTbl rgSchTddUlDlSubfrmTbl = {
913    {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},
914    {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},
915    {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},
916    {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},
917    {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},
918    {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},
919    {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}
920 };
921
922 /* SPS_INTG_FIX */
923 #ifdef LTEMAC_SPS
924 uint8_t rgSchTddSpsDlMaxRetxTbl[RGSCH_MAX_TDD_UL_DL_CFG] = {
925    /* 0 */ 6,
926    /* 1 */ 7,
927    /* 2 */ 8,
928    /* 3 */ 11,
929    /* 4 */ 12,
930    /* 5 */ 13,
931    /* 6 */ 7};
932
933 #endif
934
935
936 /* Special Subframes in OFDM symbols */
937 /* ccpu00134197-MOD-Correct the number of symbols */
938 RgSchTddSplSubfrmInfoTbl rgSchTddSplSubfrmInfoTbl = {
939         {3,  1, 1, 3,   1, 1},
940         {9,  1, 1, 8,   1, 1},
941         {10, 1, 1, 9,   1, 1},
942         {11, 1, 1, 10,  1, 1},
943         {12, 1, 1, 3,   2, 2},
944         {3,  2, 2, 8,   2, 2},
945         {9,  2, 2, 9,   2, 2},
946         {10, 2, 2, 0,   0, 0},
947         {11, 2, 2, 0,   0, 0}
948 };
949
950 /* PHICH 'm' value Table */
951 RgSchTddPhichMValTbl rgSchTddPhichMValTbl = {
952         {2, 1, 0, 0, 0, 2, 1, 0, 0, 0},
953         {0, 1, 0, 0, 1, 0, 1, 0, 0, 1},
954         {0, 0, 0, 1, 0, 0, 0, 0, 1, 0},
955         {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
956         {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
957         {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
958         {1, 1, 0, 0, 0, 1, 1, 0, 0, 1}
959 };
960
961 /* PHICH 'K' value Table */
962 RgSchTddKPhichTbl rgSchTddKPhichTbl = {
963         {0, 0, 4, 7, 6, 0, 0, 4, 7, 6},
964         {0, 0, 4, 6, 0, 0, 0, 4, 6, 0},
965         {0, 0, 6, 0, 0, 0, 0, 6, 0, 0},
966         {0, 0, 6, 6, 6, 0, 0, 0, 0, 0},
967         {0, 0, 6, 6, 0, 0, 0, 0, 0, 0},
968         {0, 0, 6, 0, 0, 0, 0, 0, 0, 0},
969         {0, 0, 4, 6, 6, 0, 0, 4, 7, 0}
970 };
971
972 /* Uplink association index 'K' value Table */
973 RgSchTddUlAscIdxKDashTbl rgSchTddUlAscIdxKDashTbl = {
974         {0, 0, 6, 4, 0, 0, 0, 6, 4, 0},
975         {0, 0, 4, 0, 0, 0, 0, 4, 0, 0},
976         {0, 0, 4, 4, 4, 0, 0, 0, 0, 0},
977         {0, 0, 4, 4, 0, 0, 0, 0, 0, 0},
978         {0, 0, 4, 0, 0, 0, 0, 0, 0, 0},
979         {0, 0, 7, 7, 5, 0, 0, 7, 7, 0}
980 };
981
982
983 /* PUSCH 'K' value Table */
984 RgSchTddPuschTxKTbl rgSchTddPuschTxKTbl = {
985         {4, 6, 0, 0, 0, 4, 6, 0, 0, 0},
986         {0, 6, 0, 0, 4, 0, 6, 0, 0, 4},
987         {0, 0, 0, 4, 0, 0, 0, 0, 4, 0},
988         {4, 0, 0, 0, 0, 0, 0, 0, 4, 4},
989         {0, 0, 0, 0, 0, 0, 0, 0, 4, 4},
990         {0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
991         {7, 7, 0, 0, 0, 7, 7, 0, 0, 5}
992 };
993
994 /* PDSCH to PUCCH Table for DL Harq Feed back. Based on the 
995    Downlink association set index 'K' table */
996 uint8_t rgSchTddPucchTxTbl[7][10] = {
997         {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
998         {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
999         {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1000         {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1001         {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1002         {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1003         {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1004 };
1005
1006 /* Table to fetch the next DL sf idx for applying the 
1007    new CFI. The next Dl sf Idx at which the new CFI 
1008    is applied is always the starting Sf of the next ACK/NACK
1009    Fdbk bundle. 
1010    
1011    Ex: In Cfg-2, sf4 and sf9 are the only subframes at which 
1012        a new ACK/NACK bundle of DL subframes can start
1013        
1014    D  S  U  D  D  D  S  U  D  D  D  S  U  D  D  D  S  U  D  D    
1015                4              9
1016    
1017    dlSf Array for Cfg-2:
1018    sfNum:  0  1  3  4  5  6  8  9  0  1   3  4  5  6  8  9 
1019    sfIdx:  0  1  2  3  4  5  6  7  8  9  10 11 12 12 14 15 
1020     
1021    If CFI changes at sf0,  nearest DL SF bundle >= 4 TTI is sf4
1022    So at sf4 the new CFI can be applied. To arrive at sf4 from
1023    sf0, the sfIdx has to be increased by 3 */  
1024                  
1025 uint8_t rgSchTddPdcchSfIncTbl[7][10] = {
1026  /* A/N Bundl: 0,1,5,6*/   {2,  1,  0, 0, 0, 2, 1,  0,  0,  0},
1027  /* A/N Bundl: 0,4,5,9*/   {2,  2,  0, 0, 3, 2, 2,  0,  0,  3},
1028  /* A/N Bundl: 4,9*/       {3,  6,  0, 5, 4, 3, 6,  0,  5,  4},
1029  /* A/N Bundl: 1,7,9*/     {4,  3,  0, 0, 0, 4, 5,  4,  6,  5},
1030  /* A/N Bundl: 0,6*/       {4,  3,  0, 0, 6, 5, 4,  7,  6,  5},
1031  /* A/N Bundl: 9*/         {8,  7,  0, 6, 5, 4, 12, 11, 10, 9},
1032  /* A/N Bundl: 0,1,5,6,9*/ {2,  1,  0, 0, 0, 2, 2,  0,  0,  3}
1033 };
1034    
1035
1036 /* combine compilation fixes */
1037 #ifdef LTEMAC_SPS
1038 /* subframe offset values to be used when twoIntervalsConfig is enabled in UL
1039  * SPS for a UE */
1040 RgSchTddSfOffTbl rgSchTddSfOffTbl = {
1041         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1042         {0, 0, 1, -1,  0, 0, 0,  1, -1, 0},
1043         {0, 0, 5,  0,  0, 0, 0, -5,  0, 0},
1044         {0, 0, 1,  1, -2, 0, 0,  0,  0, 0},
1045         {0, 0, 1, -1,  0, 0, 0,  0,  0, 0},
1046         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1047         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0}
1048 };
1049
1050
1051 /* Table to determine when uplink SPS configured grants should
1052  * explicitly be reserved in a subframe. When enries are same
1053  * as that of Msg3SubfrmTbl, indicates competition with msg3.
1054  * As of now, this is same as Msg3SubfrmTbl (leaving out uldlcfg 2),
1055  * except that all 255s are now zeros. */
1056 RgSchTddSpsUlRsrvTbl rgSchTddSpsUlRsrvTbl = {
1057         {0,    0,  0,  6,  8,  0, 0,  0,  6,  8},
1058         {0,    0,  6,  9,  0,  0, 0,  6,  9,  0},
1059         {0,    0,  10,  0,  0,  0, 0,  10,  0,  0},
1060         {0,   0,  0,  0,  8,  0, 7,  7,  14,  0},
1061         {0,   0,  0,  9,  0,  0, 7,  15,  0, 0},
1062         {0,   0,  10,  0,  0,  0, 16,  0, 0, 0},
1063         {0,    0,  0,  0,  8,  0, 0,  0,  9,  0}
1064 };
1065
1066 /* Inverse DL Assoc Set index Table */
1067 RgSchTddInvDlAscSetIdxTbl rgSchTddInvDlAscSetIdxTbl = {
1068        {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1069        {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1070        {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1071        {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1072        {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1073        {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1074        {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1075 };
1076
1077 #endif /* (LTEMAC_SPS ) */
1078
1079 /* Number of Uplink subframes Table */
1080 static uint8_t rgSchTddNumUlSf[] = {6, 4, 2, 3, 2, 1, 5};
1081
1082 /* Downlink HARQ processes Table */
1083 RgSchTddUlNumHarqProcTbl rgSchTddUlNumHarqProcTbl = { 7, 4, 2, 3, 2, 1, 6};
1084
1085 /* Uplink HARQ processes Table */
1086 RgSchTddDlNumHarqProcTbl rgSchTddDlNumHarqProcTbl = { 4, 7, 10, 9, 12, 15, 6};
1087
1088 /* Downlink association index set 'K' value Table */
1089 RgSchTddDlAscSetIdxKTbl rgSchTddDlAscSetIdxKTbl = {
1090         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1091
1092         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1093
1094         { {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}} },
1095
1096         { {0, {0}}, {0, {0}}, {3, {7, 6, 11}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1097
1098         { {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}} },
1099
1100         { {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}} },
1101
1102         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1103 };
1104
1105  /* ccpu132282-ADD-the table rgSchTddDlAscSetIdxKTbl is rearranged in 
1106   * decreasing order of Km, this is used to calculate the NCE used for 
1107   * calculating N1Pucch Resource for Harq*/
1108 RgSchTddDlAscSetIdxKTbl rgSchTddDlHqPucchResCalTbl = {
1109         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1110
1111         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1112
1113         { {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}} },
1114
1115         { {0, {0}}, {0, {0}}, {3, {11, 7, 6}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1116
1117         { {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}} },
1118
1119         { {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}} },
1120
1121         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1122 };
1123
1124 /* Minimum number of Ack/Nack feeback information to be
1125    stored for each UL-DL configuration */
1126 RgSchTddANFdbkMapTbl rgSchTddANFdbkMapTbl = {4, 4, 2, 3, 2, 1, 5};
1127
1128 /* Uplink switch points and number of UL subframes Table */
1129 RgSchTddMaxUlSubfrmTbl rgSchTddMaxUlSubfrmTbl = {
1130      {2,3,3}, {2,2,2}, {2,1,1}, {1,3,0}, {1,2,0}, {1,1,0}, {2,3,2}
1131 };
1132
1133 /* Uplink switch points and number of DL subframes Table */
1134 RgSchTddMaxDlSubfrmTbl rgSchTddMaxDlSubfrmTbl = {
1135      {2,2,2}, {2,3,3}, {2,4,4}, {1,7,0}, {1,8,0}, {1,9,0}, {2,2,3}
1136 };
1137
1138 /* Number of UL subframes present before a particular subframe */
1139 RgSchTddNumUlSubfrmTbl rgSchTddNumUlSubfrmTbl = {
1140         {0, 0, 1, 2, 3, 3, 3, 4, 5, 6},
1141         {0, 0, 1, 2, 2, 2, 2, 3, 4, 4},
1142         {0, 0, 1, 1, 1, 1, 1, 2, 2, 2},
1143         {0, 0, 1, 2, 3, 3, 3, 3, 3, 3},
1144         {0, 0, 1, 2, 2, 2, 2, 2, 2, 2},
1145         {0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
1146         {0, 0, 1, 2, 3, 3, 3, 4, 5, 5}
1147 };
1148
1149 /* Number of DL subframes present till a particular subframe */
1150 RgSchTddNumDlSubfrmTbl rgSchTddNumDlSubfrmTbl = {
1151         {1, 2, 2, 2, 2, 3, 4, 4, 4, 4},
1152         {1, 2, 2, 2, 3, 4, 5, 5, 5, 6},
1153         {1, 2, 2, 3, 4, 5, 6, 6, 7, 8},
1154         {1, 2, 2, 2, 2, 3, 4, 5, 6, 7},
1155         {1, 2, 2, 2, 3, 4, 5, 6, 7, 8},
1156         {1, 2, 2, 3, 4, 5, 6, 7, 8, 9},
1157         {1, 2, 2, 2, 2, 3, 4, 4, 4, 5}
1158 };
1159
1160
1161 /* Nearest possible UL subframe Index from UL subframe
1162  * DL Index < UL Index */
1163 RgSchTddLowDlSubfrmIdxTbl rgSchTddLowDlSubfrmIdxTbl = {
1164         {0, 1, 1, 1, 1, 5, 6, 6, 6, 6},
1165         {0, 1, 1, 1, 4, 5, 6, 6, 6, 9},
1166         {0, 1, 1, 3, 4, 5, 6, 6, 8, 9},
1167         {0, 1, 1, 1, 1, 5, 6, 7, 8, 9},
1168         {0, 1, 1, 1, 4, 5, 6, 7, 8, 9},
1169         {0, 1, 1, 3, 4, 5, 6, 7, 8, 9},
1170         {0, 1, 1, 1, 1, 5, 6, 6, 6, 9}
1171 };
1172
1173 /* Nearest possible DL subframe Index from UL subframe
1174  * DL Index > UL Index
1175  * 10 represents Next SFN low DL Idx */
1176 RgSchTddHighDlSubfrmIdxTbl rgSchTddHighDlSubfrmIdxTbl = {
1177         {0, 1, 5, 5, 5, 5, 6, 10, 10, 10},
1178         {0, 1, 4, 4, 4, 5, 6,  9,  9,  9},
1179         {0, 1, 3, 3, 4, 5, 6,  8,  8,  9},
1180         {0, 1, 5, 5, 5, 5, 6,  7,  8,  9},
1181         {0, 1, 4, 4, 4, 5, 6,  7,  8,  9},
1182         {0, 1, 3, 3, 4, 5, 6,  7,  8,  9},
1183         {0, 1, 5, 5, 5, 5, 6,  9,  9,  9}
1184 };
1185
1186 /* RACH Message3 related information */
1187 RgSchTddMsg3SubfrmTbl rgSchTddMsg3SubfrmTbl = {
1188         {7,      6,  255,  255,  255,  7,   6,  255,  255,  255},
1189         {7,      6,  255,  255,    8,  7,   6,  255,  255,    8},
1190         {7,      6,  255,  9,      8,  7,   6,  255,    9,    8},
1191         {12,    11,  255,  255,  255,  7,   6,    6,    6,   13},
1192         {12,    11,  255,  255,    8,  7,   6,    6,   14,   13},
1193         {12,    11,  255,    9,    8,  7,   6,   15,   14,   13},
1194         {7,      6,  255,  255,  255,  7,   6,  255,  255,    8}
1195 };
1196
1197 /* ccpu00132341-DEL Removed rgSchTddRlsDlSubfrmTbl and used Kset table for 
1198  * releasing DL HARQs */
1199
1200 /* DwPTS Scheduling Changes Start */
1201 /* Provides the number of Cell Reference Signals in DwPTS
1202  * region per RB */
1203 static uint8_t  rgSchCmnDwptsCrs[2][3] = {/* [Spl Sf cfg][Ant Port] */
1204            {4, 8,  16}, /* Spl Sf cfg 1,2,3,6,7,8 */
1205            {6, 12, 20}, /* Spl Sf cfg 4 */
1206 };
1207
1208 static S8  rgSchCmnSplSfDeltaItbs[9] = RG_SCH_DWPTS_ITBS_ADJ;
1209 /* DwPTS Scheduling Changes End */
1210 #endif
1211
1212
1213 static uint32_t rgSchCmnBsrTbl[64] = {
1214    0, 10, 12, 14, 17, 19, 22, 26,
1215    31, 36, 42, 49, 57, 67, 78, 91,
1216    107, 125, 146, 171, 200, 234, 274, 321,
1217    376, 440, 515, 603, 706, 826, 967, 1132,
1218    1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
1219    4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
1220    16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
1221    58255, 68201, 79846, 93479, 109439, 128125, 150000, 220000
1222 };
1223
1224 static uint32_t rgSchCmnExtBsrTbl[64] = {
1225    0, 10, 13, 16, 19, 23, 29, 35,
1226    43, 53, 65, 80, 98, 120, 147, 181,
1227    223, 274, 337, 414, 509, 625, 769, 945,
1228    1162, 1429, 1757, 2161, 2657, 3267, 4017, 4940,
1229    6074, 7469, 9185, 11294, 13888, 17077, 20999, 25822,
1230    31752, 39045, 48012, 59039, 72598, 89272, 109774, 134986,
1231    165989, 204111, 250990, 308634, 379519, 466683, 573866, 705666,
1232    867737, 1067031, 1312097, 1613447, 1984009, 2439678, 3000000, 3100000
1233 };
1234
1235 uint8_t rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI];
1236
1237 RgSchTbSzTbl rgTbSzTbl = {
1238  {
1239    {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},
1240    {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},
1241    {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},
1242    {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},
1243    {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},
1244    {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},
1245    {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},
1246    {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},
1247    {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},
1248    {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},
1249    {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},
1250    {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},
1251    {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},
1252    {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},
1253    {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},
1254    {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},
1255    {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},
1256    {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},
1257    {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},
1258    {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},
1259    {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},
1260    {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},
1261    {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},
1262    {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},
1263    {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},
1264    {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},
1265    {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}
1266  },
1267  {
1268    {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},
1269    {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},
1270    {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},
1271    {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},
1272    {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},
1273    {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},
1274    {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},
1275    {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},
1276    {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},
1277    {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},
1278    {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},
1279    {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},
1280    {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},
1281    {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},
1282    {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},
1283    {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},
1284    {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},
1285    {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},
1286    {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},
1287    {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},
1288    {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},
1289    {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},
1290    {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},
1291    {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},
1292    {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},
1293    {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},
1294    {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}
1295  }
1296 };
1297 RgSchUlIMcsTbl rgUlIMcsTbl = {
1298    {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
1299    {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10},
1300    {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14},
1301    {4, 15}, {4, 16}, {4, 17}, {4, 18}, {4, 19},
1302    {6, 19}, {6, 20}, {6, 21}, {6, 22}, {6, 23},
1303    {6, 24}, {6, 25}, {6, 26}
1304 };
1305 RgSchUeCatTbl rgUeCatTbl = {
1306    /*Column1:Maximum number of bits of an UL-SCH 
1307              transport block transmitted within a TTI
1308              - maxUlBits
1309      Column2:Maximum number of bits of a DLSCH
1310              transport block received within a TTI 
1311              - maxDlBits
1312      Column3:Total number of soft channel bits 
1313              - maxSftChBits
1314      Column4:Support for 64QAM in UL 
1315              - ul64qamSup
1316      Column5:Maximum number of DL-SCH transport
1317              block bits received within a TTI
1318              - maxDlTbBits
1319      Column6:Maximum number of supported layers for 
1320              spatial multiplexing in DL 
1321              - maxTxLyrs*/
1322    {5160,  {10296,0},      250368,  FALSE, 10296,  1},
1323    {25456, {51024,0},      1237248, FALSE, 51024,  2},
1324    {51024, {75376,0},      1237248, FALSE, 102048, 2},
1325    {51024, {75376,0},      1827072, FALSE, 150752, 2},
1326    {75376, {149776,0},     3667200, TRUE,  299552, 4},
1327    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1328    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1329    {149776,{299856,0},     35982720,TRUE,  2998560, 8}
1330 };
1331
1332 /* [ccpu00138532]-ADD-The below table stores the min HARQ RTT time
1333    in Downlink for TDD and FDD. Indices 0 to 6 map to tdd UL DL config 0-6. 
1334    Index 7 map to FDD */    
1335 uint8_t rgSchCmnHarqRtt[8] = {4,7,10,9,12,15,6,8};
1336 /* Number of CFI Switchover Index is equals to 7 TDD Indexes + 1 FDD index */
1337 uint8_t rgSchCfiSwitchOvrWinLen[] = {7, 4, 2, 3, 2, 1, 6, 8};
1338
1339 /* EffTbl is calculated for single layer and two layers.
1340   * CqiToTbs is calculated for single layer and two layers */
1341 RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1342 RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1343 /* New variable to store UL effiency values for normal and extended CP*/
1344 RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1];
1345 RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1346 RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1347 RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
1348 RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1349 RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1350 RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1351 RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1352 /* Include CRS REs while calculating Efficiency */
1353 RgSchCmnTbSzEff *rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI];
1354 RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP];
1355 #ifdef LTE_TDD
1356 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3, 1};
1357 #else
1358 /* Added matrix 'rgRaPrmblToRaFrmTbl'for computation of RA sub-frames from RA preamble */
1359 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3};
1360 #endif
1361
1362  RgUlSchdInits        rgSchUlSchdInits;
1363  RgDlSchdInits        rgSchDlSchdInits;
1364  RgDlfsSchdInits      rgSchDlfsSchdInits;
1365 #ifdef EMTC_ENABLE
1366  RgEmtcUlSchdInits        rgSchEmtcUlSchdInits;
1367  RgEmtcDlSchdInits        rgSchEmtcDlSchdInits;
1368 #endif
1369
1370 /* RACHO : start */
1371 static S16 rgSCHCmnUeIdleExdThrsld ARGS((
1372 RgSchCellCb     *cell,
1373 RgSchUeCb       *ue
1374 ));
1375 RgSchUeCb* rgSCHCmnGetHoUe ARGS((
1376 RgSchCellCb           *cell,
1377 uint16_t                   rapId
1378 ));
1379 static Void rgSCHCmnDelDedPreamble ARGS((
1380 RgSchCellCb           *cell,
1381 uint8_t                    preambleId
1382 ));
1383 RgSchUeCb* rgSCHCmnGetPoUe ARGS((
1384 RgSchCellCb           *cell,
1385 uint16_t                   rapId,
1386 CmLteTimingInfo       timingInfo
1387 ));
1388 static Void rgSCHCmnDelRachInfo ARGS((
1389 RgSchCellCb  *cell,
1390 RgSchUeCb    *ue
1391 ));
1392 static S16 rgSCHCmnUlRbAllocForPoHoUe ARGS((
1393 RgSchCellCb           *cell,
1394 RgSchUlSf             *sf,
1395 RgSchUeCb             *ue,
1396 uint8_t                    maxRb
1397 ));
1398 static Void rgSCHCmnHdlHoPo ARGS((
1399 RgSchCellCb           *cell,
1400 CmLListCp             *raRspLst,
1401 RgSchRaReqInfo        *raReq
1402 ));
1403 static Void rgSCHCmnAllocPoHoGrnt ARGS((
1404 RgSchCellCb           *cell,
1405 CmLListCp             *raRspLst,
1406 RgSchUeCb             *ue,
1407 RgSchRaReqInfo        *raReq
1408 ));
1409 static Void rgSCHCmnFillPdcchOdr2Sf ARGS((
1410 RgSchCellCb *cell,
1411 RgSchUeCb   *ue,
1412 RgSchPdcch  *pdcc,
1413 uint8_t          rapId,
1414 uint8_t          prachMskIdx
1415 ));
1416 static Void rgSCHCmnDlAdd2PdcchOdrQ ARGS((
1417 RgSchCellCb                *cell,
1418 RgSchUeCb                  *ue
1419 ));
1420 static Void rgSCHCmnDlRmvFrmPdcchOdrQ ARGS((
1421 RgSchCellCb                *cell,
1422 RgSchUeCb                  *ue
1423 ));
1424 static Void rgSCHCmnUpdNxtPrchMskIdx ARGS((
1425 RgSchCellCb  *cell
1426 ));
1427 static Void rgSCHCmnUpdRachParam ARGS((
1428 RgSchCellCb  *cell
1429 ));
1430 static S16 rgSCHCmnAllocPOParam ARGS((
1431 RgSchCellCb  *cell,
1432 RgSchDlSf    *dlSf,
1433 RgSchUeCb    *ue,
1434 RgSchPdcch   **pdcch,
1435 uint8_t           *rapId,
1436 uint8_t           *prachMskIdx
1437 ));
1438 static Void rgSCHCmnGenPdcchOrder ARGS((
1439 RgSchCellCb  *cell,
1440 RgSchDlSf    *dlSf
1441 ));
1442 static Void rgSCHCmnCfgRachDedPrm ARGS((
1443 RgSchCellCb   *cell
1444 ));
1445 /* RACHO : end */
1446
1447 static Void rgSCHCmnHdlUlInactUes ARGS((
1448 RgSchCellCb  *cell
1449 ));
1450 static Void rgSCHCmnHdlDlInactUes ARGS((
1451 RgSchCellCb  *cell
1452 ));
1453 static Void rgSCHCmnUlInit ARGS((Void
1454 ));
1455 static Void rgSCHCmnDlInit ARGS((Void
1456 ));
1457 static Void rgSCHCmnInitDlRbAllocInfo ARGS((
1458 RgSchCmnDlRbAllocInfo  *allocInfo
1459 ));
1460 static Void rgSCHCmnUpdUlCompEffBsr ARGS((
1461 RgSchUeCb *ue
1462 ));
1463 #if RG_UNUSED
1464 static Void rgSCHCmnUlSetAllUnSched  ARGS((
1465 RgSchCmnUlRbAllocInfo *allocInfo
1466 ));
1467 static Void rgSCHCmnUlUpdSf ARGS((
1468          RgSchCellCb           *cell,
1469          RgSchCmnUlRbAllocInfo *allocInfo,
1470          RgSchUlSf     *sf
1471          ));
1472 static Void rgSCHCmnUlHndlAllocRetx ARGS((
1473          RgSchCellCb           *cell,
1474          RgSchCmnUlRbAllocInfo *allocInfo,
1475          RgSchUlSf     *sf,
1476          RgSchUlAlloc  *alloc
1477          ));
1478 #endif
1479 static Void rgSCHCmnGrpPwrCntrlPucch ARGS((
1480 RgSchCellCb  *cell,
1481 RgSchDlSf    *dlSf
1482 ));
1483 static Void rgSCHCmnGrpPwrCntrlPusch ARGS((
1484 RgSchCellCb  *cell,
1485 RgSchUlSf    *ulSf
1486 ));
1487 static Void rgSCHCmnDelUeFrmRefreshQ ARGS((
1488 RgSchCellCb     *cell,
1489 RgSchUeCb       *ue
1490 ));
1491 static S16 rgSCHCmnTmrExpiry ARGS((
1492 PTR cb,               /* Pointer to timer control block */
1493 S16 tmrEvnt           /* Timer Event */
1494 ));
1495 static S16 rgSCHCmnTmrProc ARGS((
1496 RgSchCellCb *cell
1497 ));
1498 static Void rgSCHCmnAddUeToRefreshQ ARGS((
1499 RgSchCellCb     *cell,
1500 RgSchUeCb       *ue,
1501 uint32_t             wait
1502 ));
1503 static Void rgSCHCmnDlCcchRetx ARGS((
1504 RgSchCellCb             *cell,
1505 RgSchCmnDlRbAllocInfo   *allocInfo
1506 ));
1507 static Void rgSCHCmnUpdUeMimoInfo ARGS((
1508 RgrUeCfg     *ueCfg,
1509 RgSchCmnDlUe *ueDl,
1510 RgSchCellCb  *cell,
1511 RgSchCmnCell *cellSchd
1512 ));
1513 static Void rgSCHCmnUpdUeUlCqiInfo ARGS((
1514 RgSchCellCb   *cell,
1515 RgSchUeCb     *ue,
1516 RgSchCmnUlUe  *ueUl,
1517 RgSchCmnUe    *ueSchCmn,
1518 RgSchCmnCell  *cellSchd,
1519 Bool          isEcp 
1520 ));
1521 #ifdef RGR_V1
1522 static Void rgSCHCmnDlCcchSduRetx ARGS((
1523 RgSchCellCb             *cell,
1524 RgSchCmnDlRbAllocInfo   *allocInfo
1525 ));
1526 static Void rgSCHCmnDlCcchSduTx ARGS((
1527 RgSchCellCb             *cell,
1528 RgSchCmnDlRbAllocInfo   *allocInfo
1529 ));
1530 static S16 rgSCHCmnCcchSduAlloc ARGS((
1531 RgSchCellCb                *cell,
1532 RgSchUeCb                  *ueCb,
1533 RgSchCmnDlRbAllocInfo      *allocInfo
1534 ));
1535 static S16 rgSCHCmnCcchSduDedAlloc ARGS((
1536 RgSchCellCb                *cell,
1537 RgSchUeCb                  *ueCb
1538 ));
1539 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc ARGS((
1540 RgSchCellCb           *cell,
1541 RgSchUeCb             *ueCb,
1542 RgSchDlSf             *dlSf
1543 ));
1544 #endif
1545 static Void rgSCHCmnInitVars ARGS((
1546          RgSchCellCb *cell
1547          ));
1548
1549 /*ccpu00117180 - DEL - Moved rgSCHCmnUpdVars to .x as its access is now */
1550 static Void rgSCHCmnUlRbAllocForLst ARGS((
1551          RgSchCellCb           *cell,
1552          RgSchUlSf             *sf,
1553          uint32_t                   count,
1554          CmLListCp             *reqLst,
1555          CmLListCp             *schdLst,
1556          CmLListCp             *nonSchdLst,
1557          Bool                  isNewTx
1558          ));
1559 static S16 rgSCHCmnUlRbAllocForUe ARGS((
1560          RgSchCellCb           *cell,
1561          RgSchUlSf             *sf,
1562          RgSchUeCb             *ue,
1563          uint8_t                    maxRb,
1564          RgSchUlHole           *hole
1565          ));
1566 static Void rgSCHCmnMsg3GrntReq ARGS((
1567          RgSchCellCb     *cell,
1568          CmLteRnti       rnti,
1569          Bool            preamGrpA,
1570          RgSchUlHqProcCb *hqProc,
1571          RgSchUlAlloc    **ulAllocRef,
1572          uint8_t              *hqProcIdRef
1573          ));
1574 static Void rgSCHCmnDlCcchRarAlloc ARGS((
1575 RgSchCellCb             *cell
1576 ));
1577 static Void rgSCHCmnDlCcchTx ARGS((
1578 RgSchCellCb             *cell,
1579 RgSchCmnDlRbAllocInfo   *allocInfo
1580 ));
1581 static Void rgSCHCmnDlBcchPcch ARGS((
1582 RgSchCellCb             *cell,
1583 RgSchCmnDlRbAllocInfo   *allocInfo,
1584 RgInfSfAlloc            *subfrmAlloc
1585 ));
1586 Bool rgSCHCmnChkInWin ARGS((
1587 CmLteTimingInfo   frm,
1588 CmLteTimingInfo   start,
1589 CmLteTimingInfo   end
1590 ));
1591 Bool rgSCHCmnChkPastWin ARGS((
1592 CmLteTimingInfo   frm,
1593 CmLteTimingInfo   end
1594 ));
1595 static Void rgSCHCmnClcAlloc ARGS((
1596 RgSchCellCb             *cell,
1597 RgSchDlSf               *sf,
1598 RgSchClcDlLcCb          *lch,
1599 uint16_t                     rnti,
1600 RgSchCmnDlRbAllocInfo   *allocInfo
1601 ));
1602 #ifndef LTEMAC_SPS
1603 static Void rgSCHCmnClcRbAlloc ARGS((
1604 RgSchCellCb             *cell,
1605 uint32_t                     bo,
1606 uint8_t                      cqi,
1607 uint8_t                      *rb,
1608 uint32_t                     *tbs,
1609 uint8_t                      *mcs,
1610 RgSchDlSf               *sf 
1611 ));
1612 #endif
1613
1614 static S16 rgSCHCmnMsg4Alloc ARGS((
1615 RgSchCellCb                *cell,
1616 RgSchRaCb                  *raCb,
1617 RgSchCmnDlRbAllocInfo      *allocInfo
1618 ));
1619 static S16 rgSCHCmnMsg4DedAlloc ARGS((
1620 RgSchCellCb                *cell,
1621 RgSchRaCb                  *raCb
1622 ));
1623 static Void rgSCHCmnDlRaRsp ARGS((
1624 RgSchCellCb                *cell,
1625 RgSchCmnDlRbAllocInfo      *allocInfo
1626 ));
1627 static S16 rgSCHCmnRaRspAlloc ARGS((
1628 RgSchCellCb             *cell,
1629 RgSchDlSf               *subFrm,
1630 uint16_t                     rntiIdx,
1631 uint16_t                     rarnti,
1632 uint8_t                      noRaRnti,
1633 RgSchCmnDlRbAllocInfo   *allocInfo
1634 ));
1635 static Void rgSCHCmnUlUeDelAllocs ARGS((
1636 RgSchCellCb  *cell,
1637 RgSchUeCb   *ue
1638 ));
1639 static Void rgSCHCmnDlSetUeAllocLmt ARGS((
1640 RgSchCellCb   *cell,
1641 RgSchCmnDlUe  *ueDl,
1642 Bool          isEmtcUe
1643 ));
1644 static S16 rgSCHCmnDlRgrCellCfg ARGS((
1645 RgSchCellCb    *cell,
1646 RgrCellCfg     *cfg,
1647 RgSchErrInfo   *err
1648 ));
1649 static Void rgSCHCmnUlAdapRetx ARGS((
1650 RgSchUlAlloc    *alloc,
1651 RgSchUlHqProcCb *proc
1652 ));
1653 static Void rgSCHCmnUlUpdAllocRetx ARGS((
1654 RgSchCellCb    *cell,
1655 RgSchUlAlloc   *alloc
1656 ));
1657 static Void rgSCHCmnUlSfReTxAllocs ARGS((
1658 RgSchCellCb *cell,
1659 RgSchUlSf   *sf
1660 ));
1661 /* Fix: syed Adaptive Msg3 Retx crash. */
1662 #ifdef TFU_UPGRADE
1663 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1664 ((
1665 RgSchCellCb *cell,
1666 RgSchUeCb    *ue,
1667 RgrUeRecfg   *ueRecfg,
1668 uint8_t numTxPorts
1669 ));
1670 #else
1671 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1672 ((
1673 RgSchCellCb *cell,
1674 RgSchUeCb    *ue,
1675 RgrUeRecfg   *ueRecfg
1676 ));
1677 #endif
1678
1679
1680 /*
1681  * DL RB allocation specific functions
1682  */
1683
1684 static Void rgSCHCmnDlRbAlloc ARGS((
1685 RgSchCellCb           *cell,
1686 RgSchCmnDlRbAllocInfo *allocInfo
1687 ));
1688 static Void rgSCHCmnNonDlfsRbAlloc ARGS((
1689 RgSchCellCb           *cell,
1690 RgSchCmnDlRbAllocInfo *allocInfo
1691 ));
1692 static S16 rgSCHCmnNonDlfsCmnRbAlloc ARGS((
1693 RgSchCellCb           *cell,
1694 RgSchDlRbAlloc        *cmnAllocInfo));
1695
1696 #ifndef LTE_TDD
1697 static Void rgSCHCmnNonDlfsPbchRbAllocAdj ARGS((
1698 RgSchCellCb           *cell,
1699 RgSchDlRbAlloc        *cmnAllocInfo,
1700 uint8_t                    pbchSsRsSym,
1701 Bool                  isBcchPcch
1702 ));
1703 /* Added function to adjust TBSize*/
1704 static Void rgSCHCmnNonDlfsPbchTbSizeAdj ARGS((
1705 RgSchDlRbAlloc        *allocInfo,
1706 uint8_t                    numOvrlapgPbchRb,
1707 uint8_t                    pbchSsRsSym,
1708 uint8_t                    idx,
1709 uint32_t                   bytesReq
1710 ));
1711
1712 /* Added function to find num of overlapping PBCH rb*/
1713 static Void rgSCHCmnFindNumPbchOvrlapRbs ARGS((
1714 RgSchCellCb           *cell,
1715 RgSchDlSf             *dlSf,
1716 RgSchDlRbAlloc        *allocInfo,
1717 uint8_t                    *numOvrlapgPbchRb
1718 ));
1719
1720 static uint8_t rgSCHCmnFindNumAddtlRbsAvl ARGS((
1721 RgSchCellCb           *cell,
1722 RgSchDlSf             *dlSf,
1723 RgSchDlRbAlloc        *allocInfo
1724 ));
1725 #ifdef DEBUGP
1726 #ifdef UNUSED_FUNC
1727 static Void rgSCHCmnFindCodeRate ARGS((
1728 RgSchCellCb           *cell,
1729 RgSchDlSf             *dlSf,
1730 RgSchDlRbAlloc        *allocInfo,
1731 uint8_t                    idx
1732 ));
1733 #endif
1734 #endif
1735 #endif
1736 static Void rgSCHCmnNonDlfsMsg4Alloc ARGS((
1737 RgSchCellCb           *cell,
1738 RgSchCmnMsg4RbAlloc   *msg4AllocInfo,
1739 uint8_t                    isRetx
1740 ));
1741 static S16 rgSCHCmnNonDlfsMsg4RbAlloc ARGS((
1742 RgSchCellCb           *cell,
1743 RgSchRaCb             *raCb,
1744 RgSchDlSf             *dlSf
1745 ));
1746
1747 static S16 rgSCHCmnNonDlfsUeRbAlloc ARGS((
1748 RgSchCellCb           *cell,
1749 RgSchUeCb             *ue,
1750 RgSchDlSf             *dlSf,
1751 uint8_t                    *isDlBwAvail
1752 ));
1753 #ifndef LTEMAC_SPS
1754 static uint32_t rgSCHCmnCalcRiv ARGS(( uint8_t bw,
1755          uint8_t           rbStart,
1756          uint8_t           numRb));
1757 #endif
1758
1759 #ifdef LTE_TDD
1760 static Void rgSCHCmnUpdHqAndDai ARGS((
1761 RgSchDlHqProcCb   *hqP,
1762 RgSchDlSf         *subFrm,
1763 RgSchDlHqTbCb     *tbCb,
1764 uint8_t                tbAllocIdx
1765 ));
1766 static S16 rgSCHCmnUlCalcAvailBw ARGS((
1767 RgSchCellCb *cell,
1768 RgrCellCfg  *cellCfg,
1769 uint8_t          cfi,
1770 uint8_t          *rbStartRef,
1771 uint8_t          *bwAvailRef
1772 ));
1773 static S16 rgSCHCmnDlKdashUlAscInit ARGS((
1774 RgSchCellCb *cell
1775 ));
1776 static S16 rgSCHCmnDlANFdbkInit ARGS((
1777 RgSchCellCb *cell
1778 ));
1779 static S16 rgSCHCmnDlNpValInit ARGS((
1780 RgSchCellCb *cell
1781 ));
1782 static S16 rgSCHCmnDlCreateRachPrmLst ARGS((
1783 RgSchCellCb *cell
1784 ));
1785 static S16 rgSCHCmnDlCpyRachInfo ARGS((
1786 RgSchCellCb        *cell,
1787 RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES],
1788 uint8_t                 raArrSz
1789 ));
1790 static S16 rgSCHCmnDlRachInfoInit ARGS((
1791 RgSchCellCb *cell
1792 ));
1793 static S16 rgSCHCmnDlPhichOffsetInit ARGS((
1794 RgSchCellCb *cell
1795 ));
1796 #endif
1797 #ifdef TFU_UPGRADE
1798 static Void rgSCHCmnFindUlCqiUlTxAnt ARGS
1799 ((
1800  RgSchCellCb          *cell,
1801  RgSchUeCb            *ue,
1802  uint8_t                          wideCqi
1803  ));
1804  static RgSchCmnRank rgSCHCmnComputeRank ARGS
1805 ((
1806  RgrTxMode    txMode,
1807  uint32_t          *pmiBitMap,
1808  uint8_t           numTxPorts
1809  ));
1810
1811  static RgSchCmnRank rgSCHCmnComp2TxMode3 ARGS
1812 ((
1813  uint32_t *pmiBitMap
1814  ));
1815
1816   static RgSchCmnRank rgSCHCmnComp4TxMode3 ARGS
1817 ((
1818  uint32_t *pmiBitMap
1819  ));
1820
1821   static RgSchCmnRank rgSCHCmnComp2TxMode4 ARGS
1822 ((
1823  uint32_t *pmiBitMap
1824  ));
1825
1826   static RgSchCmnRank rgSCHCmnComp4TxMode4 ARGS
1827 ((
1828  uint32_t *pmiBitMap
1829  ));
1830
1831  static uint8_t rgSCHCmnCalcWcqiFrmSnr ARGS
1832 ((
1833  RgSchCellCb        *cell,
1834  TfuSrsRpt        *srsRpt
1835  ));
1836 #endif
1837
1838 /* comcodsepa : start */
1839 \f
1840 /**
1841  * @brief This function computes efficiency and stores in a table.
1842  *
1843  * @details
1844  *
1845  *     Function: rgSCHCmnCompEff
1846  *     Purpose:  this function computes the efficiency as number of
1847  *               bytes per 1024 symbols. The CFI table is also filled
1848  *               with the same information such that comparison is valid
1849  *
1850  *     Invoked by: Scheduler
1851  *
1852  *  @param[in]  uint8_t            noPdcchSym
1853  *  @param[in]  uint8_t            cpType
1854  *  @param[in]  uint8_t            txAntIdx
1855  *  @param[in]  RgSchCmnTbSzEff* effTbl
1856  *  @return  Void
1857  *
1858  **/
1859 static Void rgSCHCmnCompEff(uint8_t noPdcchSym,uint8_t cpType,uint8_t txAntIdx,RgSchCmnTbSzEff *effTbl)
1860 {
1861    uint8_t   noResPerRb;
1862    uint8_t   noSymPerRb;
1863    uint8_t   resOfCrs; /* Effective REs occupied by CRS */
1864    uint8_t   i, j;
1865
1866
1867    switch (cpType)
1868    {
1869       case RG_SCH_CMN_NOR_CP:
1870          noSymPerRb = 14;
1871          break;
1872       case RG_SCH_CMN_EXT_CP:
1873          noSymPerRb = 12;
1874          break;
1875       default:
1876          /* Generate a log error. This case should never be executed */
1877          return;
1878    }
1879
1880    /* Depending on the Tx Antenna Index, deduct the
1881     * Resource elements for the CRS */
1882    switch (txAntIdx)
1883    {
1884       case 0:
1885          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
1886          break;
1887       case 1:
1888          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
1889          break;
1890       case 2:
1891          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
1892          break;
1893       default:
1894          /* Generate a log error. This case should never be executed */
1895          return;
1896    }
1897    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
1898    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1899    {
1900       (*effTbl)[i] = 0;
1901       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1902       {
1903          /* This line computes the coding efficiency per 1024 REs */
1904          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1905       }
1906       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1907    }
1908    return;
1909 }
1910 /**
1911  * @brief This function computes efficiency and stores in a table.
1912  *
1913  * @details
1914  *
1915  *     Function: rgSCHCmnCompUlEff
1916  *     Purpose:  this function computes the efficiency as number of
1917  *               bytes per 1024 symbols. The CFI table is also filled
1918  *               with the same information such that comparison is valid
1919  *
1920  *     Invoked by: Scheduler
1921  *
1922  *  @param[in]  uint8_t            noUlRsSym
1923  *  @param[in]  uint8_t            cpType
1924  *  @param[in]  uint8_t            txAntIdx
1925  *  @param[in]  RgSchCmnTbSzEff* effTbl
1926  *  @return  Void
1927  *
1928  **/
1929 static Void rgSCHCmnCompUlEff(uint8_t noUlRsSym,uint8_t cpType,RgSchCmnTbSzEff *effTbl)
1930 {
1931    uint8_t noResPerRb;
1932    uint8_t noSymPerRb;
1933    uint8_t i, j;
1934
1935
1936    switch (cpType)
1937    {
1938       case RG_SCH_CMN_NOR_CP:
1939          noSymPerRb = 14;
1940          break;
1941       case RG_SCH_CMN_EXT_CP:
1942          noSymPerRb = 12;
1943          break;
1944       default:
1945          /* Generate a log error. This case should never be executed */
1946          return;
1947    }
1948
1949    noResPerRb = ((noSymPerRb - noUlRsSym) * RB_SCH_CMN_NUM_SCS_PER_RB);
1950    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1951    {
1952       (*effTbl)[i] = 0;
1953       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1954       {
1955          /* This line computes the coding efficiency per 1024 REs */
1956          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1957       }
1958       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1959    }
1960    return;
1961 }
1962
1963 /**
1964  * @brief This function computes efficiency for 2 layers and stores in a table.
1965  *
1966  * @details
1967  *
1968  *     Function: rgSCHCmn2LyrCompEff
1969  *     Purpose:  this function computes the efficiency as number of
1970  *               bytes per 1024 symbols. The CFI table is also filled
1971  *               with the same information such that comparison is valid
1972  *
1973  *     Invoked by: Scheduler
1974  *
1975  *  @param[in]  uint8_t            noPdcchSym
1976  *  @param[in]  uint8_t            cpType
1977  *  @param[in]  uint8_t            txAntIdx
1978  *  @param[in]  RgSchCmnTbSzEff* effTbl2Lyr
1979  *  @return  Void
1980  *
1981  **/
1982 static Void rgSCHCmn2LyrCompEff(uint8_t noPdcchSym,uint8_t cpType,uint8_t txAntIdx,RgSchCmnTbSzEff *effTbl2Lyr)
1983 {
1984    uint8_t  noResPerRb;
1985    uint8_t  noSymPerRb;
1986    uint8_t  resOfCrs; /* Effective REs occupied by CRS */
1987    uint8_t  i, j;
1988
1989
1990    switch (cpType)
1991    {
1992       case RG_SCH_CMN_NOR_CP:
1993          noSymPerRb = 14;
1994          break;
1995       case RG_SCH_CMN_EXT_CP:
1996          noSymPerRb = 12;
1997          break;
1998       default:
1999          /* Generate a log error. This case should never be executed */
2000          return;
2001    }
2002
2003    /* Depending on the Tx Antenna Index, deduct the
2004     * Resource elements for the CRS */
2005    switch (txAntIdx)
2006    {
2007       case 0:
2008          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
2009          break;
2010       case 1:
2011          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
2012          break;
2013       case 2:
2014          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
2015          break;
2016       default:
2017          /* Generate a log error. This case should never be executed */
2018          return;
2019    }
2020
2021    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
2022    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
2023    {
2024       (*effTbl2Lyr)[i] = 0;
2025       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
2026       {
2027          /* This line computes the coding efficiency per 1024 REs */
2028          (*effTbl2Lyr)[i] += (rgTbSzTbl[1][i][j] * 1024) / (noResPerRb * (j+1));
2029       }
2030       (*effTbl2Lyr)[i] /= RG_SCH_CMN_NUM_RBS;
2031    }
2032    return;
2033 }
2034
2035 \f
2036 /**
2037  * @brief This function initializes the rgSchCmnDciFrmtSizes table.
2038  *
2039  * @details
2040  *
2041  *     Function: rgSCHCmnGetDciFrmtSizes
2042  *     Purpose:  This function determines the sizes of all
2043  *               the available DCI Formats. The order of
2044  *               bits addition for each format is inaccordance
2045  *               with the specs.
2046  *     Invoked by: rgSCHCmnRgrCellCfg
2047  *
2048  *  @return  Void
2049  *
2050  **/
2051 static Void rgSCHCmnGetDciFrmtSizes(RgSchCellCb *cell)
2052 {
2053
2054
2055    /* DCI Format 0 size determination */
2056    rgSchCmnDciFrmtSizes[0] = 1 +
2057                              1 +
2058                              rgSCHUtlLog32bitNbase2((cell->bwCfg.ulTotalBw * \
2059                              (cell->bwCfg.ulTotalBw + 1))/2) +
2060                              5 +
2061                              1 +
2062                              2 +
2063                              3 +
2064 #ifdef LTE_TDD
2065                              2 +
2066                              2 +
2067 #endif
2068                              1;
2069    /* DCI Format 1 size determination */
2070    rgSchCmnDciFrmtSizes[1] = 1 +
2071    RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2072                              5 +
2073 #ifndef LTE_TDD
2074                              3 +
2075 #else
2076                              4 + 2 + /* HqProc Id and DAI */
2077 #endif
2078                              1 +
2079                              2 +
2080                              2;
2081
2082    /* DCI Format 1A size determination */
2083    rgSchCmnDciFrmtSizes[2] = 1 + /* Flag for format0/format1a differentiation */
2084                1 + /* Localized/distributed VRB assignment flag */
2085                5 + /* For mcs */
2086 #ifndef LTE_TDD
2087                3 + /* Harq process Id */
2088 #else
2089                4 + /* Harq process Id */
2090                2 + /* UL Index or DAI */
2091 #endif
2092                1 + /* New Data Indicator */
2093                2 + /* For RV */
2094                2 + /* For tpc */
2095                1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2096                    (cell->bwCfg.dlTotalBw + 1))/2);
2097                /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
2098                   Since VRB is local */
2099
2100    /* DCI Format 1B size determination */
2101    rgSchCmnDciFrmtSizes[3] = 1 +
2102                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2103                              (cell->bwCfg.dlTotalBw + 1))/2) +
2104                              5 +
2105                              3 +
2106 #ifdef LTE_TDD
2107                              1 + /* HqP */
2108                              2 + /* Dai */
2109 #endif
2110                              1 +
2111                              2 +
2112                              2 +
2113                              ((cell->numTxAntPorts == 4)? 4:2) +
2114                              1;
2115
2116    /* DCI Format 1C size determination */
2117    /* Approximation: NDLVrbGap1 ~= Nprb for DL */
2118    rgSchCmnDciFrmtSizes[4] = (cell->bwCfg.dlTotalBw < 50)? 0:1 +
2119                              (cell->bwCfg.dlTotalBw < 50)?
2120                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/2 * \
2121                                 (cell->bwCfg.dlTotalBw/2 + 1))/2)) :
2122                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/4 * \
2123                                 (cell->bwCfg.dlTotalBw/4 + 1))/2)) +
2124                              5;
2125
2126    /* DCI Format 1D size determination */
2127    rgSchCmnDciFrmtSizes[5] = 1 +
2128                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2129                              (cell->bwCfg.dlTotalBw + 1))/2) +
2130                              5 +
2131                              3 +
2132 #ifdef LTE_TDD
2133                              1 + 2 +
2134 #endif
2135                              1 +
2136                              2 +
2137                              2 +
2138                              ((cell->numTxAntPorts == 4)? 4:2) +
2139                              1;
2140
2141    /* DCI Format 2 size determination */
2142    rgSchCmnDciFrmtSizes[6] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2143                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2144                              2 +
2145 #ifdef LTE_TDD
2146                              2 + 1 +
2147 #endif
2148                              3 +
2149                              1 +
2150                              (5 + 1 + 2)*2 +
2151                              ((cell->numTxAntPorts == 4)? 6:3);
2152
2153    /* DCI Format 2A size determination */
2154    rgSchCmnDciFrmtSizes[7] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2155                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2156                              2 +
2157 #ifdef LTE_TDD
2158                              2 + 1 +
2159 #endif
2160                              3 +
2161                              1 +
2162                              (5 + 1 + 2)*2 +
2163                              ((cell->numTxAntPorts == 4)? 2:0);
2164
2165    /* DCI Format 3 size determination */
2166    rgSchCmnDciFrmtSizes[8] = rgSchCmnDciFrmtSizes[0];
2167
2168    /* DCI Format 3A size determination */
2169    rgSchCmnDciFrmtSizes[9] = rgSchCmnDciFrmtSizes[0];
2170
2171    return;
2172 }
2173
2174
2175 /**
2176  * @brief This function initializes the cmnCell->dciAggrLvl table.
2177  *
2178  * @details
2179  *
2180  *     Function: rgSCHCmnGetCqiDciFrmt2AggrLvl
2181  *     Purpose:  This function determines the Aggregation level
2182  *               for each CQI level against each DCI format.
2183  *     Invoked by: rgSCHCmnRgrCellCfg
2184  *
2185  *  @return  Void
2186  *
2187  **/
2188 static Void rgSCHCmnGetCqiDciFrmt2AggrLvl(RgSchCellCb *cell)
2189 {
2190    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2191    uint8_t            i;
2192    uint8_t            j;
2193
2194
2195    for (i = 0; i < RG_SCH_CMN_MAX_CQI; i++)
2196    {
2197       for (j = 0; j < 10; j++)
2198       {
2199          uint32_t pdcchBits; /* Actual number of phy bits needed for a given DCI Format
2200                * for a given CQI Level */
2201          pdcchBits = (rgSchCmnDciFrmtSizes[j] * 1024)/rgSchCmnCqiPdcchEff[i];
2202                         /* V5G_211 : 6.6 */
2203          if (pdcchBits < 192)
2204          {
2205              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL2;
2206              continue;
2207          }
2208          if (pdcchBits < 384)
2209          {
2210              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL4;
2211              continue;
2212          }
2213          if (pdcchBits < 768)
2214          {
2215              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL8;
2216              continue;
2217          }
2218          cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL16;
2219       }
2220    }
2221    return;
2222 }
2223 \f
2224 /**
2225  * @brief This function initializes all the data for the scheduler.
2226  *
2227  * @details
2228  *
2229  *     Function: rgSCHCmnDlInit
2230  *     Purpose:  This function initializes the following information:
2231  *               1. Efficiency table
2232  *               2. CQI to table index - It is one row for upto 3 RBs
2233  *                  and another row for greater than 3 RBs
2234  *                  currently extended prefix is compiled out.
2235  *     Invoked by: MAC intialization code..may be ActvInit
2236  *
2237  *  @return  Void
2238  *
2239  **/
2240 static Void rgSCHCmnDlInit()
2241 {
2242    uint8_t  i;
2243    S16      j;
2244    S16      k;
2245    uint8_t  idx;
2246    RgSchCmnTbSzEff  *effTbl;
2247    RgSchCmnCqiToTbs *tbsTbl;
2248
2249
2250    /* 0 corresponds to Single layer case, 1 corresponds to 2 layers case*/
2251    /* Init Efficiency table for normal cyclic prefix */
2252    /*Initialize Efficiency table for Layer Index 0 */
2253    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2254    /*Initialize Efficiency table for each of the CFI indices. The
2255     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2256    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[0];
2257    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[0];
2258    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[0];
2259    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[0];
2260    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2261    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[0];
2262    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[0];
2263    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[0];
2264    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[0];
2265    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2266    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[0];
2267    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[0];
2268    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[0];
2269    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[0];
2270
2271    /*Initialize CQI to TBS table for Layer Index 0 for Normal CP */
2272    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[0];
2273    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[0];
2274    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[0];
2275    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[0];
2276
2277    /*Intialize Efficency table for Layer Index 1 */
2278    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2279    /*Initialize Efficiency table for each of the CFI indices. The
2280     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2281    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[1];
2282    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[1];
2283    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[1];
2284    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[1];
2285    /*Initialize Efficiency table for Tx Antenna Port Index 1 */
2286    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[1];
2287    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[1];
2288    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[1];
2289    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[1];
2290    /*Initialize Efficiency table for Tx Antenna Port Index 2 */
2291    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[1];
2292    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[1];
2293    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[1];
2294    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[1];
2295
2296    /*Initialize CQI to TBS table for Layer Index 1 for Normal CP */
2297    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[1];
2298    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[1];
2299    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[1];
2300    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[1];
2301
2302    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2303    {
2304       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2305       {
2306          /* EfficiencyTbl calculation incase of 2 layers for normal CP  */
2307          rgSCHCmnCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx,\
2308                rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]);
2309          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx, \
2310                rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]);
2311       }
2312    }
2313
2314    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2315    {
2316       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2317       {
2318          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i];
2319          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][i];
2320          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2321                (j >= 0) && (k > 0); --j)
2322          {
2323             /* ADD CQI to MCS mapping correction
2324             * single dimensional array is replaced by 2 dimensions for different CFI*/
2325             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2326             {
2327                (*tbsTbl)[k--] = (uint8_t)j;
2328             }
2329          }
2330          for (; k > 0; --k)
2331          {
2332             (*tbsTbl)[k] = 0;
2333          }
2334          /* effTbl,tbsTbl calculation incase of 2 layers for normal CP */
2335          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i];
2336          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][i];
2337          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2338                (j >= 0) && (k > 0); --j)
2339          {
2340             /* ADD CQI to MCS mapping correction
2341             * single dimensional array is replaced by 2 dimensions for different CFI*/
2342             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2343             {
2344                (*tbsTbl)[k--] = (uint8_t)j;
2345             }
2346          }
2347          for (; k > 0; --k)
2348          {
2349             (*tbsTbl)[k] = 0;
2350          }
2351       }
2352    }
2353
2354    /* Efficiency Table for Extended CP */
2355    /*Initialize Efficiency table for Layer Index 0 */
2356    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2357    /*Initialize Efficiency table for each of the CFI indices. The
2358     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2359    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[0];
2360    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[0];
2361    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[0];
2362    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[0];
2363    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2364    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[0];
2365    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[0];
2366    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[0];
2367    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[0];
2368    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2369    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[0];
2370    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[0];
2371    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[0];
2372    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[0];
2373
2374    /*Initialize CQI to TBS table for Layer Index 0 for Extended CP */
2375    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[0];
2376    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[0];
2377    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[0];
2378    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[0];
2379
2380    /*Initialize Efficiency table for Layer Index 1 */
2381    /*Initialize Efficiency table for each of the CFI indices. The
2382     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2383    /*Initialize Efficency table for Tx Antenna Port Index 0 */
2384    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[1];
2385    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[1];
2386    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[1];
2387    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[1];
2388    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2389    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[1];
2390    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[1];
2391    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[1];
2392    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[1];
2393    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2394    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[1];
2395    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[1];
2396    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[1];
2397    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[1];
2398
2399    /*Initialize CQI to TBS table for Layer Index 1 for Extended CP */
2400    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[1];
2401    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[1];
2402    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[1];
2403    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[1];
2404    /* Activate this code when extended cp is supported */
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          /* EfficiencyTbl calculation incase of 2 layers for extendedl CP  */
2410          rgSCHCmnCompEff( (uint8_t)(i + 1 ), (uint8_t)RG_SCH_CMN_EXT_CP, idx,\
2411                rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]);
2412          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), (uint8_t) RG_SCH_CMN_EXT_CP,idx, \
2413                rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]);
2414       }
2415    }
2416
2417    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2418    {
2419       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2420       {
2421          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i];
2422          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][i];
2423          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2424                (j >= 0) && (k > 0); --j)
2425          {
2426             /* ADD CQI to MCS mapping correction
2427             * single dimensional array is replaced by 2 dimensions for different CFI*/
2428             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2429             {
2430                (*tbsTbl)[k--] = (uint8_t)j;
2431             }
2432          }
2433          for (; k > 0; --k)
2434          {
2435             (*tbsTbl)[k] = 0;
2436          }
2437          /* effTbl,tbsTbl calculation incase of 2 layers for extended CP */
2438          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i];
2439          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][i];
2440          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2441                (j >= 0) && (k > 0); --j)
2442          {
2443            /* ADD CQI to MCS mapping correction
2444             * single dimensional array is replaced by 2 dimensions for different CFI*/
2445             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2446             {
2447                (*tbsTbl)[k--] = (uint8_t)j;
2448             }
2449          }
2450          for (; k > 0; --k)
2451          {
2452             (*tbsTbl)[k] = 0;
2453          }
2454       }
2455    }
2456    return;
2457 }
2458 \f
2459 /**
2460  * @brief This function initializes all the data for the scheduler.
2461  *
2462  * @details
2463  *
2464  *     Function: rgSCHCmnUlInit
2465  *     Purpose:  This function initializes the following information:
2466  *               1. Efficiency table
2467  *               2. CQI to table index - It is one row for upto 3 RBs
2468  *                  and another row for greater than 3 RBs
2469  *                  currently extended prefix is compiled out.
2470  *     Invoked by: MAC intialization code..may be ActvInit
2471  *
2472  *  @return  Void
2473  *
2474  **/
2475 static Void rgSCHCmnUlInit()
2476 {
2477    uint8_t            *mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_NOR_CP][0];
2478    RgSchCmnTbSzEff    *effTbl    = &rgSchCmnNorUlEff[0];
2479    const RgSchCmnUlCqiInfo *cqiTbl = &rgSchCmnUlCqiTbl[0];
2480    S16              i;
2481    S16              j;
2482
2483    /* Initaializing new variable added for UL eff */
2484    rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP] = &rgSchCmnNorUlEff[0];
2485    /* Reason behind using 3 as the number of symbols to rule out for
2486     * efficiency table computation would be that we are using 2 symbols for
2487     * DMRS(1 in each slot) and 1 symbol for SRS*/
2488    rgSCHCmnCompUlEff(RGSCH_UL_SYM_DMRS_SRS,RG_SCH_CMN_NOR_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP]);
2489
2490    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2491          i >= 0 && j > 0; --i)
2492    {
2493       if ((*effTbl)[i] <= cqiTbl[j].eff)
2494       {
2495          mapTbl[j--] = (uint8_t)i;
2496       }
2497    }
2498    for (; j > 0; --j)
2499    {
2500       mapTbl[j] = 0;
2501    }
2502    effTbl    = &rgSchCmnExtUlEff[0];
2503    mapTbl    = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_EXT_CP][0];
2504
2505    /* Initaializing new variable added for UL eff */
2506    rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP] = &rgSchCmnExtUlEff[0];
2507    /* Reason behind using 3 as the number of symbols to rule out for
2508     * efficiency table computation would be that we are using 2 symbols for
2509     * DMRS(1 in each slot) and 1 symbol for SRS*/
2510    rgSCHCmnCompUlEff(3,RG_SCH_CMN_EXT_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP]);
2511
2512    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2513          i >= 0 && j > 0; --i)
2514    {
2515       if ((*effTbl)[i] <= cqiTbl[j].eff)
2516       {
2517          mapTbl[j--] = (uint8_t)i;
2518       }
2519    }
2520    for (; j > 0; --j)
2521    {
2522       mapTbl[j] = 0;
2523    }
2524    rgSCHPwrInit();
2525    return;
2526 }
2527
2528 /**
2529  * @brief This function initializes all the data for the scheduler.
2530  *
2531  * @details
2532  *
2533  *     Function: rgSCHCmnInit
2534  *     Purpose:  This function initializes the following information:
2535  *               1. Efficiency table
2536  *               2. CQI to table index - It is one row for upto 3 RBs
2537  *                  and another row for greater than 3 RBs
2538  *                  currently extended prefix is compiled out.
2539  *     Invoked by: MAC intialization code..may be ActvInit
2540  *
2541  *  @return  Void
2542  *
2543  **/
2544 Void rgSCHCmnInit()
2545 {
2546    uint8_t   idx;
2547
2548    rgSCHCmnDlInit();
2549    rgSCHCmnUlInit();
2550 #ifdef EMTC_ENABLE
2551    rgSCHEmtcCmnDlInit();
2552    rgSCHEmtcCmnUlInit();
2553 #endif      
2554 #ifdef LTEMAC_SPS
2555    rgSCHCmnSpsInit();
2556 #endif
2557
2558    /* Init the function pointers */
2559    rgSchCmnApis.rgSCHRgrUeCfg         = rgSCHCmnRgrUeCfg;
2560    rgSchCmnApis.rgSCHRgrUeRecfg       = rgSCHCmnRgrUeRecfg;
2561    rgSchCmnApis.rgSCHFreeUe           = rgSCHCmnUeDel;
2562    rgSchCmnApis.rgSCHRgrCellCfg       = rgSCHCmnRgrCellCfg;
2563    rgSchCmnApis.rgSCHRgrCellRecfg     = rgSCHCmnRgrCellRecfg;
2564    rgSchCmnApis.rgSCHFreeCell         = rgSCHCmnCellDel;
2565    rgSchCmnApis.rgSCHRgrLchCfg        = rgSCHCmnRgrLchCfg;
2566    rgSchCmnApis.rgSCHRgrLcgCfg        = rgSCHCmnRgrLcgCfg;
2567    rgSchCmnApis.rgSCHRgrLchRecfg      = rgSCHCmnRgrLchRecfg;
2568    rgSchCmnApis.rgSCHRgrLcgRecfg      = rgSCHCmnRgrLcgRecfg;
2569    rgSchCmnApis.rgSCHFreeDlLc         = rgSCHCmnFreeDlLc;
2570    rgSchCmnApis.rgSCHFreeLcg          = rgSCHCmnLcgDel;
2571    rgSchCmnApis.rgSCHRgrLchDel        = rgSCHCmnRgrLchDel;
2572    rgSchCmnApis.rgSCHActvtUlUe        = rgSCHCmnActvtUlUe;
2573    rgSchCmnApis.rgSCHActvtDlUe        = rgSCHCmnActvtDlUe;
2574    rgSchCmnApis.rgSCHHdlUlTransInd    = rgSCHCmnHdlUlTransInd;
2575    rgSchCmnApis.rgSCHDlDedBoUpd       = rgSCHCmnDlDedBoUpd;
2576    rgSchCmnApis.rgSCHUlRecMsg3Alloc   = rgSCHCmnUlRecMsg3Alloc;
2577    rgSchCmnApis.rgSCHUlCqiInd         = rgSCHCmnUlCqiInd;
2578    rgSchCmnApis.rgSCHPucchDeltaPwrInd = rgSCHPwrPucchDeltaInd;
2579    rgSchCmnApis.rgSCHUlHqProcForUe    = rgSCHCmnUlHqProcForUe;
2580 #ifdef RG_UNUSED
2581    rgSchCmnApis.rgSCHUpdUlHqProc      = rgSCHCmnUpdUlHqProc;
2582 #endif
2583    rgSchCmnApis.rgSCHUpdBsrShort      = rgSCHCmnUpdBsrShort;
2584    rgSchCmnApis.rgSCHUpdBsrTrunc      = rgSCHCmnUpdBsrTrunc;
2585    rgSchCmnApis.rgSCHUpdBsrLong       = rgSCHCmnUpdBsrLong;
2586    rgSchCmnApis.rgSCHUpdPhr           = rgSCHCmnUpdPhr;
2587    rgSchCmnApis.rgSCHUpdExtPhr        = rgSCHCmnUpdExtPhr;
2588    rgSchCmnApis.rgSCHContResUlGrant   = rgSCHCmnContResUlGrant;
2589    rgSchCmnApis.rgSCHSrRcvd           = rgSCHCmnSrRcvd;
2590    rgSchCmnApis.rgSCHFirstRcptnReq    = rgSCHCmnFirstRcptnReq;
2591    rgSchCmnApis.rgSCHNextRcptnReq     = rgSCHCmnNextRcptnReq;
2592    rgSchCmnApis.rgSCHFirstHqFdbkAlloc = rgSCHCmnFirstHqFdbkAlloc;
2593    rgSchCmnApis.rgSCHNextHqFdbkAlloc  = rgSCHCmnNextHqFdbkAlloc;
2594    rgSchCmnApis.rgSCHDlProcAddToRetx  = rgSCHCmnDlProcAddToRetx;
2595    rgSchCmnApis.rgSCHDlCqiInd         = rgSCHCmnDlCqiInd;
2596 #ifdef EMTC_ENABLE
2597    rgSchCmnApis.rgSCHUlProcAddToRetx  = rgSCHCmnEmtcUlProcAddToRetx;
2598 #endif
2599 #ifdef TFU_UPGRADE
2600    rgSchCmnApis.rgSCHSrsInd           = rgSCHCmnSrsInd;
2601 #endif
2602    rgSchCmnApis.rgSCHDlTARpt          = rgSCHCmnDlTARpt;
2603    rgSchCmnApis.rgSCHDlRlsSubFrm      = rgSCHCmnDlRlsSubFrm;
2604    rgSchCmnApis.rgSCHUeReset          = rgSCHCmnUeReset;
2605 #ifdef LTEMAC_SPS
2606    rgSchCmnApis.rgSCHHdlCrntiCE         = rgSCHCmnHdlCrntiCE;
2607    rgSchCmnApis.rgSCHDlProcAck        = rgSCHCmnDlProcAck;
2608    rgSchCmnApis.rgSCHDlRelPdcchFbk    = rgSCHCmnDlRelPdcchFbk;
2609    rgSchCmnApis.rgSCHUlSpsRelInd      = rgSCHCmnUlSpsRelInd;
2610    rgSchCmnApis.rgSCHUlSpsActInd      = rgSCHCmnUlSpsActInd;
2611    rgSchCmnApis.rgSCHUlCrcFailInd     = rgSCHCmnUlCrcFailInd;
2612    rgSchCmnApis.rgSCHUlCrcInd     = rgSCHCmnUlCrcInd;
2613 #endif
2614    rgSchCmnApis.rgSCHDrxStrtInActvTmrInUl = rgSCHCmnDrxStrtInActvTmrInUl;
2615    rgSchCmnApis.rgSCHUpdUeDataIndLcg      = rgSCHCmnUpdUeDataIndLcg;
2616
2617    for (idx = 0; idx < RGSCH_NUM_SCHEDULERS; ++idx)
2618    {
2619       rgSchUlSchdInits[idx](&rgSchUlSchdTbl[idx]);
2620       rgSchDlSchdInits[idx](&rgSchDlSchdTbl[idx]);
2621    }
2622 #ifdef EMTC_ENABLE 
2623    for (idx = 0; idx < RGSCH_NUM_EMTC_SCHEDULERS; ++idx)
2624    {
2625       rgSchEmtcUlSchdInits[idx](&rgSchEmtcUlSchdTbl[idx]);
2626       rgSchEmtcDlSchdInits[idx](&rgSchEmtcDlSchdTbl[idx]);
2627    }
2628 #endif
2629 #if (defined (RG_PHASE2_SCHED) && defined(TFU_UPGRADE))
2630    for (idx = 0; idx < RGSCH_NUM_DLFS_SCHEDULERS; ++idx)
2631    {
2632       rgSchDlfsSchdInits[idx](&rgSchDlfsSchdTbl[idx]);
2633    }
2634 #endif
2635 #ifdef LTE_ADV
2636    rgSchCmnApis.rgSCHRgrSCellUeCfg         = rgSCHCmnRgrSCellUeCfg;
2637    rgSchCmnApis.rgSCHRgrSCellUeDel         = rgSCHCmnRgrSCellUeDel;
2638 #endif
2639    return;
2640 }
2641
2642 \f
2643 /**
2644  * @brief This function is a wrapper to call scheduler specific API.
2645  *
2646  * @details
2647  *
2648  *     Function: rgSCHCmnDlRlsSubFrm
2649  *     Purpose:  Releases scheduler Information from DL SubFrm.
2650  *
2651  *     Invoked by: DHM
2652  *
2653  *  @param[in]   RgSchCellCb     *cell
2654  *  @param[out]  CmLteTimingInfo frm
2655  *  @return  Void
2656  *
2657  **/
2658 Void rgSCHCmnDlRlsSubFrm(RgSchCellCb *cell,CmLteTimingInfo frm)
2659 {
2660    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2661    RgSchDlSf     *sf;
2662
2663
2664    /* Get the pointer to the subframe */
2665    sf = rgSCHUtlSubFrmGet(cell, frm);
2666
2667    rgSCHUtlSubFrmPut(cell, sf);
2668    if (sf->dlfsSf)
2669    {
2670       /* Re-initialize DLFS specific information for the sub-frame */
2671       cellSch->apisDlfs->rgSCHDlfsReinitSf(cell, sf);
2672    }
2673    return;
2674 }
2675
2676
2677 \f
2678 /**
2679  * @brief This function is the starting function for DL allocation.
2680  *
2681  * @details
2682  *
2683  *     Function: rgSCHCmnDlCmnChAlloc
2684  *     Purpose:  Scheduling for downlink. It performs allocation in the order
2685  *               of priority wich BCCH/PCH first, CCCH, Random Access and TA.
2686  *
2687  *     Invoked by: Scheduler
2688  *
2689  *  @param[in]  RgSchCellCb*           cell
2690  *  @param[out] RgSchCmnDlRbAllocInfo* allocInfo
2691  *  @return  Void
2692  *
2693  **/
2694 static Void rgSCHCmnDlCcchRarAlloc(RgSchCellCb *cell)
2695 {
2696    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2697
2698
2699    rgSCHCmnDlCcchRetx(cell, &cellSch->allocInfo);
2700    /* LTE_ADV_FLAG_REMOVED_START */
2701    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2702    {
2703       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2704       {
2705          /*eNodeB need to blank the subframe */
2706       }
2707       else
2708       {
2709          rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2710       }
2711    }
2712    else
2713    {
2714       rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2715    }
2716    /* LTE_ADV_FLAG_REMOVED_END */
2717
2718 #ifdef RGR_V1
2719
2720    /*Added these function calls for processing CCCH SDU arriving
2721     * after guard timer expiry.Functions differ from above two functions
2722     * in using ueCb instead of raCb.*/
2723    rgSCHCmnDlCcchSduRetx(cell, &cellSch->allocInfo);
2724    /* LTE_ADV_FLAG_REMOVED_START */
2725    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2726    {
2727       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2728       {
2729          /*eNodeB need to blank the subframe */
2730       }
2731       else
2732       {
2733          rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2734       }
2735    }
2736    else
2737    {
2738       rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2739    }
2740    /* LTE_ADV_FLAG_REMOVED_END */
2741 #endif
2742
2743 #ifdef LTE_TDD
2744    if(cellSch->ul.msg3SchdIdx != RGSCH_INVALID_INFO)
2745    {
2746       /* Do not schedule msg3 if there is a CFI change ongoing */
2747       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2748       {
2749          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2750       }
2751    }
2752 #else
2753    /* LTE_ADV_FLAG_REMOVED_START */
2754    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2755    {
2756       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2757       {
2758          /*eNodeB need to blank the subframe */
2759       }
2760       else
2761       {
2762          /* Do not schedule msg3 if there is a CFI change ongoing */
2763          if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2764          {
2765             rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2766          }
2767       }
2768    }
2769    else
2770    {
2771       /* Do not schedule msg3 if there is a CFI change ongoing */
2772       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2773       {
2774          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2775       }
2776    }
2777    /* LTE_ADV_FLAG_REMOVED_END */
2778 #endif
2779
2780    return;
2781 }
2782
2783 #ifdef RGR_V1
2784 /**
2785  * @brief Scheduling for CCCH SDU.
2786  *
2787  * @details
2788  *
2789  *     Function: rgSCHCmnCcchSduAlloc
2790  *     Purpose:  Scheduling for CCCH SDU
2791  *
2792  *     Invoked by: Scheduler
2793  *
2794  *  @param[in]  RgSchCellCb*          cell
2795  *  @param[in]  RgSchUeCb*            ueCb
2796  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2797  *  @return  S16
2798  *
2799  **/
2800 static S16 rgSCHCmnCcchSduAlloc(RgSchCellCb *cell,RgSchUeCb *ueCb,RgSchCmnDlRbAllocInfo *allocInfo)
2801 {
2802    RgSchDlRbAlloc  *rbAllocInfo;
2803    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
2804    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2805
2806
2807    /* Return if subframe BW exhausted */
2808    if (allocInfo->ccchSduAlloc.ccchSduDlSf->bw <=
2809        allocInfo->ccchSduAlloc.ccchSduDlSf->bwAssigned)
2810    {
2811       DU_LOG("\nERROR  -->  SCH : bw<=bwAssigned for UEID:%d",ueCb->ueId);
2812       return RFAILED;
2813    }
2814
2815    if (rgSCHDhmGetCcchSduHqProc(ueCb, cellSch->dl.time, &(ueDl->proc)) != ROK)
2816    {
2817       DU_LOG("\nERROR  -->  SCH : rgSCHDhmGetCcchSduHqProc failed UEID:%d",ueCb->ueId);
2818       return RFAILED;
2819    }
2820
2821    rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
2822    rbAllocInfo->dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2823
2824    if (rgSCHCmnCcchSduDedAlloc(cell, ueCb) != ROK)
2825    {
2826       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
2827       rgSCHDhmRlsHqpTb(ueDl->proc, 0, FALSE);
2828       DU_LOG("\nERROR  -->  SCH : rgSCHCmnCcchSduDedAlloc failed UEID:%d",ueCb->ueId);
2829       return RFAILED;
2830    }
2831    cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduTxLst, &ueDl->proc->reqLnk);
2832    ueDl->proc->reqLnk.node = (PTR)ueDl->proc;
2833    allocInfo->ccchSduAlloc.ccchSduDlSf->schdCcchUe++;
2834
2835    return ROK;
2836 }
2837 /**
2838  * @brief This function scheduler for downlink CCCH messages.
2839  *
2840  * @details
2841  *
2842  *     Function: rgSCHCmnDlCcchSduTx
2843  *     Purpose:  Scheduling for downlink CCCH
2844  *
2845  *     Invoked by: Scheduler
2846  *
2847  *  @param[in]  RgSchCellCb           *cell
2848  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2849  *  @return  Void
2850  *
2851  **/
2852 static Void rgSCHCmnDlCcchSduTx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2853 {
2854    CmLList      *node;
2855    RgSchUeCb    *ueCb;
2856    RgSchCmnDlUe *ueCmnDl;
2857    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2858    RgSchDlSf    *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2859    
2860
2861    node = cell->ccchSduUeLst.first;
2862    while(node)
2863    {
2864       if(cellSch->dl.maxCcchPerDlSf &&
2865             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2866       {
2867          break;
2868       }
2869       else
2870       {
2871          ueCb = (RgSchUeCb *)(node->node);
2872          ueCmnDl  = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2873          node = node->next;
2874          /* Fix : syed postpone scheduling for this
2875           * until msg4 is done */
2876          /* Fix : syed RLC can erroneously send CCCH SDU BO 
2877           * twice. Hence an extra guard to avoid if already 
2878           * scheduled for RETX */
2879          if ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
2880                (!ueCmnDl->proc))
2881          {
2882             if ((rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)) != ROK)
2883             {
2884                break;
2885             }
2886          }
2887          else
2888          {
2889             DU_LOG("\nERROR  -->  SCH :  THIS SHOULD "
2890                      "NEVER HAPPEN for UEID:%d", ueCb->ueId);
2891             continue;
2892          }
2893       }
2894    }
2895    return;
2896 }
2897 #endif
2898 \f
2899 /**
2900  * @brief This function scheduler for downlink CCCH messages.
2901  *
2902  * @details
2903  *
2904  *     Function: rgSCHCmnDlCcchTx
2905  *     Purpose:  Scheduling for downlink CCCH
2906  *
2907  *     Invoked by: Scheduler
2908  *
2909  *  @param[in]  RgSchCellCb           *cell
2910  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2911  *  @return  Void
2912  *
2913  **/
2914 static Void rgSCHCmnDlCcchTx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2915 {
2916    CmLList       *node;
2917    RgSchRaCb     *raCb;
2918    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2919    RgSchDlSf     *dlSf = allocInfo->msg4Alloc.msg4DlSf;
2920
2921    node = cell->raInfo.toBeSchdLst.first;
2922    while(node)
2923    {
2924       if(cellSch->dl.maxCcchPerDlSf &&
2925             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2926       {
2927          break;
2928       }
2929       else
2930       {
2931
2932          raCb = (RgSchRaCb *)(node->node);
2933          node = node->next;
2934          /* Address allocation for this UE for MSG 4 */
2935          /* Allocation for Msg4 */
2936          if ((rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)) != ROK)
2937          {
2938             break;
2939          }
2940       }
2941    }
2942    return;
2943 }
2944
2945 #ifdef RGR_V1
2946 /**
2947  * @brief This function scheduler for downlink CCCH messages.
2948  *
2949  * @details
2950  *
2951  *     Function: rgSCHCmnDlCcchSduRetx
2952  *     Purpose:  Scheduling for downlink CCCH
2953  *
2954  *     Invoked by: Scheduler
2955  *
2956  *  @param[in]  RgSchCellCb           *cell
2957  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2958  *  @return  Void
2959  *
2960  **/
2961 static Void rgSCHCmnDlCcchSduRetx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2962 {
2963    RgSchDlRbAlloc  *rbAllocInfo;
2964    CmLList         *node;
2965    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
2966    RgSchUeCb       *ueCb;
2967    RgSchDlHqProcCb *hqP;
2968    uint8_t         retxBw = 0;
2969    RgSchCmnDlUe    *ueDl;
2970    RgSchDlSf       *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2971    
2972
2973    node = cellSch->dl.ccchSduRetxLst.first;
2974    while(node)
2975    {
2976       if(cellSch->dl.maxCcchPerDlSf &&
2977             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2978       {
2979          break;
2980       }
2981       else
2982       {
2983
2984          hqP = (RgSchDlHqProcCb *)(node->node);
2985          node = node->next;
2986
2987          /* DwPts Scheduling Changes Start */      
2988 #ifdef LTE_TDD
2989          if (rgSCHCmnRetxAvoidTdd(allocInfo->ccchSduAlloc.ccchSduDlSf, 
2990                   cell, hqP) == TRUE)
2991          {
2992             continue;  
2993          }
2994 #endif
2995          /* DwPts Scheduling Changes End */     
2996
2997          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
2998          {
2999             break;
3000          }
3001          ueCb = (RgSchUeCb*)(hqP->hqE->ue);
3002          ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
3003
3004          rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3005          /* Fill RB Alloc Info */
3006          rbAllocInfo->dlSf = dlSf;
3007          rbAllocInfo->tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3008          rbAllocInfo->rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3009          /* Fix : syed iMcs setting did not correspond to RETX */
3010          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3011                rbAllocInfo->tbInfo[0].imcs);
3012          rbAllocInfo->rnti = ueCb->ueId;
3013          rbAllocInfo->tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3014          /* Fix : syed Copying info in entirety without depending on stale TX information */
3015          rbAllocInfo->tbInfo[0].tbCb = &hqP->tbInfo[0];
3016          rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
3017          /* Fix : syed Assigning proc to scratchpad */ 
3018          ueDl->proc = hqP;
3019
3020          retxBw += rbAllocInfo->rbsReq;
3021
3022          cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduRetxLst, \
3023                &hqP->reqLnk);
3024          hqP->reqLnk.node = (PTR)hqP;
3025          dlSf->schdCcchUe++;
3026       }
3027    }
3028    dlSf->bwAssigned += retxBw;
3029    return;
3030 }
3031 #endif
3032 \f
3033 /**
3034  * @brief This function scheduler for downlink CCCH messages.
3035  *
3036  * @details
3037  *
3038  *     Function: rgSCHCmnDlCcchRetx
3039  *     Purpose:  Scheduling for downlink CCCH
3040  *
3041  *     Invoked by: Scheduler
3042  *
3043  *  @param[in]  RgSchCellCb           *cell
3044  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3045  *  @return  Void
3046  *
3047  **/
3048 static Void rgSCHCmnDlCcchRetx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
3049 {
3050    CmLList           *node;
3051    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3052    RgSchRaCb         *raCb;
3053    RgSchDlHqProcCb   *hqP;
3054    uint8_t           retxBw = 0;
3055    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3056         
3057
3058    node = cellSch->dl.msg4RetxLst.first;
3059    while(node)
3060    {
3061       if(cellSch->dl.maxCcchPerDlSf &&
3062             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3063       {
3064          break;
3065       }
3066       else
3067       {
3068          hqP = (RgSchDlHqProcCb *)(node->node);
3069
3070          node = node->next;
3071
3072          /* DwPts Scheduling Changes Start */     
3073 #ifdef LTE_TDD      
3074          if (rgSCHCmnRetxAvoidTdd(allocInfo->msg4Alloc.msg4DlSf, 
3075                   cell, hqP) == TRUE)
3076          {
3077             continue;  
3078          }
3079 #endif      
3080          /* DwPts Scheduling Changes End */      
3081
3082          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3083          {
3084             break;
3085          }
3086          raCb = (RgSchRaCb*)(hqP->hqE->raCb);
3087          /* Fill RB Alloc Info */
3088          raCb->rbAllocInfo.dlSf = dlSf;
3089          raCb->rbAllocInfo.tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3090          raCb->rbAllocInfo.rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3091          /* Fix : syed iMcs setting did not correspond to RETX */
3092          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3093                raCb->rbAllocInfo.tbInfo[0].imcs);
3094          raCb->rbAllocInfo.rnti = raCb->tmpCrnti;
3095          raCb->rbAllocInfo.tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3096          /* Fix; syed Copying info in entirety without depending on stale TX information */
3097          raCb->rbAllocInfo.tbInfo[0].tbCb = &hqP->tbInfo[0];
3098          raCb->rbAllocInfo.tbInfo[0].schdlngForTb = TRUE;
3099
3100          retxBw += raCb->rbAllocInfo.rbsReq;
3101
3102          cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4RetxLst, \
3103                &hqP->reqLnk);
3104          hqP->reqLnk.node = (PTR)hqP;
3105          dlSf->schdCcchUe++;
3106       }
3107    }
3108    dlSf->bwAssigned += retxBw;
3109    return;
3110 }
3111
3112 \f
3113 /**
3114  * @brief This function implements scheduler DL allocation for
3115  *        for broadcast (on PDSCH) and paging.
3116  *
3117  * @details
3118  *
3119  *     Function: rgSCHCmnDlBcchPcch
3120  *     Purpose:  This function implements scheduler for DL allocation
3121  *               for broadcast (on PDSCH) and paging.
3122  *
3123  *     Invoked by: Scheduler
3124  *
3125  *  @param[in]  RgSchCellCb*     cell
3126  *  @return  S16
3127  *      -# ROK
3128  *      -# RFAILED
3129  **/
3130 static Void rgSCHCmnDlBcchPcch(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo,RgInfSfAlloc *subfrmAlloc)
3131 {
3132    CmLteTimingInfo   frm;
3133    RgSchDlSf         *sf;
3134    RgSchClcDlLcCb    *pcch;
3135    RgSchClcBoRpt     *bo;
3136 #ifndef RGR_SI_SCH
3137    Bool              valid;
3138    RgSchClcDlLcCb    *bcch, *bch;
3139 #endif/*RGR_SI_SCH*/
3140
3141
3142    frm   = cell->crntTime;
3143 #ifdef LTEMAC_HDFDD
3144    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
3145       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
3146    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
3147 #else
3148   // RGSCH_SUBFRAME_INDEX(frm);
3149    //RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
3150 #endif
3151
3152    /* Compute the subframe for which allocation is being made        */
3153    /* essentially, we need pointer to the dl frame for this subframe */
3154    sf = rgSCHUtlSubFrmGet(cell, frm);
3155
3156
3157 #ifndef RGR_SI_SCH
3158    bch = rgSCHDbmGetBcchOnBch(cell);
3159 #if (ERRCLASS & ERRCLS_DEBUG)
3160    if (bch == NULLP)
3161    {
3162       DU_LOG("\nERROR  -->  SCH : BCCH on BCH is not configured");
3163       return;
3164    }
3165 #endif
3166    if (bch->boLst.first != NULLP)
3167    {
3168       bo = (RgSchClcBoRpt *)(bch->boLst.first->node);
3169       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3170       {
3171          sf->bch.tbSize = bo->bo;
3172          cmLListDelFrm(&bch->boLst, bch->boLst.first);
3173          /* ccpu00117052 - MOD - Passing double pointer
3174             for proper NULLP assignment*/
3175          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(*bo));
3176          rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, bch->lcId,TRUE);
3177       }
3178    }
3179    else
3180    {
3181       if ((frm.sfn % 4 == 0) && (frm.subframe == 0))
3182       {
3183       }
3184    }
3185
3186    allocInfo->bcchAlloc.schdFirst = FALSE;
3187    bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
3188 #if (ERRCLASS & ERRCLS_DEBUG)
3189    if (bcch == NULLP)
3190    {
3191       DU_LOG("\nERROR  -->  SCH : BCCH on DLSCH is not configured");
3192       return;
3193    }
3194 #endif
3195    if (bcch->boLst.first != NULLP)
3196    {
3197       bo = (RgSchClcBoRpt *)(bcch->boLst.first->node);
3198
3199       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3200       {
3201          allocInfo->bcchAlloc.schdFirst = TRUE;
3202          /* Time to perform allocation for this BCCH transmission */
3203          rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3204       }
3205    }
3206
3207    if(!allocInfo->bcchAlloc.schdFirst)
3208    {
3209       CmLList   *lnk;
3210       bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
3211 #if (ERRCLASS & ERRCLS_DEBUG)
3212       if (bcch == NULLP)
3213       {
3214          DU_LOG("\nERROR  -->  SCH : BCCH on DLSCH is not configured");
3215          return;
3216       }
3217 #endif
3218       lnk = bcch->boLst.first;
3219       while (lnk != NULLP)
3220       {
3221          bo = (RgSchClcBoRpt *)(lnk->node);
3222          lnk = lnk->next;
3223          valid = rgSCHCmnChkInWin(frm, bo->timeToTx, bo->maxTimeToTx);
3224
3225          if(valid)
3226          {
3227             bo->i = RGSCH_CALC_SF_DIFF(frm, bo->timeToTx);
3228             /* Time to perform allocation for this BCCH transmission */
3229             rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3230             break;
3231          }
3232          else
3233          {
3234             valid = rgSCHCmnChkPastWin(frm, bo->maxTimeToTx);
3235             if(valid)
3236             {
3237                cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
3238                /* ccpu00117052 - MOD - Passing double pointer
3239                   for proper NULLP assignment*/
3240                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo,
3241                      sizeof(RgSchClcBoRpt));
3242             }
3243          }
3244       }
3245    }
3246 #else
3247    rgSCHDlSiSched(cell, allocInfo, subfrmAlloc);
3248 #endif/*RGR_SI_SCH*/
3249
3250    pcch = rgSCHDbmGetPcch(cell);
3251 #ifdef ERRCLS_KW
3252    if (pcch == NULLP)
3253    {
3254       DU_LOG("\nERROR  -->  SCH : PCCH on DLSCH is not configured");
3255       return;
3256    }
3257 #endif
3258    if (pcch->boLst.first != NULLP)
3259    {
3260       bo = (RgSchClcBoRpt *)(pcch->boLst.first->node);
3261
3262       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3263       {
3264          /* Time to perform allocation for this PCCH transmission */
3265          rgSCHCmnClcAlloc(cell, sf, pcch, RGSCH_P_RNTI, allocInfo);
3266       }
3267    }
3268    return;
3269 }
3270
3271 /*
3272 *
3273 *       Fun:   rgSCHCmnChkInWin
3274 *
3275 *       Desc:  This function checks if frm occurs in window
3276 *
3277 *       Ret:   TRUE      - if in window
3278 *              FALSE     - otherwise
3279 *
3280 *       Notes: None
3281 *
3282 *       File:  rg_sch_cmn.c
3283 *
3284 */
3285 Bool rgSCHCmnChkInWin(CmLteTimingInfo frm,CmLteTimingInfo start,CmLteTimingInfo end)
3286 {
3287    Bool    inWin = FALSE;
3288
3289
3290    if (end.sfn > start.sfn)
3291    {
3292       if (frm.sfn > start.sfn
3293             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3294       {
3295          if (frm.sfn < end.sfn
3296 #ifdef EMTC_ENABLE
3297                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3298 #else
3299                || (frm.sfn == end.sfn && frm.slot <= start.slot))
3300 #endif
3301          {
3302             inWin = TRUE;
3303          }
3304       }
3305    }
3306    /* Testing for wrap around, sfn wraparound check should be enough */
3307    else if (end.sfn < start.sfn)
3308    {
3309       if (frm.sfn > start.sfn
3310             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3311       {
3312          inWin = TRUE;
3313       }
3314       else
3315       {
3316          if (frm.sfn < end.sfn
3317                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3318          {
3319             inWin = TRUE;
3320          }
3321       }
3322    }
3323    else  /* start.sfn == end.sfn */
3324    {
3325       if (frm.sfn == start.sfn
3326             && (frm.slot >= start.slot
3327                && frm.slot <= end.slot))
3328       {
3329          inWin = TRUE;
3330       }
3331    }
3332
3333    return (inWin);
3334 } /* end of rgSCHCmnChkInWin*/
3335
3336 /*
3337 *
3338 *       Fun:   rgSCHCmnChkPastWin
3339 *
3340 *       Desc:  This function checks if frm has gone past window edge
3341 *
3342 *       Ret:   TRUE      - if past window edge
3343 *              FALSE     - otherwise
3344 *
3345 *       Notes: None
3346 *
3347 *       File:  rg_sch_cmn.c
3348 *
3349 */
3350 Bool rgSCHCmnChkPastWin(CmLteTimingInfo frm,CmLteTimingInfo end)
3351 {
3352    CmLteTimingInfo  refFrm = end;
3353    Bool             pastWin;
3354
3355
3356    RGSCH_INCR_FRAME(refFrm.sfn);
3357    RGSCH_INCR_SUB_FRAME(end, 1);
3358    pastWin = rgSCHCmnChkInWin(frm, end, refFrm);
3359
3360    return (pastWin);
3361 } /* end of rgSCHCmnChkPastWin*/
3362 \f
3363 /**
3364  * @brief This function implements allocation of the resources for common
3365  * channels BCCH, PCCH.
3366  *
3367  * @details
3368  *
3369  *     Function: rgSCHCmnClcAlloc
3370  *     Purpose:  This function implements selection of number of RBs based
3371  *               the allowed grant for the service. It is also responsible
3372  *               for selection of MCS for the transmission.
3373  *
3374  *     Invoked by: Scheduler
3375  *
3376  *  @param[in]  RgSchCellCb                *cell,
3377  *  @param[in]  RgSchDlSf                  *sf,
3378  *  @param[in]  RgSchClcDlLcCb             *lch,
3379  *  @param[in]  uint16_t                        rnti,
3380  *  @param[out] RgSchCmnDlRbAllocInfo      *allocInfo
3381  *  @return     Void
3382  *
3383  **/
3384 static Void rgSCHCmnClcAlloc(RgSchCellCb *cell,RgSchDlSf *sf,RgSchClcDlLcCb  *lch,uint16_t rnti,RgSchCmnDlRbAllocInfo *allocInfo)
3385 {
3386    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3387    RgSchClcBoRpt        *bo;
3388    uint32_t                  rb=0;
3389    uint8_t                   mcs;
3390    uint32_t                  tbs;
3391 #ifdef LTE_TDD   
3392    uint8_t                   lostRe;
3393    uint8_t                   cfi = cellDl->currCfi;  
3394 #endif
3395
3396
3397    bo = (RgSchClcBoRpt *)(lch->boLst.first->node);
3398
3399    mcs = bo->mcs;
3400    tbs = bo->bo;
3401    /* rgSCHCmnClcRbAllocForFxdTb(cell, bo->bo, cellDl->ccchCqi, &rb);*/
3402    if(cellDl->bitsPerRb==0)
3403    {
3404       while ((rgTbSzTbl[0][0][rb]) < (tbs*8))
3405       {
3406          rb++;
3407       }
3408       rb = rb+1;
3409    }
3410    else
3411    {
3412       rb = RGSCH_CEIL((tbs*8), cellDl->bitsPerRb);
3413    }
3414    /* DwPTS Scheduling Changes Start */   
3415 #ifdef LTE_TDD
3416    if(sf->sfType == RG_SCH_SPL_SF_DATA) 
3417    {
3418       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
3419
3420       /* Calculate the less RE's because of DwPTS */
3421       lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
3422
3423       /* Increase number of RBs in Spl SF to compensate for lost REs */
3424       rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
3425    }
3426 #endif
3427    /* DwPTS Scheduling Changes End */   
3428    /*ccpu00115595- end*/
3429    /* additional check to see if required RBs
3430     * exceeds the available */
3431    if (rb > sf->bw - sf->bwAssigned)
3432    {
3433       DU_LOG("\nERROR  -->  SCH : BW allocation "
3434                 "failed for CRNTI:%d",rnti);
3435       return;
3436    }
3437
3438    /* Update the subframe Allocated BW field */
3439    sf->bwAssigned = sf->bwAssigned + rb;
3440    /* Fill in the BCCH/PCCH transmission info to the RBAllocInfo struct */
3441    if (rnti == RGSCH_SI_RNTI)
3442    {
3443       allocInfo->bcchAlloc.rnti = rnti;
3444       allocInfo->bcchAlloc.dlSf = sf;
3445       allocInfo->bcchAlloc.tbInfo[0].bytesReq = tbs;
3446       allocInfo->bcchAlloc.rbsReq = rb;
3447       allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
3448       allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
3449       /* Nprb indication at PHY for common Ch */
3450       allocInfo->bcchAlloc.nPrb = bo->nPrb;
3451    }
3452    else
3453    {
3454       allocInfo->pcchAlloc.rnti = rnti;
3455       allocInfo->pcchAlloc.dlSf = sf;
3456       allocInfo->pcchAlloc.tbInfo[0].bytesReq = tbs;
3457       allocInfo->pcchAlloc.rbsReq = rb;
3458       allocInfo->pcchAlloc.tbInfo[0].imcs = mcs;
3459       allocInfo->pcchAlloc.tbInfo[0].noLyr = 1;
3460       allocInfo->pcchAlloc.nPrb = bo->nPrb;
3461    }
3462    return;
3463 }
3464
3465 \f
3466 /**
3467  * @brief This function implements PDCCH allocation for common channels.
3468  *
3469  * @details
3470  *
3471  *     Function: rgSCHCmnCmnPdcchAlloc
3472  *     Purpose:  This function implements allocation of PDCCH for a UE.
3473  *               1. This uses index 0 of PDCCH table for efficiency.
3474  *               2. Uses he candidate PDCCH count for the aggr level.
3475  *               3. Look for availability for each candidate and choose
3476  *                  the first one available.
3477  *
3478  *     Invoked by: Scheduler
3479  *
3480  *  @param[in]  RgSchCellCb           *cell
3481  *  @param[in]  RgSchDlSf             *sf
3482  *  @return     RgSchPdcch *
3483  *               -# NULLP when unsuccessful
3484  *
3485  **/
3486 RgSchPdcch *rgSCHCmnCmnPdcchAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm)
3487 {
3488    CmLteAggrLvl         aggrLvl;
3489    RgSchPdcchInfo       *pdcchInfo;
3490    RgSchPdcch           *pdcch;
3491    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
3492    uint8_t              numCce;  /*store num CCEs based on 
3493                                   aggregation level */
3494
3495    aggrLvl   = cellSch->dl.cmnChAggrLvl;
3496
3497    pdcchInfo = &(subFrm->pdcchInfo);
3498
3499     /* Updating the no. of nCce in pdcchInfo, in case if CFI
3500     * was changed  */
3501 #ifdef LTE_TDD
3502    if(subFrm->nCce != pdcchInfo->nCce)
3503    {   
3504       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3505    }
3506 #else   
3507    if(cell->nCce != pdcchInfo->nCce)
3508    {
3509       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3510    }
3511 #endif  
3512
3513    switch (aggrLvl)
3514    {
3515       case CM_LTE_AGGR_LVL4:
3516         numCce = 4;
3517         break;
3518       case CM_LTE_AGGR_LVL8:
3519         numCce = 8;
3520         break;
3521                 case CM_LTE_AGGR_LVL16:
3522         numCce = 16;
3523         break;
3524       default:
3525         return (NULLP);
3526    }
3527
3528    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3529    {
3530 #ifdef LTEMAC_SPS
3531       pdcch->isSpsRnti = FALSE;
3532 #endif
3533       /* Increment the CCE used counter in the current subframe */
3534       subFrm->cceCnt += numCce;
3535       pdcch->pdcchSearchSpace = RG_SCH_CMN_SEARCH_SPACE;
3536
3537       return (pdcch);
3538    }
3539
3540    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3541    subFrm->isCceFailure = TRUE;
3542    DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN COMMON SEARCH SPACE aggr:%u", 
3543             aggrLvl);
3544    return (NULLP);
3545 }
3546
3547 \f
3548 /**
3549  * @brief This function implements bandwidth allocation for common channels.
3550  *
3551  * @details
3552  *
3553  *     Function: rgSCHCmnClcRbAlloc
3554  *     Purpose:  This function implements bandwith allocation logic
3555  *               for common control channels.
3556  *
3557  *     Invoked by: Scheduler
3558  *
3559  *  @param[in]  RgSchCellCb*  cell
3560  *  @param[in]  uint32_t           bo
3561  *  @param[in]  uint8_t            cqi
3562  *  @param[in]  uint8_t            *rb
3563  *  @param[in]  uint32_t           *tbs
3564  *  @param[in]  uint8_t            *mcs
3565  *  @param[in]  RgSchDlSf     *sf
3566  *  @return  Void
3567  *
3568  **/
3569 #ifdef LTEMAC_SPS
3570 Void rgSCHCmnClcRbAlloc
3571 (
3572 RgSchCellCb  *cell,
3573 uint32_t     bo,
3574 uint8_t      cqi,
3575 uint8_t      *rb,
3576 uint32_t     *tbs,
3577 uint8_t      *mcs,
3578 uint8_t      *iTbs,
3579 Bool         isSpsBo,
3580 RgSchDlSf    *sf 
3581 )
3582 #else
3583 static Void rgSCHCmnClcRbAlloc
3584 (
3585 RgSchCellCb  *cell,
3586 uint32_t     bo,
3587 uint8_t      cqi,
3588 uint8_t      *rb,
3589 uint32_t     *tbs,
3590 uint8_t      *mcs,
3591 RgSchDlSf    *sf 
3592 )
3593 #endif /* LTEMAC_SPS */
3594 {
3595    uint8_t          iTbsVal;
3596    RgSchCmnTbSzEff  *effTbl;
3597    uint32_t         eff;
3598    uint32_t         noRes;
3599    RgSchCmnCell     *cellSch = RG_SCH_CMN_GET_CELL(cell);
3600    uint8_t          cfi = cellSch->dl.currCfi;
3601    uint32_t         tmpRb=0;
3602
3603    /* first get the CQI to MCS table and determine the number of RBs */
3604    effTbl = (RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]);
3605    iTbsVal = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[cqi];
3606    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3607
3608    /* Efficiency is number of bits per 1024 REs */
3609    eff  = (*effTbl)[iTbsVal];
3610
3611    /* Get the number of REs needed for this bo  */
3612    noRes = ((bo * 8 * 1024) / eff );
3613
3614    /* Get the number of RBs needed for this transmission */
3615    /* Number of RBs = No of REs / No of REs per RB       */
3616    tmpRb = RGSCH_CEIL(noRes, cellSch->dl.noResPerRb[cfi]);
3617    /* KWORK_FIX: added check to see if rb has crossed maxRb*/
3618    RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3619    if (tmpRb > cellSch->dl.maxDlBwPerUe)
3620    {
3621       tmpRb = cellSch->dl.maxDlBwPerUe;
3622    }
3623    while ((rgTbSzTbl[0][iTbsVal][tmpRb-1]/8) < bo && 
3624            (tmpRb < cellSch->dl.maxDlBwPerUe))
3625    {
3626       tmpRb++;
3627       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3628    }
3629    *tbs =  rgTbSzTbl[0][iTbsVal][tmpRb-1]/8;
3630    *rb = (uint8_t)tmpRb;
3631    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3632
3633    return;
3634 }
3635
3636 \f
3637
3638 /**
3639  * @brief Scheduling for MSG4.
3640  *
3641  * @details
3642  *
3643  *     Function: rgSCHCmnMsg4Alloc
3644  *     Purpose:  Scheduling for MSG4
3645  *
3646  *     Invoked by: Scheduler
3647  *
3648  *  @param[in]  RgSchCellCb*          cell
3649  *  @param[in]  RgSchRaCb*            raCb
3650  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3651  *  @return  S16
3652  *
3653  **/
3654 static S16 rgSCHCmnMsg4Alloc(RgSchCellCb *cell,RgSchRaCb *raCb,RgSchCmnDlRbAllocInfo *allocInfo)
3655 {
3656    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
3657
3658
3659    /* SR_RACH_STATS : MSG4 TO BE TXED */
3660    rgNumMsg4ToBeTx++;
3661    /* Return if subframe BW exhausted */
3662    if (allocInfo->msg4Alloc.msg4DlSf->bw <=
3663        allocInfo->msg4Alloc.msg4DlSf->bwAssigned)
3664    {
3665       DU_LOG("\nERROR  -->  SCH : bw<=bwAssigned");
3666       return RFAILED;
3667    }
3668
3669    if (rgSCHDhmGetMsg4HqProc(raCb, cellSch->dl.time) != ROK)
3670    {
3671       DU_LOG("\nERROR  -->  SCH : rgSCHDhmGetMsg4HqProc failed");
3672       return RFAILED;
3673    }
3674
3675    raCb->rbAllocInfo.dlSf = allocInfo->msg4Alloc.msg4DlSf;
3676
3677    if (rgSCHCmnMsg4DedAlloc(cell, raCb) != ROK)
3678    {
3679       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
3680       rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, FALSE);
3681       DU_LOG("\nERROR  -->  SCH : rgSCHCmnMsg4DedAlloc failed.");
3682       return RFAILED;
3683    }
3684    cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4TxLst, &raCb->dlHqE->msg4Proc->reqLnk);
3685    raCb->dlHqE->msg4Proc->reqLnk.node = (PTR)raCb->dlHqE->msg4Proc;
3686    allocInfo->msg4Alloc.msg4DlSf->schdCcchUe++;
3687
3688    return ROK;
3689 }
3690
3691 \f
3692 /**
3693  * @brief This function implements PDCCH allocation for an UE.
3694  *
3695  * @details
3696  *
3697  *     Function: PdcchAlloc
3698  *     Purpose:  This function implements allocation of PDCCH for an UE.
3699  *               1. Get the aggregation level for the CQI of the UE.
3700  *               2. Get the candidate PDCCH count for the aggr level.
3701  *               3. Look for availability for each candidate and choose
3702  *                  the first one available.
3703  *
3704  *     Invoked by: Scheduler
3705  *
3706  *  @param[in]  cell
3707  *  @param[in]  subFrm
3708  *  @param[in]  cqi
3709  *  @param[in]  dciFrmt
3710  *  @return  RgSchPdcch *
3711  *         -# NULLP when unsuccessful
3712  *
3713  **/
3714 RgSchPdcch *rgSCHCmnPdcchAlloc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlSf *subFrm,uint8_t cqi,TfuDciFormat dciFrmt,Bool isDtx)
3715 {
3716    CmLteAggrLvl     aggrLvl;
3717    RgSchPdcchInfo   *pdcchInfo;
3718    RgSchPdcch       *pdcch;
3719
3720
3721    /* 3.1 consider the selected DCI format size in determining the
3722     * aggregation level */
3723    //TODO_SID Need to update. Currently using 4 aggregation level
3724    aggrLvl   = CM_LTE_AGGR_LVL2;//cellSch->dciAggrLvl[cqi][dciFrmt];
3725
3726 #ifdef LTE_ADV
3727    if((dciFrmt == TFU_DCI_FORMAT_1A) &&
3728       ((ue) && (ue->allocCmnUlPdcch)) )
3729    {
3730       pdcch = rgSCHCmnCmnPdcchAlloc(cell, subFrm);
3731       /* Since CRNTI Scrambled */
3732       if(NULLP != pdcch)
3733       {
3734          pdcch->dciNumOfBits = ue->dciSize.cmnSize[dciFrmt];
3735         // prc_trace_format_string(PRC_TRACE_GROUP_PS, PRC_TRACE_INFO_LOW,"Forcing alloc in CMN search spc size %d fmt %d \n",
3736         // pdcch->dciNumOfBits, dciFrmt);
3737       }
3738       return (pdcch);
3739    }
3740 #endif
3741
3742    /* Incrementing aggrLvl by 1 if it not AGGR_LVL8(MAX SIZE)
3743     * inorder to increse the redudancy bits for better decoding of UE */
3744    if (isDtx)
3745    {
3746       if (aggrLvl != CM_LTE_AGGR_LVL16)
3747       {
3748          switch(aggrLvl)
3749          {
3750             case CM_LTE_AGGR_LVL2:
3751                aggrLvl = CM_LTE_AGGR_LVL4;
3752                 break;
3753             case CM_LTE_AGGR_LVL4:
3754                aggrLvl = CM_LTE_AGGR_LVL8;
3755                break;
3756             case CM_LTE_AGGR_LVL8:
3757                aggrLvl = CM_LTE_AGGR_LVL16;
3758                break;
3759             default:
3760                break;
3761          }
3762          /* aggrLvl   += 1; */
3763       }
3764    }
3765
3766    pdcchInfo = &subFrm->pdcchInfo;
3767
3768    /* Updating the no. of nCce in pdcchInfo, in case if CFI
3769     * was changed  */
3770 #ifdef LTE_TDD
3771    if(subFrm->nCce != pdcchInfo->nCce)
3772    {   
3773       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3774    }
3775 #else   
3776    if(cell->nCce != pdcchInfo->nCce)
3777    {
3778       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3779    }
3780 #endif       
3781
3782    if (pdcchInfo->nCce < (1 << (aggrLvl - 1)))
3783    {
3784       /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3785       subFrm->isCceFailure = TRUE;
3786       DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", 
3787             aggrLvl);
3788
3789       return (NULLP);
3790    }
3791
3792    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3793    {
3794       /* SR_RACH_STATS : Reset isTBMsg4 */
3795       pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4= FALSE;         
3796       pdcch->dci.u.format0Info.isSrGrant = FALSE;
3797 #ifdef LTEMAC_SPS
3798       pdcch->isSpsRnti = FALSE;
3799 #endif
3800       /* Increment the CCE used counter in the current subframe */
3801       subFrm->cceCnt += aggrLvl;
3802       pdcch->pdcchSearchSpace = RG_SCH_UE_SPECIFIC_SEARCH_SPACE;
3803       if (ue != NULLP)
3804                 {
3805 #ifdef LTE_ADV
3806                  if (ue->cell != cell)
3807                  {
3808                     /* Secondary Cell */
3809                     //pdcch->dciNumOfBits = ue->dciSize.noUlCcSize[dciFrmt];
3810                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
3811                  }
3812                  else
3813 #endif
3814                  {
3815                     //pdcch->dciNumOfBits = ue->dciSize.dedSize[dciFrmt];
3816                     //TODO_SID Need to update dci size.
3817                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
3818                  }
3819                 }
3820       else
3821       {
3822          /* MSG4 */
3823          pdcch->dciNumOfBits = cell->dciSize.size[dciFrmt];
3824       }
3825       return (pdcch);
3826    }
3827
3828    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3829    subFrm->isCceFailure = TRUE;
3830
3831    DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)",
3832          aggrLvl);
3833    return (NULLP);
3834 }
3835
3836 #ifdef RGR_V1
3837 /**
3838  * @brief This function implements BW allocation for CCCH SDU
3839  *
3840  * @details
3841  *
3842  *     Function: rgSCHCmnCcchSduDedAlloc
3843  *     Purpose:  Downlink bandwidth Allocation for CCCH SDU.
3844  *
3845  *     Invoked by: Scheduler
3846  *
3847  *  @param[in]  RgSchCellCb*     cell
3848  *  @param[out] RgSchUeCb        *ueCb
3849  *  @return S16
3850  *
3851  **/
3852 static S16 rgSCHCmnCcchSduDedAlloc(RgSchCellCb *cell,RgSchUeCb *ueCb)
3853 {
3854    RgSchDlHqEnt   *hqE = NULLP;
3855    uint32_t       effBo;
3856    RgSchDlRbAlloc *rbAllocinfo = NULLP;
3857    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3858    uint8_t        iTbs;
3859    uint8_t        numRb;
3860 #ifdef LTE_TDD
3861    uint8_t        cfi     = cellDl->currCfi;
3862 #endif
3863
3864
3865    rbAllocinfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3866
3867    effBo  =   ueCb->dlCcchInfo.bo + RGSCH_CCCH_SDU_HDRSIZE;
3868
3869 #ifndef LTEMAC_SPS
3870    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
3871                       &rbAllocinfo->tbInfo[0].bytesReq,
3872                       &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
3873 #else /* LTEMAC_SPS */
3874    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
3875                       &rbAllocinfo->tbInfo[0].bytesReq,\
3876                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, 
3877                       rbAllocinfo->dlSf);
3878 #endif /* LTEMAC_SPS */
3879
3880    iTbs = 0;
3881    /* Cannot exceed the total number of RBs in the cell */
3882    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
3883                                    rbAllocinfo->dlSf->bwAssigned)))
3884    {
3885       /* Check if atleast one allocation was possible.
3886          This may be the case where the Bw is very less and
3887          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
3888       if (rbAllocinfo->dlSf->bwAssigned == 0)
3889       {
3890          numRb   = rbAllocinfo->dlSf->bw;
3891          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
3892          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
3893          {
3894             iTbs++;
3895          }
3896          rbAllocinfo->rbsReq = numRb;
3897          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
3898          /* DwPTS Scheduling Changes Start */
3899 #ifdef LTE_TDD
3900          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
3901          {
3902             rbAllocinfo->tbInfo[0].bytesReq =
3903                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1,cfi);
3904          }
3905 #endif
3906          /* DwPTS Scheduling Changes End */
3907          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
3908       }
3909       else
3910       {
3911          return RFAILED;
3912       }
3913    }
3914
3915    /* Update the subframe Allocated BW field */
3916    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
3917                                    rbAllocinfo->rbsReq;
3918    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
3919    rbAllocinfo->tbInfo[0].tbCb = &hqE->ccchSduProc->tbInfo[0];
3920    rbAllocinfo->rnti = ueCb->ueId;
3921    rbAllocinfo->tbInfo[0].noLyr = 1;
3922
3923    return ROK;
3924 }
3925 #endif
3926 \f
3927 /**
3928  * @brief This function implements BW allocation for MSG4
3929  *
3930  * @details
3931  *
3932  *     Function: rgSCHCmnMsg4DedAlloc
3933  *     Purpose:  Downlink bandwidth Allocation for MSG4.
3934  *
3935  *     Invoked by: Scheduler
3936  *
3937  *  @param[in]  RgSchCellCb*     cell
3938  *  @param[out] RgSchRaCb        *raCb
3939  *  @return S16
3940  *
3941  **/
3942 static S16 rgSCHCmnMsg4DedAlloc(RgSchCellCb *cell,RgSchRaCb *raCb)
3943 {
3944    uint32_t          effBo;
3945    RgSchDlRbAlloc    *rbAllocinfo = &raCb->rbAllocInfo;
3946    uint8_t           iTbs;
3947    uint8_t           numRb;
3948 #ifdef LTE_TDD
3949    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3950    uint8_t           cfi     = cellDl->currCfi;
3951 #endif
3952
3953
3954    effBo  = raCb->dlCcchInfo.bo + RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE;
3955
3956 #ifndef LTEMAC_SPS
3957    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
3958          &rbAllocinfo->tbInfo[0].bytesReq,\
3959          &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
3960 #else /* LTEMAC_SPS */
3961    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
3962                       &rbAllocinfo->tbInfo[0].bytesReq,\
3963                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE,
3964                       rbAllocinfo->dlSf);
3965 #endif /* LTEMAC_SPS */
3966
3967    iTbs = 0;
3968    /* Cannot exceed the total number of RBs in the cell */
3969    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
3970                rbAllocinfo->dlSf->bwAssigned)))
3971    {
3972       /* Check if atleast one allocation was possible.
3973          This may be the case where the Bw is very less and
3974          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
3975       if (rbAllocinfo->dlSf->bwAssigned == 0)
3976       {
3977          numRb   = rbAllocinfo->dlSf->bw;
3978          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
3979          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
3980          {
3981             iTbs++;
3982          }
3983          rbAllocinfo->rbsReq = numRb;
3984          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
3985          /* DwPTS Scheduling Changes Start */
3986 #ifdef LTE_TDD
3987          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
3988          {
3989             rbAllocinfo->tbInfo[0].bytesReq =
3990                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1, cfi);
3991          }
3992 #endif
3993          /* DwPTS Scheduling Changes End */
3994          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
3995       }
3996       else
3997       {
3998          return RFAILED;
3999       }
4000    }
4001
4002    /* Update the subframe Allocated BW field */
4003    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4004                                    rbAllocinfo->rbsReq;
4005    rbAllocinfo->rnti = raCb->tmpCrnti;
4006    rbAllocinfo->tbInfo[0].tbCb = &raCb->dlHqE->msg4Proc->tbInfo[0];
4007    rbAllocinfo->tbInfo[0].schdlngForTb = TRUE;
4008    rbAllocinfo->tbInfo[0].noLyr = 1;
4009
4010    return ROK;
4011 }
4012
4013 #ifdef LTE_TDD
4014 /**
4015  * @brief This function implements scheduling for RA Response.
4016  *
4017  * @details
4018  *
4019  *     Function: rgSCHCmnDlRaRsp
4020  *     Purpose:  Downlink scheduling for RA responses.
4021  *
4022  *     Invoked by: Scheduler
4023  *
4024  *  @param[in]  RgSchCellCb*     cell
4025  *  @return  Void
4026  *
4027  **/
4028 static Void rgSCHCmnDlRaRsp(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
4029 {
4030    CmLteTimingInfo      frm;
4031    CmLteTimingInfo      schFrm;
4032    RgSchDlSf            *subFrm;
4033    uint16_t             rarnti;
4034    uint8_t              i;
4035    uint8_t              noRaRnti=0;
4036    uint8_t              raIdx;
4037    RgSchTddRachRspLst   *rachRsp;
4038    uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
4039    uint8_t              sfnIdx;
4040    uint8_t              subfrmIdx;
4041    uint16_t             rntiIdx=0;
4042
4043    frm   = cell->crntTime;
4044    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4045
4046    /* Compute the subframe for which allocation is being made        */
4047    /* essentially, we need pointer to the dl frame for this subframe */
4048    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4049
4050    /* Get the RACH Response scheduling related information
4051     * for the subframe with RA index */
4052    raIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][frm.subframe]-1;
4053
4054    rachRsp = &cell->rachRspLst[raIdx];
4055
4056    for(sfnIdx = 0; sfnIdx < rachRsp->numRadiofrms; sfnIdx++)
4057    {
4058       /* For all scheduled RACH Responses in SFNs */
4059       schFrm = frm;
4060       RG_SCH_CMN_DECR_FRAME(schFrm.sfn, rachRsp->rachRsp[sfnIdx].sfnOffset);
4061       /* For all scheduled RACH Responses in subframes */
4062       for(subfrmIdx = 0;
4063             subfrmIdx < rachRsp->rachRsp[sfnIdx].numSubfrms; subfrmIdx++)
4064       {
4065          schFrm.subframe = rachRsp->rachRsp[sfnIdx].subframe[subfrmIdx];
4066          /* compute the last RA RNTI used in the previous subframe */
4067          raIdx = (((schFrm.sfn % cell->raInfo.maxRaSize) * \
4068                   RGSCH_NUM_SUB_FRAMES * RGSCH_MAX_RA_RNTI_PER_SUBFRM) \
4069                                     + schFrm.subframe);
4070
4071          /* For all RA RNTIs within a subframe */
4072
4073          for(i=0; (i < RGSCH_MAX_RA_RNTI_PER_SUBFRM) && \
4074                (noRaRnti < RGSCH_MAX_TDD_RA_RSP_ALLOC); i++)
4075          {
4076             rarnti = (schFrm.subframe + RGSCH_NUM_SUB_FRAMES*i + 1);
4077             rntiIdx = (raIdx + RGSCH_NUM_SUB_FRAMES*i);
4078
4079             if (cell->raInfo.raReqLst[rntiIdx].first != NULLP)
4080             {
4081                /* compute the next RA RNTI */
4082                if (rgSCHCmnRaRspAlloc(cell, subFrm, rntiIdx,
4083                         rarnti, noRaRnti, allocInfo) != ROK)
4084                {
4085                   /* The resources are exhausted */
4086                   break;
4087                }
4088                noRaRnti++;
4089             }
4090          }
4091          noRaRnti=0;
4092       }
4093    }
4094
4095    return;
4096 }
4097 #else
4098 /**
4099  * @brief This function implements scheduling for RA Response.
4100  *
4101  * @details
4102  *
4103  *     Function: rgSCHCmnDlRaRsp
4104  *     Purpose:  Downlink scheduling for RA responses.
4105  *
4106  *     Invoked by: Scheduler
4107  *
4108  *  @param[in]  RgSchCellCb*          cell
4109  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
4110  *  @return  Void
4111  *
4112  **/
4113 static Void rgSCHCmnDlRaRsp(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
4114 {
4115    CmLteTimingInfo frm;
4116    CmLteTimingInfo winStartFrm;
4117    RgSchDlSf       *subFrm;
4118    uint8_t         winStartIdx;
4119    uint8_t         winGap;
4120    uint8_t         rarnti;
4121    uint8_t         raIdx;
4122    RgSchCmnCell    *sched;
4123    uint8_t         i,noRaRnti=0;
4124
4125    frm   = cell->crntTime;
4126    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4127
4128    /* Compute the subframe for which allocation is being made        */
4129    /* essentially, we need pointer to the dl frame for this subframe */
4130    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4131    sched   = RG_SCH_CMN_GET_CELL(cell);
4132
4133    /* ccpu00132523 - Window Start calculated by considering RAR window size, 
4134     * RAR Wait period, Subframes occuppied for respective preamble format*/
4135    winGap = (sched->dl.numRaSubFrms-1) + (cell->rachCfg.raWinSize-1) 
4136              +RGSCH_RARSP_WAIT_PERIOD;
4137
4138    /* Window starting occassion is retrieved using the gap and tried to 
4139     * fit to the size of raReqLst array*/ 
4140    RGSCHDECRFRMCRNTTIME(frm, winStartFrm, winGap);
4141
4142         //5G_TODO TIMING update. Need to check
4143    winStartIdx = (winStartFrm.sfn & 1) * RGSCH_MAX_RA_RNTI+ winStartFrm.slot;
4144
4145    for(i = 0; ((i < cell->rachCfg.raWinSize) && (noRaRnti < RG_SCH_CMN_MAX_CMN_PDCCH)); i++)
4146    {
4147       raIdx = (winStartIdx + i) % RGSCH_RAREQ_ARRAY_SIZE;
4148
4149       if (cell->raInfo.raReqLst[raIdx].first != NULLP)
4150       {
4151          allocInfo->raRspAlloc[noRaRnti].biEstmt = \
4152                          (!i * RGSCH_ONE_BIHDR_SIZE);
4153          rarnti = raIdx % RGSCH_MAX_RA_RNTI+ 1;
4154          if (rgSCHCmnRaRspAlloc(cell, subFrm, raIdx,
4155                                  rarnti, noRaRnti, allocInfo) != ROK)
4156          {
4157             /* The resources are exhausted */
4158             break;
4159          }
4160          /* ccpu00132523- If all the RAP ids are not scheduled then need not 
4161           * proceed for next RA RNTIs*/
4162          if(allocInfo->raRspAlloc[noRaRnti].numRapids < cell->raInfo.raReqLst[raIdx].count)
4163          {
4164             break;
4165          }
4166          noRaRnti++; /* Max of RG_SCH_CMN_MAX_CMN_PDCCH RARNTIs
4167                         for response allocation */
4168       }
4169    }
4170    return;
4171 }
4172 #endif
4173
4174 \f
4175 /**
4176  * @brief This function allocates the resources for an RARNTI.
4177  *
4178  * @details
4179  *
4180  *     Function: rgSCHCmnRaRspAlloc
4181  *     Purpose:  Allocate resources to a RARNTI.
4182  *               0. Allocate PDCCH for sending the response.
4183  *               1. Locate the number of RA requests pending for the RARNTI.
4184  *               2. Compute the size of data to be built.
4185  *               3. Using common channel CQI, compute the number of RBs.
4186  *
4187  *     Invoked by: Scheduler
4188  *
4189  *  @param[in]  RgSchCellCb             *cell,
4190  *  @param[in]  RgSchDlSf               *subFrm,
4191  *  @param[in]  uint16_t                     rarnti,
4192  *  @param[in]  uint8_t                      noRaRnti
4193  *  @param[out] RgSchCmnDlRbAllocInfo   *allocInfo
4194  *  @return  S16
4195  *
4196  **/
4197 static S16 rgSCHCmnRaRspAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm,uint16_t raIndex,uint16_t rarnti,uint8_t noRaRnti,RgSchCmnDlRbAllocInfo *allocInfo)
4198 {
4199    RgSchCmnDlCell   *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4200    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4201    uint16_t         noBytes;
4202    uint32_t         rb = 0;
4203    uint32_t         tbs;
4204    /*ccpu00116700,ccpu00116708- Corrected the wrong type for mcs*/
4205    uint8_t          mcs;
4206    CmLListCp        *reqLst;
4207    /* RACH handling related changes */
4208    Bool             isAlloc = FALSE;
4209    static uint8_t   schdNumRapid = 0;
4210    uint8_t          remNumRapid = 0;
4211    uint8_t          nPrb = 0;
4212    S32              allwdTbSz = 0;
4213 #ifdef LTE_TDD   
4214    uint16_t         lostRe;  
4215    uint8_t          cfi = cellDl->currCfi;  
4216 #endif   
4217
4218 #ifndef RGR_V1
4219    UNUSED(cellUl);
4220 #endif
4221
4222    /* ccpu00132523: Resetting the schdRap Id count in every scheduling subframe*/
4223    if(noRaRnti == 0)
4224    {
4225       schdNumRapid = 0;
4226    }
4227
4228
4229    if (subFrm->bw == subFrm->bwAssigned)
4230    {
4231       DU_LOG("\nERROR  -->  SCH : bw == bwAssigned RARNTI:%d",rarnti);
4232       return RFAILED;
4233    }
4234
4235    reqLst = &cell->raInfo.raReqLst[raIndex];
4236    if (reqLst->count == 0)
4237    {
4238       DU_LOG("\nERROR  -->  SCH : reqLst Count=0 RARNTI:%d",rarnti);
4239       return RFAILED;
4240    }
4241    remNumRapid = reqLst->count;
4242
4243 #ifdef RGR_V1
4244    /* Limit number of rach rsps to maxMsg3PerUlsf */
4245    if ( schdNumRapid+remNumRapid > cellUl->maxMsg3PerUlSf )
4246    {
4247       remNumRapid = cellUl->maxMsg3PerUlSf-schdNumRapid;
4248    }
4249 #endif
4250  
4251    while (remNumRapid)
4252    {
4253       /* Try allocating for as many RAPIDs as possible */
4254       /* BI sub-header size to the tbSize requirement */
4255       noBytes  = RGSCH_GET_RAR_BYTES(remNumRapid) +\
4256                  allocInfo->raRspAlloc[noRaRnti].biEstmt;
4257       if ((allwdTbSz = rgSCHUtlGetAllwdCchTbSz(noBytes*8, &nPrb, &mcs)) == -1)
4258       {
4259          remNumRapid--;
4260          continue;
4261       }
4262
4263       /* rgSCHCmnClcRbAllocForFxdTb(cell, allwdTbSz/8, cellDl->ccchCqi, &rb);*/
4264       if(cellDl->bitsPerRb==0)
4265       {
4266          while ((rgTbSzTbl[0][0][rb]) <(uint32_t) allwdTbSz)
4267          {
4268             rb++;
4269          }
4270          rb = rb+1;
4271       }
4272       else
4273       {
4274          rb = RGSCH_CEIL(allwdTbSz, cellDl->bitsPerRb);
4275       }
4276       /* DwPTS Scheduling Changes Start */      
4277 #ifdef LTE_TDD      
4278       if (subFrm->sfType == RG_SCH_SPL_SF_DATA)
4279       {
4280          RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
4281
4282          /* Calculate the less RE's because of DwPTS */
4283          lostRe = rb * (cellDl->noResPerRb[cfi] - 
4284                                   cellDl->numReDwPts[cfi]);
4285           
4286          /* Increase number of RBs in Spl SF to compensate for lost REs */
4287          rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]);
4288       }
4289 #endif      
4290       /* DwPTS Scheduling Changes End */
4291
4292       /*ccpu00115595- end*/
4293       if (rb > subFrm->bw - subFrm->bwAssigned)
4294       {
4295          remNumRapid--;
4296          continue;
4297       }
4298       /* Allocation succeeded for 'remNumRapid' */
4299       isAlloc = TRUE;
4300       tbs = allwdTbSz/8;
4301       DU_LOG("\nINFO  -->  SCH : RAR alloc noBytes:%u,allwdTbSz:%u,tbs:%u,rb:%u\n",
4302                                       noBytes,allwdTbSz,tbs,rb);
4303       break;
4304    }
4305    if (!isAlloc)
4306    {
4307       DU_LOG("\nERROR  -->  SCH : BW alloc Failed");
4308       return RFAILED;
4309    }
4310
4311    subFrm->bwAssigned = subFrm->bwAssigned + rb;
4312
4313    /* Fill AllocInfo structure */
4314    allocInfo->raRspAlloc[noRaRnti].rnti = rarnti;
4315    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].bytesReq = tbs;
4316    allocInfo->raRspAlloc[noRaRnti].rbsReq = rb;
4317    allocInfo->raRspAlloc[noRaRnti].dlSf = subFrm;
4318    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].imcs = mcs;
4319    allocInfo->raRspAlloc[noRaRnti].raIndex = raIndex;
4320    /* RACH changes for multiple RAPID handling */
4321    allocInfo->raRspAlloc[noRaRnti].numRapids = remNumRapid;
4322    allocInfo->raRspAlloc[noRaRnti].nPrb = nPrb;
4323    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].noLyr = 1;
4324    allocInfo->raRspAlloc[noRaRnti].vrbgReq = RGSCH_CEIL(nPrb,MAX_5GTF_VRBG_SIZE); 
4325    schdNumRapid += remNumRapid; 
4326    return ROK;
4327 }
4328
4329 /***********************************************************
4330  *
4331  *     Func : rgSCHCmnUlAllocFillRbInfo
4332  *
4333  *     Desc : Fills the start RB and the number of RBs for
4334  *            uplink allocation.
4335  *
4336  *     Ret  : void
4337  *
4338  *     Notes:
4339  *
4340  *     File :
4341  *
4342  **********************************************************/
4343 Void rgSCHCmnUlAllocFillRbInfo(RgSchCellCb *cell,RgSchUlSf *sf,RgSchUlAlloc  *alloc)
4344 {
4345     RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4346     RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4347     uint8_t             cfi = cellDl->currCfi;
4348
4349
4350    alloc->grnt.rbStart = (alloc->sbStart * cellUl->sbSize) + 
4351                                     cell->dynCfiCb.bwInfo[cfi].startRb;
4352
4353    /* Num RBs = numSbAllocated * sbSize - less RBs in the last SB */
4354    alloc->grnt.numRb = (alloc->numSb * cellUl->sbSize);
4355
4356    return;
4357 }
4358
4359 /**
4360  * @brief Grant request for Msg3.
4361  *
4362  * @details
4363  *
4364  *     Function : rgSCHCmnMsg3GrntReq
4365  *
4366  *     This is invoked by downlink scheduler to request allocation
4367  *     for msg3.
4368  *     Steps:
4369  *     - Attempt to allocate msg3 in the current msg3 subframe
4370  *       Allocation attempt based on whether preamble is from group A
4371  *       and the value of MESSAGE_SIZE_GROUP_A
4372  *     - Link allocation with passed RNTI and msg3 HARQ process
4373  *     - Set the HARQ process ID (*hqProcIdRef)
4374  *
4375  *  @param[in]  RgSchCellCb       *cell
4376  *  @param[in]  CmLteRnti         rnti
4377  *  @param[in]  Bool              preamGrpA
4378  *  @param[in]  RgSchUlHqProcCb   *hqProc
4379  *  @param[out] RgSchUlAlloc      **ulAllocRef
4380  *  @param[out] uint8_t                *hqProcIdRef
4381  *  @return  Void
4382  **/
4383 static Void rgSCHCmnMsg3GrntReq
4384 (
4385 RgSchCellCb     *cell,
4386 CmLteRnti       rnti,
4387 Bool            preamGrpA,
4388 RgSchUlHqProcCb *hqProc,
4389 RgSchUlAlloc    **ulAllocRef,
4390 uint8_t         *hqProcIdRef
4391 )
4392 {
4393    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4394    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
4395    RgSchUlHole     *hole;
4396    RgSchUlAlloc    *alloc;
4397    uint8_t         iMcs;
4398    uint8_t         numSb;
4399
4400
4401    *ulAllocRef = NULLP;
4402
4403    /* Fix: ccpu00120610 Use remAllocs from subframe during msg3 allocation */
4404    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
4405    {
4406       return;
4407    }
4408    if (preamGrpA == FALSE)
4409    {
4410       numSb = cellUl->ra.prmblBNumSb;
4411       iMcs  = cellUl->ra.prmblBIMcs;
4412    }
4413    else
4414    {
4415       numSb = cellUl->ra.prmblANumSb;
4416       iMcs  = cellUl->ra.prmblAIMcs;
4417    }
4418
4419    if ((hole = rgSCHUtlUlHoleFirst(sf)) != NULLP)
4420    {
4421       if(*sf->allocCountRef == 0)
4422       {
4423          RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4424          /* Reinitialize the hole */
4425          if (sf->holeDb->count == 1 && (hole->start == 0)) /* Sanity check of holeDb */
4426          {
4427             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;
4428             /* Re-Initialize available subbands because of CFI change*/
4429             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
4430          }
4431          else
4432          {
4433             DU_LOG("\nERROR  -->  SCH :  holeDb sanity check failed RNTI:%d",rnti);
4434          } 
4435       }
4436       if (numSb <= hole->num)
4437       {
4438          uint8_t iTbs;
4439          alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
4440          rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
4441          alloc->grnt.iMcs     = iMcs;
4442          alloc->grnt.iMcsCrnt = iMcs;
4443          iTbs                 = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
4444          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); 
4445          /* To include the length and ModOrder in DataRecp Req.*/
4446          alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
4447          RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
4448          /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
4449          alloc->grnt.nDmrs    = 0;
4450          alloc->grnt.hop      = 0;
4451          alloc->grnt.delayBit = 0;
4452          alloc->grnt.isRtx    = FALSE;
4453          *ulAllocRef          = alloc;
4454          *hqProcIdRef         = (cellUl->msg3SchdHqProcIdx);
4455          hqProc->procId       = *hqProcIdRef;
4456          hqProc->ulSfIdx      = (cellUl->msg3SchdIdx);
4457          alloc->rnti          = rnti;
4458          alloc->ue            = NULLP;
4459          alloc->pdcch         = FALSE;
4460          alloc->forMsg3       = TRUE;
4461          alloc->hqProc        = hqProc;
4462          rgSCHUhmNewTx(hqProc, (uint8_t)(cell->rachCfg.maxMsg3Tx - 1), alloc);
4463          DU_LOG("\nDEBUG  -->  SCH : RNTI:%d MSG3 ALLOC proc(%lu)procId(%d)schdIdx(%d)\n",
4464                alloc->rnti,
4465                ((PTR)alloc->hqProc),
4466                alloc->hqProc->procId,
4467                alloc->hqProc->ulSfIdx);
4468          DU_LOG("\nDEBUG  -->  SCH : alloc(%p)maxMsg3Tx(%d)",
4469                ((void *)alloc),
4470                cell->rachCfg.maxMsg3Tx);
4471       }
4472    }
4473
4474    return;
4475 }
4476
4477 \f
4478 /**
4479  * @brief This function determines the allocation limits and
4480  *        parameters that aid in DL scheduling.
4481  *
4482  * @details
4483  *
4484  *     Function: rgSCHCmnDlSetUeAllocLmt
4485  *     Purpose:  This function determines the Maximum RBs
4486  *               a UE is eligible to get based on softbuffer
4487  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4488  *               specific parameters like iTbs, eff and noLyrs
4489  *               are also set in this function. This function
4490  *               is called while UE configuration and UeDlCqiInd.
4491  *
4492  *     Invoked by: Scheduler
4493  *
4494  *  @param[in]  RgSchCellCb   *cellCb
4495  *  @param[in]  RgSchCmnDlUe  *ueDl
4496  *  @return  Void
4497  *
4498  **/
4499 static Void rgSCHCmnDlSetUeAllocLmt(RgSchCellCb *cell,RgSchCmnDlUe *ueDl,Bool isEmtcUe)
4500 {
4501    uint8_t       modOrder;
4502    uint32_t      maxRb;
4503    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4504    uint8_t       cfi = cellSch->dl.currCfi;
4505
4506
4507 #ifdef EMTC_ENABLE
4508    if(TRUE == isEmtcUe)
4509    {
4510       /* ITbs for CW0 for 1 Layer Tx */
4511       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4512                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4513       /* ITbs for CW0 for 2 Layer Tx */
4514       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4515                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4516       /* Eff for CW0 for 1 Layer Tx */
4517       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4518                                             [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4519       /* Eff for CW0 for 2 Layer Tx */
4520       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4521                                             [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4522
4523       /* ITbs for CW1 for 1 Layer Tx */
4524       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4525                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4526       /* ITbs for CW1 for 2 Layer Tx */
4527       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4528                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4529       /* Eff for CW1 for 1 Layer Tx */
4530       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4531                                             [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4532       /* Eff for CW1 for 2 Layer Tx */
4533       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4534                                             [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4535    }
4536    else
4537 #endif 
4538    {
4539       /* ITbs for CW0 for 1 Layer Tx */
4540       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4541                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4542       /* ITbs for CW0 for 2 Layer Tx */
4543       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4544                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4545       /* Eff for CW0 for 1 Layer Tx */
4546       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4547                                         [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4548       /* Eff for CW0 for 2 Layer Tx */
4549       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4550                                         [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4551       
4552       /* ITbs for CW1 for 1 Layer Tx */
4553       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4554                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4555       /* ITbs for CW1 for 2 Layer Tx */
4556       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4557                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4558       /* Eff for CW1 for 1 Layer Tx */
4559       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4560                                         [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4561       /* Eff for CW1 for 2 Layer Tx */
4562       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4563                                         [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4564    }
4565
4566 //#ifdef DL_LA 
4567   // ueDl->laCb.cqiBasediTbs =  ueDl->mimoInfo.cwInfo[0].iTbs[0] * 100;
4568 //#endif
4569    /* Assigning noLyrs to each CW assuming optimal Spatial multiplexing
4570     * capability */
4571    (ueDl->mimoInfo.ri/2 == 0)? (ueDl->mimoInfo.cwInfo[0].noLyr = 1) : \
4572               (ueDl->mimoInfo.cwInfo[0].noLyr = ueDl->mimoInfo.ri/2);
4573    ueDl->mimoInfo.cwInfo[1].noLyr = ueDl->mimoInfo.ri - ueDl->mimoInfo.cwInfo[0].noLyr;
4574    /* rg002.101:ccpu00102106: correcting DL harq softbuffer limitation logic.
4575     * The maxTbSz is the maximum number of PHY bits a harq process can
4576     * hold. Hence we limit our allocation per harq process based on this.
4577     * Earlier implementation we misinterpreted the maxTbSz to be per UE
4578     * per TTI, but in fact it is per Harq per TTI. */
4579    /* rg002.101:ccpu00102106: cannot exceed the harq Tb Size
4580     * and harq Soft Bits limit.*/
4581
4582    /* Considering iTbs corresponding to 2 layer transmission for
4583     * codeword0(approximation) and the maxLayers supported by
4584     * this UE at this point of time. */
4585    RG_SCH_CMN_TBS_TO_MODODR(ueDl->mimoInfo.cwInfo[0].iTbs[1], modOrder);
4586
4587    /* Bits/modOrder gives #REs, #REs/noResPerRb gives #RBs */
4588    /* rg001.301 -MOD- [ccpu00119213] : avoiding wraparound */
4589    maxRb = ((ueDl->maxSbSz)/(cellSch->dl.noResPerRb[cfi] * modOrder *\
4590                    ueDl->mimoInfo.ri));
4591    if (cellSch->dl.isDlFreqSel)
4592    {
4593       /* Rounding off to left nearest multiple of RBG size */
4594       maxRb -= maxRb % cell->rbgSize;
4595    }
4596    ueDl->maxRb = RGSCH_MIN(maxRb, cellSch->dl.maxDlBwPerUe);
4597    if (cellSch->dl.isDlFreqSel)
4598    {
4599       /* Rounding off to right nearest multiple of RBG size */
4600       if (ueDl->maxRb % cell->rbgSize)
4601       {
4602          ueDl->maxRb += (cell->rbgSize - 
4603                          (ueDl->maxRb % cell->rbgSize));
4604       }
4605    }
4606
4607    /* Set the index of the cwInfo, which is better in terms of
4608     * efficiency. If RI<2, only 1 CW, hence btrCwIdx shall be 0 */
4609    if (ueDl->mimoInfo.ri < 2)
4610    {
4611       ueDl->mimoInfo.btrCwIdx = 0;
4612    }
4613    else
4614    {
4615       if (ueDl->mimoInfo.cwInfo[0].eff[ueDl->mimoInfo.cwInfo[0].noLyr-1] <\
4616           ueDl->mimoInfo.cwInfo[1].eff[ueDl->mimoInfo.cwInfo[1].noLyr-1])
4617       {
4618          ueDl->mimoInfo.btrCwIdx = 1;
4619       }
4620       else
4621       {
4622          ueDl->mimoInfo.btrCwIdx = 0;
4623       }
4624    }
4625
4626    return;
4627    }
4628
4629 #ifdef DL_LA
4630
4631 /**
4632  * @brief This function updates TX Scheme.
4633  *
4634  * @details
4635  *
4636  *     Function: rgSCHCheckAndSetTxScheme 
4637  *     Purpose:  This function determines the Maximum RBs
4638  *               a UE is eligible to get based on softbuffer
4639  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4640  *               specific parameters like iTbs, eff and noLyrs
4641  *               are also set in this function. This function
4642  *               is called while UE configuration and UeDlCqiInd.
4643  *
4644  *     Invoked by: Scheduler
4645  *
4646  *  @param[in]  RgSchCellCb   *cell
4647  *  @param[in]  RgSchUeCb     *ue
4648  *  @return  Void
4649  *
4650  **/
4651 static Void rgSCHCheckAndSetTxScheme(RgSchCellCb *cell,RgSchUeCb *ue)
4652 {
4653    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4654    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue ,cell);
4655    uint8_t       cfi = cellSch->dl.currCfi;
4656    uint8_t       maxiTbs;
4657    uint8_t       cqiBasediTbs;
4658    uint8_t       actualiTbs;
4659
4660
4661    maxiTbs      = (*(RgSchCmnCqiToTbs*)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4662                 [RG_SCH_CMN_MAX_CQI - 1];
4663    cqiBasediTbs = (ueDl->laCb[0].cqiBasediTbs)/100;
4664    actualiTbs   = ueDl->mimoInfo.cwInfo[0].iTbs[0];
4665
4666    if((actualiTbs < RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR) && (cqiBasediTbs >
4667      actualiTbs) && ((cqiBasediTbs - actualiTbs) > RG_SCH_TXSCHEME_CHNG_THRSHD)) 
4668    {
4669       RG_SCH_CMN_SET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
4670    }
4671    
4672    if(actualiTbs >= maxiTbs)
4673    {
4674       RG_SCH_CMN_UNSET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
4675    }
4676
4677    return;
4678 }
4679
4680 /**
4681  * @brief This function determines the allocation limits and
4682  *        parameters that aid in DL scheduling.
4683  *
4684  * @details
4685  *
4686  *     Function: rgSCHCmnDlSetUeAllocLmtLa
4687  *     Purpose:  This function determines the Maximum RBs
4688  *               a UE is eligible to get based on softbuffer
4689  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4690  *               specific parameters like iTbs, eff and noLyrs
4691  *               are also set in this function. This function
4692  *               is called while UE configuration and UeDlCqiInd.
4693  *
4694  *     Invoked by: Scheduler
4695  *
4696  *  @param[in]  RgSchCellCb   *cell
4697  *  @param[in]  RgSchUeCb     *ue
4698  *  @return  Void
4699  *
4700  **/
4701 Void rgSCHCmnDlSetUeAllocLmtLa(RgSchCellCb *cell,RgSchUeCb *ue)
4702 {
4703    uint8_t       modOrder;
4704    uint32_t      maxRb;
4705    uint8_t       reportediTbs;
4706    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4707    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
4708    uint8_t       cfi = cellSch->dl.currCfi;
4709    uint8_t       maxiTbs;
4710    uint8_t       cwIdx = 0; 
4711
4712
4713    maxiTbs      = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1];
4714    if(ueDl->cqiFlag == TRUE)
4715    {
4716       for(cwIdx=0; cwIdx < RG_SCH_CMN_MAX_CW_PER_UE; cwIdx++)
4717       {
4718          S32 iTbsNew;
4719
4720          /* Calcluating the reported iTbs for code word 0 */
4721          reportediTbs = ue->ue5gtfCb.mcs; 
4722
4723          iTbsNew = (S32) reportediTbs;
4724
4725          if(!ueDl->laCb[cwIdx].notFirstCqi)
4726          {
4727             /* This is the first CQI report from UE */
4728             ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
4729             ueDl->laCb[cwIdx].notFirstCqi  =  TRUE;
4730          }
4731          else if ((RG_ITBS_DIFF(reportediTbs, ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0])) > 5)
4732          {
4733             /* Ignore this iTBS report and mark that last iTBS report was */
4734             /* ignored so that subsequently we reset the LA algorithm     */
4735             ueDl->laCb[cwIdx].lastiTbsIgnored = TRUE;
4736             ueDl->laCb[cwIdx].numLastiTbsIgnored++;
4737             if( ueDl->laCb[cwIdx].numLastiTbsIgnored > 10)
4738             {
4739                /* CQI reported by UE is not catching up. Reset the LA algorithm */
4740                ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
4741                ueDl->laCb[cwIdx].deltaiTbs = 0;
4742                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
4743                ueDl->laCb[cwIdx].numLastiTbsIgnored = 0;
4744             }
4745          }
4746          else
4747          {
4748             if (ueDl->laCb[cwIdx].lastiTbsIgnored != TRUE)
4749             {
4750                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
4751                      (80 * ueDl->laCb[cwIdx].cqiBasediTbs))/100;
4752             }
4753             else
4754             {
4755                /* Reset the LA as iTbs in use caught up with the value   */
4756                /* reported by UE.                                        */
4757                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
4758                      (80 * ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] * 100))/100;
4759                ueDl->laCb[cwIdx].deltaiTbs = 0;
4760                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
4761             }
4762          }
4763
4764          iTbsNew = (ueDl->laCb[cwIdx].cqiBasediTbs + ueDl->laCb[cwIdx].deltaiTbs)/100;
4765
4766          RG_SCH_CHK_ITBS_RANGE(iTbsNew, maxiTbs);       
4767
4768          ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] = RGSCH_MIN(iTbsNew, cell->thresholds.maxDlItbs);
4769          //ueDl->mimoInfo.cwInfo[cwIdx].iTbs[1] = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
4770 #ifdef RG_5GTF
4771          ue->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
4772          /*
4773          DU_LOG("\nINFO   -->  SCH : reportediTbs[%d] cqiBasediTbs[%d] deltaiTbs[%d] iTbsNew[%d] mcs[%d] cwIdx[%d]\n", 
4774                  reportediTbs, ueDl->laCb[cwIdx].cqiBasediTbs, ueDl->laCb[cwIdx].deltaiTbs,
4775                  iTbsNew, ue->ue5gtfCb.mcs, cwIdx);
4776          */
4777 #endif
4778
4779          if((ue->mimoInfo.txMode != RGR_UE_TM_3) && (ue->mimoInfo.txMode != RGR_UE_TM_4))
4780          {
4781             break; 
4782          }
4783       }
4784       ueDl->cqiFlag = FALSE;
4785    } 
4786
4787
4788    return;
4789 }
4790 #endif
4791 /***********************************************************
4792  *
4793  *     Func : rgSCHCmnDlUeResetTemp
4794  *
4795  *     Desc : Reset whatever variables where temporarily used
4796  *            during UE scheduling.
4797  *
4798  *     Ret  : Void
4799  *
4800  *     Notes:
4801  *
4802  *     File :
4803  *
4804  **********************************************************/
4805 Void rgSCHCmnDlHqPResetTemp(RgSchDlHqProcCb *hqP)
4806 {
4807
4808    /* Fix: syed having a hqP added to Lists for RB assignment rather than
4809     * a UE, as adding UE was limiting handling some scenarios */ 
4810     hqP->reqLnk.node = (PTR)NULLP;
4811     hqP->schdLstLnk.node = (PTR)NULLP;
4812
4813    return;
4814 }  /* rgSCHCmnDlHqPResetTemp */
4815
4816 /***********************************************************
4817  *
4818  *     Func : rgSCHCmnDlUeResetTemp
4819  *
4820  *     Desc : Reset whatever variables where temporarily used
4821  *            during UE scheduling.
4822  *
4823  *     Ret  : Void
4824  *
4825  *     Notes:
4826  *
4827  *     File :
4828  *
4829  **********************************************************/
4830 Void rgSCHCmnDlUeResetTemp(RgSchUeCb *ue,RgSchDlHqProcCb *hqP)
4831 {
4832    RgSchDlRbAlloc  *allocInfo;
4833    RgSchCmnDlUe    *cmnUe = RG_SCH_CMN_GET_DL_UE(ue,hqP->hqE->cell);
4834 #ifdef LTE_ADV
4835    Void           *tmpCb;
4836 #endif
4837
4838
4839    /* Fix : syed check for UE's existence was useless.
4840     * Instead we need to check that reset is done only for the 
4841     * information of a scheduled harq proc, which is cmnUe->proc.
4842     * Reset should not be done for non-scheduled hqP */
4843    if((cmnUe->proc == hqP) || (cmnUe->proc == NULLP))
4844    {
4845       cmnUe->proc = NULLP;
4846       allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, hqP->hqE->cell);
4847 #ifdef LTE_ADV
4848       tmpCb = allocInfo->laaCb;
4849 #endif
4850       memset(allocInfo, 0, sizeof(RgSchDlRbAlloc));
4851       allocInfo->rnti = ue->ueId;
4852 #ifdef LTE_ADV
4853       allocInfo->laaCb = tmpCb;
4854 #endif
4855       /* Fix: syed moving this to a common function for both scheduled
4856        * and non-scheduled UEs */
4857       cmnUe->outStndAlloc = 0;
4858    }
4859    rgSCHCmnDlHqPResetTemp(hqP);
4860
4861    return;
4862 }  /* rgSCHCmnDlUeResetTemp */
4863
4864 /***********************************************************
4865  *
4866  *     Func : rgSCHCmnUlUeResetTemp
4867  *
4868  *     Desc : Reset whatever variables where temporarily used
4869  *            during UE scheduling.
4870  *
4871  *     Ret  : Void
4872  *
4873  *     Notes:
4874  *
4875  *     File :
4876  *
4877  **********************************************************/
4878 Void rgSCHCmnUlUeResetTemp(RgSchCellCb *cell,RgSchUeCb *ue)
4879 {
4880    RgSchCmnUlUe *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue,cell);
4881
4882    memset(&cmnUlUe->alloc, 0, sizeof(cmnUlUe->alloc));
4883
4884    return;
4885 }  /* rgSCHCmnUlUeResetTemp */
4886
4887
4888 \f
4889 /**
4890  * @brief This function fills the PDCCH information from dlProc.
4891  *
4892  * @details
4893  *
4894  *     Function: rgSCHCmnFillPdcch
4895  *     Purpose:  This function fills in the PDCCH information
4896  *               obtained from the RgSchDlRbAlloc
4897  *               during common channel scheduling(P, SI, RA - RNTI's).
4898  *
4899  *     Invoked by: Downlink Scheduler
4900  *
4901  *  @param[out] RgSchPdcch*       pdcch
4902  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
4903  *  @return  Void
4904  *
4905  **/
4906 Void rgSCHCmnFillPdcch(RgSchCellCb *cell,RgSchPdcch *pdcch,RgSchDlRbAlloc *rbAllocInfo)
4907 {
4908
4909    /* common channel pdcch filling,
4910     * only 1A and Local is supported */
4911    pdcch->rnti                       = rbAllocInfo->rnti;
4912    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
4913    switch(rbAllocInfo->dciFormat)
4914    {
4915 #ifdef RG_5GTF  /* ANOOP: ToDo: DCI format B1/B2 filling */
4916       case TFU_DCI_FORMAT_B1:
4917          {
4918             /* ToDo: Anoop */
4919             pdcch->dci.u.formatB1Info.formatType = 0;
4920             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].cmnGrnt.xPDSCHRange;
4921             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].cmnGrnt.rbAssign;
4922             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = 0;
4923             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
4924             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = 0;
4925             //pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].ndi;
4926             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].cmnGrnt.rv;
4927             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
4928             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
4929             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
4930             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
4931             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
4932             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
4933             //TODO_SID: Need to update
4934             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
4935             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
4936             pdcch->dci.u.formatB1Info.SRS_Config = 0;
4937             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
4938             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
4939             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
4940             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].cmnGrnt.SCID;
4941             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
4942             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
4943             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
4944
4945             break; /* case TFU_DCI_FORMAT_B1: */
4946          }
4947
4948       case TFU_DCI_FORMAT_B2:
4949          {
4950             //DU_LOG("\nINFO   -->  SCH : RG_5GTF:: Pdcch filling with DCI format B2\n");
4951             /* ToDo: Anoop */
4952             break; /* case TFU_DCI_FORMAT_B2: */
4953          }
4954 #endif
4955       case TFU_DCI_FORMAT_1A:
4956          pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
4957
4958          /*Nprb indication at PHY for common Ch
4959           *setting least significant bit of tpc field to 1 if
4960           nPrb=3 and 0 otherwise. */
4961          if (rbAllocInfo->nPrb == 3)
4962          {
4963             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 1;
4964          }
4965          else
4966          {
4967             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 0;
4968          }
4969          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
4970          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
4971          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
4972                                                                    rbAllocInfo->tbInfo[0].imcs;
4973          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = 0;
4974          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = 0;
4975          /* Add RIV CALC */
4976          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
4977             TFU_ALLOC_TYPE_RIV;
4978          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
4979             rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
4980                   rbAllocInfo->allocInfo.raType2.rbStart,
4981                   rbAllocInfo->allocInfo.raType2.numRb);
4982
4983 #ifdef LTE_TDD
4984          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = \
4985                                                                            FALSE;
4986 #ifdef TFU_TDD
4987          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
4988          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
4989 #endif
4990 #endif
4991          break; /* case TFU_DCI_FORMAT_1A: */
4992       case TFU_DCI_FORMAT_1:
4993          pdcch->dci.u.format1Info.tpcCmd = 0;
4994          /* Avoiding this check,as we dont support Type1 RA */
4995 #ifdef RG_UNUSED
4996          if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
4997          {
4998 #endif
4999             pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5000             pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5001                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5002                 & 0xff);
5003             pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5004                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5005                 & 0x00ff);
5006             pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5007                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5008                 & 0x0000ff);
5009             pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5010                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5011 #ifdef RG_UNUSED
5012          }
5013 #endif
5014          pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5015          pdcch->dci.u.format1Info.allocInfo.ndi = 0;
5016          pdcch->dci.u.format1Info.allocInfo.mcs = rbAllocInfo->tbInfo[0].imcs;
5017          pdcch->dci.u.format1Info.allocInfo.rv = 0;
5018 #ifdef TFU_TDD
5019          pdcch->dci.u.format1Info.dai = 1;
5020 #endif
5021          break;
5022       default:
5023          DU_LOG("\nERROR  -->  SCH : Allocator's icorrect "
5024             "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5025          break;
5026    }
5027    return;
5028 }
5029
5030 #ifdef LTE_TDD
5031 /**
5032  * @brief This function finds whether the subframe is special subframe or not.
5033  *
5034  * @details
5035  *
5036  *     Function: rgSCHCmnIsSplSubfrm
5037  *     Purpose:  This function finds the subframe index of the special subframe
5038  *               and finds whether the current DL index matches it or not.
5039  *
5040  *     Invoked by: Scheduler
5041  *
5042  *  @param[in] uint8_t                   splfrmCnt
5043  *  @param[in] uint8_t                   curSubfrmIdx
5044  *  @param[in] uint8_t                   periodicity
5045  *  @param[in] RgSchTddSubfrmInfo   *subfrmInfo
5046  *  @return  Bool
5047  *
5048  **/
5049 static Bool rgSCHCmnIsSplSubfrm(uint8_t splfrmCnt,uint8_t curSubfrmIdx,uint8_t periodicity,RgSchTddSubfrmInfo *subfrmInfo)
5050 {
5051    uint8_t dlSfCnt = 0;
5052    uint8_t splfrmIdx  = 0;
5053
5054    if(splfrmCnt > 0)
5055    {
5056       if(periodicity == RG_SCH_CMN_5_MS_PRD)
5057       {
5058          if(splfrmCnt%2)
5059          {
5060             dlSfCnt = ((splfrmCnt-1)/2) *\
5061                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5062             dlSfCnt = dlSfCnt + subfrmInfo->numFrmHf1;
5063          }
5064          else
5065          {
5066             dlSfCnt = (splfrmCnt/2) * \
5067                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5068          }
5069       }
5070       else
5071       {
5072          dlSfCnt = splfrmCnt * subfrmInfo->numFrmHf1;
5073       }
5074       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1 +\
5075                   (periodicity*splfrmCnt - dlSfCnt);
5076    }
5077    else
5078    {
5079       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1;
5080    }
5081
5082    if(splfrmIdx == curSubfrmIdx)
5083    {
5084       return (TRUE);
5085    }
5086
5087    return (FALSE);
5088 }
5089
5090 /**
5091  * @brief This function updates DAI or UL index.
5092  *
5093  * @details
5094  *
5095  *     Function: rgSCHCmnUpdHqAndDai
5096  *     Purpose:  Updates the DAI based on UL-DL Configuration
5097  *               index and UE. It also updates the HARQ feedback
5098  *               time and 'm' index.
5099  *
5100  *     Invoked by: TOM
5101  *
5102  *  @param[in]  RgDlHqProcCb  *hqP
5103  *  @param[in]  RgSchDlSf     *subFrm
5104  *  @param[in]  RgSchDlHqTbCb *tbCb
5105  *  @param[in]  uint8_t            tbAllocIdx
5106  *  @return  Void
5107  *
5108  **/
5109 static Void rgSCHCmnUpdHqAndDai(RgSchDlHqProcCb *hqP,RgSchDlSf *subFrm,RgSchDlHqTbCb *tbCb,uint8_t tbAllocIdx)
5110 {
5111    RgSchUeCb      *ue = hqP->hqE->ue;
5112    
5113
5114    if(subFrm != NULLP)
5115    {
5116       /* set the time at which UE shall send the feedback
5117        * for this process */
5118       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5119             subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5120       tbCb->fdbkTime.subframe = subFrm->dlFdbkInfo.subframe;
5121       tbCb->m = subFrm->dlFdbkInfo.m;
5122    }
5123    else
5124    {
5125       /* set the time at which UE shall send the feedback
5126        * for this process */
5127       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5128             hqP->subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5129       tbCb->fdbkTime.subframe = hqP->subFrm->dlFdbkInfo.subframe;
5130       tbCb->m = hqP->subFrm->dlFdbkInfo.m;
5131    }
5132
5133    /* ccpu00132340-MOD- DAI need to be updated for first TB only*/
5134    if(ue && !tbAllocIdx)
5135    {
5136       Bool   havePdcch = (tbCb->hqP->pdcch ? TRUE : FALSE);
5137       uint8_t     dlDai;
5138       
5139       dlDai = rgSCHCmnUpdDai(ue, &tbCb->fdbkTime, tbCb->m, havePdcch,tbCb->hqP,
5140             &tbCb->dai);
5141       if(havePdcch)
5142       {/* Non SPS occasions */
5143          tbCb->hqP->pdcch->dlDai = dlDai;
5144          /* hqP->ulDai is used for N1 resource filling
5145           * when SPS occaions present in a bundle */
5146          tbCb->hqP->ulDai = tbCb->dai;
5147          tbCb->hqP->dlDai = dlDai;
5148       }
5149    }
5150
5151    /* Updatijng pucchFdbkIdx for both PUCCH or PUSCH
5152       fdbk reception */
5153    tbCb->pucchFdbkIdx = tbCb->hqP->ulDai;
5154
5155    return;
5156 }
5157
5158
5159 /**
5160  * @brief This function updates DAI or UL index.
5161  *
5162  * @details
5163  *
5164  *     Function: rgSCHCmnUpdDai
5165  *     Purpose:  Updates the DAI in the ack-nack info, a valid
5166  *               ue should be passed
5167  *
5168  *     Invoked by: TOM
5169  *
5170  *  @param[in]  RgDlHqProcCb  *hqP
5171  *  @param[in]  RgSchDlSf     *subFrm
5172  *  @param[in]  RgSchDlHqTbCb *tbCb
5173  *  @return  uint8_t dlDai 
5174  *
5175  **/
5176 uint8_t rgSCHCmnUpdDai
5177 (
5178 RgSchUeCb       *ue,
5179 CmLteTimingInfo *fdbkTime,
5180 uint8_t         m,
5181 Bool            havePdcch,
5182 RgSchDlHqProcCb *hqP,
5183 uint8_t         *ulDai
5184 )
5185 {
5186    RgSchTddANInfo *anInfo;
5187    uint8_t servCellIdx;
5188    uint8_t ackNackFdbkArrSize;
5189
5190    if(hqP != NULLP)
5191    {/* Non SPS */
5192 #ifdef LTE_ADV
5193       servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5194             hqP->hqE->cell->cellId,
5195             ue);
5196 #else
5197      servCellIdx = RGSCH_PCELL_INDEX;
5198 #endif
5199       ackNackFdbkArrSize = hqP->hqE->cell->ackNackFdbkArrSize;
5200    }else
5201    {/* SPS on primary cell */
5202       servCellIdx = RGSCH_PCELL_INDEX;
5203       ackNackFdbkArrSize = ue->cell->ackNackFdbkArrSize;
5204    }
5205
5206
5207    anInfo = rgSCHUtlGetUeANFdbkInfo(ue, fdbkTime,servCellIdx);
5208
5209    /* If no ACK/NACK feedback already present, create a new one */
5210    if(NULLP == anInfo)
5211    {
5212       anInfo = &ue->cellInfo[servCellIdx]->anInfo[ue->cellInfo[servCellIdx]->nextFreeANIdx];
5213       anInfo->sfn = fdbkTime->sfn;
5214       anInfo->subframe = fdbkTime->subframe;
5215       anInfo->latestMIdx = m;
5216       /* Fixing DAI value - ccpu00109162 */
5217       /* Handle TDD case as in MIMO definition of the function */
5218       anInfo->ulDai = 1;
5219       if (havePdcch)
5220       {
5221          anInfo->dlDai = 1;
5222       }
5223       anInfo->isSpsOccasion = FALSE;
5224       /* set the free Index to store  Ack/Nack Information*/
5225       ue->cellInfo[servCellIdx]->nextFreeANIdx = (ue->cellInfo[servCellIdx]->nextFreeANIdx + 1) %
5226          ackNackFdbkArrSize;
5227
5228    }
5229    else
5230    {
5231       anInfo->latestMIdx = m;
5232       /* Fixing DAI value - ccpu00109162 */
5233       /* Handle TDD case as in MIMO definition of the function */
5234       anInfo->ulDai = anInfo->ulDai + 1;
5235       if (havePdcch)
5236       {
5237          anInfo->dlDai = anInfo->dlDai + 1;
5238       }
5239    }
5240 #ifdef LTE_ADV
5241    /* ignoring the Scell check,
5242     * for primary cell this field is unused*/
5243    if(hqP != NULLP)
5244    {/* SPS*/
5245       anInfo->n1ResTpcIdx = hqP->tpc;
5246    }
5247
5248    if(ulDai)
5249    {/* As this not required for release pdcch */
5250       *ulDai = anInfo->ulDai;
5251    }
5252 #endif
5253    return (anInfo->dlDai);
5254
5255 }
5256 #endif /* ifdef LTE_TDD */
5257
5258 uint32_t rgHqRvRetxCnt[4][2];
5259 uint32_t rgUlrate_grant;
5260
5261 /**
5262  * @brief This function fills the HqP TB with rbAllocInfo.
5263  *
5264  * @details
5265  *
5266  *     Function: rgSCHCmnFillHqPTb
5267  *     Purpose:  This function fills in the HqP TB with rbAllocInfo.
5268  *
5269  *     Invoked by: rgSCHCmnFillHqPTb
5270  *
5271  *  @param[in]  RgSchCellCb*      cell
5272  *  @param[in]  RgSchDlRbAlloc    *rbAllocInfo,
5273  *  @param[in]  uint8_t                tbAllocIdx
5274  *  @param[in]  RgSchPdcch        *pdcch
5275  *  @return  Void
5276  *
5277  **/
5278 #ifdef LTEMAC_SPS
5279 Void rgSCHCmnFillHqPTb
5280 (
5281 RgSchCellCb    *cell,
5282 RgSchDlRbAlloc *rbAllocInfo,
5283 uint8_t        tbAllocIdx,
5284 RgSchPdcch     *pdcch
5285 )
5286 #else
5287 static Void rgSCHCmnFillHqPTb
5288 (
5289 RgSchCellCb    *cell,
5290 RgSchDlRbAlloc *rbAllocInfo,
5291 uint8_t        tbAllocIdx,
5292 RgSchPdcch     *pdcch
5293 )
5294 #endif /* LTEMAC_SPS */
5295 {
5296    RgSchCmnDlCell     *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5297    RgSchDlTbAllocInfo *tbAllocInfo = &rbAllocInfo->tbInfo[tbAllocIdx];
5298    RgSchDlHqTbCb      *tbInfo = tbAllocInfo->tbCb;
5299    RgSchDlHqProcCb    *hqP = tbInfo->hqP;
5300
5301
5302    /*ccpu00120365-ADD-if tb is disabled, set mcs=0,rv=1.
5303     * Relevant for DCI format 2 & 2A as per 36.213-7.1.7.2
5304     */
5305    if ( tbAllocInfo->isDisabled)
5306    {
5307
5308       tbInfo->dlGrnt.iMcs = 0;
5309       tbInfo->dlGrnt.rv   = 1;
5310    }
5311    /* Fill for TB retransmission */
5312    else if (tbInfo->txCntr > 0)
5313    {
5314
5315       tbInfo->timingInfo = cmnCellDl->time;
5316       /* Fix */
5317       if ((tbInfo->isAckNackDtx == TFU_HQFDB_DTX)) 
5318       {
5319          tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;         
5320          rgHqRvRetxCnt[tbInfo->dlGrnt.rv][tbInfo->tbIdx]++;
5321       }
5322       else
5323       {
5324          tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[++(tbInfo->ccchSchdInfo.rvIdx) & 0x03];
5325       }
5326
5327       /* fill the scheduler information of hqProc */
5328       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5329       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx,hqP->tbInfo,tbInfo->tbIdx );
5330       rgSCHDhmHqTbRetx(hqP->hqE, tbInfo->timingInfo, hqP, tbInfo->tbIdx);
5331    }
5332    /* Fill for TB transmission */
5333    else
5334    {
5335       /* Fill the HqProc */
5336       tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;
5337       tbInfo->tbSz = tbAllocInfo->bytesAlloc;
5338       tbInfo->timingInfo = cmnCellDl->time;
5339
5340       tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[0];
5341       /* fill the scheduler information of hqProc */
5342       tbInfo->ccchSchdInfo.rvIdx = 0;
5343       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5344       /* DwPts Scheduling Changes Start */
5345       /* DwPts Scheduling Changes End */ 
5346       cell->measurements.dlBytesCnt += tbAllocInfo->bytesAlloc;
5347    }
5348
5349    /*ccpu00120365:-ADD-only add to subFrm list if tb is not disabled */
5350    if ( tbAllocInfo->isDisabled == FALSE )
5351    {
5352       /* Set the number of transmitting SM layers for this TB */
5353       tbInfo->numLyrs = tbAllocInfo->noLyr;
5354       /* Set the TB state as WAITING to indicate TB has been
5355        * considered for transmission */
5356       tbInfo->state  = HQ_TB_WAITING;
5357       hqP->subFrm = rbAllocInfo->dlSf;
5358       tbInfo->hqP->pdcch  = pdcch;
5359       //tbInfo->dlGrnt.numRb = rbAllocInfo->rbsAlloc;
5360       rgSCHUtlDlHqPTbAddToTx(hqP->subFrm, hqP, tbInfo->tbIdx);
5361    }
5362    return;
5363 }
5364
5365 /**
5366  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5367  *
5368  * @details
5369  *
5370  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5371  *     Purpose:  This function fills in the PDCCH information
5372  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5373  *               for dedicated service scheduling. It also
5374  *               obtains TPC to be filled in from the power module.
5375  *               Assign the PDCCH to HQProc.
5376  *
5377  *     Invoked by: Downlink Scheduler
5378  *
5379  *  @param[in]  RgSchCellCb*      cell
5380  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5381  *  @param[in]  RgDlHqProc*       hqP
5382  *  @param[out]  RgSchPdcch        *pdcch
5383  *  @param[in]   uint8_t               tpc
5384  *  @return  Void
5385  *
5386  **/
5387 static Void rgSCHCmnFillHqPPdcchDciFrmtB1B2
5388 (
5389 RgSchCellCb     *cell,
5390 RgSchDlRbAlloc  *rbAllocInfo,
5391 RgSchDlHqProcCb *hqP,
5392 RgSchPdcch      *pdcch,
5393 uint8_t         tpc
5394 )
5395 {
5396
5397
5398    rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);   
5399    //Currently hardcoding values here.
5400    //DU_LOG("\nINFO   -->  SCH : Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
5401    switch(rbAllocInfo->dciFormat)
5402    {
5403       case TFU_DCI_FORMAT_B1:
5404          {
5405             pdcch->dci.u.formatB1Info.formatType = 0;
5406             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5407             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5408             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5409             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5410             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5411             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5412             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5413             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5414             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5415             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5416             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5417             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5418             //TODO_SID: Need to update
5419             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5420             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5421             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5422             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5423             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5424             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5425             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5426             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5427             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5428             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5429             break;
5430          }
5431       case TFU_DCI_FORMAT_B2:
5432          {
5433             pdcch->dci.u.formatB2Info.formatType = 1;
5434             pdcch->dci.u.formatB2Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5435             pdcch->dci.u.formatB2Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5436             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5437             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5438             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5439             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5440             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5441             pdcch->dci.u.formatB2Info.CSI_BSI_BRI_Req = 0;
5442             pdcch->dci.u.formatB2Info.CSIRS_BRRS_TxTiming = 0;
5443             pdcch->dci.u.formatB2Info.CSIRS_BRRS_SymbIdx = 0;
5444             pdcch->dci.u.formatB2Info.CSIRS_BRRS_ProcInd = 0;
5445             pdcch->dci.u.formatB2Info.xPUCCH_TxTiming = 0;
5446             //TODO_SID: Need to update
5447             pdcch->dci.u.formatB2Info.freqResIdx_xPUCCH = 0;
5448             pdcch->dci.u.formatB2Info.beamSwitch  = 0;
5449             pdcch->dci.u.formatB2Info.SRS_Config = 0;
5450             pdcch->dci.u.formatB2Info.SRS_Symbol = 0;
5451             //TODO_SID: Need to check.Currently setting 4(2 layer, ports(8,9) w/o OCC).
5452             pdcch->dci.u.formatB2Info.AntPorts_numLayers = 4;
5453             pdcch->dci.u.formatB2Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5454             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5455             pdcch->dci.u.formatB2Info.tpcCmd = 1; //tpc;
5456             pdcch->dci.u.formatB2Info.DL_PCRS = 0;
5457             break;
5458          }
5459          default:
5460             DU_LOG("\nERROR  -->  SCH :  5GTF_ERROR Allocator's incorrect "
5461                "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5462             break;
5463    }
5464    
5465    return;
5466 }
5467
5468 uint32_t totPcellSCell;
5469 uint32_t addedForScell;
5470 uint32_t addedForScell1;
5471 uint32_t addedForScell2;
5472 /**
5473  * @brief This function fills the PDCCH information from dlProc.
5474  *
5475  * @details
5476  *
5477  *     Function: rgSCHCmnFillHqPPdcch
5478  *     Purpose:  This function fills in the PDCCH information
5479  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5480  *               for dedicated service scheduling. It also
5481  *               obtains TPC to be filled in from the power module.
5482  *               Assign the PDCCH to HQProc.
5483  *
5484  *     Invoked by: Downlink Scheduler
5485  *
5486  *  @param[in]  RgSchCellCb*      cell
5487  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5488  *  @param[in]  RgDlHqProc*       hqP
5489  *  @return  Void
5490  *
5491  **/
5492 Void rgSCHCmnFillHqPPdcch(RgSchCellCb *cell,RgSchDlRbAlloc *rbAllocInfo,RgSchDlHqProcCb *hqP)
5493 {
5494    RgSchCmnDlCell *cmnCell = RG_SCH_CMN_GET_DL_CELL(cell);
5495    RgSchPdcch     *pdcch = rbAllocInfo->pdcch;
5496    uint8_t        tpc = 1;
5497
5498
5499    if (hqP->hqE->ue)
5500    {
5501 #ifdef LTE_ADV
5502       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5503       {
5504          tpc = hqP->tpc;
5505       }
5506       else
5507 #endif
5508       {
5509          tpc = rgSCHPwrPucchTpcForUe(cell, hqP->hqE->ue);
5510       }
5511       /* Fix: syed moving this to a common function for both scheduled
5512        * and non-scheduled UEs */
5513
5514       pdcch->ue = hqP->hqE->ue;
5515       if (hqP->hqE->ue->csgMmbrSta == FALSE)
5516       {
5517          cmnCell->ncsgPrbCnt += rbAllocInfo->rbsAlloc;
5518       }
5519       cmnCell->totPrbCnt += rbAllocInfo->rbsAlloc;
5520 #ifdef TENB_STATS
5521       {
5522          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlPrbUsg += 
5523             rbAllocInfo->rbsAlloc;
5524          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw0iTbs += 
5525             rbAllocInfo->tbInfo[0].iTbs;
5526          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw0iTbs ++; 
5527          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
5528             (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5529
5530 #ifdef LTE_ADV
5531       totPcellSCell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5532       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5533       {
5534          addedForScell +=  (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5535          addedForScell1 += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5536 /*
5537          DU_LOG("\nINFO   -->  SCH :  Hqp %d cell %d addedForScell %lu addedForScell1 %lu sfn:sf %d:%d \n",
5538          hqP->procId,
5539          hqP->hqE->cell->cellId,
5540          addedForScell,
5541          addedForScell1,
5542          cell->crntTime.sfn,
5543          cell->crntTime.slot);
5544          */
5545       }
5546 #endif
5547          hqP->hqE->cell->tenbStats->sch.dlPrbUsage[0] += 
5548             rbAllocInfo->rbsAlloc;
5549          hqP->hqE->cell->tenbStats->sch.dlSumCw0iTbs += 
5550             rbAllocInfo->tbInfo[0].iTbs;
5551          hqP->hqE->cell->tenbStats->sch.dlNumCw0iTbs ++; 
5552          hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
5553             (rbAllocInfo->tbInfo[0].bytesAlloc << 3); 
5554          if (rbAllocInfo->tbInfo[1].schdlngForTb)
5555          {
5556             hqP->hqE->cell->tenbStats->sch.dlSumCw1iTbs += 
5557                rbAllocInfo->tbInfo[1].iTbs;
5558             hqP->hqE->cell->tenbStats->sch.dlNumCw1iTbs ++; 
5559             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw1iTbs += 
5560                rbAllocInfo->tbInfo[1].iTbs;
5561             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw1iTbs ++; 
5562             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
5563                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5564
5565
5566 #ifdef LTE_ADV
5567             if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5568             {
5569                addedForScell +=  (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5570                addedForScell2 += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5571 /*
5572          DU_LOG("\nINFO   -->  SCH :  Hqp %d cell %d addedForScell %lu addedForScell2 %lu \n",
5573          hqP->procId,
5574          hqP->hqE->cell->cellId,
5575          addedForScell,
5576          addedForScell2);
5577          */
5578             }
5579             totPcellSCell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5580 #endif
5581
5582
5583             hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
5584                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5585          }
5586          /*
5587          DU_LOG("\nINFO   -->  SCH : add DL TPT is %lu  sfn:sf %d:%d \n", hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt ,
5588          cell->crntTime.sfn,
5589          cell->crntTime.slot);
5590          */
5591       }
5592 #endif
5593    }
5594
5595    pdcch->rnti                       = rbAllocInfo->rnti;
5596    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
5597    /* Update subframe and pdcch info in HqTb control block */
5598    switch(rbAllocInfo->dciFormat)
5599    {
5600 #ifdef RG_5GTF  
5601       case TFU_DCI_FORMAT_B1:
5602       case TFU_DCI_FORMAT_B2:
5603            {
5604         // DU_LOG("\nINFO   -->  SCH : RG_5GTF:: Pdcch filling with DCI format B1/B2\n");
5605               rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, \
5606                     pdcch, tpc);
5607               break;
5608            }
5609 #endif
5610       default:
5611          DU_LOG("\nERROR  -->  SCH : Allocator's incorrect dciForamt Fill for RNTI:%d",rbAllocInfo->rnti);
5612          break;
5613    }
5614    return;
5615 }
5616 #ifdef UNUSED_FUNC
5617 /**
5618  * @brief This function fills the PDCCH DCI format 1 information from dlProc.
5619  *
5620  * @details
5621  *
5622  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1
5623  *     Purpose:  This function fills in the PDCCH information
5624  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5625  *               for dedicated service scheduling. It also
5626  *               obtains TPC to be filled in from the power module.
5627  *               Assign the PDCCH to HQProc.
5628  *
5629  *     Invoked by: Downlink Scheduler
5630  *
5631  *  @param[in]  RgSchCellCb*      cell
5632  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5633  *  @param[in]  RgDlHqProc*       hqP
5634  *  @param[out]  RgSchPdcch        *pdcch
5635  *  @param[in]   uint8_t               tpc
5636  *  @return  Void
5637  *
5638  **/
5639
5640 static Void rgSCHCmnFillHqPPdcchDciFrmt1
5641 (
5642 RgSchCellCb     *cell,
5643 RgSchDlRbAlloc  *rbAllocInfo,
5644 RgSchDlHqProcCb *hqP,
5645 RgSchPdcch      *pdcch,
5646 uint8_t         tpc
5647 )
5648 {
5649
5650 #ifdef LTE_TDD
5651    RgSchTddANInfo *anInfo;
5652 #endif
5653
5654 #ifdef LTEMAC_SPS
5655 /* For activation or reactivation,
5656  * Harq ProcId should be 0 */
5657    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5658 #endif
5659
5660
5661     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5662     pdcch->dci.u.format1Info.tpcCmd = tpc;
5663      /* Avoiding this check,as we dont support Type1 RA */
5664 #ifdef RG_UNUSED
5665     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
5666     {
5667 #endif
5668        pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5669        pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5670          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5671                & 0xff);
5672        pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5673          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5674                & 0x00ff);
5675        pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5676            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5677                & 0x0000ff);
5678        pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5679            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5680 #ifdef RG_UNUSED
5681     }
5682 #endif
5683 #ifdef LTEMAC_SPS
5684     if ((!(hqP->tbInfo[0].txCntr)) &&
5685        (cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5686          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5687          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)))
5688        )
5689     {
5690        pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5691     }
5692     else
5693     {
5694       pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
5695     }
5696 #else
5697     pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
5698 #endif
5699
5700     pdcch->dci.u.format1Info.allocInfo.ndi = 
5701                         rbAllocInfo->tbInfo[0].tbCb->ndi;
5702     pdcch->dci.u.format1Info.allocInfo.mcs = 
5703                         rbAllocInfo->tbInfo[0].imcs;
5704     pdcch->dci.u.format1Info.allocInfo.rv = 
5705                         rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5706 #ifdef LTE_TDD
5707        if(hqP->hqE->ue != NULLP)
5708        {
5709 #ifdef LTE_ADV
5710            uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5711                                         hqP->hqE->cell->cellId,
5712                                         hqP->hqE->ue);
5713
5714            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5715                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5716 #else
5717            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5718                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5719 #endif
5720 #ifdef TFU_TDD
5721           if(anInfo)
5722           {
5723              pdcch->dci.u.format1Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5724           }
5725           else
5726           {
5727                /* Fixing DAI value - ccpu00109162 */
5728              pdcch->dci.u.format1Info.dai = RG_SCH_MAX_DAI_IDX;
5729           }
5730 #endif
5731        }
5732        else
5733        {
5734             /* always 0 for RACH */
5735            pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5736 #ifdef TFU_TDD
5737             /* Fixing DAI value - ccpu00109162 */
5738            pdcch->dci.u.format1Info.dai = 1;
5739 #endif
5740        }
5741 #endif
5742  
5743
5744        return;
5745 }
5746 /**
5747  * @brief This function fills the PDCCH DCI format 1A information from dlProc.
5748  *
5749  * @details
5750  *
5751  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1A
5752  *     Purpose:  This function fills in the PDCCH information
5753  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5754  *               for dedicated service scheduling. It also
5755  *               obtains TPC to be filled in from the power module.
5756  *               Assign the PDCCH to HQProc.
5757  *
5758  *     Invoked by: Downlink Scheduler
5759  *
5760  *  @param[in]  RgSchCellCb*      cell
5761  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5762  *  @param[in]  RgDlHqProc*       hqP
5763  *  @param[out]  RgSchPdcch        *pdcch
5764  *  @param[in]   uint8_t               tpc
5765  *  @return  Void
5766  *
5767  **/
5768 static Void rgSCHCmnFillHqPPdcchDciFrmt1A
5769 (
5770 RgSchCellCb     *cell,
5771 RgSchDlRbAlloc  *rbAllocInfo,
5772 RgSchDlHqProcCb *hqP,
5773 RgSchPdcch      *pdcch,
5774 uint8_t         tpc
5775 )
5776 {
5777
5778 #ifdef LTE_TDD
5779    RgSchTddANInfo     *anInfo;
5780 #endif
5781
5782 #ifdef LTEMAC_SPS
5783    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5784 #endif
5785
5786
5787     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5788     pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
5789     pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = tpc;
5790     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
5791       rbAllocInfo->tbInfo[0].imcs;
5792     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = TRUE;
5793 #ifdef LTEMAC_SPS
5794     if ((!(hqP->tbInfo[0].txCntr)) &&
5795        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5796          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5797          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
5798        ))
5799     {
5800        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = 0;
5801     }
5802     else
5803     {
5804       pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val
5805                                                 = hqP->procId;
5806     }
5807 #else
5808     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val =
5809                                               hqP->procId;
5810 #endif
5811     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = \
5812        rbAllocInfo->tbInfo[0].tbCb->ndi;
5813     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = \
5814        rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5815          /* As of now, we do not support Distributed allocations */
5816     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
5817     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
5818     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
5819             TFU_ALLOC_TYPE_RIV;
5820     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
5821     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5822                   rbAllocInfo->allocInfo.raType2.rbStart,
5823                   rbAllocInfo->allocInfo.raType2.numRb);
5824 #ifdef LTE_TDD
5825     if(hqP->hqE->ue != NULLP)
5826     {
5827 #ifdef LTE_ADV
5828        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5829                                         hqP->hqE->cell->cellId,
5830                                         hqP->hqE->ue);
5831        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5832                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5833 #else
5834        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5835                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5836 #endif
5837 #ifdef TFU_TDD
5838        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5839        if(anInfo)
5840        {
5841           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 
5842                               RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5843        }
5844        else
5845        {
5846           /* Fixing DAI value - ccpu00109162 */
5847           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = RG_SCH_MAX_DAI_IDX;
5848           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
5849                     rbAllocInfo->rnti);
5850        }
5851 #endif
5852     }
5853     else
5854     {
5855             /* always 0 for RACH */
5856        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres
5857                                                                      = FALSE;
5858 #ifdef TFU_TDD
5859        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5860             /* Fixing DAI value - ccpu00109162 */
5861        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
5862 #endif
5863     }
5864 #endif
5865  
5866     return;
5867 }       
5868 /**
5869  * @brief This function fills the PDCCH DCI format 1B information from dlProc.
5870  *
5871  * @details
5872  *
5873  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1B
5874  *     Purpose:  This function fills in the PDCCH information
5875  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5876  *               for dedicated service scheduling. It also
5877  *               obtains TPC to be filled in from the power module.
5878  *               Assign the PDCCH to HQProc.
5879  *
5880  *     Invoked by: Downlink Scheduler
5881  *
5882  *  @param[in]  RgSchCellCb*      cell
5883  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5884  *  @param[in]  RgDlHqProc*       hqP
5885  *  @param[out]  RgSchPdcch        *pdcch
5886  *  @param[in]   uint8_t               tpc
5887  *  @return  Void
5888  *
5889  **/
5890 static Void rgSCHCmnFillHqPPdcchDciFrmt1B
5891 (
5892 RgSchCellCb     *cell,
5893 RgSchDlRbAlloc  *rbAllocInfo,
5894 RgSchDlHqProcCb *hqP,
5895 RgSchPdcch      *pdcch,
5896 uint8_t         tpc
5897 )
5898 {
5899
5900 #ifdef LTE_TDD
5901    RgSchTddANInfo     *anInfo;
5902 #endif
5903
5904 #ifdef LTEMAC_SPS
5905    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5906 #endif
5907
5908
5909     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5910     pdcch->dci.u.format1bInfo.tpcCmd  = tpc;
5911     pdcch->dci.u.format1bInfo.allocInfo.mcs     = \
5912            rbAllocInfo->tbInfo[0].imcs;
5913 #ifdef LTEMAC_SPS
5914     if ((!(hqP->tbInfo[0].txCntr)) &&
5915        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5916          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5917          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
5918        ))
5919     {
5920        pdcch->dci.u.format1bInfo.allocInfo.harqProcId = 0;
5921     }
5922     else
5923     {
5924       pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
5925     }
5926 #else
5927     pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
5928 #endif
5929     pdcch->dci.u.format1bInfo.allocInfo.ndi     = \
5930           rbAllocInfo->tbInfo[0].tbCb->ndi;
5931     pdcch->dci.u.format1bInfo.allocInfo.rv      = \
5932            rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5933          /* As of now, we do not support Distributed allocations */
5934     pdcch->dci.u.format1bInfo.allocInfo.isLocal = TRUE;
5935     pdcch->dci.u.format1bInfo.allocInfo.nGap2.pres = NOTPRSNT;
5936     pdcch->dci.u.format1bInfo.allocInfo.alloc.type =
5937             TFU_ALLOC_TYPE_RIV;
5938     pdcch->dci.u.format1bInfo.allocInfo.alloc.u.riv =
5939     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5940                   rbAllocInfo->allocInfo.raType2.rbStart,
5941                   rbAllocInfo->allocInfo.raType2.numRb);
5942          /* Fill precoding Info */
5943     pdcch->dci.u.format1bInfo.allocInfo.pmiCfm = \
5944                rbAllocInfo->mimoAllocInfo.precIdxInfo >> 4;
5945     pdcch->dci.u.format1bInfo.allocInfo.tPmi   = \
5946                rbAllocInfo->mimoAllocInfo.precIdxInfo & 0x0F;
5947 #ifdef LTE_TDD
5948     if(hqP->hqE->ue != NULLP)
5949     {
5950 #ifdef LTE_ADV
5951        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5952                                         hqP->hqE->cell->cellId,
5953                                         hqP->hqE->ue);
5954        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5955              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5956 #else
5957        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5958              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5959 #endif
5960 #ifdef TFU_TDD
5961        if(anInfo)
5962        {
5963           pdcch->dci.u.format1bInfo.dai = 
5964                          RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5965        }
5966        else
5967        {
5968           pdcch->dci.u.format1bInfo.dai = RG_SCH_MAX_DAI_IDX;
5969           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
5970                    rbAllocInfo->rnti);
5971        }
5972 #endif
5973     }
5974 #endif
5975        
5976     return;
5977
5978 }
5979 /**
5980  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5981  *
5982  * @details
5983  *
5984  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5985  *     Purpose:  This function fills in the PDCCH information
5986  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5987  *               for dedicated service scheduling. It also
5988  *               obtains TPC to be filled in from the power module.
5989  *               Assign the PDCCH to HQProc.
5990  *
5991  *     Invoked by: Downlink Scheduler
5992  *
5993  *  @param[in]  RgSchCellCb*      cell
5994  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5995  *  @param[in]  RgDlHqProc*       hqP
5996  *  @param[out]  RgSchPdcch        *pdcch
5997  *  @param[in]   uint8_t               tpc
5998  *  @return  Void
5999  *
6000  **/
6001 static Void rgSCHCmnFillHqPPdcchDciFrmt2
6002 (
6003 RgSchCellCb     *cell,
6004 RgSchDlRbAlloc  *rbAllocInfo,
6005 RgSchDlHqProcCb *hqP,
6006 RgSchPdcch      *pdcch,
6007 uint8_t         tpc
6008 )
6009 {
6010
6011 #ifdef LTE_TDD
6012    RgSchTddANInfo     *anInfo;
6013 #endif
6014
6015 #ifdef LTEMAC_SPS
6016 /* ccpu00119023-ADD-For activation or reactivation,
6017  * Harq ProcId should be 0 */
6018    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6019 #endif
6020
6021
6022     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6023     /*ccpu00120365:-ADD-call also if tb is disabled */
6024     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6025         rbAllocInfo->tbInfo[1].isDisabled)
6026     {
6027         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6028     }
6029     pdcch->dci.u.format2Info.tpcCmd = tpc;
6030          /* Avoiding this check,as we dont support Type1 RA */
6031 #ifdef RG_UNUSED
6032     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6033     {
6034 #endif
6035         pdcch->dci.u.format2Info.allocInfo.isAllocType0 = TRUE;
6036         pdcch->dci.u.format2Info.allocInfo.resAllocMap[0] =
6037           ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6038                & 0xff);
6039         pdcch->dci.u.format2Info.allocInfo.resAllocMap[1] =
6040            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6041                & 0x00ff);
6042         pdcch->dci.u.format2Info.allocInfo.resAllocMap[2] =
6043                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6044                 & 0x0000ff);
6045         pdcch->dci.u.format2Info.allocInfo.resAllocMap[3] =
6046                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6047 #ifdef RG_UNUSED
6048     }
6049 #endif
6050 #ifdef LTEMAC_SPS
6051     if ((!(hqP->tbInfo[0].txCntr)) &&
6052        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6053          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6054          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6055        ))
6056     {
6057        pdcch->dci.u.format2Info.allocInfo.harqProcId = 0;
6058     }
6059     else
6060     {
6061       pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6062     }
6063 #else
6064      pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6065 #endif
6066          /* Initialize the TB info for both the TBs */
6067      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].mcs = 0;
6068      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].rv  = 1;
6069      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].mcs = 0;
6070      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].rv  = 1;
6071          /* Fill tbInfo for scheduled TBs */
6072      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6073         tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6074      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6075         tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6076      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6077             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6078           /* If we reach this function. It is safely assumed that
6079            *  rbAllocInfo->tbInfo[0] always has non default valid values.
6080            *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6081      if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6082      {
6083             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6084                 tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6085             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6086                 tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6087             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6088                 tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6089      }
6090      pdcch->dci.u.format2Info.allocInfo.transSwap =
6091              rbAllocInfo->mimoAllocInfo.swpFlg;
6092      pdcch->dci.u.format2Info.allocInfo.precoding =
6093              rbAllocInfo->mimoAllocInfo.precIdxInfo;
6094 #ifdef LTE_TDD
6095      if(hqP->hqE->ue != NULLP)
6096      {
6097
6098 #ifdef LTE_ADV
6099         uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6100                                         hqP->hqE->cell->cellId,
6101                                         hqP->hqE->ue);
6102         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6103                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6104 #else
6105         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6106                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6107 #endif
6108 #ifdef TFU_TDD
6109         if(anInfo)
6110         {
6111            pdcch->dci.u.format2Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6112         }
6113         else
6114         {
6115            pdcch->dci.u.format2Info.dai = RG_SCH_MAX_DAI_IDX;
6116            DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
6117                     rbAllocInfo->rnti);
6118         }
6119 #endif
6120      }
6121 #endif
6122
6123      return;
6124 }
6125 /**
6126  * @brief This function fills the PDCCH DCI format 2A information from dlProc.
6127  *
6128  * @details
6129  *
6130  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2A
6131  *     Purpose:  This function fills in the PDCCH information
6132  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6133  *               for dedicated service scheduling. It also
6134  *               obtains TPC to be filled in from the power module.
6135  *               Assign the PDCCH to HQProc.
6136  *
6137  *     Invoked by: Downlink Scheduler
6138  *
6139  *  @param[in]  RgSchCellCb*      cell
6140  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6141  *  @param[in]  RgDlHqProc*       hqP
6142  *  @param[out]  RgSchPdcch        *pdcch
6143  *  @param[in]   uint8_t               tpc
6144  *  @return  Void
6145  *
6146  **/
6147 static Void rgSCHCmnFillHqPPdcchDciFrmt2A
6148 (
6149 RgSchCellCb     *cell,
6150 RgSchDlRbAlloc  *rbAllocInfo,
6151 RgSchDlHqProcCb *hqP,
6152 RgSchPdcch      *pdcch,
6153 uint8_t         tpc
6154 )
6155 {
6156 #ifdef LTE_TDD
6157    RgSchTddANInfo     *anInfo;
6158 #endif
6159
6160 #ifdef LTEMAC_SPS
6161    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6162 #endif
6163
6164
6165     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6166     /*ccpu00120365:-ADD-call also if tb is disabled */
6167     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6168           rbAllocInfo->tbInfo[1].isDisabled)
6169     {
6170
6171         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6172     }
6173
6174     pdcch->dci.u.format2AInfo.tpcCmd = tpc;
6175          /* Avoiding this check,as we dont support Type1 RA */
6176 #ifdef RG_UNUSED
6177     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6178     {
6179 #endif
6180         pdcch->dci.u.format2AInfo.allocInfo.isAllocType0 = TRUE;
6181         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[0] =
6182               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6183                & 0xff);
6184         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[1] =
6185               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6186                & 0x00ff);
6187         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[2] =
6188                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6189                 & 0x0000ff);
6190         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[3] =
6191                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6192 #ifdef RG_UNUSED
6193     }
6194 #endif
6195 #ifdef LTEMAC_SPS
6196     if ((!(hqP->tbInfo[0].txCntr)) &&
6197        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6198          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6199          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6200        ))
6201     {
6202        pdcch->dci.u.format2AInfo.allocInfo.harqProcId = 0;
6203     }
6204     else
6205     {
6206       pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6207     }
6208 #else
6209     pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6210 #endif
6211          /* Initialize the TB info for both the TBs */
6212     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].mcs = 0;
6213     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].rv  = 1;
6214     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].mcs = 0;
6215     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].rv  = 1;
6216          /* Fill tbInfo for scheduled TBs */
6217     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6218             tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6219     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6220             tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6221     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6222             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6223          /* If we reach this function. It is safely assumed that
6224           *  rbAllocInfo->tbInfo[0] always has non default valid values.
6225           *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6226
6227     if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6228     {
6229             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6230                tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6231             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6232                tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6233             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6234                tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6235
6236     }
6237     pdcch->dci.u.format2AInfo.allocInfo.transSwap =
6238             rbAllocInfo->mimoAllocInfo.swpFlg;
6239     pdcch->dci.u.format2AInfo.allocInfo.precoding =
6240             rbAllocInfo->mimoAllocInfo.precIdxInfo;
6241 #ifdef LTE_TDD
6242     if(hqP->hqE->ue != NULLP)
6243     {
6244 #ifdef LTE_ADV
6245        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6246                                         hqP->hqE->cell->cellId,
6247                                         hqP->hqE->ue);
6248        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6249                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6250 #else
6251        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6252                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6253 #endif
6254 #ifdef TFU_TDD
6255        if(anInfo)
6256        {
6257           pdcch->dci.u.format2AInfo.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6258        }
6259        else
6260        {
6261           pdcch->dci.u.format2AInfo.dai = RG_SCH_MAX_DAI_IDX;
6262           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
6263                    rbAllocInfo->rnti);
6264        }
6265 #endif
6266      }
6267 #endif
6268
6269
6270     return;
6271 }
6272 #endif
6273 /**
6274  * @brief init of Sch vars.
6275  *
6276  * @details
6277  *
6278  *     Function: rgSCHCmnInitVars
6279        Purpose:  Initialization of various UL subframe indices
6280  *
6281  *  @param[in]  RgSchCellCb *cell
6282  *  @return  Void
6283  *
6284  **/
6285 static Void rgSCHCmnInitVars(RgSchCellCb *cell)
6286 {
6287    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6288
6289
6290    cellUl->idx         = RGSCH_INVALID_INFO;
6291    cellUl->schdIdx     = RGSCH_INVALID_INFO;
6292    cellUl->schdHqProcIdx = RGSCH_INVALID_INFO;
6293    cellUl->msg3SchdIdx = RGSCH_INVALID_INFO;
6294 #ifdef EMTC_ENBLE
6295    cellUl->emtcMsg3SchdIdx = RGSCH_INVALID_INFO;
6296 #endif
6297    cellUl->msg3SchdHqProcIdx = RGSCH_INVALID_INFO;
6298    cellUl->rcpReqIdx   = RGSCH_INVALID_INFO;
6299    cellUl->hqFdbkIdx[0] = RGSCH_INVALID_INFO;
6300    cellUl->hqFdbkIdx[1] = RGSCH_INVALID_INFO;
6301    cellUl->reTxIdx[0]   = RGSCH_INVALID_INFO;
6302    cellUl->reTxIdx[1]   = RGSCH_INVALID_INFO;
6303   /* Stack Crash problem for TRACE5 Changes. Added the return below */
6304   return;
6305
6306 }
6307
6308 #ifndef LTE_TDD
6309 /**
6310  * @brief Updation of Sch vars per TTI.
6311  *
6312  * @details
6313  *
6314  *     Function: rgSCHCmnUpdVars
6315  *     Purpose:  Updation of Sch vars per TTI.
6316  *
6317  *  @param[in]  RgSchCellCb *cell
6318  *  @return  Void
6319  *
6320  **/
6321 Void rgSCHCmnUpdVars(RgSchCellCb *cell)
6322 {
6323    CmLteTimingInfo   timeInfo;
6324    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6325    uint16_t idx;
6326
6327
6328    idx = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot);
6329    cellUl->idx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6330 #ifdef UL_ADPT_DBG     
6331    DU_LOG("\nDEBUG  -->  SCH : 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.slot);
6332 #endif    
6333    /* Need to scheduler for after SCHED_DELTA */
6334    /* UL allocation has been advanced by 1 subframe
6335     * so that we do not wrap around and send feedback
6336     * before the data is even received by the PHY */
6337    /* Introduced timing delta for UL control */
6338    idx = (cellUl->idx + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA);
6339    cellUl->schdIdx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6340
6341    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6342             TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)
6343    cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6344
6345    /* ccpu00127193 filling schdTime for logging and enhancement purpose*/
6346    cellUl->schdTime = timeInfo;
6347
6348    /* msg3 scheduling two subframes after general scheduling */
6349    idx = (cellUl->idx + RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA);
6350    cellUl->msg3SchdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6351
6352    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6353             RG_SCH_CMN_DL_DELTA+ RGSCH_RARSP_MSG3_DELTA)
6354    cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6355
6356    idx = (cellUl->idx + TFU_RECPREQ_DLDELTA);
6357
6358    cellUl->rcpReqIdx   = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6359
6360    /* Downlink harq feedback is sometime after data reception / harq failure */
6361    /* Since feedback happens prior to scheduling being called, we add 1 to   */
6362    /* take care of getting the correct subframe for feedback                 */
6363    idx = (cellUl->idx - TFU_CRCIND_ULDELTA + RG_SCH_CMN_UL_NUM_SF);
6364 #ifdef UL_ADPT_DBG     
6365    DU_LOG("\nDEBUG  -->  SCH : 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);
6366 #endif
6367    cellUl->hqFdbkIdx[0]   = (idx % (RG_SCH_CMN_UL_NUM_SF));
6368
6369    idx = ((cellUl->schdIdx) % (RG_SCH_CMN_UL_NUM_SF));
6370
6371    cellUl->reTxIdx[0] = (uint8_t) idx;
6372 #ifdef UL_ADPT_DBG     
6373    DU_LOG("\nDEBUG  -->  SCH : cellUl->hqFdbkIdx[0] %d cellUl->reTxIdx[0] %d \n",cellUl->hqFdbkIdx[0], cellUl->reTxIdx[0] );
6374 #endif
6375    /* RACHO: update cmn sched specific RACH variables,
6376     * mainly the prachMaskIndex */
6377    rgSCHCmnUpdRachParam(cell);
6378
6379    return;
6380 }
6381 #endif
6382
6383 #ifdef LTE_TDD
6384
6385 /**
6386  * @brief To get uplink subframe index associated with current PHICH
6387  *        transmission.
6388  *
6389  * @details
6390  *
6391  *     Function: rgSCHCmnGetPhichUlSfIdx
6392  *     Purpose:  Gets uplink subframe index associated with current PHICH
6393  *               transmission based on SFN and subframe no
6394  *
6395  *  @param[in]  CmLteTimingInfo  *timeInfo
6396  *  @param[in]  RgSchCellCb              *cell
6397  *  @return uint8_t
6398  *
6399  **/
6400 uint8_t  rgSCHCmnGetPhichUlSfIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6401 {
6402    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6403    RgSchDlSf       *dlsf;
6404    uint8_t         ulDlCfgIdx = cell->ulDlCfgIdx;
6405    uint8_t         idx;
6406    uint16_t        numUlSf;
6407    uint16_t        sfn;
6408    uint8_t         subframe;
6409
6410
6411    dlsf = rgSCHUtlSubFrmGet(cell, *timeInfo);
6412
6413    if(dlsf->phichOffInfo.sfnOffset == RGSCH_INVALID_INFO)
6414    {
6415       return (RGSCH_INVALID_INFO);
6416    }
6417    subframe = dlsf->phichOffInfo.subframe;
6418
6419    sfn = (RGSCH_MAX_SFN + timeInfo->sfn -
6420                    dlsf->phichOffInfo.sfnOffset) % RGSCH_MAX_SFN;
6421
6422    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
6423     * wrap case such that idx will be proper*/
6424    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6425    numUlSf = ((numUlSf * sfn) + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subframe]) - 1;
6426    idx = numUlSf % (cellUl->numUlSubfrms);
6427
6428    return (idx);
6429 }
6430
6431 /**
6432  * @brief To get uplink subframe index.
6433  *
6434  * @details
6435  *
6436  *
6437  *     Function: rgSCHCmnGetUlSfIdx
6438  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
6439  *
6440  *  @param[in]  CmLteTimingInfo  *timeInfo
6441  *  @param[in]  uint8_t               ulDlCfgIdx
6442  *  @return uint8_t
6443  *
6444  **/
6445 uint8_t  rgSCHCmnGetUlSfIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6446 {
6447    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6448    uint8_t  ulDlCfgIdx = cell->ulDlCfgIdx;
6449    uint8_t  idx = 0;
6450    uint16_t numUlSf;
6451
6452
6453    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
6454     * wrap case such that idx will be proper*/
6455    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6456    numUlSf = ((numUlSf * timeInfo->sfn) + \
6457          rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe]) - 1;
6458    idx = numUlSf % (cellUl->numUlSubfrms);
6459
6460    return (idx);
6461 }
6462
6463 #endif
6464
6465 /**
6466  * @brief To get uplink hq index.
6467  *
6468  * @details
6469  *
6470  *
6471  *     Function: rgSCHCmnGetUlHqProcIdx
6472  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
6473  *
6474  *  @param[in]  CmLteTimingInfo  *timeInfo
6475  *  @param[in]  uint8_t               ulDlCfgIdx
6476  *  @return uint8_t
6477  *
6478  **/
6479 uint8_t  rgSCHCmnGetUlHqProcIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6480 {
6481    uint8_t  procId;
6482    uint32_t numUlSf;
6483   
6484 #ifndef LTE_TDD
6485    numUlSf  = (timeInfo->sfn * RGSCH_NUM_SUB_FRAMES_5G + timeInfo->slot);
6486    procId   = numUlSf % RGSCH_NUM_UL_HQ_PROC;
6487 #else
6488    uint8_t  ulDlCfgIdx = cell->ulDlCfgIdx;
6489    /*ccpu00130639 - MOD - To get correct UL HARQ Proc IDs for all UL/DL Configs*/
6490    uint8_t  numUlSfInSfn;
6491    S8       sfnCycle = cell->tddHqSfnCycle;
6492    uint8_t  numUlHarq = rgSchTddUlNumHarqProcTbl[ulDlCfgIdx]
6493
6494    /* TRACE 5 Changes */
6495
6496    /* Calculate the number of UL SF in one SFN */
6497    numUlSfInSfn = RGSCH_NUM_SUB_FRAMES -
6498                rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6499
6500    /* Check for the SFN wrap around case */
6501    if(cell->crntTime.sfn == 1023 && timeInfo->sfn == 0)
6502    {
6503       sfnCycle++;
6504    }
6505    else if(cell->crntTime.sfn == 0 && timeInfo->sfn == 1023)
6506    {
6507       /* sfnCycle decremented by 1 */
6508       sfnCycle = (sfnCycle + numUlHarq-1) % numUlHarq;
6509    }
6510    /* Calculate the total number of UL sf */
6511    /*  -1 is done since uplink sf are counted from 0 */
6512    numUlSf = numUlSfInSfn *  (timeInfo->sfn + (sfnCycle*1024)) +
6513                   rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->slot] - 1;
6514
6515    procId = numUlSf % numUlHarq;   
6516 #endif
6517    return (procId);
6518 }
6519
6520
6521 /* UL_ALLOC_CHANGES */
6522 /***********************************************************
6523  *
6524  *     Func : rgSCHCmnUlFreeAlloc
6525  *
6526  *     Desc : Free an allocation - invokes UHM and releases
6527  *            alloc for the scheduler
6528  *            Doest need subframe as argument
6529  *
6530  *     Ret  :
6531  *
6532  *     Notes:
6533  *
6534  *     File :
6535  *
6536  **********************************************************/
6537 Void rgSCHCmnUlFreeAlloc(RgSchCellCb *cell,RgSchUlAlloc *alloc)
6538 {
6539    RgSchUlHqProcCb *hqProc;
6540
6541    if (alloc->forMsg3)
6542    {
6543       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
6544       if ((alloc->hqProc->remTx == 0) &&
6545           (alloc->hqProc->rcvdCrcInd == FALSE) &&
6546           (alloc->raCb))
6547       {
6548          RgSchRaCb      *raCb = alloc->raCb;
6549          rgSCHUhmFreeProc(alloc->hqProc, cell);
6550          rgSCHUtlUlAllocRelease(alloc);
6551          rgSCHRamDelRaCb(cell, raCb, TRUE);
6552          return;
6553       }
6554    }
6555    
6556    hqProc = alloc->hqProc;
6557    rgSCHUtlUlAllocRelease(alloc);
6558    rgSCHUhmFreeProc(hqProc, cell);
6559    return;
6560 }
6561
6562
6563 /***********************************************************
6564  *
6565  *     Func : rgSCHCmnUlFreeAllocation
6566  *
6567  *     Desc : Free an allocation - invokes UHM and releases
6568  *            alloc for the scheduler
6569  *
6570  *     Ret  :
6571  *
6572  *     Notes:
6573  *
6574  *     File :
6575  *
6576  **********************************************************/
6577 Void rgSCHCmnUlFreeAllocation(RgSchCellCb *cell,RgSchUlSf *sf,RgSchUlAlloc *alloc)
6578 {
6579    RgSchUlHqProcCb *hqProc;
6580
6581
6582    if (alloc->forMsg3)
6583    {
6584       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
6585       if ((alloc->hqProc->remTx == 0) &&
6586           (alloc->hqProc->rcvdCrcInd == FALSE) &&
6587           (alloc->raCb))
6588       {
6589          RgSchRaCb      *raCb = alloc->raCb;
6590          rgSCHUhmFreeProc(alloc->hqProc, cell);
6591          rgSCHUtlUlAllocRls(sf, alloc);
6592          rgSCHRamDelRaCb(cell, raCb, TRUE);
6593          return;
6594       }
6595    }
6596    
6597    hqProc = alloc->hqProc;
6598    rgSCHUhmFreeProc(hqProc, cell);
6599 #ifdef LTE_L2_MEAS
6600    /* re-setting the PRB count while freeing the allocations */
6601    sf->totPrb = 0;
6602 #endif
6603    rgSCHUtlUlAllocRls(sf, alloc);
6604
6605    return;
6606 }
6607
6608 /**
6609  * @brief This function implements PDCCH allocation for an UE
6610  *        in the currently running subframe.
6611  *
6612  * @details
6613  *
6614  *     Function: rgSCHCmnPdcchAllocCrntSf
6615  *     Purpose:  This function determines current DL subframe
6616  *               and UE DL CQI to call the actual pdcch allocator
6617  *               function.
6618  *               Note that this function is called only
6619  *               when PDCCH request needs to be made during
6620  *               uplink scheduling.
6621  *
6622  *     Invoked by: Scheduler
6623  *
6624  *  @param[in]  RgSchCellCb  *cell
6625  *  @param[in]  RgSchUeCb    *ue
6626  *  @return  RgSchPdcch *
6627  *         -# NULLP when unsuccessful
6628  **/
6629 RgSchPdcch *rgSCHCmnPdcchAllocCrntSf(RgSchCellCb *cell,RgSchUeCb *ue)
6630 {
6631    CmLteTimingInfo frm = cell->crntTime;
6632    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
6633    RgSchDlSf       *sf;
6634    RgSchPdcch      *pdcch = NULLP;
6635
6636    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
6637    sf = rgSCHUtlSubFrmGet(cell, frm);
6638
6639 #ifdef LTE_ADV
6640    if (ue->allocCmnUlPdcch)
6641    {
6642       pdcch = rgSCHCmnCmnPdcchAlloc(cell, sf);
6643       /* Since CRNTI Scrambled */
6644       if(NULLP != pdcch)
6645       {
6646          pdcch->dciNumOfBits = ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
6647       }
6648    }
6649    else
6650 #endif
6651    {
6652       //pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, y, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_0, FALSE);
6653                 pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_A1, FALSE);
6654    }
6655    return (pdcch);
6656 }
6657
6658 /***********************************************************
6659  *
6660  *     Func : rgSCHCmnUlAllocFillNdmrs
6661  *
6662  *     Desc : Determines and fills N_dmrs for a UE uplink
6663  *            allocation.
6664  *
6665  *     Ret  :
6666  *
6667  *     Notes: N_dmrs determination is straightforward, so
6668  *            it is configured per subband
6669  *
6670  *     File :
6671  *
6672  **********************************************************/
6673 Void rgSCHCmnUlAllocFillNdmrs(RgSchCmnUlCell *cellUl,RgSchUlAlloc *alloc)
6674 {
6675    alloc->grnt.nDmrs = cellUl->dmrsArr[alloc->sbStart];
6676    return;
6677 }
6678
6679 /***********************************************************
6680  *
6681  *     Func : rgSCHCmnUlAllocLnkHqProc
6682  *
6683  *     Desc : Links a new allocation for an UE with the
6684  *            appropriate HARQ process of the UE.
6685  *
6686  *     Ret  :
6687  *
6688  *     Notes:
6689  *
6690  *     File :
6691  *
6692  **********************************************************/
6693 Void rgSCHCmnUlAllocLnkHqProc(RgSchUeCb *ue,RgSchUlAlloc *alloc,RgSchUlHqProcCb *proc,Bool isRetx)
6694 {
6695
6696    if(TRUE == isRetx)
6697    {
6698       rgSCHCmnUlAdapRetx(alloc, proc);
6699    }
6700    else
6701    {
6702 #ifdef LTE_L2_MEAS /* L2_COUNTERS */
6703       alloc->ue = ue;
6704 #endif
6705       rgSCHUhmNewTx(proc, (((RgUeUlHqCb*)proc->hqEnt)->maxHqRetx), alloc);
6706    }
6707    return;
6708 }
6709
6710 /**
6711  * @brief This function releases a PDCCH in the subframe that is
6712  *        currently being allocated for.
6713  *
6714  * @details
6715  *
6716  *     Function: rgSCHCmnPdcchRlsCrntSf
6717  *     Purpose:  This function determines current DL subframe
6718  *               which is considered for PDCCH allocation,
6719  *               and then calls the actual function that
6720  *               releases a PDCCH in a specific subframe.
6721  *               Note that this function is called only
6722  *               when PDCCH release needs to be made during
6723  *               uplink scheduling.
6724  *
6725  *     Invoked by: Scheduler
6726  *
6727  *  @param[in]  RgSchCellCb  *cell
6728  *  @param[in]  RgSchPdcch   *pdcch
6729  *  @return  Void
6730  **/
6731 Void rgSCHCmnPdcchRlsCrntSf(RgSchCellCb *cell,RgSchPdcch *pdcch)
6732 {
6733    CmLteTimingInfo frm = cell->crntTime;
6734    RgSchDlSf *sf;
6735
6736    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
6737    sf = rgSCHUtlSubFrmGet(cell, frm);
6738    rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, pdcch);
6739    return;
6740 }
6741 /***********************************************************
6742  *
6743  *     Func : rgSCHCmnUlFillPdcchWithAlloc
6744  *
6745  *     Desc : Fills a PDCCH with format 0 information.
6746  *
6747  *     Ret  :
6748  *
6749  *     Notes:
6750  *
6751  *     File :
6752  *
6753  **********************************************************/
6754 Void rgSCHCmnUlFillPdcchWithAlloc(RgSchPdcch *pdcch,RgSchUlAlloc *alloc,RgSchUeCb *ue)
6755 {
6756
6757    pdcch->ue = ue;
6758    pdcch->rnti = alloc->rnti;
6759    //pdcch->dci.dciFormat = TFU_DCI_FORMAT_A2;
6760    pdcch->dci.dciFormat = alloc->grnt.dciFrmt;
6761
6762    //Currently hardcoding values here.
6763    //DU_LOG("\nINFO   -->  SCH : Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
6764    switch(pdcch->dci.dciFormat)
6765    {
6766       case TFU_DCI_FORMAT_A1:
6767                 {
6768                         pdcch->dci.u.formatA1Info.formatType = 0;
6769          pdcch->dci.u.formatA1Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
6770          pdcch->dci.u.formatA1Info.xPUSCH_TxTiming = 0;
6771          pdcch->dci.u.formatA1Info.RBAssign = alloc->grnt.rbAssign;
6772          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
6773          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
6774          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
6775          pdcch->dci.u.formatA1Info.CSI_BSI_BRI_Req = 0;
6776          pdcch->dci.u.formatA1Info.CSIRS_BRRS_TxTiming = 0;
6777          pdcch->dci.u.formatA1Info.CSIRS_BRRS_SymbIdx = 0;
6778          pdcch->dci.u.formatA1Info.CSIRS_BRRS_ProcInd = 0;
6779          pdcch->dci.u.formatA1Info.numBSI_Reports = 0;
6780          pdcch->dci.u.formatA1Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
6781          pdcch->dci.u.formatA1Info.beamSwitch  = 0;
6782          pdcch->dci.u.formatA1Info.SRS_Config = 0;
6783          pdcch->dci.u.formatA1Info.SRS_Symbol = 0;
6784          pdcch->dci.u.formatA1Info.REMapIdx_DMRS_PCRS_numLayers = 0;
6785          pdcch->dci.u.formatA1Info.SCID = alloc->grnt.SCID;
6786          pdcch->dci.u.formatA1Info.PMI = alloc->grnt.PMI;
6787          pdcch->dci.u.formatA1Info.UL_PCRS = 0;
6788          pdcch->dci.u.formatA1Info.tpcCmd = alloc->grnt.tpc;
6789                         break;
6790       }
6791                 case TFU_DCI_FORMAT_A2:
6792                 {
6793                         pdcch->dci.u.formatA2Info.formatType = 1;
6794          pdcch->dci.u.formatA2Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
6795          pdcch->dci.u.formatA2Info.xPUSCH_TxTiming = 0;
6796          pdcch->dci.u.formatA2Info.RBAssign = alloc->grnt.rbAssign;
6797          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
6798          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
6799          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
6800          pdcch->dci.u.formatA2Info.CSI_BSI_BRI_Req = 0;
6801          pdcch->dci.u.formatA2Info.CSIRS_BRRS_TxTiming = 0;
6802          pdcch->dci.u.formatA2Info.CSIRS_BRRS_SymbIdx = 0;
6803          pdcch->dci.u.formatA2Info.CSIRS_BRRS_ProcInd = 0;
6804          pdcch->dci.u.formatA2Info.numBSI_Reports = 0;
6805          pdcch->dci.u.formatA2Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
6806          pdcch->dci.u.formatA2Info.beamSwitch  = 0;
6807          pdcch->dci.u.formatA2Info.SRS_Config = 0;
6808          pdcch->dci.u.formatA2Info.SRS_Symbol = 0;
6809          pdcch->dci.u.formatA2Info.REMapIdx_DMRS_PCRS_numLayers = 0;
6810          pdcch->dci.u.formatA2Info.SCID = alloc->grnt.SCID;
6811          pdcch->dci.u.formatA2Info.PMI = alloc->grnt.PMI;
6812          pdcch->dci.u.formatA2Info.UL_PCRS = 0;
6813          pdcch->dci.u.formatA2Info.tpcCmd = alloc->grnt.tpc;
6814                         break;
6815                 }
6816       default:
6817          DU_LOG("\nERROR  -->  SCH :  5GTF_ERROR UL Allocator's icorrect "
6818                "dciForamt Fill RNTI:%d",alloc->rnti);
6819          break;
6820    }    
6821    
6822
6823    return;
6824 }
6825
6826 /***********************************************************
6827  *
6828  *     Func : rgSCHCmnUlAllocFillTpc
6829  *
6830  *     Desc : Determines and fills TPC for an UE allocation.
6831  *
6832  *     Ret  :
6833  *
6834  *     Notes:
6835  *
6836  *     File :
6837  *
6838  **********************************************************/
6839 Void rgSCHCmnUlAllocFillTpc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchUlAlloc *alloc)
6840 {
6841    alloc->grnt.tpc = rgSCHPwrPuschTpcForUe(cell, ue);
6842    return;
6843 }
6844
6845
6846 /***********************************************************
6847  *
6848  *     Func : rgSCHCmnAddUeToRefreshQ
6849  *
6850  *     Desc : Adds a UE to refresh queue, so that the UE is
6851  *            periodically triggered to refresh it's GBR and
6852  *            AMBR values.
6853  *
6854  *     Ret  :
6855  *
6856  *     Notes:
6857  *
6858  *     File :
6859  *
6860  **********************************************************/
6861 static Void rgSCHCmnAddUeToRefreshQ(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t wait)
6862 {
6863    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
6864    CmTmrArg       arg;
6865    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
6866
6867    UNUSED(cell);
6868
6869    memset(&arg, 0, sizeof(arg));
6870    arg.tqCp   = &sched->tmrTqCp;
6871    arg.tq     = sched->tmrTq;
6872    arg.timers = &ueSchd->tmr;
6873    arg.cb     = (PTR)ue;
6874    arg.tNum   = 0;
6875    arg.max    = 1;
6876    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
6877    arg.wait   = wait;
6878    cmPlcCbTq(&arg);
6879    return;
6880 }
6881
6882 /**
6883  * @brief Perform UE reset procedure.
6884  *
6885  * @details
6886  *
6887  *     Function : rgSCHCmnUlUeReset
6888  *
6889  *     This functions performs BSR resetting and
6890  *     triggers UL specific scheduler
6891  *     to Perform UE reset procedure.
6892  *
6893  *  @param[in]  RgSchCellCb  *cell
6894  *  @param[in]  RgSchUeCb    *ue
6895  *  @return  Void
6896  **/
6897 static Void rgSCHCmnUlUeReset(RgSchCellCb  *cell,RgSchUeCb    *ue)
6898 {
6899    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
6900    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
6901    uint8_t              lcgCnt=0;
6902    RgSchCmnLcg          *lcgCmn;
6903    CmLList              *node;
6904    RgSchCmnAllocRecord  *allRcd;
6905
6906    ue->ul.minReqBytes = 0;
6907    ue->ul.totalBsr = 0;
6908    ue->ul.effBsr = 0;
6909    ue->ul.nonGbrLcgBs = 0;
6910    ue->ul.effAmbr = ue->ul.cfgdAmbr;
6911
6912    node = ueUl->ulAllocLst.first;
6913    while (node)
6914    {
6915       allRcd = (RgSchCmnAllocRecord *)node->node;
6916       allRcd->alloc = 0;
6917       node = node->next;
6918    }
6919    for(lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++)
6920    {
6921       lcgCmn = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[lcgCnt]);
6922       lcgCmn->bs = 0;
6923       lcgCmn->reportedBs = 0;
6924       lcgCmn->effGbr = lcgCmn->cfgdGbr;
6925       lcgCmn->effDeltaMbr = lcgCmn->deltaMbr;
6926    }
6927    rgSCHCmnUlUeDelAllocs(cell, ue);
6928
6929    ue->isSrGrant = FALSE;
6930
6931    cellSchd->apisUl->rgSCHUlUeReset(cell, ue);
6932
6933    /* Stack Crash problem for TRACE5 changes. Added the return below */
6934    return;
6935
6936 }
6937
6938 /**
6939  * @brief RESET UL CQI and DL CQI&RI to conservative values
6940     * for a reestablishing UE.
6941  *
6942  * @details
6943  *
6944  *     Function : rgSCHCmnResetRiCqi 
6945  *     
6946  *     RESET UL CQI and DL CQI&RI to conservative values
6947  *     for a reestablishing UE
6948  *
6949  *  @param[in]  RgSchCellCb  *cell
6950  *  @param[in]  RgSchUeCb    *ue
6951  *  @return  Void
6952  **/
6953 static Void rgSCHCmnResetRiCqi(RgSchCellCb *cell,RgSchUeCb *ue)
6954 {
6955    RgSchCmnCell  *cellSchd = RG_SCH_CMN_GET_CELL(cell);
6956    RgSchCmnUe    *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
6957    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
6958    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
6959
6960
6961    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, 
6962          cell->isCpUlExtend);
6963
6964    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
6965    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
6966    ueDl->mimoInfo.ri = 1;
6967    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
6968           (ue->mimoInfo.txMode == RGR_UE_TM_6))
6969    {
6970       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
6971    }
6972    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
6973    {
6974       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
6975    }
6976 #ifdef EMTC_ENABLE   
6977    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
6978 #else
6979    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
6980 #endif      
6981
6982 #ifdef TFU_UPGRADE
6983    /* Request for an early Aper CQI in case of reest */
6984    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
6985    if(acqiCb && acqiCb->aCqiCfg.pres)
6986    {
6987       acqiCb->aCqiTrigWt = 0;
6988    }
6989 #endif   
6990
6991    return;
6992 }
6993
6994 /**
6995  * @brief Perform UE reset procedure.
6996  *
6997  * @details
6998  *
6999  *     Function : rgSCHCmnDlUeReset
7000  *
7001  *     This functions performs BO resetting and
7002  *     triggers DL specific scheduler
7003  *     to Perform UE reset procedure.
7004  *
7005  *  @param[in]  RgSchCellCb  *cell
7006  *  @param[in]  RgSchUeCb    *ue
7007  *  @return  Void
7008  **/
7009 static Void rgSCHCmnDlUeReset(RgSchCellCb  *cell,RgSchUeCb *ue)
7010 {
7011    RgSchCmnCell   *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7012    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
7013    RgSchCmnDlUe   *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7014
7015
7016    if (ueDl->rachInfo.poLnk.node != NULLP)
7017    {
7018       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
7019    }
7020
7021    /* Fix: syed Remove from TA List if this UE is there.
7022     * If TA Timer is running. Stop it */
7023    if (ue->dlTaLnk.node)
7024    {
7025       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
7026       ue->dlTaLnk.node = (PTR)NULLP;
7027    }
7028    else if (ue->taTmr.tmrEvnt != TMR_NONE)
7029    {
7030       rgSCHTmrStopTmr(cell, ue->taTmr.tmrEvnt, ue);
7031    }
7032
7033    cellSchd->apisDl->rgSCHDlUeReset(cell, ue);
7034 #ifdef LTE_ADV
7035    if (ue->numSCells)
7036    {
7037       rgSCHSCellDlUeReset(cell,ue);
7038    }
7039 #endif
7040 }
7041
7042 /**
7043  * @brief Perform UE reset procedure.
7044  *
7045  * @details
7046  *
7047  *     Function : rgSCHCmnUeReset
7048  *
7049  *     This functions triggers specific scheduler
7050  *     to Perform UE reset procedure.
7051  *
7052  *  @param[in]  RgSchCellCb  *cell
7053  *  @param[in]  RgSchUeCb    *ue
7054  *  @return  S16
7055  *      -# ROK
7056  *      -# RFAILED
7057  **/
7058 Void rgSCHCmnUeReset(RgSchCellCb  *cell,RgSchUeCb *ue)
7059 {
7060    uint8_t idx;
7061    Pst     pst;
7062    RgInfResetHqEnt   hqEntRstInfo;
7063
7064    /* RACHO: remove UE from pdcch, handover and rapId assoc Qs */
7065    rgSCHCmnDelRachInfo(cell, ue);
7066
7067    rgSCHPwrUeReset(cell, ue);
7068
7069    rgSCHCmnUlUeReset(cell, ue);
7070    rgSCHCmnDlUeReset(cell, ue);
7071    
7072 #ifdef LTE_ADV
7073    /* Making allocCmnUlPdcch TRUE to allocate DCI0/1A from Common search space.
7074       As because multiple cells are added hence 2 bits CqiReq is there 
7075       This flag will be set to FALSE once we will get Scell READY */
7076    ue->allocCmnUlPdcch = TRUE;
7077 #endif
7078
7079    /* Fix : syed RESET UL CQI and DL CQI&RI to conservative values
7080     * for a reestablishing UE */
7081    /*Reset Cqi Config for all the configured cells*/
7082    for (idx = 0;idx < CM_LTE_MAX_CELLS; idx++)
7083    {
7084       if (ue->cellInfo[idx] != NULLP) 
7085       {   
7086          rgSCHCmnResetRiCqi(ue->cellInfo[idx]->cell, ue);
7087       }
7088    }
7089    /*After Reset Trigger APCQI for Pcell*/
7090    RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7091    if(pCellInfo->acqiCb.aCqiCfg.pres)
7092    {
7093       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
7094    }
7095
7096 /* sending HqEnt reset to MAC */
7097    hqEntRstInfo.cellId = cell->cellId;
7098    hqEntRstInfo.crnti  = ue->ueId;
7099
7100    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
7101    RgSchMacRstHqEnt(&pst,&hqEntRstInfo);
7102
7103    return;
7104 }
7105
7106 /**
7107  * @brief UE out of MeasGap or AckNackReptn.
7108  *
7109  * @details
7110  *
7111  *     Function : rgSCHCmnActvtUlUe
7112  *
7113  *     This functions triggers specific scheduler
7114  *     to start considering it for scheduling.
7115  *
7116  *  @param[in]  RgSchCellCb  *cell
7117  *  @param[in]  RgSchUeCb    *ue
7118  *  @return  S16
7119  *      -# ROK
7120  *      -# RFAILED
7121  **/
7122 Void rgSCHCmnActvtUlUe(RgSchCellCb *cell,RgSchUeCb *ue)
7123 {
7124    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7125
7126    /* : take care of this in UL retransmission */
7127    cellSchd->apisUl->rgSCHUlActvtUe(cell, ue);
7128    return;
7129 }
7130
7131 /**
7132  * @brief UE out of MeasGap or AckNackReptn.
7133  *
7134  * @details
7135  *
7136  *     Function : rgSCHCmnActvtDlUe
7137  *
7138  *     This functions triggers specific scheduler
7139  *     to start considering it for scheduling.
7140  *
7141  *  @param[in]  RgSchCellCb  *cell
7142  *  @param[in]  RgSchUeCb    *ue
7143  *  @return  S16
7144  *      -# ROK
7145  *      -# RFAILED
7146  **/
7147 Void rgSCHCmnActvtDlUe(RgSchCellCb *cell,RgSchUeCb *ue)
7148 {
7149    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7150
7151    cellSchd->apisDl->rgSCHDlActvtUe(cell, ue);
7152    return;
7153 }
7154
7155 /**
7156  * @brief This API is invoked to indicate scheduler of a CRC indication.
7157  *
7158  * @details
7159  *
7160  *     Function : rgSCHCmnHdlUlTransInd
7161  *      This API is invoked to indicate scheduler of a CRC indication.
7162  *
7163  *  @param[in]  RgSchCellCb     *cell
7164  *  @param[in]  RgSchUeCb       *ue
7165  *  @param[in]  CmLteTimingInfo timingInfo
7166  *
7167  *  @return Void
7168  **/
7169 Void rgSCHCmnHdlUlTransInd(RgSchCellCb *cell,RgSchUeCb *ue,CmLteTimingInfo timingInfo)
7170 {
7171
7172    /* Update the latest UL dat/sig transmission time */
7173    RGSCHCPYTIMEINFO(timingInfo, ue->ul.ulTransTime);
7174    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
7175    {
7176       /* Some UL Transmission from this UE.
7177        * Activate this UE if it was inactive */
7178       RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7179       RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7180    }
7181    return;
7182 }
7183
7184 #ifdef TFU_UPGRADE
7185
7186 /**
7187  * @brief Compute the minimum Rank based on Codebook subset
7188  *        restriction configuration for 4 Tx Ports and Tx Mode 4.
7189  *
7190  * @details
7191  *
7192  *     Function : rgSCHCmnComp4TxMode4
7193  *
7194  *     Depending on BitMap set at CBSR during Configuration
7195  *      - return the least possible Rank
7196  *
7197  *
7198  *  @param[in]  uint32_t *pmiBitMap
7199  *  @return  RgSchCmnRank
7200  **/
7201 static RgSchCmnRank rgSCHCmnComp4TxMode4(uint32_t *pmiBitMap)
7202 {
7203    uint32_t bitMap0, bitMap1;
7204    bitMap0 = pmiBitMap[0];
7205    bitMap1 = pmiBitMap[1];
7206    if((bitMap1) & 0xFFFF)
7207    {
7208       return  (RG_SCH_CMN_RANK_1);
7209    }
7210    else if((bitMap1>>16) & 0xFFFF)
7211    {
7212       return  (RG_SCH_CMN_RANK_2);
7213    }
7214    else if((bitMap0) & 0xFFFF)
7215    {
7216       return  (RG_SCH_CMN_RANK_3);
7217    }
7218    else if((bitMap0>>16) & 0xFFFF)
7219    {
7220       return  (RG_SCH_CMN_RANK_4);
7221    }
7222    else
7223    {
7224       return  (RG_SCH_CMN_RANK_1);
7225    }
7226 }
7227
7228
7229 /**
7230  * @brief Compute the minimum Rank based on Codebook subset
7231  *        restriction configuration for 2 Tx Ports and Tx Mode 4.
7232  *
7233  * @details
7234  *
7235  *     Function : rgSCHCmnComp2TxMode4
7236  *
7237  *     Depending on BitMap set at CBSR during Configuration
7238  *      - return the least possible Rank
7239  *
7240  *
7241  *  @param[in]  uint32_t *pmiBitMap
7242  *  @return  RgSchCmnRank
7243  **/
7244 static RgSchCmnRank rgSCHCmnComp2TxMode4(uint32_t *pmiBitMap)
7245 {
7246    uint32_t bitMap0;
7247    bitMap0 = pmiBitMap[0];
7248    if((bitMap0>>26)& 0x0F)
7249    {
7250       return  (RG_SCH_CMN_RANK_1);
7251    }
7252    else if((bitMap0>>30) & 3)
7253    {
7254       return  (RG_SCH_CMN_RANK_2);
7255    }
7256    else
7257    {
7258       return  (RG_SCH_CMN_RANK_1);
7259    }
7260 }
7261
7262 /**
7263  * @brief Compute the minimum Rank based on Codebook subset
7264  *        restriction configuration for 4 Tx Ports and Tx Mode 3.
7265  *
7266  * @details
7267  *
7268  *     Function : rgSCHCmnComp4TxMode3
7269  *
7270  *     Depending on BitMap set at CBSR during Configuration
7271  *      - return the least possible Rank
7272  *
7273  *
7274  *  @param[in]  uint32_t *pmiBitMap
7275  *  @return  RgSchCmnRank
7276  **/
7277 static RgSchCmnRank rgSCHCmnComp4TxMode3(uint32_t *pmiBitMap)
7278 {
7279    uint32_t bitMap0;
7280    bitMap0 = pmiBitMap[0];
7281    if((bitMap0>>28)& 1)
7282    {
7283       return  (RG_SCH_CMN_RANK_1);
7284    }
7285    else if((bitMap0>>29) &1)
7286    {
7287       return  (RG_SCH_CMN_RANK_2);
7288    }
7289    else if((bitMap0>>30) &1)
7290    {
7291       return  (RG_SCH_CMN_RANK_3);
7292    }
7293    else if((bitMap0>>31) &1)
7294    {
7295       return  (RG_SCH_CMN_RANK_4);
7296    }
7297    else
7298    {
7299       return  (RG_SCH_CMN_RANK_1);
7300    }
7301 }
7302
7303 /**
7304  * @brief Compute the minimum Rank based on Codebook subset
7305  *        restriction configuration for 2 Tx Ports and Tx Mode 3.
7306  *
7307  * @details
7308  *
7309  *     Function : rgSCHCmnComp2TxMode3
7310  *
7311  *     Depending on BitMap set at CBSR during Configuration
7312  *      - return the least possible Rank
7313  *
7314  *
7315  *  @param[in]  uint32_t *pmiBitMap
7316  *  @return  RgSchCmnRank
7317  **/
7318 static RgSchCmnRank rgSCHCmnComp2TxMode3(uint32_t *pmiBitMap)
7319 {
7320    uint32_t bitMap0;
7321    bitMap0 = pmiBitMap[0];
7322    if((bitMap0>>30)& 1)
7323    {
7324       return  (RG_SCH_CMN_RANK_1);
7325    }
7326    else if((bitMap0>>31) &1)
7327    {
7328       return  (RG_SCH_CMN_RANK_2);
7329    }
7330    else
7331    {
7332       return  (RG_SCH_CMN_RANK_1);
7333    }
7334 }
7335
7336 /**
7337  * @brief Compute the minimum Rank based on Codebook subset
7338  *        restriction configuration.
7339  *
7340  * @details
7341  *
7342  *     Function : rgSCHCmnComputeRank
7343  *
7344  *     Depending on Num Tx Ports and Transmission mode
7345  *      - return the least possible Rank
7346  *
7347  *
7348  *  @param[in]  RgrTxMode txMode
7349  *  @param[in]  uint32_t *pmiBitMap
7350  *  @param[in]  uint8_t numTxPorts
7351  *  @return  RgSchCmnRank
7352  **/
7353 static RgSchCmnRank rgSCHCmnComputeRank(RgrTxMode txMode,uint32_t *pmiBitMap,uint8_t numTxPorts)
7354 {
7355
7356    if (numTxPorts ==2 && txMode == RGR_UE_TM_3)
7357    {
7358       return  (rgSCHCmnComp2TxMode3(pmiBitMap));
7359    }
7360    else if (numTxPorts ==4 && txMode == RGR_UE_TM_3)
7361    {
7362       return  (rgSCHCmnComp4TxMode3(pmiBitMap));
7363    }
7364    else if (numTxPorts ==2 && txMode == RGR_UE_TM_4)
7365    {
7366       return  (rgSCHCmnComp2TxMode4(pmiBitMap));
7367    }
7368    else if (numTxPorts ==4 && txMode == RGR_UE_TM_4)
7369    {
7370       return  (rgSCHCmnComp4TxMode4(pmiBitMap));
7371    }
7372    else
7373    {
7374       return  (RG_SCH_CMN_RANK_1);
7375    }
7376 }
7377
7378 #endif
7379
7380 /**
7381  * @brief Harq Entity Deinitialization for CMN SCH.
7382  *
7383  * @details
7384  *
7385  *     Function : rgSCHCmnDlDeInitHqEnt 
7386  *
7387  *     Harq Entity Deinitialization for CMN SCH 
7388  *
7389  *  @param[in]  RgSchCellCb  *cell
7390  *  @param[in]  RgSchDlHqEnt *hqE 
7391  *  @return  VOID
7392  **/
7393 /*KWORK_FIX:Changed function return type to void */
7394 Void rgSCHCmnDlDeInitHqEnt(RgSchCellCb  *cell,RgSchDlHqEnt *hqE)
7395 {
7396    RgSchCmnCell    *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7397    RgSchDlHqProcCb *hqP;
7398    uint8_t         cnt;
7399    S16             ret;
7400
7401    ret = cellSchd->apisDl->rgSCHDlUeHqEntDeInit(cell, hqE);
7402    /* Free only If the Harq proc are created*/
7403    if(RFAILED == ret)
7404    {
7405    }
7406
7407    for(cnt = 0; cnt < hqE->numHqPrcs; cnt++)
7408    {
7409       hqP = &hqE->procs[cnt];
7410       if ((RG_SCH_CMN_GET_DL_HQP(hqP)))
7411       {
7412          rgSCHUtlFreeSBuf(cell->instIdx,
7413               (Data**)(&(hqP->sch)), (sizeof(RgSchCmnDlHqProc)));
7414       }
7415    }
7416 #ifdef LTE_ADV
7417    rgSCHLaaDeInitDlHqProcCb (cell, hqE);
7418 #endif
7419
7420    return;
7421 }
7422
7423 /**
7424  * @brief Harq Entity initialization for CMN SCH.
7425  *
7426  * @details
7427  *
7428  *     Function : rgSCHCmnDlInitHqEnt 
7429  *
7430  *     Harq Entity initialization for CMN SCH 
7431  *
7432  *  @param[in]  RgSchCellCb  *cell
7433  *  @param[in]  RgSchUeCb    *ue
7434  *  @return  S16
7435  *      -# ROK
7436  *      -# RFAILED
7437  **/
7438 S16 rgSCHCmnDlInitHqEnt(RgSchCellCb *cell,RgSchDlHqEnt *hqEnt)
7439 {
7440    RgSchDlHqProcCb *hqP;
7441    uint8_t         cnt;
7442    RgSchCmnCell    *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7443
7444    for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
7445    {
7446       hqP = &hqEnt->procs[cnt];
7447       if (rgSCHUtlAllocSBuf(cell->instIdx,
7448                (Data**)&(hqP->sch), (sizeof(RgSchCmnDlHqProc))) != ROK)
7449       {
7450          return RFAILED;
7451       }
7452    }
7453 #ifdef EMTC_ENABLE
7454    if((cell->emtcEnable) &&(hqEnt->ue->isEmtcUe))
7455    {
7456       if(ROK != cellSchd->apisEmtcDl->rgSCHDlUeHqEntInit(cell, hqEnt))
7457       {
7458          return RFAILED;
7459       }
7460
7461    }
7462    else
7463 #endif
7464    {
7465       if(ROK != cellSchd->apisDl->rgSCHDlUeHqEntInit(cell, hqEnt))
7466       {
7467          return RFAILED;
7468       }
7469    }
7470
7471    return ROK;
7472 }  /* rgSCHCmnDlInitHqEnt */
7473
7474 /**
7475  * @brief This function computes distribution of refresh period
7476  *
7477  * @details
7478  *
7479  *     Function: rgSCHCmnGetRefreshDist 
7480  *     Purpose: This function computes distribution of refresh period
7481  *              This is required to align set of UEs refresh
7482  *              around the different consecutive subframe.
7483  *               
7484  *     Invoked by: rgSCHCmnGetRefreshPerDist
7485  *
7486  *  @param[in]  RgSchCellCb        *cell
7487  *  @param[in]  RgSchUeCb          *ue
7488  *  @return  Void
7489  *
7490  **/
7491 static uint8_t rgSCHCmnGetRefreshDist(RgSchCellCb *cell,RgSchUeCb *ue)
7492 {
7493    uint8_t   refOffst;
7494
7495    for(refOffst = 0; refOffst < RGSCH_MAX_REFRESH_OFFSET; refOffst++)
7496    {
7497       if(cell->refreshUeCnt[refOffst] < RGSCH_MAX_REFRESH_GRPSZ)
7498       {
7499          cell->refreshUeCnt[refOffst]++;
7500          ue->refreshOffset = refOffst;
7501          /* DU_LOG("\nINFO   -->  SCH : UE[%d] refresh offset[%d]. Cell refresh ue count[%d].\n", ue->ueId, refOffst,  cell->refreshUeCnt[refOffst]); */
7502          return (refOffst);
7503       }
7504    }
7505   
7506    DU_LOG("\nERROR  -->  SCH : Allocation of refresh distribution failed\n");
7507    /* We should not enter here  normally, but incase of failure, allocating from  last offset*/
7508    cell->refreshUeCnt[refOffst-1]++;
7509    ue->refreshOffset = refOffst-1;
7510
7511    return (refOffst-1);
7512 }
7513 /**
7514  * @brief This function computes initial Refresh Wait Period.
7515  *
7516  * @details
7517  *
7518  *     Function: rgSCHCmnGetRefreshPer 
7519  *     Purpose: This function computes initial Refresh Wait Period.
7520  *              This is required to align multiple UEs refresh
7521  *              around the same time.
7522  *               
7523  *     Invoked by: rgSCHCmnGetRefreshPer 
7524  *
7525  *  @param[in]  RgSchCellCb        *cell
7526  *  @param[in]  RgSchUeCb          *ue
7527  *  @param[in]  uint32_t                *waitPer 
7528  *  @return  Void
7529  *
7530  **/
7531 static Void rgSCHCmnGetRefreshPer(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t *waitPer)
7532 {
7533    uint32_t  refreshPer;           
7534    uint32_t  crntSubFrm;
7535
7536
7537    refreshPer = RG_SCH_CMN_REFRESH_TIME * RG_SCH_CMN_REFRESH_TIMERES;
7538    crntSubFrm = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot;
7539    /* Fix: syed align multiple UEs to refresh at same time */
7540    *waitPer = refreshPer - (crntSubFrm % refreshPer);
7541    *waitPer = RGSCH_CEIL(*waitPer, RG_SCH_CMN_REFRESH_TIMERES);
7542    *waitPer = *waitPer + rgSCHCmnGetRefreshDist(cell, ue);
7543
7544    return;
7545 }
7546
7547
7548 #ifdef LTE_ADV
7549 /**
7550  * @brief UE initialisation for scheduler.
7551  *
7552  * @details
7553  *
7554  *     Function : rgSCHCmnRgrSCellUeCfg
7555  *
7556  *     This functions intialises UE specific scheduler 
7557  *     information for SCELL
7558  *     0. Perform basic validations
7559  *     1. Allocate common sched UE cntrl blk
7560  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
7561  *     3. Perform UL cfg
7562  *     4. Perform DLFS cfg
7563  *
7564  *  @param[in]  RgSchCellCb  *cell
7565  *  @param[in]  RgSchUeCb    *ue
7566  *  @param[out] RgSchErrInfo *err
7567  *  @return  S16
7568  *      -# ROK
7569  *      -# RFAILED
7570  **/
7571 S16 rgSCHCmnRgrSCellUeCfg(RgSchCellCb *sCell,RgSchUeCb *ue,RgrUeSecCellCfg *sCellInfoCfg,RgSchErrInfo *err)
7572 {
7573    uint8_t i;
7574    S16     ret;
7575    uint8_t cnt;
7576    RgSchCmnAllocRecord  *allRcd;
7577    RgSchDlRbAlloc       *allocInfo;
7578    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
7579    RgSchCmnUlUe         *ueUl;
7580    RgSchCmnUlUe         *ueUlPcell;
7581    RgSchCmnUe           *pCellUeSchCmn;
7582    RgSchCmnUe           *ueSchCmn;
7583    RgSchCmnDlUe         *ueDl;
7584    RgSchCmnDlUe         *pCellUeDl;
7585 #ifdef DEBUGP
7586    Inst                 inst = ue->cell->instIdx;
7587 #endif
7588    uint32_t idx = (uint8_t)((sCell->cellId - rgSchCb[sCell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
7589
7590    pCellUeSchCmn = RG_SCH_CMN_GET_UE(ue,ue->cell);
7591    pCellUeDl = &pCellUeSchCmn->dl;
7592
7593    /* 1. Allocate Common sched control block */
7594    if((rgSCHUtlAllocSBuf(sCell->instIdx,
7595                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
7596    {
7597       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED\n");
7598       err->errCause = RGSCHERR_SCH_CFG;
7599       return RFAILED;
7600    }
7601    ueSchCmn = RG_SCH_CMN_GET_UE(ue,sCell);
7602
7603    /*2.  Perform UEs downlink configuration */
7604    ueDl = &ueSchCmn->dl;
7605
7606    /*CA TODO*/
7607    ueDl->mimoInfo = pCellUeDl->mimoInfo;
7608
7609    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
7610          (ue->mimoInfo.txMode == RGR_UE_TM_6))
7611    {
7612       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_NO_PMI);
7613    }
7614    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
7615    {
7616       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_RI_1);
7617    }
7618    RGSCH_ARRAY_BOUND_CHECK(sCell->instIdx, rgUeCatTbl, pCellUeSchCmn->cmn.ueCat);
7619    ueDl->maxTbBits = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlTbBits;
7620    /*CA dev-Start*/
7621    uint8_t ri = 0;
7622    ri = RGSCH_MIN(ri, sCell->numTxAntPorts);
7623    if(((CM_LTE_UE_CAT_6 == pCellUeSchCmn->cmn.ueCat )
7624             ||(CM_LTE_UE_CAT_7 == pCellUeSchCmn->cmn.ueCat)) 
7625          && (4 == ri))
7626    {
7627       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[1];
7628    }
7629    else
7630    {
7631       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[0];
7632    }
7633    /*CA dev-End*/
7634    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
7635 #ifdef LTE_TDD
7636    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
7637          rgSchTddDlNumHarqProcTbl[sCell->ulDlCfgIdx]);
7638 #else
7639    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
7640          RGSCH_NUM_DL_HQ_PROC);
7641 #endif
7642 #ifdef EMTC_ENABLE   
7643    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, ue->isEmtcUe);
7644 #else
7645    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, FALSE);
7646 #endif      
7647
7648    /* DL ambr */
7649    /* ambrCfgd config moved to ueCb.dl, as it's not needed for per cell wise*/
7650
7651    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, sCell);
7652    allocInfo->rnti = ue->ueId;
7653
7654    /* Initializing the lastCfi value to current cfi value */
7655    ueDl->lastCfi = cellSchd->dl.currCfi;
7656
7657    if ((cellSchd->apisDl->rgSCHRgrSCellDlUeCfg(sCell, ue, err)) != ROK)
7658    {
7659       DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED\n");
7660       return RFAILED;
7661    }
7662
7663    /* TODO: enhance for DLFS RB Allocation for SCELLs in future dev */
7664
7665    /* DLFS UE Config */
7666    if (cellSchd->dl.isDlFreqSel)
7667    {
7668       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeCfg(sCell, ue, sCellInfoCfg, err)) != ROK)
7669       {
7670          DU_LOG("\nERROR  -->  SCH : DLFS UE config FAILED\n");
7671          return RFAILED;
7672       }
7673    }
7674
7675    /* TODO: Do UL SCELL CFG during UL CA dev */
7676    {
7677       ueUl = RG_SCH_CMN_GET_UL_UE(ue, sCell);
7678
7679       /* TODO_ULCA: SRS for SCELL needs to be handled in the below function call */
7680       rgSCHCmnUpdUeUlCqiInfo(sCell, ue, ueUl, ueSchCmn, cellSchd,
7681             sCell->isCpUlExtend);
7682
7683       ret = rgSCHUhmHqEntInit(sCell, ue);
7684       if (ret != ROK)
7685       {
7686          DU_LOG("\nERROR  -->  SCH : SCELL UHM HARQ Ent Init "
7687                "Failed for CRNTI:%d", ue->ueId);
7688          return RFAILED;
7689       }
7690
7691       ueUlPcell = RG_SCH_CMN_GET_UL_UE(ue, ue->cell);
7692       /* Initialize uplink HARQ related information for UE */
7693       ueUl->hqEnt.maxHqRetx = ueUlPcell->hqEnt.maxHqRetx;
7694       cmLListInit(&ueUl->hqEnt.free);
7695       cmLListInit(&ueUl->hqEnt.inUse);
7696       for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
7697       {
7698          ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
7699          ueUl->hqEnt.hqProcCb[i].procId = i;
7700          ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
7701          ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
7702 #ifdef LTEMAC_SPS
7703          /* ccpu00139513- Initializing SPS flags*/
7704          ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
7705          ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
7706 #endif
7707          cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
7708          ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
7709       }
7710
7711       /* Allocate UL BSR allocation tracking List */
7712       cmLListInit(&ueUl->ulAllocLst);
7713
7714       for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
7715       {
7716          if((rgSCHUtlAllocSBuf(sCell->instIdx,
7717                      (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
7718          {
7719             DU_LOG("\nERROR  -->  SCH : SCELL Memory allocation FAILED"
7720                   "for CRNTI:%d",ue->ueId);
7721             err->errCause = RGSCHERR_SCH_CFG;
7722             return RFAILED;
7723          }
7724          allRcd->allocTime = sCell->crntTime;
7725          cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
7726          allRcd->lnk.node = (PTR)allRcd;
7727       }
7728
7729       /* After initialising UL part, do power related init */
7730       ret = rgSCHPwrUeSCellCfg(sCell, ue, sCellInfoCfg);
7731       if (ret != ROK)
7732       {
7733          DU_LOG("\nERROR  -->  SCH : Could not do "
7734                "power config for UE CRNTI:%d",ue->ueId);
7735          return RFAILED;
7736       }
7737
7738 #ifdef EMTC_ENABLE   
7739       if(TRUE == ue->isEmtcUe)
7740       {
7741          if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
7742          {
7743             DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
7744                   "for CRNTI:%d",ue->ueId);
7745             return RFAILED;
7746          }
7747       }
7748       else
7749 #endif
7750       {
7751       if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
7752       {
7753          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
7754                "for CRNTI:%d",ue->ueId);
7755          return RFAILED;
7756       }
7757       }
7758    
7759       ue->ul.isUlCaEnabled = TRUE;
7760    }
7761
7762    return ROK;
7763 }  /* rgSCHCmnRgrSCellUeCfg */
7764
7765
7766 /**
7767  * @brief UE initialisation for scheduler.
7768  *
7769  * @details
7770  *
7771  *     Function : rgSCHCmnRgrSCellUeDel 
7772  *
7773  *     This functions Delete UE specific scheduler 
7774  *     information for SCELL
7775  *
7776  *  @param[in]  RgSchCellCb  *cell
7777  *  @param[in]  RgSchUeCb    *ue
7778  *  @return  S16
7779  *      -# ROK
7780  *      -# RFAILED
7781  **/
7782 S16 rgSCHCmnRgrSCellUeDel(RgSchUeCellInfo *sCellInfo,RgSchUeCb *ue)
7783 {
7784    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
7785    Inst         inst = ue->cell->instIdx;
7786
7787
7788    cellSchd->apisDl->rgSCHRgrSCellDlUeDel(sCellInfo, ue);
7789
7790    /* UL CA */
7791    rgSCHCmnUlUeDelAllocs(sCellInfo->cell, ue);
7792
7793 #ifdef EMTC_ENABLE   
7794    if(TRUE == ue->isEmtcUe)
7795    {
7796       cellSchd->apisEmtcUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
7797    }
7798    else
7799 #endif
7800    {
7801    cellSchd->apisUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
7802    }
7803
7804    /* DLFS UE Config */
7805    if (cellSchd->dl.isDlFreqSel)
7806    {
7807       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeDel(sCellInfo->cell, ue)) != ROK)
7808       {
7809          DU_LOG("\nERROR  -->  SCH : DLFS Scell del FAILED\n");
7810          return RFAILED;
7811       }
7812    }
7813
7814    rgSCHUtlFreeSBuf(sCellInfo->cell->instIdx,
7815          (Data**)(&(sCellInfo->sch)), (sizeof(RgSchCmnUe)));
7816
7817
7818    return ROK;
7819 }  /* rgSCHCmnRgrSCellUeDel */
7820  
7821 #endif
7822
7823 #ifdef RG_5GTF
7824 /**
7825  * @brief Handles 5gtf configuration for a UE
7826  *
7827  * @details
7828  *
7829  *     Function : rgSCHCmn5gtfUeCfg
7830  *
7831  *     Processing Steps:
7832  *
7833  *      - Return ROK
7834  *
7835  *  @param[in]  RgSchCellCb  *cell
7836  *  @param[in]  RgSchUeCb    *ue
7837  *  @param[in]  RgrUeCfg     *cfg
7838  *  @return  S16
7839  *      -# ROK
7840  *      -# RFAILED
7841  **/
7842 S16 rgSCHCmn5gtfUeCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeCfg *cfg)
7843 {
7844
7845    RgSchUeGrp *ue5gtfGrp;
7846    ue->ue5gtfCb.grpId = cfg->ue5gtfCfg.grpId;
7847    ue->ue5gtfCb.BeamId = cfg->ue5gtfCfg.BeamId;
7848    ue->ue5gtfCb.numCC = cfg->ue5gtfCfg.numCC;   
7849    ue->ue5gtfCb.mcs = cfg->ue5gtfCfg.mcs;
7850    ue->ue5gtfCb.maxPrb = cfg->ue5gtfCfg.maxPrb;
7851
7852    ue->ue5gtfCb.cqiRiPer = 100;
7853    /* 5gtf TODO: CQIs to start from (10,0)*/
7854    ue->ue5gtfCb.nxtCqiRiOccn.sfn = 10;
7855    ue->ue5gtfCb.nxtCqiRiOccn.slot = 0;
7856    ue->ue5gtfCb.rank = 1;
7857
7858    DU_LOG("\nINFO  -->  SCH : schd cfg at mac,%u,%u,%u,%u,%u\n",ue->ue5gtfCb.grpId,ue->ue5gtfCb.BeamId,ue->ue5gtfCb.numCC,
7859          ue->ue5gtfCb.mcs,ue->ue5gtfCb.maxPrb); 
7860
7861    ue5gtfGrp = &(cell->cell5gtfCb.ueGrp5gConf[ue->ue5gtfCb.BeamId]);
7862
7863    /* TODO_5GTF: Currently handling 1 group only. Need to update when multi group 
7864       scheduling comes into picture */
7865    if(ue5gtfGrp->beamBitMask & (1 << ue->ue5gtfCb.BeamId))
7866    {
7867       DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR Invalid beam id CRNTI:%d",cfg->crnti);
7868       return RFAILED;
7869    }
7870    ue5gtfGrp->beamBitMask |= (1 << ue->ue5gtfCb.BeamId);
7871
7872    return ROK;
7873 }
7874 #endif
7875
7876 /**
7877  * @brief UE initialisation for scheduler.
7878  *
7879  * @details
7880  *
7881  *     Function : rgSCHCmnRgrUeCfg
7882  *
7883  *     This functions intialises UE specific scheduler
7884  *     information
7885  *     0. Perform basic validations
7886  *     1. Allocate common sched UE cntrl blk
7887  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
7888  *     3. Perform UL cfg
7889  *     4. Perform DLFS cfg
7890  *
7891  *  @param[in]  RgSchCellCb  *cell
7892  *  @param[in]  RgSchUeCb    *ue
7893  *  @param[int] RgrUeCfg     *ueCfg
7894  *  @param[out] RgSchErrInfo *err
7895  *  @return  S16
7896  *      -# ROK
7897  *      -# RFAILED
7898  **/
7899 S16 rgSCHCmnRgrUeCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeCfg *ueCfg,RgSchErrInfo *err)
7900 {
7901    RgSchDlRbAlloc  *allocInfo;
7902    S16              ret;
7903    RgSchCmnCell     *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7904    RgSchCmnUe       *ueSchCmn;
7905    RgSchCmnUlUe     *ueUl;
7906    RgSchCmnDlUe     *ueDl;
7907    uint8_t          cnt;
7908    RgSchCmnAllocRecord  *allRcd;
7909    uint32_t         waitPer;
7910    uint32_t         idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
7911    RgSchUeCellInfo  *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7912
7913
7914    /* 1. Allocate Common sched control block */
7915    if((rgSCHUtlAllocSBuf(cell->instIdx,
7916                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
7917    {
7918       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for CRNTI:%d",ueCfg->crnti);
7919       err->errCause = RGSCHERR_SCH_CFG;
7920       return RFAILED;
7921    }
7922    ueSchCmn   = RG_SCH_CMN_GET_UE(ue,cell);
7923    ue->dl.ueDlCqiCfg = ueCfg->ueDlCqiCfg;
7924    pCellInfo->acqiCb.aCqiCfg = ueCfg->ueDlCqiCfg.aprdCqiCfg;
7925    if(ueCfg->ueCatEnum > 0 )
7926    {
7927      /*KWORK_FIX removed NULL chk for ueSchCmn*/
7928       ueSchCmn->cmn.ueCat = ueCfg->ueCatEnum - 1; 
7929    }
7930    else
7931    {
7932       ueSchCmn->cmn.ueCat = 0; /* Assuming enum values correctly set */
7933    }
7934    cmInitTimers(&ueSchCmn->cmn.tmr, 1);
7935
7936    /*2.  Perform UEs downlink configuration */
7937    ueDl = &ueSchCmn->dl;
7938    /* RACHO : store the rapId assigned for HandOver UE.
7939     * Append UE to handover list of cmnCell */
7940    if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
7941    {
7942       rgSCHCmnDelDedPreamble(cell, ueCfg->dedPreambleId.val);
7943       ueDl->rachInfo.hoRapId = ueCfg->dedPreambleId.val;
7944       cmLListAdd2Tail(&cellSchd->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
7945       ueDl->rachInfo.hoLnk.node = (PTR)ue;
7946    }
7947
7948    rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd);
7949
7950    if (ueCfg->txMode.pres == TRUE)
7951    {
7952       if ((ueCfg->txMode.txModeEnum == RGR_UE_TM_4) ||
7953             (ueCfg->txMode.txModeEnum == RGR_UE_TM_6))
7954       {
7955          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
7956       }
7957       if (ueCfg->txMode.txModeEnum == RGR_UE_TM_3)
7958       {
7959          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
7960       }
7961    }
7962    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
7963    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
7964    /*CA dev-Start*/
7965    uint8_t ri = 0;
7966    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
7967    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
7968             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
7969                   && (4 == ri))
7970    {
7971       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
7972    }
7973    else
7974    {
7975       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
7976    }
7977    /*CA dev-End*/
7978    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
7979 #ifdef LTE_TDD
7980    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
7981          rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]);
7982 #else
7983    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
7984          RGSCH_NUM_DL_HQ_PROC);
7985 #endif
7986 #ifdef EMTC_ENABLE   
7987    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
7988 #else
7989    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
7990 #endif 
7991      /* if none of the DL and UL AMBR are configured then fail the configuration
7992     */     
7993    if((ueCfg->ueQosCfg.dlAmbr == 0) && (ueCfg->ueQosCfg.ueBr == 0))
7994    {
7995       DU_LOG("\nERROR  -->  SCH : UL Ambr and DL Ambr are"
7996          "configured as 0 for CRNTI:%d",ueCfg->crnti);
7997       err->errCause = RGSCHERR_SCH_CFG;
7998       return RFAILED;
7999    }
8000    /* DL ambr */
8001    ue->dl.ambrCfgd = (ueCfg->ueQosCfg.dlAmbr * RG_SCH_CMN_REFRESH_TIME)/100;
8002
8003    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
8004    allocInfo->rnti = ue->ueId;
8005
8006    /* Initializing the lastCfi value to current cfi value */
8007    ueDl->lastCfi = cellSchd->dl.currCfi;
8008 #ifdef EMTC_ENABLE
8009    if(cell->emtcEnable && ue->isEmtcUe)
8010    {
8011       if ((cellSchd->apisEmtcDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8012       {
8013          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8014          return RFAILED;
8015       }
8016
8017    }
8018    else
8019 #endif
8020    {
8021       if ((cellSchd->apisDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8022       {
8023          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8024          return RFAILED;
8025       }
8026    }
8027
8028
8029
8030    /* 3. Initialize ul part */
8031    ueUl     = &ueSchCmn->ul;
8032
8033    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd,
8034             cell->isCpUlExtend);
8035
8036    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
8037                                RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
8038
8039    ue->ul.cfgdAmbr = (ueCfg->ueQosCfg.ueBr * RG_SCH_CMN_REFRESH_TIME)/100;
8040    ue->ul.effAmbr = ue->ul.cfgdAmbr;
8041    RGSCHCPYTIMEINFO(cell->crntTime, ue->ul.ulTransTime);
8042
8043    /* Allocate UL BSR allocation tracking List */
8044    cmLListInit(&ueUl->ulAllocLst);
8045
8046    for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
8047    {
8048       if((rgSCHUtlAllocSBuf(cell->instIdx,
8049                   (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
8050       {
8051          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED"
8052                    "for CRNTI:%d",ueCfg->crnti);
8053          err->errCause = RGSCHERR_SCH_CFG;
8054          return RFAILED;
8055       }
8056       allRcd->allocTime = cell->crntTime;
8057       cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
8058       allRcd->lnk.node = (PTR)allRcd;
8059    }
8060    /* Allocate common sch cntrl blocks for LCGs */
8061    for (cnt=0; cnt<RGSCH_MAX_LCG_PER_UE; cnt++)
8062    {
8063       ret = rgSCHUtlAllocSBuf(cell->instIdx,
8064             (Data**)&(ue->ul.lcgArr[cnt].sch), (sizeof(RgSchCmnLcg)));
8065       if (ret != ROK)
8066       {
8067          DU_LOG("\nERROR  -->  SCH : SCH struct alloc failed for CRNTI:%d",ueCfg->crnti);
8068          err->errCause = RGSCHERR_SCH_CFG;
8069          return (ret);
8070       }
8071    }
8072    /* After initialising UL part, do power related init */
8073    ret = rgSCHPwrUeCfg(cell, ue, ueCfg);
8074    if (ret != ROK)
8075    {
8076       DU_LOG("\nERROR  -->  SCH : Could not do "
8077          "power config for UE CRNTI:%d",ueCfg->crnti);
8078       return RFAILED;
8079    }
8080 #ifdef LTEMAC_SPS
8081    ret = rgSCHCmnSpsUeCfg(cell, ue, ueCfg, err);
8082    if (ret != ROK)
8083    {
8084       DU_LOG("\nERROR  -->  SCH : Could not do "
8085          "SPS config for CRNTI:%d",ueCfg->crnti);
8086       return RFAILED;
8087    }
8088 #endif /* LTEMAC_SPS */
8089
8090 #ifdef EMTC_ENABLE   
8091    if(TRUE == ue->isEmtcUe)
8092    {
8093       if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
8094       {
8095          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
8096                   "for CRNTI:%d",ueCfg->crnti);
8097          return RFAILED;
8098       }
8099    }
8100    else
8101 #endif
8102    {
8103    if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
8104    {
8105       DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
8106                "for CRNTI:%d",ueCfg->crnti);
8107       return RFAILED;
8108    }
8109    }
8110
8111    /* DLFS UE Config */
8112    if (cellSchd->dl.isDlFreqSel)
8113    {
8114       if ((cellSchd->apisDlfs->rgSCHDlfsUeCfg(cell, ue, ueCfg, err)) != ROK)
8115       {
8116          DU_LOG("\nERROR  -->  SCH : DLFS UE config FAILED"
8117                    "for CRNTI:%d",ueCfg->crnti);
8118          return RFAILED;
8119       }
8120    }
8121
8122    /* Fix: syed align multiple UEs to refresh at same time */
8123    rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
8124    /* Start UE Qos Refresh Timer */
8125    rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
8126 #ifdef RG_5GTF
8127    rgSCHCmn5gtfUeCfg(cell, ue, ueCfg);
8128 #endif
8129
8130    return ROK;
8131 }  /* rgSCHCmnRgrUeCfg */
8132
8133 /**
8134  * @brief UE TX mode reconfiguration handler.
8135  *
8136  * @details
8137  *
8138  *     Function : rgSCHCmnDlHdlTxModeRecfg
8139  *
8140  *     This functions updates UE specific scheduler
8141  *     information upon UE reconfiguration.
8142  *
8143  *  @param[in]  RgSchUeCb    *ue
8144  *  @param[in] RgrUeRecfg   *ueRecfg
8145  *  @return  Void
8146  **/
8147 #ifdef TFU_UPGRADE
8148 static Void rgSCHCmnDlHdlTxModeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,uint8_t numTxPorts)
8149 #else
8150 static Void rgSCHCmnDlHdlTxModeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg)
8151 #endif
8152 {
8153    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
8154
8155    if (ueRecfg->txMode.pres != PRSNT_NODEF)
8156    {
8157       return;
8158    }
8159    /* ccpu00140894- Starting Timer for TxMode Transition Completion*/
8160    ue->txModeTransCmplt =FALSE;
8161    rgSCHTmrStartTmr (ue->cell, ue, RG_SCH_TMR_TXMODE_TRNSTN, RG_SCH_TXMODE_TRANS_TIMER);
8162    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_CMPLT)
8163    {
8164       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell,
8165                                 RG_SCH_CMN_TD_TXMODE_RECFG);
8166      /* MS_WORKAROUND for ccpu00123186 MIMO Fix Start: need to set FORCE TD bitmap based on TX mode */
8167      ueDl->mimoInfo.ri = 1;
8168      if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8169           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
8170       {
8171          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8172       }
8173       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
8174       {
8175          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8176       }
8177       /* MIMO Fix End: need to set FORCE TD bitmap based on TX mode */
8178       return;
8179    }
8180    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_START)
8181    {
8182       /* start afresh forceTD masking */
8183       RG_SCH_CMN_INIT_FORCE_TD(ue, cell, 0);
8184       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_TXMODE_RECFG);
8185       /* Intialize MIMO related parameters of UE */
8186
8187 #ifdef TFU_UPGRADE
8188       if(ueRecfg->txMode.pres)
8189       {
8190          if((ueRecfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
8191                (ueRecfg->txMode.txModeEnum ==RGR_UE_TM_4))
8192          {
8193             if(ueRecfg->ueCodeBookRstRecfg.pres)
8194             {
8195                ueDl->mimoInfo.ri =
8196                   rgSCHCmnComputeRank(ueRecfg->txMode.txModeEnum,
8197                     ueRecfg->ueCodeBookRstRecfg.pmiBitMap, numTxPorts);
8198             }
8199             else
8200             {
8201                ueDl->mimoInfo.ri = 1;
8202             }
8203          }
8204          else
8205          {
8206             ueDl->mimoInfo.ri = 1;
8207          }
8208       }
8209       else
8210       {
8211          ueDl->mimoInfo.ri = 1;
8212       }
8213 #else
8214       ueDl->mimoInfo.ri = 1;
8215 #endif /* TFU_UPGRADE */
8216       if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8217           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
8218       {
8219          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8220       }
8221       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
8222       {
8223          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8224       }
8225       return;
8226    }
8227 }
8228 /***********************************************************
8229  *
8230  *     Func : rgSCHCmnUpdUeMimoInfo
8231  *
8232  *     Desc : Updates UL and DL Ue Information
8233  *
8234  *     Ret  :
8235  *
8236  *     Notes:
8237  *
8238  *     File :
8239  *
8240  **********************************************************/
8241 static Void rgSCHCmnUpdUeMimoInfo(RgrUeCfg *ueCfg,RgSchCmnDlUe *ueDl,RgSchCellCb  *cell,RgSchCmnCell *cellSchd)
8242 {
8243 #ifdef TFU_UPGRADE
8244    if(ueCfg->txMode.pres)
8245    {
8246       if((ueCfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
8247             (ueCfg->txMode.txModeEnum ==RGR_UE_TM_4))
8248       {
8249          if(ueCfg->ueCodeBookRstCfg.pres)
8250          {
8251             ueDl->mimoInfo.ri =
8252                rgSCHCmnComputeRank(ueCfg->txMode.txModeEnum,
8253                  ueCfg->ueCodeBookRstCfg.pmiBitMap, cell->numTxAntPorts);
8254          }
8255          else
8256          {
8257             ueDl->mimoInfo.ri = 1;
8258          }
8259       }
8260       else
8261       {
8262          ueDl->mimoInfo.ri = 1;
8263       }
8264    }
8265    else
8266    {
8267       ueDl->mimoInfo.ri = 1;
8268    }
8269
8270 #else
8271    ueDl->mimoInfo.ri = 1;
8272 #endif /*TFU_UPGRADE */
8273    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
8274    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
8275
8276    return;
8277 }
8278 /***********************************************************
8279  *
8280  *     Func : rgSCHCmnUpdUeUlCqiInfo
8281  *
8282  *     Desc : Updates UL and DL Ue Information
8283  *
8284  *     Ret  :
8285  *
8286  *     Notes:
8287  *
8288  *     File :
8289  *
8290  **********************************************************/
8291 static Void rgSCHCmnUpdUeUlCqiInfo(RgSchCellCb *cell,RgSchUeCb *ue,RgSchCmnUlUe *ueUl,RgSchCmnUe *ueSchCmn,RgSchCmnCell *cellSchd,Bool isEcp)
8292 {
8293
8294 #ifdef TFU_UPGRADE
8295    if(ue->srsCb.srsCfg.type  ==  RGR_SCH_SRS_SETUP)
8296    {
8297      if(ue->ul.ulTxAntSel.pres)
8298      {
8299        ueUl->crntUlCqi[ue->srsCb.selectedAnt] = cellSchd->ul.dfltUlCqi;
8300        ueUl->validUlCqi = ueUl->crntUlCqi[ue->srsCb.selectedAnt];
8301      }
8302      else
8303      {
8304        ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
8305        ueUl->validUlCqi =  ueUl->crntUlCqi[0];
8306      }
8307       ue->validTxAnt = ue->srsCb.selectedAnt;
8308    }
8309    else
8310    {
8311       ueUl->validUlCqi = cellSchd->ul.dfltUlCqi;
8312       ue->validTxAnt = 0;
8313    }
8314 #ifdef UL_LA
8315    ueUl->ulLaCb.cqiBasediTbs = rgSchCmnUlCqiToTbsTbl[isEcp]
8316                                                 [ueUl->validUlCqi] * 100;   
8317    ueUl->ulLaCb.deltaiTbs = 0;
8318 #endif
8319
8320 #else
8321    ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
8322 #endif /*TFU_UPGRADE */
8323    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
8324    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
8325    {
8326       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
8327    }
8328    else
8329    {
8330       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
8331    }
8332
8333    return;
8334 }
8335 /***********************************************************
8336  *
8337  *     Func : rgSCHCmnUpdUeCatCfg
8338  *
8339  *     Desc : Updates UL and DL Ue Information
8340  *
8341  *     Ret  :
8342  *
8343  *     Notes:
8344  *
8345  *     File :
8346  *
8347  **********************************************************/
8348 static Void rgSCHCmnUpdUeCatCfg(RgSchUeCb *ue,RgSchCellCb  *cell)
8349 {
8350    RgSchDlHqEnt *hqE = NULLP;
8351    RgSchCmnUlUe *ueUl     = RG_SCH_CMN_GET_UL_UE(ue,cell);
8352    RgSchCmnDlUe *ueDl     = RG_SCH_CMN_GET_DL_UE(ue,cell);
8353    RgSchCmnUe   *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
8354    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8355
8356
8357    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
8358    
8359    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
8360    /*CA dev-Start*/
8361    uint8_t ri = 0;
8362    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
8363    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
8364             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
8365          && (RG_SCH_MAX_TX_LYRS_4 == ri))
8366    {
8367       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
8368    }
8369    else
8370    {
8371       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
8372    }
8373    /*CA dev-End*/
8374    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
8375                            hqE->numHqPrcs);
8376    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
8377    {
8378       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
8379    }
8380    else
8381    {
8382       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
8383    }
8384    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
8385                    RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
8386    return;
8387 }
8388
8389 /**
8390  * @brief UE reconfiguration for scheduler.
8391  *
8392  * @details
8393  *
8394  *     Function : rgSChCmnRgrUeRecfg
8395  *
8396  *     This functions updates UE specific scheduler
8397  *     information upon UE reconfiguration.
8398  *
8399  *  @param[in]  RgSchCellCb  *cell
8400  *  @param[in]  RgSchUeCb    *ue
8401  *  @param[int] RgrUeRecfg   *ueRecfg
8402  *  @param[out] RgSchErrInfo *err
8403  *  @return  S16
8404  *      -# ROK
8405  *      -# RFAILED
8406  **/
8407 S16 rgSCHCmnRgrUeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,RgSchErrInfo *err)
8408 {
8409    RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
8410    uint32_t     waitPer;
8411
8412    /* Basic validations */
8413    if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
8414    {
8415 #ifdef TFU_UPGRADE
8416       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, cell->numTxAntPorts);
8417 #else
8418       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg);
8419 #endif /* TFU_UPGRADE */
8420    }
8421    if(ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG)
8422    {
8423       ue->csgMmbrSta = ueRecfg->csgMmbrSta;
8424    }
8425    /* Changes for UE Category reconfiguration feature */
8426    if(ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
8427    {
8428        rgSCHCmnUpdUeCatCfg(ue, cell);
8429    }
8430    if (ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG)
8431    {
8432       RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
8433       pCellInfo->acqiCb.aCqiCfg = ueRecfg->aprdDlCqiRecfg;
8434    }
8435 #ifndef TFU_UPGRADE
8436    if (ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG)
8437    {
8438       if ((ueRecfg->prdDlCqiRecfg.pres == TRUE)
8439             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD10)
8440             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD20))
8441       {
8442          DU_LOG("\nERROR  -->  SCH : Unsupported periodic CQI "
8443             "reporting mode %d for old CRNIT:%d", 
8444             (int)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->oldCrnti);
8445          err->errCause = RGSCHERR_SCH_CFG;
8446          return RFAILED;
8447       }
8448      ue->dl.ueDlCqiCfg.prdCqiCfg = ueRecfg->prdDlCqiRecfg;
8449    }
8450 #endif
8451
8452    if (ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG)
8453    {
8454       if (rgSCHPwrUeRecfg(cell, ue, ueRecfg) != ROK)
8455       {
8456          DU_LOG("\nERROR  -->  SCH : Power Reconfiguration Failed for OLD CRNTI:%d",ueRecfg->oldCrnti);
8457          return RFAILED;
8458       }
8459    }
8460
8461    if (ueRecfg->ueRecfgTypes & RGR_UE_QOS_RECFG)
8462    {
8463       /* Uplink Sched related Initialization */
8464       if ((ueRecfg->ueQosRecfg.dlAmbr == 0) && (ueRecfg->ueQosRecfg.ueBr == 0))
8465       {
8466          DU_LOG("\nERROR  -->  SCH : Ul Ambr and DL Ambr "
8467             "configured as 0 for OLD CRNTI:%d",ueRecfg->oldCrnti);
8468          err->errCause = RGSCHERR_SCH_CFG;
8469          return RFAILED;
8470       }
8471       ue->ul.cfgdAmbr = (ueRecfg->ueQosRecfg.ueBr * \
8472       RG_SCH_CMN_REFRESH_TIME)/100;
8473       /* Downlink Sched related Initialization */
8474       ue->dl.ambrCfgd = (ueRecfg->ueQosRecfg.dlAmbr * \
8475       RG_SCH_CMN_REFRESH_TIME)/100;
8476       /* Fix: syed Update the effAmbr and effUeBR fields w.r.t the
8477        * new QOS configuration */
8478       rgSCHCmnDelUeFrmRefreshQ(cell, ue);
8479       /* Fix: syed align multiple UEs to refresh at same time */
8480       rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
8481       rgSCHCmnApplyUeRefresh(cell, ue);
8482       rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
8483    }
8484 #ifdef EMTC_ENABLE   
8485    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
8486    {
8487       if ((cellSchCmn->apisEmtcUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8488       {
8489          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8490          return RFAILED;
8491       }
8492       if ((cellSchCmn->apisEmtcDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8493       {
8494          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8495          return RFAILED;
8496       }
8497    }
8498    else
8499 #endif
8500    {
8501       if ((cellSchCmn->apisUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8502       {
8503          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8504          return RFAILED;
8505       }
8506       if ((cellSchCmn->apisDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8507       {
8508          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8509          return RFAILED;
8510       }
8511    }
8512    /* DLFS UE Config */
8513    if (cellSchCmn->dl.isDlFreqSel)
8514    {
8515       if ((cellSchCmn->apisDlfs->rgSCHDlfsUeRecfg(cell, ue, \
8516          ueRecfg, err)) != ROK)
8517       {
8518          DU_LOG("\nERROR  -->  SCH : DLFS UE re-config FAILED for CRNTI:%d",ue->ueId);
8519          return RFAILED;
8520       }
8521    }
8522
8523 #ifdef LTEMAC_SPS
8524    /* Invoke re-configuration on SPS module */
8525    if (rgSCHCmnSpsUeRecfg(cell, ue, ueRecfg, err) != ROK)
8526    {
8527       DU_LOG("\nERROR  -->  SCH : DL SPS ReCFG FAILED for UE CRNTI:%d", ue->ueId);
8528       return RFAILED;
8529    }
8530 #endif
8531
8532    return ROK;
8533 }  /* rgSCHCmnRgrUeRecfg*/
8534
8535 /***********************************************************
8536  *
8537  *     Func : rgSCHCmnUlUeDelAllocs
8538  *
8539  *     Desc : Deletion of all UE allocations.
8540  *
8541  *     Ret  :
8542  *
8543  *     Notes:
8544  *
8545  *     File :
8546  *
8547  **********************************************************/
8548 static Void rgSCHCmnUlUeDelAllocs(RgSchCellCb *cell,RgSchUeCb *ue)
8549 {
8550    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
8551    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
8552    uint8_t i;
8553 #ifdef LTEMAC_SPS
8554    RgSchCmnUlUeSpsInfo   *ulSpsUe   = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
8555 #endif
8556
8557    for (i = 0; i < ueUl->hqEnt.numHqPrcs; ++i)
8558    {
8559       RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, i);
8560
8561 #ifdef ERRCLS_KW
8562       /* proc can't be NULL here */
8563       if (proc)
8564 #endif
8565       {
8566          /* R8 Upgrade */
8567          proc->ndi = 0;
8568          if (proc->alloc)
8569          {
8570             /* Added Insure Fixes Of reading Dangling memory.NULLed crntAlloc */
8571 #ifdef LTEMAC_SPS
8572             if(proc->alloc == ulSpsUe->ulSpsSchdInfo.crntAlloc)
8573             {
8574                ulSpsUe->ulSpsSchdInfo.crntAlloc = NULLP;
8575                ulSpsUe->ulSpsSchdInfo.crntAllocSf = NULLP;
8576             }
8577 #endif
8578 #ifdef EMTC_ENABLE
8579             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
8580                   proc->alloc,ue->isEmtcUe);
8581 #else
8582             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
8583                   proc->alloc);
8584 #endif
8585             /* PHY probably needn't be intimated since
8586              * whatever intimation it needs happens at the last minute
8587              */
8588          }
8589          /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
8590           * from adaptive retx List. */
8591          if (proc->reTxLnk.node)
8592          {
8593             {
8594                //TODO_SID: Need to take care
8595                cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); 
8596                proc->reTxLnk.node = (PTR)NULLP;
8597             }
8598          }
8599       }
8600    }
8601    return;
8602 }
8603
8604 /***********************************************************
8605  *
8606  *     Func : rgSCHCmnDelUeFrmRefreshQ
8607  *
8608  *     Desc : Adds a UE to refresh queue, so that the UE is
8609  *            periodically triggered to refresh it's GBR and
8610  *            AMBR values.
8611  *
8612  *     Ret  :
8613  *
8614  *     Notes:
8615  *
8616  *     File :
8617  *
8618  **********************************************************/
8619 static Void rgSCHCmnDelUeFrmRefreshQ(RgSchCellCb *cell,RgSchUeCb *ue)
8620 {
8621    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
8622    CmTmrArg       arg;
8623    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
8624
8625
8626 #ifdef RGL_SPECIFIC_CHANGES
8627    if(ue->refreshOffset < RGSCH_MAX_REFRESH_GRPSZ)
8628    {
8629       if(cell->refreshUeCnt[ue->refreshOffset])
8630       {
8631          cell->refreshUeCnt[ue->refreshOffset]--;
8632       }
8633    }
8634 #endif
8635
8636
8637    memset(&arg, 0, sizeof(arg));
8638    arg.tqCp   = &sched->tmrTqCp;
8639    arg.tq     = sched->tmrTq;
8640    arg.timers = &ueSchd->tmr;
8641    arg.cb     = (PTR)ue;
8642    arg.tNum   = 0;
8643    arg.max    = 1;
8644    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
8645
8646    cmRmvCbTq(&arg);
8647    return;
8648 }
8649
8650 /***********************************************************
8651  *
8652  *     Func : rgSCHCmnUeCcchSduDel
8653  *
8654  *     Desc : Clear CCCH SDU scheduling context.
8655  *
8656  *     Ret  :
8657  *
8658  *     Notes:
8659  *
8660  *     File :
8661  *
8662  **********************************************************/
8663 static Void rgSCHCmnUeCcchSduDel(RgSchCellCb  *cell,RgSchUeCb *ueCb)
8664 {
8665    RgSchDlHqEnt      *hqE = NULLP;
8666    RgSchDlHqProcCb   *ccchSduHqP = NULLP;
8667    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
8668
8669
8670    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
8671    if (hqE == NULLP)
8672    {
8673       return;
8674    }
8675    ccchSduHqP = hqE->ccchSduProc;
8676    if(ueCb->ccchSduLnk.node != NULLP)
8677    {
8678       /* Remove the ccchSduProc if it is in the Tx list */
8679       cmLListDelFrm(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
8680       ueCb->ccchSduLnk.node = NULLP;   
8681    }
8682    else if(ccchSduHqP != NULLP)
8683    {
8684       /* Fix for crash due to stale pdcch. Release ccch pdcch*/
8685       if(ccchSduHqP->pdcch)
8686       {
8687          cmLListDelFrm(&ccchSduHqP->subFrm->pdcchInfo.pdcchs,
8688                &ccchSduHqP->pdcch->lnk);
8689          cmLListAdd2Tail(&cell->pdcchLst, &ccchSduHqP->pdcch->lnk);
8690          ccchSduHqP->pdcch = NULLP;
8691       }
8692       if(ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node != NULLP)
8693       {
8694          /* Remove the ccchSduProc if it is in the retx list */
8695          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
8696           &ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk);
8697          /* ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node = NULLP; */
8698          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
8699       }
8700       else if ((ccchSduHqP->subFrm != NULLP) &&
8701        (ccchSduHqP->hqPSfLnk.node != NULLP))
8702       {
8703          rgSCHUtlDlHqPTbRmvFrmTx(ccchSduHqP->subFrm, 
8704                ccchSduHqP, 0, FALSE);
8705          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
8706       }
8707    }   
8708    return;
8709 }
8710
8711
8712
8713
8714 /**
8715  * @brief UE deletion for scheduler.
8716  *
8717  * @details
8718  *
8719  *     Function : rgSCHCmnUeDel
8720  *
8721  *     This functions deletes all scheduler information
8722  *     pertaining to an UE.
8723  *
8724  *  @param[in]  RgSchCellCb  *cell
8725  *  @param[in]  RgSchUeCb    *ue
8726  *  @return  Void
8727  **/
8728 Void rgSCHCmnUeDel(RgSchCellCb *cell,RgSchUeCb *ue)
8729 {
8730    RgSchDlHqEnt         *hqE = NULLP;
8731    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
8732    CmLList              *node;
8733    RgSchCmnAllocRecord  *allRcd;
8734    uint8_t              cnt;
8735    RgSchCmnCell         *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
8736    uint32_t             idx = 0;
8737
8738    if (RG_SCH_CMN_GET_UE(ue,cell) == NULLP)
8739    {
8740       /* Common scheduler config has not happened yet */
8741       return;
8742    }
8743    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
8744    if(hqE)
8745    {
8746       /* UE Free can be triggered before MSG4 done when dlHqE is not updated */
8747 #ifdef EMTC_ENABLE
8748       if(ue->isEmtcUe)
8749       {
8750          rgSCHEmtcCmnUeCcchSduDel(cell, ue);
8751       }
8752       else
8753 #endif
8754      {    
8755          rgSCHCmnUeCcchSduDel(cell, ue);
8756      }
8757    }
8758    rgSCHCmnDelUeFrmRefreshQ(cell, ue);
8759
8760    rgSCHCmnUlUeDelAllocs(cell, ue);
8761
8762    rgSCHCmnDelRachInfo(cell, ue);
8763
8764 #ifdef EMTC_ENABLE   
8765    if(TRUE == ue->isEmtcUe)
8766    {
8767       cellSchCmn->apisEmtcUl->rgSCHFreeUlUe(cell, ue);
8768    }
8769    else
8770 #endif
8771    {
8772    cellSchCmn->apisUl->rgSCHFreeUlUe(cell, ue);
8773    }
8774 #ifdef LTE_ADV
8775    if (ue->numSCells)
8776    {
8777       for(idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
8778       {
8779          if(ue->cellInfo[idx] != NULLP) 
8780          {
8781             rgSCHSCellDelUeSCell(cell,ue,idx);
8782          }
8783       }
8784
8785    }
8786 #endif
8787 #ifdef EMTC_ENABLE
8788    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
8789    {
8790       cellSchCmn->apisEmtcDl->rgSCHFreeDlUe(cell, ue);
8791    }
8792    else
8793 #endif
8794    {
8795       cellSchCmn->apisDl->rgSCHFreeDlUe(cell, ue);
8796    }
8797    rgSCHPwrUeDel(cell, ue);
8798
8799 #ifdef LTEMAC_SPS
8800    rgSCHCmnSpsUeDel(cell, ue);
8801 #endif /* LTEMAC_SPS*/
8802
8803    /* CA Dev Start*/
8804    rgSchCmnDlSfHqDel(ue, cell);
8805    /* CA Dev End*/
8806    /* DLFS UE delete */
8807    if (cellSchCmn->dl.isDlFreqSel)
8808    {
8809       cellSchCmn->apisDlfs->rgSCHDlfsUeDel(cell, ue);
8810    }
8811    node = ueUl->ulAllocLst.first;
8812
8813 /* ccpu00117052 - MOD - Passing double pointer in all the places of
8814    rgSCHUtlFreeSBuf function call for proper NULLP assignment*/
8815    while(node)
8816    {
8817       allRcd = (RgSchCmnAllocRecord *)node->node;
8818       node = node->next;
8819       cmLListDelFrm(&ueUl->ulAllocLst, &allRcd->lnk);
8820       rgSCHUtlFreeSBuf(cell->instIdx,
8821          (Data**)(&allRcd), (sizeof(RgSchCmnAllocRecord)));
8822    }
8823
8824    for(cnt = 0; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
8825    {
8826       if (ue->ul.lcgArr[cnt].sch != NULLP)
8827       {
8828          rgSCHUtlFreeSBuf(cell->instIdx,
8829             (Data**)(&(ue->ul.lcgArr[cnt].sch)), (sizeof(RgSchCmnLcg)));
8830       }
8831    }
8832
8833    /* Fix : syed Moved hqEnt deinit to rgSCHCmnDlDeInitHqEnt */
8834    idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId) & (CM_LTE_MAX_CELLS - 1));
8835    rgSCHUtlFreeSBuf(cell->instIdx,
8836          (Data**)(&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch))), (sizeof(RgSchCmnUe)));
8837    return;
8838 }  /* rgSCHCmnUeDel */
8839
8840 \f
8841 /**
8842  * @brief This function handles the common code rate configurations
8843  *        done as part of RgrCellCfg/RgrCellRecfg.
8844  *
8845  * @details
8846  *
8847  *     Function: rgSCHCmnDlCnsdrCmnRt
8848  *     Purpose:  This function handles the common code rate configurations
8849  *        done as part of RgrCellCfg/RgrCellRecfg.
8850  *
8851  *     Invoked by: Scheduler
8852  *
8853  *  @param[in]  RgSchCellCb                *cell
8854  *  @param[in]  RgrDlCmnCodeRateCfg     *dlCmnCodeRate
8855  *  @return     S16
8856  *
8857  **/
8858 static S16 rgSCHCmnDlCnsdrCmnRt(RgSchCellCb *cell,RgrDlCmnCodeRateCfg  *dlCmnCodeRate)
8859 {
8860    RgSchCmnCell *cellDl = RG_SCH_CMN_GET_CELL(cell);
8861    uint32_t     bitsPerRb;
8862    uint32_t     bitsPer2Rb;
8863    uint32_t     bitsPer3Rb;
8864    uint8_t      i, rbNum;
8865    uint32_t     pdcchBits;
8866
8867
8868    /* code rate is bits per 1024 phy bits, since modl'n scheme is 2. it is
8869     * bits per 1024/2 REs */
8870    if (dlCmnCodeRate->bcchPchRaCodeRate != 0)
8871    {
8872       bitsPerRb = ((dlCmnCodeRate->bcchPchRaCodeRate * 2) *
8873             cellDl->dl.noResPerRb[3])/1024;
8874    }
8875    else
8876    {
8877       bitsPerRb = ((RG_SCH_CMN_DEF_BCCHPCCH_CODERATE * 2) *
8878             cellDl->dl.noResPerRb[3])/1024;
8879    }
8880    /* Store bitsPerRb in cellDl->dl to use later to determine
8881     * Number of RBs for UEs with SI-RNTI, P-RNTI and RA-RNTI */
8882    cellDl->dl.bitsPerRb = bitsPerRb;
8883    /* ccpu00115595 end*/
8884    /* calculate the ITbs for 2 RBs. Initialize ITbs to MAX value */
8885    i = 0;
8886    rbNum = 2;
8887    bitsPer2Rb = bitsPerRb * rbNum;
8888    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer2Rb))
8889       i++;
8890
8891    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs2Rbs = 0) :
8892       (cellDl->dl.cmnChITbs.iTbs2Rbs = i-1);
8893
8894    /* calculate the ITbs for 3 RBs. Initialize ITbs to MAX value */
8895    i = 0;
8896    rbNum = 3;
8897    bitsPer3Rb = bitsPerRb * rbNum;
8898    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer3Rb))
8899          i++;
8900
8901    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs3Rbs = 0) :
8902       (cellDl->dl.cmnChITbs.iTbs3Rbs = i-1);
8903
8904
8905    pdcchBits = 1 + /* Flag for format0/format1a differentiation */
8906       1 + /* Localized/distributed VRB assignment flag */
8907       5 + /* For mcs */
8908 #ifndef LTE_TDD
8909       3 + /* Harq process Id */
8910 #else
8911       4 + /* Harq process Id */
8912       2 + /* UL Index or DAI */
8913 #endif
8914       1 + /* New Data Indicator */
8915       2 + /* For RV */
8916       2 + /* For tpc */
8917       1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
8918                (cell->bwCfg.dlTotalBw + 1))/2);
8919    /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
8920       Since VRB is local */
8921    /* For TDD consider DAI */
8922
8923    /* Convert the pdcchBits to actual pdcchBits required for transmission */
8924    if (dlCmnCodeRate->pdcchCodeRate != 0)
8925    {
8926       pdcchBits = (pdcchBits * 1024)/dlCmnCodeRate->pdcchCodeRate;
8927       if (pdcchBits <= 288) /* 288 : Num of pdcch bits for aggrLvl=4 */
8928       {
8929          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
8930       }
8931       else                  /* 576 : Num of pdcch bits for aggrLvl=8 */
8932       {
8933          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL8;
8934       }
8935    }
8936    else
8937    {
8938       cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
8939    }
8940    if (dlCmnCodeRate->ccchCqi == 0)
8941    {
8942       return RFAILED;
8943    }
8944    else
8945    {
8946       cellDl->dl.ccchCqi = dlCmnCodeRate->ccchCqi;
8947    }
8948    return ROK;
8949 }
8950
8951 #ifdef LTE_TDD
8952 /**
8953  * @brief This function handles the configuration of cell for the first
8954  *        time by the scheduler.
8955  *
8956  * @details
8957  *
8958  *     Function: rgSCHCmnDlRgrCellCfg
8959  *     Purpose:  Configuration received is stored into the data structures
8960  *               Also, update the scheduler with the number of frames of
8961  *               RACH preamble transmission.
8962  *
8963  *     Invoked by: BO and Scheduler
8964  *
8965  *  @param[in]  RgSchCellCb*     cell
8966  *  @param[in]  RgrCellCfg*      cfg
8967  *  @return     S16
8968  *
8969  **/
8970 static S16 rgSCHCmnDlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cfg,RgSchErrInfo *err)
8971 {
8972    RgSchCmnCell         *cellSch;
8973    uint8_t              cp;
8974    uint8_t              sfCount;
8975    uint8_t              numPdcchSym;
8976    uint8_t              noSymPerSlot;
8977    uint8_t              maxDlSubfrms = cell->numDlSubfrms;
8978    uint8_t              splSubfrmIdx = cfg->spclSfCfgIdx;
8979    uint8_t              swPtCnt = 0;
8980    Bool                 isSplfrm;
8981    RgSchTddSubfrmInfo   subfrmInfo = rgSchTddMaxUlSubfrmTbl[cell->ulDlCfgIdx];
8982    S16                  ret;
8983    uint8_t              splSfIdx;
8984    uint8_t              antPortIdx;
8985    uint8_t              numCrs;
8986    uint8_t              cfi;  
8987    uint8_t              cfiIdx;
8988    RgSchDlSf            *sf;
8989    uint8_t              splSfCfi;
8990    uint8_t              mPhich;
8991
8992    
8993
8994    cellSch = RG_SCH_CMN_GET_CELL(cell);
8995    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->\
8996                                                   rachCfg.preambleFormat];
8997    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
8998    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
8999    
9000    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
9001                        3 TTI (MAX L1+L2 processing delay at the UE) */
9002    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
9003                                  rgSchCmnHarqRtt[cell->ulDlCfgIdx] + 3; 
9004    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9005    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9006    if (cfg->maxUePerDlSf == 0)
9007    {
9008       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9009    }
9010    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
9011    {
9012       return RFAILED;
9013    }
9014
9015
9016    if (cell->bwCfg.dlTotalBw <= 10)
9017    {
9018       cfiIdx = 1;
9019       numPdcchSym = 2;
9020    }
9021    else
9022    {
9023       cfiIdx = 0;
9024       numPdcchSym = 1;
9025    }
9026    /* DwPTS Scheduling Changes Start */
9027    cellSch->dl.splSfCfg  = splSubfrmIdx;
9028  
9029    if (cfg->isCpDlExtend == TRUE)
9030    {
9031       if((0 == splSubfrmIdx) || (4 == splSubfrmIdx) ||
9032          (7 == splSubfrmIdx) || (8 == splSubfrmIdx)
9033         )
9034       {
9035          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
9036       }
9037       else
9038       {
9039          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
9040       }
9041    }
9042    else
9043    {
9044       /* Refer to 36.213 Section 7.1.7 */
9045       if((0 == splSubfrmIdx) || (5 == splSubfrmIdx))
9046       {
9047          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
9048       }
9049       else
9050       {
9051          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
9052       }
9053    }
9054    /* DwPTS Scheduling Changes End */  
9055
9056    splSfCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
9057    RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
9058    
9059    for (sfCount = 0; sfCount < maxDlSubfrms; sfCount++)
9060    {
9061       sf = cell->subFrms[sfCount];
9062       /* Sfcount matches the first special subframe occurs at Index 0
9063             * or subsequent special subframes */
9064       if(subfrmInfo.switchPoints == 1)
9065       {
9066          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
9067                                  RG_SCH_CMN_10_MS_PRD, &subfrmInfo);
9068       }
9069       else
9070       {
9071          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
9072                                  RG_SCH_CMN_5_MS_PRD, &subfrmInfo);
9073       }
9074       if(isSplfrm == TRUE)
9075       {
9076          swPtCnt++;
9077          /* DwPTS Scheduling Changes Start */        
9078          if (cell->splSubfrmCfg.isDlDataAllowed == TRUE)
9079          {
9080             sf->sfType = RG_SCH_SPL_SF_DATA;
9081          }
9082          else
9083          {
9084             sf->sfType = RG_SCH_SPL_SF_NO_DATA;
9085          }
9086          /* DwPTS Scheduling Changes End */
9087       }
9088       else
9089       {
9090          /* DwPTS Scheduling Changes Start */
9091          if (sf->sfNum != 0)
9092          {
9093             sf->sfType = RG_SCH_DL_SF;
9094          }
9095          else
9096          {
9097             sf->sfType = RG_SCH_DL_SF_0;
9098          }
9099          /* DwPTS Scheduling Changes End */
9100       }
9101       
9102       /* Calculate the number of CCEs per subframe in the cell */
9103       mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][sf->sfNum];
9104       if(cell->dynCfiCb.isDynCfiEnb == TRUE)
9105       {   
9106          /* In case if Dynamic CFI feature is enabled, default CFI 
9107           * value 1 is used  */
9108          sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][1];
9109       }
9110       else
9111       {
9112          if (sf->sfType == RG_SCH_SPL_SF_DATA)
9113          {
9114             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
9115          }
9116          else
9117          {
9118             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi)];
9119          }
9120       }   
9121    }
9122
9123    /* Intialize the RACH response scheduling related infromation */
9124    if(rgSCHCmnDlRachInfoInit(cell) != ROK)
9125    {
9126      return RFAILED;
9127    }
9128
9129    /* Allocate PRACH preamble list */
9130    rgSCHCmnDlCreateRachPrmLst(cell);
9131
9132    /* Initialize PHICH offset information */
9133    rgSCHCmnDlPhichOffsetInit(cell);
9134
9135    /* Update the size of HARQ ACK/NACK feedback table */
9136    /* The array size is increased by 2 to have enough free indices, where other
9137     * indices are busy waiting for HARQ feedback */
9138    cell->ackNackFdbkArrSize = rgSchTddANFdbkMapTbl[cell->ulDlCfgIdx] + 2; 
9139
9140    /* Initialize expected HARQ ACK/NACK feedback time */
9141    rgSCHCmnDlANFdbkInit(cell);
9142
9143    /* Initialize UL association set index */
9144    if(cell->ulDlCfgIdx != 0)
9145    {
9146       rgSCHCmnDlKdashUlAscInit(cell);
9147    }
9148
9149    if (cfg->isCpDlExtend == TRUE)
9150    {
9151       cp = RG_SCH_CMN_EXT_CP;
9152       noSymPerSlot = 6;
9153       cell->splSubfrmCfg.dwPts =
9154           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlDwPts;
9155    
9156       if ( cell->splSubfrmCfg.dwPts == 0 )
9157       {
9158          cell->isDwPtsCnted = FALSE;
9159       }
9160       else
9161       {
9162          cell->isDwPtsCnted = TRUE;
9163       }
9164
9165       if(cfg->isCpUlExtend == TRUE)
9166       {
9167          cell->splSubfrmCfg.upPts =
9168             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlExtUpPts;
9169       }
9170       else
9171       {
9172          cell->splSubfrmCfg.upPts =
9173             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlNorUpPts;
9174       }
9175    }
9176    else
9177    {
9178       cp = RG_SCH_CMN_NOR_CP;
9179       noSymPerSlot = 7;
9180       cell->splSubfrmCfg.dwPts =
9181           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlDwPts;
9182       cell->isDwPtsCnted = TRUE;
9183
9184       if(cfg->isCpUlExtend == TRUE)
9185       {
9186          cell->splSubfrmCfg.upPts =
9187             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlExtUpPts;
9188       }
9189       else
9190       {
9191          cell->splSubfrmCfg.upPts =
9192             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlNorUpPts;
9193       }
9194    }
9195
9196    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
9197    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++,cfiIdx++)
9198    {   
9199       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
9200       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
9201                                                  [cell->numTxAntPorts]][cfiIdx];
9202       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
9203       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
9204                                                  [cell->numTxAntPorts]][cfiIdx];
9205    }
9206
9207    /* Initializing the values of CFI parameters */
9208    if(cell->dynCfiCb.isDynCfiEnb)
9209    {   
9210       /* If DCFI is enabled, current CFI value will start from 1 */
9211       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
9212    }
9213    else
9214    {
9215       /* If DCFI is disabled, current CFI value is set as default max allowed CFI value */
9216       cellSch->dl.currCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
9217       cellSch->dl.newCfi = cellSch->dl.currCfi;
9218    }   
9219
9220    /* Include CRS REs while calculating Efficiency
9221     * The number of Resource Elements occupied by CRS depends on Number of
9222     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
9223     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
9224     * details of the same. Please note that PDCCH overlap symbols would not
9225     * considered in CRS REs deduction */
9226    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
9227    {
9228       cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
9229             - numPdcchSym) *RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
9230    }
9231
9232    /* DwPTS Scheduling Changes Start */
9233    antPortIdx = (cell->numTxAntPorts == 1)? 0: 
9234       ((cell->numTxAntPorts == 2)? 1: 2);     
9235
9236    if (cp == RG_SCH_CMN_NOR_CP)
9237    {
9238       splSfIdx = (splSubfrmIdx == 4)? 1: 0;   
9239    }
9240    else
9241    {
9242       splSfIdx = (splSubfrmIdx == 3)? 1: 0;
9243    }
9244
9245    numCrs = rgSchCmnDwptsCrs[splSfIdx][antPortIdx];
9246
9247    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI-1; cfi++)
9248    { 
9249       /* If CFI is 2 and Ant Port is 4, don't consider the sym 1 CRS REs */  
9250       if (antPortIdx == 2 && cfi == 2)
9251       {
9252          numCrs -= 4;      
9253       }
9254       cellSch->dl.numReDwPts[cfi]  =  ((cell->splSubfrmCfg.dwPts - cfi)*
9255                                   RB_SCH_CMN_NUM_SCS_PER_RB) - numCrs;
9256    }
9257    /* DwPTS Scheduling Changes End */
9258
9259    if (cfg->maxDlBwPerUe == 0)
9260    {
9261       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
9262    }
9263    else
9264    {
9265       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
9266    }
9267    if (cfg->maxDlRetxBw == 0)
9268    {
9269       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
9270    }
9271    else
9272    {
9273       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
9274    }
9275    /* Fix: MUE_PERTTI_DL*/
9276    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9277    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9278    if (cfg->maxUePerDlSf == 0)
9279    {
9280       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9281    }
9282    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
9283    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
9284    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
9285    {
9286       DU_LOG("\nERROR  -->  SCH : Invalid configuration !: "
9287                       "maxCcchPerDlSf %u > maxUePerDlSf %u",
9288                    cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
9289
9290       return RFAILED;
9291    }
9292    else if (!cfg->maxCcchPerDlSf)
9293    {
9294       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
9295        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
9296        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
9297        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
9298        * FLE crash in PHY as PHY has limit of 16 max*/
9299       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
9300    }
9301    else
9302    {
9303       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
9304    }
9305    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
9306    {
9307       return RFAILED;
9308    }
9309
9310    /*ccpu00118273 - ADD - start */
9311    cmLListInit(&cellSch->dl.msg4RetxLst);
9312 #ifdef RGR_V1
9313    cmLListInit(&cellSch->dl.ccchSduRetxLst);
9314 #endif
9315
9316 #ifdef RG_PHASE2_SCHED
9317    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
9318    {
9319       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
9320    }
9321    if (cfg->dlfsCfg.isDlFreqSel)
9322    {
9323       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
9324       if (ret != ROK)
9325       {
9326          return RFAILED;
9327       }
9328    }
9329    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
9330 #endif
9331
9332    /* Power related configuration */
9333    ret = rgSCHPwrCellCfg(cell, cfg);
9334    if (ret != ROK)
9335    {
9336       return RFAILED;
9337    }
9338
9339    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
9340    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
9341    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
9342    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
9343    cellSch->dl.msg4pAVal        = cfg->msg4pAVal;
9344    return ROK;
9345 }
9346 #else /* LTE_TDD */
9347 /**
9348  * @brief This function handles the configuration of cell for the first
9349  *        time by the scheduler.
9350  *
9351  * @details
9352  *
9353  *     Function: rgSCHCmnDlRgrCellCfg
9354  *     Purpose:  Configuration received is stored into the data structures
9355  *               Also, update the scheduler with the number of frames of
9356  *               RACH preamble transmission.
9357  *
9358  *     Invoked by: BO and Scheduler
9359  *
9360  *  @param[in]  RgSchCellCb*   cell
9361  *  @param[in]  RgrCellCfg*    cfg
9362  *  @param[in]  RgSchErrInfo*  err
9363  *  @return     S16
9364  *
9365  **/
9366 static S16 rgSCHCmnDlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cfg,RgSchErrInfo *err)
9367 {
9368    S16          ret;
9369    RgSchCmnCell *cellSch;
9370    uint8_t      cp;
9371    uint8_t      numPdcchSym;
9372    uint8_t      noSymPerSlot;
9373    uint8_t      cfi;  
9374    uint8_t      cfiIdx;
9375
9376
9377    cellSch = RG_SCH_CMN_GET_CELL(cell);
9378
9379    /* Initialize the parameters with the ones received in the */
9380    /* configuration.                                          */
9381
9382    /* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA
9383     * sub-frames from preamble format */
9384    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat];
9385
9386    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
9387    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
9388    
9389    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
9390                        3 TTI (MAX L1+L2 processing delay at the UE) */
9391    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
9392                                  rgSchCmnHarqRtt[7] + 3; 
9393
9394    if (cell->bwCfg.dlTotalBw <= 10)
9395    {
9396       cfiIdx = 1;
9397       numPdcchSym = 2;
9398    }
9399    else
9400    {
9401       cfiIdx = 0;
9402       numPdcchSym = 1;
9403    }
9404
9405    if (cell->isCpDlExtend == TRUE)
9406    {
9407       cp = RG_SCH_CMN_EXT_CP;
9408       noSymPerSlot = 6;
9409    }
9410    else
9411    {
9412       cp = RG_SCH_CMN_NOR_CP;
9413       noSymPerSlot = 7;
9414    }
9415
9416    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
9417    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, cfiIdx++)
9418    {   
9419       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
9420 #ifdef EMTC_ENABLE      
9421       cellSch->dl.emtcCqiToTbsTbl[0][cfi]   = rgSchEmtcCmnCqiToTbs[0][cp][cfiIdx];
9422 #endif      
9423       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
9424                                                  [cell->numTxAntPorts]][cfiIdx];
9425       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
9426 #ifdef EMTC_ENABLE      
9427       cellSch->dl.emtcCqiToTbsTbl[1][cfi]   = rgSchEmtcCmnCqiToTbs[1][cp][cfiIdx];
9428 #endif      
9429       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
9430                                                  [cell->numTxAntPorts]][cfiIdx];
9431    }
9432
9433    /* Initializing the values of CFI parameters */
9434    if(cell->dynCfiCb.isDynCfiEnb)
9435    {   
9436       /* If DCFI is enabled, current CFI value will start from 1 */
9437       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
9438    }
9439    else
9440    {
9441       /* If DCFI is disabled, current CFI value is set as default CFI value */
9442       cellSch->dl.currCfi = cellSch->cfiCfg.cfi;
9443       cellSch->dl.newCfi = cellSch->dl.currCfi;
9444    }   
9445
9446    /* Include CRS REs while calculating Efficiency
9447     * The number of Resource Elements occupied by CRS depends on Number of
9448     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
9449     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
9450     * details of the same. Please note that PDCCH overlap symbols would not
9451     * considered in CRS REs deduction */
9452    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
9453    {
9454        cellSch->dl.noResPerRb[cfi]    = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
9455             - numPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
9456    }           
9457
9458    if (cfg->maxDlBwPerUe == 0)
9459    {
9460       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
9461    }
9462    else
9463    {
9464       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
9465    }
9466    if (cfg->maxDlRetxBw == 0)
9467    {
9468       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
9469    }
9470    else
9471    {
9472       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
9473    }
9474    
9475    /* Fix: MUE_PERTTI_DL*/
9476    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9477    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9478    if (cfg->maxUePerDlSf == 0)
9479    {
9480       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9481    }
9482    /* Fix: MUE_PERTTI_DL syed validating Cell Configuration */
9483    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
9484    {
9485       DU_LOG("\nERROR  -->  SCH : FAILED MaxUePerDlSf(%u) < MaxDlUeNewTxPerTti(%u)",
9486             cellSch->dl.maxUePerDlSf,
9487             cellSch->dl.maxUeNewTxPerTti);
9488       return RFAILED;
9489    }
9490    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
9491    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
9492    {
9493       DU_LOG("\nERROR  -->  SCH : Invalid configuration !: "
9494             "maxCcchPerDlSf %u > maxUePerDlSf %u",
9495             cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
9496
9497       return RFAILED;
9498    }
9499    else if (!cfg->maxCcchPerDlSf)
9500    {
9501       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
9502        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
9503        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
9504        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
9505        * FLE crash in PHY as PHY has limit of 16 max*/
9506       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
9507    }
9508    else
9509    {
9510       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
9511    }
9512
9513
9514    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
9515    {
9516       return RFAILED;
9517    }
9518    cmLListInit(&cellSch->dl.msg4RetxLst);
9519 #ifdef RGR_V1
9520    cmLListInit(&cellSch->dl.ccchSduRetxLst);
9521 #endif
9522
9523 #ifdef RG_PHASE2_SCHED
9524    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
9525    {
9526       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
9527    }
9528    if (cfg->dlfsCfg.isDlFreqSel)
9529    {
9530       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
9531       if (ret != ROK)
9532       {
9533          return RFAILED;
9534       }
9535    }
9536    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
9537 #endif
9538
9539    /* Power related configuration */
9540    ret = rgSCHPwrCellCfg(cell, cfg);
9541    if (ret != ROK)
9542    {
9543       return RFAILED;
9544    }
9545
9546    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
9547    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
9548    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
9549    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
9550    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
9551    return ROK;
9552 }
9553 #endif /* LTE_TDD */
9554
9555 /***********************************************************
9556  *
9557  *     Func : rgSCHCmnUlCalcReqRbCeil
9558  *
9559  *     Desc : Calculate RB required to satisfy 'bytes' for
9560  *            a given CQI.
9561  *            Returns number of RBs such that requirement
9562  *            is necessarily satisfied (does a 'ceiling'
9563  *            computation).
9564  *
9565  *     Ret  : Required RBs (uint8_t)
9566  *
9567  *     Notes:
9568  *
9569  *     File :
9570  *
9571  **********************************************************/
9572 uint8_t rgSCHCmnUlCalcReqRbCeil(uint32_t bytes,uint8_t cqi,RgSchCmnUlCell *cellUl)
9573 {
9574    uint32_t numRe = RGSCH_CEIL((bytes * 8) * 1024, rgSchCmnUlCqiTbl[cqi].eff);
9575    return ((uint8_t)RGSCH_CEIL(numRe, RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl)));
9576 }
9577
9578 /***********************************************************
9579  *
9580  *     Func : rgSCHCmnPrecompMsg3Vars
9581  *
9582  *     Desc : Precomputes the following for msg3 allocation:
9583  *            1. numSb and Imcs for msg size A
9584  *            2. numSb and Imcs otherwise
9585  *
9586  *     Ret  :
9587  *
9588  *     Notes: The corresponding vars in cellUl struct is filled
9589  *            up
9590  *
9591  *     File :
9592  *
9593  **********************************************************/
9594 static S16 rgSCHCmnPrecompMsg3Vars(RgSchCmnUlCell *cellUl,uint8_t ccchCqi,uint16_t msgSzA,uint8_t sbSize,Bool isEcp)
9595 {
9596    uint8_t  numSb;
9597    uint8_t  ccchTbs;
9598    uint8_t  ccchMcs;
9599    uint8_t  numRb = 0;
9600    uint8_t  iTbs = 0;
9601    uint16_t msg3GrntSz = 0;
9602
9603
9604    if (ccchCqi > cellUl->max16qamCqi)
9605    {
9606       ccchCqi = cellUl->max16qamCqi;
9607    }
9608 /* #ifndef RG_SCH_CMN_EXP_CP_SUP For ECP Pick the index 1 */
9609    /* Fix */
9610    ccchTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
9611    ccchMcs = rgSCHCmnUlGetIMcsFrmITbs(ccchTbs, CM_LTE_UE_CAT_1);
9612    
9613    /* MCS should fit in 4 bits in RAR */
9614    if (ccchMcs >= 15)
9615    {
9616       ccchMcs = 15;
9617    }
9618    
9619    /* Limit the ccchMcs to 15 as it
9620     * can be inferred from 36.213, section 6.2 that msg3 imcs
9621     * field is 4 bits.
9622     * Since, UE doesn't exist right now, we use CAT_1 for ue
9623     * category*/
9624    while((ccchMcs = (rgSCHCmnUlGetIMcsFrmITbs(
9625                       rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi],CM_LTE_UE_CAT_1))
9626                     ) >
9627                  RG_SCH_CMN_MAX_MSG3_IMCS)
9628    {
9629       ccchCqi--;
9630    }
9631    
9632    iTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
9633    
9634    if (msgSzA < RGSCH_MIN_MSG3_GRNT_SZ)
9635    {
9636       return RFAILED;
9637    }
9638    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(msgSzA, ccchCqi, cellUl), sbSize);
9639    
9640    numRb   = numSb * sbSize;
9641    msg3GrntSz = 8 * msgSzA;
9642
9643    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
9644    {
9645       ++numSb;
9646       numRb   = numSb * sbSize;
9647    }
9648    while (rgSchCmnMult235Tbl[numSb].match != numSb)
9649    {
9650       ++numSb;
9651    }
9652    /* Reversed(Corrected) the assignment for preamble-GrpA
9653     * Refer- TG36.321- section- 5.1.2*/
9654    cellUl->ra.prmblBNumSb = numSb;
9655    cellUl->ra.prmblBIMcs  = ccchMcs;
9656    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(RGSCH_MIN_MSG3_GRNT_SZ, \
9657                       ccchCqi, cellUl),
9658          sbSize);
9659
9660    numRb   = numSb * sbSize;
9661    msg3GrntSz = 8 * RGSCH_MIN_MSG3_GRNT_SZ;
9662    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
9663    {
9664       ++numSb;
9665       numRb   = numSb * sbSize;
9666    }
9667    while (rgSchCmnMult235Tbl[numSb].match != numSb)
9668    {
9669       ++numSb;
9670    }
9671    /* Reversed(Corrected) the assignment for preamble-GrpA
9672     * Refer- TG36.321- section- 5.1.2*/
9673    cellUl->ra.prmblANumSb = numSb;
9674    cellUl->ra.prmblAIMcs  = ccchMcs;
9675    return ROK;
9676 }
9677
9678 uint32_t gPrntPucchDet=0;
9679
9680 #ifdef LTE_TDD
9681 /***********************************************************
9682  *
9683  *     Func : rgSCHCmnUlCalcAvailBw
9684  *
9685  *     Desc : Calculates bandwidth available for PUSCH scheduling.
9686  *
9687  *     Ret  : S16 (ROK/RFAILED)
9688  *
9689  *     Notes:
9690  *
9691  *     File :
9692  *
9693  **********************************************************/
9694 static S16 rgSCHCmnUlCalcAvailBw(RgSchCellCb *cell,RgrCellCfg *cellCfg,uint8_t cfi,uint8_t *rbStartRef,uint8_t  *bwAvailRef)
9695 {
9696    uint8_t  c        = 3;
9697    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
9698    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
9699    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
9700    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
9701    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
9702    uint8_t  n1PerRb;
9703    uint8_t  totalCce;
9704    uint16_t n1Max;
9705    uint8_t  n1Rb;
9706    uint32_t mixedRb;
9707    uint8_t  exclRb; /* RBs to exclude */
9708    uint8_t  n1RbPart;
9709    uint8_t  puschRbStart;
9710    /* To avoid PUCCH and PUSCH collision issue */
9711    uint8_t  P;
9712    uint8_t  n1PlusOne;
9713    uint8_t  mi;
9714    /* Maximum value of M as per Table 10.1-1 */
9715    uint8_t  M[RGSCH_MAX_TDD_UL_DL_CFG] = {1, 2, 4, 3, 4, 9, 1};
9716
9717
9718    if (cell->isCpUlExtend)
9719    {
9720       c = 2;
9721    }
9722
9723    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
9724
9725    /* Considering the max no. of CCEs for PUSCH BW calculation 
9726     * based on min mi value */
9727    if (cell->ulDlCfgIdx == 0 || cell->ulDlCfgIdx == 6)
9728    {
9729       mi = 1;
9730    }
9731    else
9732    { 
9733       mi = 0;
9734    }
9735    
9736    totalCce = cell->dynCfiCb.cfi2NCceTbl[mi][cfi];
9737
9738    P        = rgSCHCmnGetPValFrmCCE(cell, totalCce-1);
9739    n1PlusOne = cell->rgSchTddNpValTbl[P + 1];
9740    n1Max    = (M[cell->ulDlCfgIdx] - 1)*n1PlusOne + (totalCce-1) + n1Pucch;
9741
9742    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
9743     * TS 36.211  */
9744    n1RbPart = (c*n1Cs)/pucchDeltaShft;
9745    n1Rb = (n1Max - n1RbPart)/ n1PerRb;
9746    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
9747
9748    /* get the total Number of RB's to be excluded for PUSCH */
9749    /* ccpu00137339 */
9750    if(n1Pucch < n1RbPart)
9751    {
9752       exclRb = n2Rb;
9753    }
9754    else
9755    {
9756       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
9757    }
9758    puschRbStart = exclRb/2 + 1; 
9759
9760    /* Num of PUCCH RBs = puschRbStart*2 */
9761    if (puschRbStart * 2 >= ulBw)
9762    {
9763       DU_LOG("\nERROR  -->  SCH : No bw available for PUSCH");
9764       return RFAILED;
9765    }
9766
9767    *rbStartRef = puschRbStart;
9768    *bwAvailRef = ulBw -  puschRbStart * 2;
9769  
9770    if(cell->pucchCfg.maxPucchRb !=0 && 
9771          (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
9772    {
9773       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
9774    }
9775     
9776    return ROK;
9777 }
9778 #else
9779
9780 /***********************************************************
9781  *
9782  *     Func : rgSCHCmnUlCalcAvailBw
9783  *
9784  *     Desc : Calculates bandwidth available for PUSCH scheduling.
9785  *
9786  *     Ret  : S16 (ROK/RFAILED)
9787  *
9788  *     Notes:
9789  *
9790  *     File :
9791  *
9792  **********************************************************/
9793 static S16 rgSCHCmnUlCalcAvailBw(RgSchCellCb *cell,RgrCellCfg *cellCfg,uint8_t cfi,uint8_t *rbStartRef,uint8_t *bwAvailRef)
9794 {
9795    uint8_t  c        = 3;
9796    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
9797    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
9798    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
9799    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
9800    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
9801    uint8_t  n1PerRb;
9802    uint8_t  totalCce;
9803    uint16_t n1Max;
9804    uint8_t  n1Rb;
9805    uint32_t mixedRb;
9806    uint8_t  exclRb; /* RBs to exclude */
9807    uint8_t  n1RbPart;
9808    uint8_t  puschRbStart;
9809 #ifdef LTE_ADV
9810    uint16_t numOfN3PucchRb;
9811    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);  
9812 #endif
9813    
9814
9815    if (cell->isCpUlExtend)
9816    {
9817       c = 2;
9818    }
9819
9820    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
9821
9822    totalCce = cell->dynCfiCb.cfi2NCceTbl[0][cfi];
9823
9824    n1Max    = n1Pucch + totalCce-1;
9825
9826    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
9827     * TS 36.211  */
9828    n1RbPart = (c*n1Cs)/pucchDeltaShft;
9829    n1Rb = (uint8_t)((n1Max - n1RbPart) / n1PerRb);
9830    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
9831
9832    /* get the total Number of RB's to be excluded for PUSCH */
9833    /* ccpu00137339 */
9834    if(n1Pucch < n1RbPart)
9835    {
9836       exclRb = n2Rb;
9837    }
9838    else
9839    {
9840       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
9841    }
9842    /*Support for PUCCH Format 3*/
9843 #ifdef LTE_ADV
9844    if (cell->isPucchFormat3Sptd)
9845    {
9846       numOfN3PucchRb = RGSCH_CEIL(cellSch->dl.maxUePerDlSf,5); 
9847       exclRb = exclRb + numOfN3PucchRb;
9848    }
9849 #endif
9850    puschRbStart = exclRb/2 + 1;
9851
9852    if(gPrntPucchDet)
9853    {
9854 #ifndef ALIGN_64BIT
9855         DU_LOG("\nDEBUG  -->  SCH : CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%ld:%d:%d:%d:%d:%d]\n",
9856         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
9857 #else
9858         DU_LOG("\nDEBUG  -->  SCH : CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%d:%d:%d:%d:%d:%d]\n",
9859         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
9860 #endif
9861    }
9862
9863    if (puschRbStart*2 >= ulBw)
9864    {
9865       DU_LOG("\nERROR  -->  SCH : No bw available for PUSCH");
9866       return RFAILED;
9867    }
9868
9869    *rbStartRef = puschRbStart;
9870    *bwAvailRef = ulBw - puschRbStart * 2;
9871
9872    if(cell->pucchCfg.maxPucchRb !=0 && 
9873       (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
9874    {
9875       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
9876    }
9877    
9878    return ROK;
9879 }
9880 #endif
9881
9882
9883
9884 /***********************************************************
9885  *
9886  *     Func : rgSCHCmnUlCellInit
9887  *
9888  *     Desc : Uplink scheduler initialisation for cell.
9889  *
9890  *     Ret  : S16
9891  *
9892  *     Notes:
9893  *
9894  *     File :
9895  *
9896  **********************************************************/
9897 static S16 rgSCHCmnUlCellInit(RgSchCellCb  *cell,RgrCellCfg *cellCfg)
9898 {
9899    S16            ret;
9900    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
9901    uint8_t maxUePerUlSf = cellCfg->maxUePerUlSf;
9902 #ifdef RGR_V1
9903    /* Added configuration for maximum number of MSG3s */
9904    uint8_t maxMsg3PerUlSf = cellCfg->maxMsg3PerUlSf;
9905 #endif
9906    uint8_t maxUlBwPerUe = cellCfg->maxUlBwPerUe;
9907    uint8_t sbSize       = cellCfg->puschSubBand.size;
9908    uint8_t i;
9909    uint8_t rbStart;
9910    uint8_t bwAvail;
9911    uint8_t cfi;  
9912    uint8_t maxSbPerUe;
9913    uint8_t numSb;
9914 #ifdef LTE_TDD
9915    uint16_t ulDlCfgIdx = cell->ulDlCfgIdx;
9916    /* [ccpu00127294]-MOD-Change the max Ul subfrms size in TDD */
9917    uint8_t  maxSubfrms = 2 * rgSchTddNumUlSf[ulDlCfgIdx]; 
9918    uint8_t  ulToDlMap[12] = {0}; /* maximum 6 Subframes in UL  * 2 */
9919    uint8_t  maxUlsubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
9920                                            [RGSCH_NUM_SUB_FRAMES-1];
9921    uint16_t subfrm;
9922    S8       dlIdx;
9923 #else
9924    uint8_t  maxSubfrms = RG_SCH_CMN_UL_NUM_SF;
9925 #endif
9926 #ifdef LTE_L2_MEAS
9927    uint8_t  idx;
9928 #endif
9929    uint8_t  iTbs;
9930 #if (defined(LTE_L2_MEAS) )
9931    Inst  inst         = cell->instIdx;
9932 #endif /* #if (defined(LTE_L2_MEAS) || defined(DEBUGP) */
9933    RgSchCmnCell      *cellSch =  (RgSchCmnCell *)(cell->sc.sch);
9934    
9935
9936    cellUl->maxUeNewTxPerTti = cellCfg->maxUlUeNewTxPerTti;
9937    if (maxUePerUlSf == 0)
9938    {
9939       maxUePerUlSf = RG_SCH_CMN_MAX_UE_PER_UL_SF;
9940    }
9941 #ifdef RGR_V1
9942    if (maxMsg3PerUlSf == 0)
9943    {
9944       maxMsg3PerUlSf = RG_SCH_CMN_MAX_MSG3_PER_UL_SF;
9945    }
9946    /*  fixed the problem while sending raRsp 
9947     * if maxMsg3PerUlSf is greater than 
9948     * RGSCH_MAX_RNTI_PER_RARNTI 
9949     * */
9950    if(maxMsg3PerUlSf > RGSCH_MAX_RNTI_PER_RARNTI)
9951    {
9952       maxMsg3PerUlSf = RGSCH_MAX_RNTI_PER_RARNTI; 
9953    } 
9954
9955    if(maxMsg3PerUlSf > maxUePerUlSf)
9956    {
9957       maxMsg3PerUlSf =  maxUePerUlSf;   
9958    }
9959    
9960    /*cellUl->maxAllocPerUlSf = maxUePerUlSf + maxMsg3PerUlSf;*/
9961    /*Max MSG3 should be a subset of Max UEs*/
9962    cellUl->maxAllocPerUlSf = maxUePerUlSf;
9963    cellUl->maxMsg3PerUlSf = maxMsg3PerUlSf;
9964 #else
9965    cellUl->maxAllocPerUlSf = maxUePerUlSf;
9966 #endif
9967    /* Fix: MUE_PERTTI_UL syed validating Cell Configuration */
9968    if (cellUl->maxAllocPerUlSf < cellUl->maxUeNewTxPerTti)
9969    {
9970       DU_LOG("\nERROR  -->  SCH : FAILED: MaxUePerUlSf(%u) < MaxUlUeNewTxPerTti(%u)",
9971             cellUl->maxAllocPerUlSf,
9972             cellUl->maxUeNewTxPerTti);
9973       return RFAILED;
9974    }
9975
9976 #ifdef LTE_L2_MEAS
9977 #ifdef LTE_TDD
9978    for(idx = 0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
9979 #else
9980    for(idx = 0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
9981 #endif
9982    {
9983
9984       ret = rgSCHUtlAllocSBuf(inst,  (Data **)&(cell->sfAllocArr[idx].
9985               ulUeInfo.ulAllocInfo), (cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)));
9986       if (ret != ROK)
9987       {
9988          DU_LOG("\nERROR  -->  SCH : Memory allocation failed ");
9989             return (ret);
9990       }
9991    }
9992 #endif
9993    if (maxUlBwPerUe == 0)
9994    {
9995       /* ccpu00139362- Setting to configured UL BW instead of MAX BW(100)*/
9996       maxUlBwPerUe = cell->bwCfg.ulTotalBw;
9997    }
9998    cellUl->maxUlBwPerUe = maxUlBwPerUe;
9999
10000    /* FOR RG_SCH_CMN_EXT_CP_SUP */
10001    if (!cellCfg->isCpUlExtend)
10002    {
10003       cellUl->ulNumRePerRb = 12 * (14 - RGSCH_UL_SYM_DMRS_SRS);
10004    }
10005    else
10006    {
10007       cellUl->ulNumRePerRb = 12 * (12 - RGSCH_UL_SYM_DMRS_SRS);
10008    }
10009
10010    if (sbSize != rgSchCmnMult235Tbl[sbSize].match)
10011    {
10012       DU_LOG("\nERROR  -->  SCH : Invalid subband size %d", sbSize);
10013       return RFAILED;
10014    }
10015         //Setting the subband size to 4 which is size of VRBG in 5GTF
10016 #ifdef RG_5GTF
10017         sbSize = MAX_5GTF_VRBG_SIZE;
10018 #endif
10019         
10020    maxSbPerUe = maxUlBwPerUe / sbSize;
10021    if (maxSbPerUe == 0)
10022    {
10023       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlCellInit(): "
10024          "maxUlBwPerUe/sbSize is zero");
10025       return RFAILED;
10026    }
10027    cellUl->maxSbPerUe = rgSchCmnMult235Tbl[maxSbPerUe].prvMatch;
10028
10029    /* CQI related updations */
10030    if ((!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->ulCmnCodeRate.ccchCqi))
10031          || (!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->trgUlCqi.trgCqi)))
10032    {
10033       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlCellInit(): "
10034          "Invalid cqi");
10035       return RFAILED;
10036    }
10037    cellUl->dfltUlCqi = cellCfg->ulCmnCodeRate.ccchCqi;
10038
10039    /* Changed the logic to determine maxUlCqi.
10040     * For a 16qam UE, maxUlCqi is the CQI Index at which
10041     * efficiency is as close as possible to RG_SCH_MAX_CODE_RATE_16QAM
10042     * Refer to 36.213-8.6.1 */
10043     for (i = RG_SCH_CMN_UL_NUM_CQI - 1;i > 0; --i)
10044    {
10045        DU_LOG("\nINFO  -->  SCH : CQI %u:iTbs %u",i, 
10046             rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]);
10047 #ifdef MAC_SCH_STATS
10048       /* ccpu00128489 ADD Update mcs in hqFailStats here instead of at CRC 
10049        * since CQI to MCS mapping does not change. The only exception is for 
10050        * ITBS = 19 where the MCS can be 20 or 21 based on the UE cat. We 
10051        * choose 20, instead of 21, ie UE_CAT_3 */
10052       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
10053       RG_SCH_CMN_UL_TBS_TO_MCS(iTbs, hqFailStats.ulCqiStat[i - 1].mcs);
10054 #endif
10055    }
10056    for (i = RG_SCH_CMN_UL_NUM_CQI - 1; i != 0; --i)
10057    {
10058       /* Fix for ccpu00123912*/
10059       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
10060       if (iTbs <= RGSCH_UL_16QAM_MAX_ITBS) /* corresponds to 16QAM */
10061       {
10062          DU_LOG("\nINFO  -->  SCH : 16 QAM CQI %u", i);
10063          cellUl->max16qamCqi = i;
10064          break;
10065       }
10066    }
10067
10068 #ifdef EMTC_ENABLE
10069    /* Precompute useful values for RA msg3 */
10070    ret = rgSCHCmnPrecompEmtcMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
10071          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
10072    if (ret != ROK)
10073    {
10074       return (ret);
10075    }
10076 #endif   
10077
10078    /* Precompute useful values for RA msg3 */
10079    ret = rgSCHCmnPrecompMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
10080          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
10081    if (ret != ROK)
10082    {
10083       return (ret);
10084    }
10085
10086    cellUl->sbSize  = sbSize;
10087    
10088 #ifdef LTE_TDD  
10089    cellUl->numUlSubfrms = maxSubfrms;
10090
10091    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->ulSfArr,
10092             cellUl->numUlSubfrms * sizeof(RgSchUlSf));
10093
10094    if (ret != ROK)
10095    {
10096       cellUl->numUlSubfrms = 0;
10097       return (ret);
10098    }
10099
10100    /* store the DL subframe corresponding to the PUSCH offset
10101     * in their respective UL subframe */
10102    for(i=0; i < RGSCH_NUM_SUB_FRAMES; i++)
10103    {
10104       if(rgSchTddPuschTxKTbl[ulDlCfgIdx][i] != 0)
10105       {
10106          subfrm = (i + rgSchTddPuschTxKTbl[ulDlCfgIdx][i]) % \
10107                                  RGSCH_NUM_SUB_FRAMES;
10108          subfrm = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subfrm]-1;
10109          dlIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][i]-1;
10110          RGSCH_ARRAY_BOUND_CHECK( cell->instIdx, ulToDlMap, subfrm);
10111          ulToDlMap[subfrm] = dlIdx;
10112       }
10113    }
10114    /* Copy the information in the remaining UL subframes based
10115     * on number of HARQ processes */
10116    for(i=maxUlsubfrms; i < maxSubfrms; i++)
10117    {
10118       subfrm = i-maxUlsubfrms;
10119       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, i);
10120       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, subfrm)
10121       ulToDlMap[i] = ulToDlMap[subfrm];
10122    }
10123 #endif
10124
10125    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++)
10126    {
10127 #ifdef LTE_TDD        
10128       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
10129 #else
10130       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
10131 #endif
10132       if (ret != ROK)
10133       {
10134          return (ret);
10135       }
10136
10137       if (cfi == 1)
10138       {
10139          cell->ulAvailBw = bwAvail;
10140       }
10141
10142       numSb = bwAvail/sbSize; 
10143
10144       cell->dynCfiCb.bwInfo[cfi].startRb  = rbStart;
10145       cell->dynCfiCb.bwInfo[cfi].numSb    = numSb;
10146    }
10147
10148    if(0 == cell->dynCfiCb.maxCfi)
10149    {
10150       DU_LOG("\nERROR  -->  SCH : Incorrect Default CFI(%u), maxCfi(%u), maxPucchRb(%d)",
10151                cellSch->cfiCfg.cfi, cell->dynCfiCb.maxCfi, 
10152                cell->pucchCfg.maxPucchRb);
10153             
10154       return RFAILED;
10155    }
10156
10157    /* DMRS values */
10158    cellUl->dmrsArrSize = cell->dynCfiCb.bwInfo[1].numSb;
10159    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->dmrsArr,
10160          cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10161    if (ret != ROK)
10162    {
10163       return (ret);
10164    }
10165    for (i = 0; i < cellUl->dmrsArrSize; ++i)
10166    {
10167       cellUl->dmrsArr[i] = cellCfg->puschSubBand.dmrs[i];
10168    }
10169  
10170    /* Init subframes */
10171    for (i = 0; i < maxSubfrms; ++i)
10172    {
10173       ret = rgSCHUtlUlSfInit(cell, &cellUl->ulSfArr[i], i,
10174                              cellUl->maxAllocPerUlSf);
10175       if (ret != ROK)
10176       {
10177          for (; i != 0; --i)
10178          {
10179             rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[i-1]);
10180          }
10181          /* ccpu00117052 - MOD - Passing double pointer
10182             for proper NULLP assignment*/
10183          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(cellUl->dmrsArr)),
10184                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10185 #ifdef LTE_TDD
10186          /* ccpu00117052 - MOD - Passing double pointer
10187             for proper NULLP assignment*/
10188          rgSCHUtlFreeSBuf(cell->instIdx,
10189             (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
10190 #endif
10191          return (ret);
10192       }
10193    }
10194    RG_SCH_RESET_HCSG_UL_PRB_CNTR(cellUl);
10195    return ROK;
10196 }
10197
10198 /**
10199  * @brief Scheduler processing on cell configuration.
10200  *
10201  * @details
10202  *
10203  *     Function : rgSCHCmnRgrCellCfg
10204  *
10205  *     This function does requisite initialisation
10206  *     and setup for scheduler1 when a cell is
10207  *     configured.
10208  *
10209  *  @param[in]  RgSchCellCb   *cell
10210  *  @param[in]  RgrCellCfg    *cellCfg
10211  *  @param[out] RgSchErrInfo  *err
10212  *  @return  S16
10213  *      -# ROK
10214  *      -# RFAILED
10215  **/
10216 S16 rgSCHCmnRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cellCfg,RgSchErrInfo *err)
10217 {
10218    S16 ret;
10219    RgSchCmnCell *cellSch;
10220
10221    /* As part of RGR cell configuration, validate the CRGCellCfg
10222     * There is no trigger for crgCellCfg from SC1 */
10223    /* Removed failure check for Extended CP */
10224
10225    if (((ret = rgSCHUtlAllocSBuf(cell->instIdx,
10226       (Data**)&(cell->sc.sch), (sizeof(RgSchCmnCell)))) != ROK))
10227    {
10228       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED");
10229       err->errCause = RGSCHERR_SCH_CFG;
10230       return (ret);
10231    }
10232    cellSch = (RgSchCmnCell *)(cell->sc.sch);
10233    cellSch->cfiCfg = cellCfg->cfiCfg;
10234    cellSch->trgUlCqi.trgCqi = cellCfg->trgUlCqi.trgCqi;
10235    /* Initialize the scheduler refresh timer queues */
10236    cellSch->tmrTqCp.nxtEnt = 0;
10237    cellSch->tmrTqCp.tmrLen = RG_SCH_CMN_NUM_REFRESH_Q;
10238
10239    /* RACHO Intialize the RACH ded Preamble Information */
10240    rgSCHCmnCfgRachDedPrm(cell);
10241 #ifdef LTE_TDD
10242    /* Initialize 'Np' value for each 'p' used for
10243     * HARQ ACK/NACK reception */
10244    rgSCHCmnDlNpValInit(cell);
10245 #endif
10246
10247    /* Initialize 'Np' value for each 'p' used for
10248     * HARQ ACK/NACK reception */
10249 #ifdef LTE_TDD
10250    rgSCHCmnDlNpValInit(cell);
10251 #endif
10252
10253    /* Now perform uplink related initializations  */
10254    ret = rgSCHCmnUlCellInit(cell, cellCfg);
10255    if (ret != ROK)
10256    {
10257       /* There is no downlink deinit to be performed */
10258       err->errCause = RGSCHERR_SCH_CFG;
10259       return (ret);
10260    }
10261    ret = rgSCHCmnDlRgrCellCfg(cell, cellCfg, err);
10262    if (ret != ROK)
10263    {
10264       err->errCause = RGSCHERR_SCH_CFG;
10265       return (ret);
10266    }
10267    /* DL scheduler has no initializations to make */
10268    /* As of now DL scheduler always returns ROK   */
10269
10270    rgSCHCmnGetDciFrmtSizes(cell);
10271    rgSCHCmnGetCqiDciFrmt2AggrLvl(cell);
10272 #ifdef EMTC_ENABLE 
10273    rgSCHCmnGetEmtcDciFrmtSizes(cell);
10274    rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl(cell);
10275 #endif /* EMTC_ENABLE  */
10276
10277 #ifdef EMTC_ENABLE   
10278    if(TRUE == cellCfg->emtcEnable)
10279    {
10280       cellSch->apisEmtcUl = &rgSchEmtcUlSchdTbl[0];
10281       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
10282       if (ret != ROK)
10283       {
10284          return (ret);
10285       }
10286    }
10287 #endif
10288    cellSch->apisUl = &rgSchUlSchdTbl[RG_SCH_CMN_GET_UL_SCHED_TYPE(cell)];
10289    ret = cellSch->apisUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
10290    if (ret != ROK)
10291    {
10292       return (ret);
10293    }
10294 #ifdef EMTC_ENABLE   
10295    if(TRUE == cellCfg->emtcEnable)
10296    {
10297       cellSch->apisEmtcDl = &rgSchEmtcDlSchdTbl[0];
10298       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
10299       if (ret != ROK)
10300       {
10301          return (ret);
10302       }
10303    }
10304 #endif
10305    cellSch->apisDl = &rgSchDlSchdTbl[RG_SCH_CMN_GET_DL_SCHED_TYPE(cell)];
10306 #ifdef LTEMAC_SPS
10307    /* Perform SPS specific initialization for the cell */
10308    ret = rgSCHCmnSpsCellCfg(cell, cellCfg, err);
10309    if (ret != ROK)
10310    {
10311       return (ret);
10312    }
10313 #endif
10314    ret = cellSch->apisDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
10315    if (ret != ROK)
10316    {
10317       return (ret);
10318    }
10319    rgSCHCmnInitVars(cell);
10320
10321    return ROK;
10322 }  /* rgSCHCmnRgrCellCfg*/
10323
10324 \f
10325 /**
10326  * @brief This function handles the reconfiguration of cell.
10327  *
10328  * @details
10329  *
10330  *     Function: rgSCHCmnRgrCellRecfg
10331  *     Purpose:  Update the reconfiguration parameters.
10332  *
10333  *     Invoked by: Scheduler
10334  *
10335  *  @param[in]  RgSchCellCb*  cell
10336  *  @return  Void
10337  *
10338  **/
10339 S16 rgSCHCmnRgrCellRecfg(RgSchCellCb *cell,RgrCellRecfg *recfg,RgSchErrInfo *err)
10340 {
10341    S16                  ret;
10342    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
10343    RgSchCmnUlCell       *cellUl  = RG_SCH_CMN_GET_UL_CELL(cell);
10344
10345
10346    if (recfg->recfgTypes & RGR_CELL_UL_CMNRATE_RECFG)
10347    {
10348       uint8_t   oldCqi = cellUl->dfltUlCqi;
10349       if (!RG_SCH_CMN_UL_IS_CQI_VALID(recfg->ulCmnCodeRate.ccchCqi))
10350       {
10351          err->errCause = RGSCHERR_SCH_CFG;
10352          DU_LOG("\nERROR  -->  SCH : rgSCHCmnRgrCellRecfg(): "
10353             "Invalid cqi");
10354          return RFAILED;
10355       }
10356       cellUl->dfltUlCqi = recfg->ulCmnCodeRate.ccchCqi;
10357       ret = rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
10358             cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
10359       if (ret != ROK)
10360       {
10361          cellUl->dfltUlCqi = oldCqi;
10362          rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
10363                cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
10364          return (ret);
10365       }
10366    }
10367
10368    if (recfg->recfgTypes & RGR_CELL_DL_CMNRATE_RECFG)
10369    {
10370       if (rgSCHCmnDlCnsdrCmnRt(cell, &recfg->dlCmnCodeRate) != ROK)
10371       {
10372          err->errCause = RGSCHERR_SCH_CFG;
10373          return RFAILED;
10374       }
10375    }
10376  
10377 #ifdef EMTC_ENABLE  
10378    if(TRUE == cell->emtcEnable) 
10379    {
10380       /* Invoke UL sched for cell Recfg */
10381       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
10382       if (ret != ROK)
10383       {
10384          return RFAILED;
10385       }
10386
10387       /* Invoke DL sched for cell Recfg */
10388       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
10389       if (ret != ROK)
10390       {
10391          return RFAILED;
10392       }
10393    }
10394    else
10395 #endif
10396    {
10397    /* Invoke UL sched for cell Recfg */
10398    ret = cellSch->apisUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
10399    if (ret != ROK)
10400    {
10401       return RFAILED;
10402    }
10403
10404    /* Invoke DL sched for cell Recfg */
10405    ret = cellSch->apisDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
10406    if (ret != ROK)
10407    {
10408       return RFAILED;
10409    }
10410    }
10411
10412    if (recfg->recfgTypes & RGR_CELL_DLFS_RECFG)
10413    {
10414       ret = cellSch->apisDlfs->rgSCHDlfsCellRecfg(cell, recfg, err);
10415       if (ret != ROK)
10416       {
10417          return RFAILED;
10418       }
10419       cellSch->dl.isDlFreqSel = recfg->dlfsRecfg.isDlFreqSel;
10420    }
10421
10422    if (recfg->recfgTypes & RGR_CELL_PWR_RECFG)
10423    {
10424       ret = rgSCHPwrCellRecfg(cell, recfg);
10425       if (ret != ROK)
10426       {
10427          return RFAILED;
10428       }
10429    }
10430
10431    return ROK;
10432 }
10433
10434 /***********************************************************
10435  *
10436  *     Func : rgSCHCmnUlCellDeinit
10437  *
10438  *     Desc : Uplink scheduler de-initialisation for cell.
10439  *
10440  *     Ret  : S16
10441  *
10442  *     Notes:
10443  *
10444  *     File :
10445  *
10446  **********************************************************/
10447 static Void rgSCHCmnUlCellDeinit(RgSchCellCb *cell)
10448 {
10449    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
10450    uint8_t          ulSfIdx;
10451 #ifdef LTE_TDD
10452    uint8_t        maxSubfrms = cellUl->numUlSubfrms;
10453 #endif
10454 #ifdef LTE_L2_MEAS
10455    CmLList       *lnk = NULLP;
10456    RgSchL2MeasCb *measCb;
10457 #endif
10458 #ifdef LTE_L2_MEAS
10459 #ifdef LTE_TDD
10460    for(ulSfIdx = 0; ulSfIdx < RGSCH_SF_ALLOC_SIZE; ulSfIdx++)
10461 #else
10462    for(ulSfIdx = 0; ulSfIdx < RGSCH_NUM_SUB_FRAMES; ulSfIdx++)
10463 #endif
10464    {
10465       if(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo != NULLP)
10466       {
10467          /* ccpu00117052 - MOD - Passing double pointer
10468             for proper NULLP assignment*/
10469          rgSCHUtlFreeSBuf(cell->instIdx,
10470          (Data **)(&(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo)),
10471          cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc));
10472
10473          /* ccpu00117052 - DEL - removed explicit NULLP assignment
10474             as it is done in above utility function */
10475       }
10476    }
10477    /* Free the memory allocated to measCb */
10478    lnk = cell->l2mList.first;
10479    while(lnk != NULLP)
10480    {
10481       measCb = (RgSchL2MeasCb *)lnk->node;
10482       cmLListDelFrm(&cell->l2mList, lnk);
10483       lnk = lnk->next;
10484    /* ccpu00117052 - MOD - Passing double pointer
10485    for proper NULLP assignment*/
10486       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\
10487                           sizeof(RgSchL2MeasCb));
10488    }
10489 #endif
10490    if (cellUl->dmrsArr != NULLP)
10491    {
10492       /* ccpu00117052 - MOD - Passing double pointer
10493       for proper NULLP assignment*/
10494       rgSCHUtlFreeSBuf(cell->instIdx,(Data **)(&(cellUl->dmrsArr)),
10495                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10496    }
10497    /* De-init subframes */
10498 #ifdef LTE_TDD
10499    for (ulSfIdx = 0; ulSfIdx < maxSubfrms; ++ulSfIdx)
10500 #else
10501    for (ulSfIdx = 0; ulSfIdx < RG_SCH_CMN_UL_NUM_SF; ++ulSfIdx)
10502 #endif
10503    {
10504       rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[ulSfIdx]);
10505    }
10506
10507 #ifdef LTE_TDD
10508    if (cellUl->ulSfArr != NULLP)
10509    {
10510       /* ccpu00117052 - MOD - Passing double pointer
10511       for proper NULLP assignment*/
10512       rgSCHUtlFreeSBuf(cell->instIdx,
10513          (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
10514    }
10515 #endif
10516
10517    return;
10518 }
10519
10520 /**
10521  * @brief Scheduler processing for cell delete.
10522  *
10523  * @details
10524  *
10525  *     Function : rgSCHCmnCellDel
10526  *
10527  *     This functions de-initialises and frees memory
10528  *     taken up by scheduler1 for the entire cell.
10529  *
10530  *  @param[in]  RgSchCellCb  *cell
10531  *  @return  Void
10532  **/
10533 Void rgSCHCmnCellDel(RgSchCellCb *cell)
10534 {
10535    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10536
10537 #ifdef LTE_L2_MEAS
10538    glblTtiCnt = 0;
10539 #endif
10540    if (cellSch == NULLP)
10541    {
10542       return;
10543    }
10544    /* Perform the deinit for the UL scheduler */
10545    rgSCHCmnUlCellDeinit(cell);
10546 #ifdef EMTC_ENABLE
10547    if(TRUE == cell->emtcEnable)
10548    {
10549       if (cellSch->apisEmtcUl)
10550       {
10551          cellSch->apisEmtcUl->rgSCHFreeUlCell(cell);
10552       }
10553    }
10554 #endif 
10555    if (cellSch->apisUl)
10556    {
10557       /* api pointer checks added (here and below in
10558        * this function). pl check. - antriksh */
10559       cellSch->apisUl->rgSCHFreeUlCell(cell);
10560    }
10561
10562    /* Perform the deinit for the DL scheduler */
10563    cmLListInit(&cellSch->dl.taLst);
10564    if (cellSch->apisDl)
10565    {
10566       cellSch->apisDl->rgSCHFreeDlCell(cell);
10567    }
10568 #ifdef EMTC_ENABLE
10569    if (cellSch->apisEmtcDl)
10570    {
10571       rgSCHEmtcInitTaLst(&cellSch->dl);
10572
10573       cellSch->apisEmtcDl->rgSCHFreeDlCell(cell);
10574    }
10575 #endif
10576
10577    /* DLFS de-initialization */
10578    if (cellSch->dl.isDlFreqSel && cellSch->apisDlfs)
10579    {
10580       cellSch->apisDlfs->rgSCHDlfsCellDel(cell);
10581    }
10582
10583    rgSCHPwrCellDel(cell);
10584 #ifdef LTEMAC_SPS
10585    rgSCHCmnSpsCellDel(cell);
10586 #endif
10587
10588    /* ccpu00117052 - MOD - Passing double pointer
10589    for proper NULLP assignment*/
10590    rgSCHUtlFreeSBuf(cell->instIdx,
10591       (Data**)(&(cell->sc.sch)), (sizeof(RgSchCmnCell)));
10592    return;
10593 }  /* rgSCHCmnCellDel */
10594
10595 \f
10596 /**
10597  * @brief This function validates QOS parameters for DL.
10598  *
10599  * @details
10600  *
10601  *     Function: rgSCHCmnValidateDlQos
10602  *     Purpose:  This function validates QOS parameters for DL.
10603  *
10604  *     Invoked by: Scheduler
10605  *
10606  *  @param[in] CrgLchQosCfg    *dlQos
10607  *  @return                    S16
10608  *
10609  **/
10610 static S16 rgSCHCmnValidateDlQos(RgrLchQosCfg *dlQos)
10611 {
10612    uint8_t qci = dlQos->qci;
10613    if ( qci < RG_SCH_CMN_MIN_QCI || qci > RG_SCH_CMN_MAX_QCI )
10614    {
10615       return RFAILED;
10616    }
10617
10618    if ((qci >= RG_SCH_CMN_GBR_QCI_START) &&
10619        (qci <= RG_SCH_CMN_GBR_QCI_END))
10620    {
10621       if ((dlQos->mbr == 0) || (dlQos->mbr < dlQos->gbr))
10622       {
10623          return RFAILED;
10624       }
10625    }
10626    return ROK;
10627 }
10628
10629 /**
10630  * @brief Scheduler invocation on logical channel addition.
10631  *
10632  * @details
10633  *
10634  *     Function : rgSCHCmnRgrLchCfg
10635  *
10636  *     This functions does required processing when a new
10637  *     (dedicated) logical channel is added. Assumes lcg
10638  *     pointer in ulLc is set.
10639  *
10640  *  @param[in]  RgSchCellCb  *cell
10641  *  @param[in]  RgSchUeCb    *ue
10642  *  @param[in]  RgSchDlLcCb  *dlLc
10643  *  @param[int] RgrLchCfg    *lcCfg
10644  *  @param[out] RgSchErrInfo *err
10645  *  @return  S16
10646  *      -# ROK
10647  *      -# RFAILED
10648  **/
10649 S16 rgSCHCmnRgrLchCfg
10650 (
10651 RgSchCellCb  *cell,
10652 RgSchUeCb    *ue,
10653 RgSchDlLcCb  *dlLc,
10654 RgrLchCfg *lcCfg,
10655 RgSchErrInfo *err
10656 )
10657 {
10658    S16 ret;
10659
10660    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10661
10662
10663    ret = rgSCHUtlAllocSBuf(cell->instIdx,
10664       (Data**)&((dlLc)->sch), (sizeof(RgSchCmnDlSvc)));
10665    if (ret != ROK)
10666    {
10667       DU_LOG("\nERROR  -->  SCH : rgSCHCmnRgrLchCfg(): "
10668          "SCH struct alloc failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10669       err->errCause = RGSCHERR_SCH_CFG;
10670       return (ret);
10671    }
10672    if(lcCfg->lcType != CM_LTE_LCH_DCCH)
10673    {
10674       ret = rgSCHCmnValidateDlQos(&lcCfg->dlInfo.dlQos);
10675       if (ret != ROK)
10676       {
10677          DU_LOG("\nERROR  -->  SCH : rgSchCmnCrgLcCfg(): "
10678             "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10679          err->errCause = RGSCHERR_SCH_CFG;
10680          return (ret);
10681       }
10682       /* Perform DL service activation in the scheduler */
10683       ((RgSchCmnDlSvc *)(dlLc->sch))->qci = lcCfg->dlInfo.dlQos.qci;
10684       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = rgSchCmnDlQciPrio[lcCfg->dlInfo.dlQos.qci - 1];
10685       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcCfg->dlInfo.dlQos.gbr * \
10686       RG_SCH_CMN_REFRESH_TIME)/100;
10687       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcCfg->dlInfo.dlQos.mbr * \
10688       RG_SCH_CMN_REFRESH_TIME)/100;
10689    }
10690    else
10691    {
10692      /*assigning highest priority to DCCH */
10693     ((RgSchCmnDlSvc *)(dlLc->sch))->prio=RG_SCH_CMN_DCCH_PRIO; 
10694    }   
10695    dlLc->ue = ue;
10696    dlLc->lcType=lcCfg->lcType;
10697
10698 #ifdef EMTC_ENABLE
10699    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
10700    {
10701       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcCfg(cell, ue,dlLc ,lcCfg, err);
10702       if (ret != ROK)
10703       {
10704          return RFAILED;
10705       }
10706    }
10707    else
10708 #endif 
10709    {
10710       ret = cellSch->apisDl->rgSCHRgrDlLcCfg(cell, ue, dlLc, lcCfg, err);
10711       if (ret != ROK)
10712       {
10713          return RFAILED;
10714       }
10715    }
10716    
10717 #ifdef EMTC_ENABLE
10718    if(TRUE == ue->isEmtcUe)
10719    {
10720       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
10721       if (ret != ROK)
10722       {
10723          return RFAILED;
10724       }
10725    }
10726    else
10727 #endif 
10728    {
10729    ret = cellSch->apisUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
10730    if (ret != ROK)
10731    {
10732       return RFAILED;
10733    }
10734    }
10735    
10736 #ifdef LTE_ADV
10737    if (ue->numSCells)
10738    {
10739       rgSCHSCellDlLcCfg(cell, ue, dlLc);
10740    }
10741 #endif
10742
10743
10744 #ifdef LTEMAC_SPS
10745    if(lcCfg->dlInfo.dlSpsCfg.isSpsEnabled)
10746    {
10747       /* Invoke SPS module if SPS is enabled for the service */
10748       ret = rgSCHCmnSpsDlLcCfg(cell, ue, dlLc, lcCfg, err);
10749       if (ret != ROK)
10750       {
10751          DU_LOG("\nERROR  -->  SCH : rgSchCmnRgrLchCfg(): "
10752             "SPS configuration failed for DL LC for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10753          err->errCause = RGSCHERR_SCH_CFG;
10754          return RFAILED;
10755       }
10756    }
10757 #endif
10758
10759    return ROK;
10760 }
10761
10762 /**
10763  * @brief Scheduler invocation on logical channel addition.
10764  *
10765  * @details
10766  *
10767  *     Function : rgSCHCmnRgrLchRecfg
10768  *
10769  *     This functions does required processing when an existing
10770  *     (dedicated) logical channel is reconfigured. Assumes lcg
10771  *     pointer in ulLc is set to the old value.
10772  *     Independent of whether new LCG is meant to be configured,
10773  *     the new LCG scheduler information is accessed and possibly modified.
10774  *
10775  *  @param[in]  RgSchCellCb  *cell
10776  *  @param[in]  RgSchUeCb    *ue
10777  *  @param[in]  RgSchDlLcCb  *dlLc
10778  *  @param[int] RgrLchRecfg  *lcRecfg
10779  *  @param[out] RgSchErrInfo *err
10780  *  @return  S16
10781  *      -# ROK
10782  *      -# RFAILED
10783  **/
10784 S16 rgSCHCmnRgrLchRecfg
10785 (
10786 RgSchCellCb  *cell,
10787 RgSchUeCb    *ue,
10788 RgSchDlLcCb  *dlLc,
10789 RgrLchRecfg  *lcRecfg,
10790 RgSchErrInfo *err
10791 )
10792 {
10793    S16   ret;
10794    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10795
10796
10797    if(dlLc->lcType != CM_LTE_LCH_DCCH)
10798    {
10799       ret = rgSCHCmnValidateDlQos(&lcRecfg->dlRecfg.dlQos);
10800    
10801       if (ret != ROK)
10802       {
10803          DU_LOG("\nERROR  -->  SCH : DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10804          err->errCause = RGSCHERR_SCH_CFG;
10805          return (ret);
10806       }
10807       if (((RgSchCmnDlSvc *)(dlLc->sch))->qci != lcRecfg->dlRecfg.dlQos.qci)
10808       {
10809          DU_LOG("\nERROR  -->  SCH : Qci, hence lc Priority change "
10810             "not supported for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10811          err->errCause = RGSCHERR_SCH_CFG;
10812          return (ret);
10813       }
10814       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcRecfg->dlRecfg.dlQos.gbr * \
10815       RG_SCH_CMN_REFRESH_TIME)/100;
10816       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcRecfg->dlRecfg.dlQos.mbr * \
10817       RG_SCH_CMN_REFRESH_TIME)/100;
10818    }
10819    else
10820    {
10821       /*assigning highest priority to DCCH */
10822       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = RG_SCH_CMN_DCCH_PRIO; 
10823    }
10824    
10825 #ifdef EMTC_ENABLE
10826    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
10827    {
10828       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10829       if (ret != ROK)
10830       {
10831          return RFAILED;
10832       }
10833       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
10834       if (ret != ROK)
10835       {
10836          return RFAILED;
10837       }
10838    }
10839    else
10840 #endif 
10841    {
10842    ret = cellSch->apisDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10843    if (ret != ROK)
10844    {
10845       return RFAILED;
10846    }
10847    ret = cellSch->apisUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
10848    if (ret != ROK)
10849    {
10850       return RFAILED;
10851    }
10852    }
10853     
10854 #ifdef LTEMAC_SPS
10855    if (lcRecfg->recfgTypes & RGR_DL_LC_SPS_RECFG)
10856    {
10857       /* Invoke SPS module if SPS is enabled for the service */
10858       if(lcRecfg->dlRecfg.dlSpsRecfg.isSpsEnabled)
10859       {
10860          ret = rgSCHCmnSpsDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10861          if (ret != ROK)
10862          {
10863             DU_LOG("\nERROR  -->  SCH : SPS re-configuration not "
10864                   "supported for dlLC Ignore this CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10865          }
10866       }
10867       return ROK;
10868    }
10869 #endif
10870
10871    return ROK;
10872 }
10873
10874 /**
10875  * @brief Scheduler invocation on logical channel addition.
10876  *
10877  * @details
10878  *
10879  *     Function : rgSCHCmnRgrLcgCfg
10880  *
10881  *     This functions does required processing when a new
10882  *     (dedicated) logical channel is added. Assumes lcg
10883  *     pointer in ulLc is set.
10884  *
10885  *  @param[in]  RgSchCellCb  *cell,
10886  *  @param[in]  RgSchUeCb    *ue,
10887  *  @param[in]  RgSchLcgCb   *lcg,
10888  *  @param[in]  RgrLcgCfg    *lcgCfg,
10889  *  @param[out] RgSchErrInfo *err
10890  *  @return  S16
10891  *      -# ROK
10892  *      -# RFAILED
10893  **/
10894 S16 rgSCHCmnRgrLcgCfg
10895 (
10896 RgSchCellCb  *cell,
10897 RgSchUeCb    *ue,
10898 RgSchLcgCb   *lcg,
10899 RgrLcgCfg    *lcgCfg,
10900 RgSchErrInfo *err
10901 )
10902 {
10903    S16 ret;
10904    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10905    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].sch));
10906
10907
10908    ulLcg->cfgdGbr = (lcgCfg->ulInfo.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
10909    ulLcg->effGbr  = ulLcg->cfgdGbr;
10910    ulLcg->deltaMbr = ((lcgCfg->ulInfo.mbr - lcgCfg->ulInfo.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
10911    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
10912
10913 #ifdef EMTC_ENABLE
10914    if(TRUE == ue->isEmtcUe)
10915    {
10916       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
10917       if (ret != ROK)
10918       {
10919          return RFAILED;
10920       }
10921    }
10922    else
10923 #endif
10924    {
10925    ret = cellSch->apisUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
10926    if (ret != ROK)
10927    {
10928       return RFAILED;
10929    }
10930    }
10931    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
10932    {
10933       /* Indicate MAC that this LCG is GBR LCG */
10934       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcgCfg->ulInfo.lcgId, TRUE);
10935    }
10936    return ROK;
10937 }
10938
10939 /**
10940  * @brief Scheduler invocation on logical channel addition.
10941  *
10942  * @details
10943  *
10944  *     Function : rgSCHCmnRgrLcgRecfg
10945  *
10946  *     This functions does required processing when a new
10947  *     (dedicated) logical channel is added. Assumes lcg
10948  *     pointer in ulLc is set.
10949  *
10950  *  @param[in]  RgSchCellCb  *cell,
10951  *  @param[in]  RgSchUeCb    *ue,
10952  *  @param[in]  RgSchLcgCb   *lcg,
10953  *  @param[in]  RgrLcgRecfg  *reCfg,
10954  *  @param[out] RgSchErrInfo *err
10955  *  @return  S16
10956  *      -# ROK
10957  *      -# RFAILED
10958  **/
10959 S16 rgSCHCmnRgrLcgRecfg
10960 (
10961 RgSchCellCb  *cell,
10962 RgSchUeCb    *ue,
10963 RgSchLcgCb   *lcg,
10964 RgrLcgRecfg  *reCfg,
10965 RgSchErrInfo *err
10966 )
10967 {
10968    S16 ret;
10969    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10970    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[reCfg->ulRecfg.lcgId].sch));
10971    
10972
10973    ulLcg->cfgdGbr = (reCfg->ulRecfg.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
10974    ulLcg->effGbr  = ulLcg->cfgdGbr;
10975    ulLcg->deltaMbr = ((reCfg->ulRecfg.mbr - reCfg->ulRecfg.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
10976    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
10977  
10978 #ifdef EMTC_ENABLE
10979    if(TRUE == ue->isEmtcUe)
10980    {
10981       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
10982       if (ret != ROK)
10983       {
10984          return RFAILED;
10985       }
10986    }
10987    else
10988 #endif
10989    {
10990    ret = cellSch->apisUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
10991    if (ret != ROK)
10992    {
10993       return RFAILED;
10994    }
10995    }
10996    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
10997    {
10998       /* Indicate MAC that this LCG is GBR LCG */
10999       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, TRUE);
11000    }
11001    else
11002    {
11003       /* In case of RAB modification */
11004       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, FALSE);
11005    }
11006    return ROK;
11007 }
11008
11009 /***********************************************************
11010  *
11011  *     Func : rgSCHCmnRgrLchDel
11012  *
11013  *     Desc : Scheduler handling for a (dedicated)
11014  *             uplink logical channel being deleted.
11015  *
11016  *     Ret  :
11017  *
11018  *     Notes:
11019  *
11020  *     File :
11021  **********************************************************/
11022 S16 rgSCHCmnRgrLchDel(RgSchCellCb *cell,RgSchUeCb *ue,CmLteLcId lcId,uint8_t lcgId)
11023 {
11024    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11025 #ifdef EMTC_ENABLE
11026    if(TRUE == ue->isEmtcUe)
11027    {
11028       cellSch->apisEmtcUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
11029    }
11030    else
11031 #endif
11032    {
11033    cellSch->apisUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
11034    }
11035    return ROK;
11036 }
11037
11038 /***********************************************************
11039  *
11040  *     Func : rgSCHCmnLcgDel
11041  *
11042  *     Desc : Scheduler handling for a (dedicated)
11043  *             uplink logical channel being deleted.
11044  *
11045  *     Ret  :
11046  *
11047  *     Notes:
11048  *
11049  *     File :
11050  *
11051  **********************************************************/
11052 Void rgSCHCmnLcgDel(RgSchCellCb *cell,RgSchUeCb *ue,RgSchLcgCb *lcg)
11053 {
11054    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11055    RgSchCmnLcg  *lcgCmn = RG_SCH_CMN_GET_UL_LCG(lcg);
11056
11057    if (lcgCmn == NULLP)
11058    {
11059       return;
11060    }
11061
11062    if (RGSCH_IS_GBR_BEARER(lcgCmn->cfgdGbr))
11063    {
11064       /* Indicate MAC that this LCG is GBR LCG */
11065       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcg->lcgId, FALSE);
11066    }
11067
11068 #ifdef LTEMAC_SPS
11069    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
11070    {
11071       rgSCHCmnSpsUlLcgDel(cell, ue, lcg);
11072    }
11073 #endif /* LTEMAC_SPS */
11074
11075    lcgCmn->effGbr     = 0;
11076    lcgCmn->reportedBs = 0;
11077    lcgCmn->cfgdGbr    = 0;
11078    /* set lcg bs to 0. Deletion of control block happens
11079     * at the time of UE deletion. */
11080    lcgCmn->bs = 0;
11081 #ifdef EMTC_ENABLE
11082    if(TRUE == ue->isEmtcUe)
11083    {
11084       cellSch->apisEmtcUl->rgSCHFreeUlLcg(cell, ue, lcg);
11085    }
11086    else
11087 #endif
11088    {
11089    cellSch->apisUl->rgSCHFreeUlLcg(cell, ue, lcg);
11090    }
11091    return;
11092 }
11093
11094 \f
11095 /**
11096  * @brief This function deletes a service from scheduler.
11097  *
11098  * @details
11099  *
11100  *     Function: rgSCHCmnFreeDlLc
11101  *     Purpose:  This function is made available through a FP for
11102  *               making scheduler aware of a service being deleted from UE.
11103  *
11104  *     Invoked by: BO and Scheduler
11105  *
11106  *  @param[in]  RgSchCellCb*  cell
11107  *  @param[in]  RgSchUeCb*    ue
11108  *  @param[in]  RgSchDlLcCb*  svc
11109  *  @return  Void
11110  *
11111  **/
11112 Void rgSCHCmnFreeDlLc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
11113 {
11114    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11115    if (svc->sch == NULLP)
11116    {
11117       return;
11118    }
11119 #ifdef EMTC_ENABLE
11120     if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
11121     {
11122       cellSch->apisEmtcDl->rgSCHFreeDlLc(cell, ue, svc);
11123     }
11124     else
11125 #endif
11126    {
11127       cellSch->apisDl->rgSCHFreeDlLc(cell, ue, svc);
11128    }
11129
11130 #ifdef LTE_ADV
11131    if (ue->numSCells)
11132    {
11133       rgSCHSCellDlLcDel(cell, ue, svc);
11134    }
11135 #endif
11136
11137 #ifdef LTEMAC_SPS
11138    /* If SPS service, invoke SPS module */
11139    if (svc->dlLcSpsCfg.isSpsEnabled)
11140    {
11141       rgSCHCmnSpsDlLcDel(cell, ue, svc);
11142    }
11143 #endif
11144
11145    /* ccpu00117052 - MOD - Passing double pointer
11146    for proper NULLP assignment*/
11147    rgSCHUtlFreeSBuf(cell->instIdx,
11148          (Data**)(&(svc->sch)), (sizeof(RgSchCmnDlSvc)));
11149
11150 #ifdef LTE_ADV
11151    rgSCHLaaDeInitDlLchCb(cell, svc);
11152 #endif
11153
11154    return;
11155 }
11156
11157 #ifdef RGR_V1
11158
11159 /**
11160  * @brief This function Processes the Final Allocations
11161  *        made by the RB Allocator against the requested
11162  *        CCCH SDURetx Allocations.
11163  *
11164  * @details
11165  *
11166  *     Function: rgSCHCmnDlCcchSduRetxFnlz
11167  *     Purpose:  This function Processes the Final Allocations
11168  *               made by the RB Allocator against the requested
11169  *               CCCH Retx Allocations.
11170  *               Scans through the scheduled list of ccchSdu retrans
11171  *               fills the corresponding pdcch, adds the hqProc to
11172  *               the corresponding SubFrm and removes the hqP from
11173  *               cells retx List.
11174  *
11175  *     Invoked by: Common Scheduler
11176  *
11177  *  @param[in]  RgSchCellCb           *cell
11178  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11179  *  @return  Void
11180  *
11181  **/
11182 static Void rgSCHCmnDlCcchSduRetxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11183 {
11184    CmLList           *node;
11185    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11186    RgSchDlRbAlloc    *rbAllocInfo;
11187    RgSchDlHqProcCb   *hqP;
11188    RgSchUeCb         *ue;
11189
11190    /* Traverse through the Scheduled Retx List */
11191    node = allocInfo->ccchSduAlloc.schdCcchSduRetxLst.first;
11192    while (node)
11193    {
11194       hqP = (RgSchDlHqProcCb *)(node->node);
11195       ue = hqP->hqE->ue;
11196       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
11197       node = node->next;
11198       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11199
11200       /* Remove the HqP from cell's ccchSduRetxLst */
11201       cmLListDelFrm(&cmnCellDl->ccchSduRetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
11202       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
11203
11204       /* Fix: syed dlAllocCb reset should be performed.
11205        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11206       rgSCHCmnDlUeResetTemp(ue, hqP);
11207    }
11208    /* Fix: syed dlAllocCb reset should be performed.
11209     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11210    node = allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst.first;
11211    while(node)
11212    {
11213       hqP = (RgSchDlHqProcCb *)(node->node);
11214       ue = hqP->hqE->ue;
11215       node = node->next;
11216       /* reset the UE allocation Information */
11217       rgSCHCmnDlUeResetTemp(ue, hqP);
11218    }
11219    return;
11220 }
11221 #endif
11222 /**
11223  * @brief This function Processes the Final Allocations
11224  *        made by the RB Allocator against the requested
11225  *        CCCH Retx Allocations.
11226  *
11227  * @details
11228  *
11229  *     Function: rgSCHCmnDlCcchRetxFnlz
11230  *     Purpose:  This function Processes the Final Allocations
11231  *               made by the RB Allocator against the requested
11232  *               CCCH Retx Allocations.
11233  *               Scans through the scheduled list of msg4 retrans
11234  *               fills the corresponding pdcch, adds the hqProc to
11235  *               the corresponding SubFrm and removes the hqP from
11236  *               cells retx List.
11237  *
11238  *     Invoked by: Common Scheduler
11239  *
11240  *  @param[in]  RgSchCellCb           *cell
11241  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11242  *  @return  Void
11243  *
11244  **/
11245 static Void rgSCHCmnDlCcchRetxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11246 {
11247    CmLList           *node;
11248    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11249    RgSchDlRbAlloc    *rbAllocInfo;
11250    RgSchDlHqProcCb   *hqP;
11251    RgSchRaCb         *raCb;
11252
11253    /* Traverse through the Scheduled Retx List */
11254    node = allocInfo->msg4Alloc.schdMsg4RetxLst.first;
11255    while (node)
11256    {
11257       hqP = (RgSchDlHqProcCb *)(node->node);
11258       raCb = hqP->hqE->raCb;
11259       rbAllocInfo = &raCb->rbAllocInfo;
11260       node = node->next;
11261       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11262
11263       /* Remove the HqP from cell's msg4RetxLst */
11264       cmLListDelFrm(&cmnCellDl->msg4RetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
11265       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
11266       /* Fix: syed dlAllocCb reset should be performed.
11267        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11268       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
11269       rgSCHCmnDlHqPResetTemp(hqP);
11270    }
11271    /* Fix: syed dlAllocCb reset should be performed.
11272     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11273    node = allocInfo->msg4Alloc.nonSchdMsg4RetxLst.first;
11274    while(node)
11275    {
11276       hqP = (RgSchDlHqProcCb *)(node->node);
11277       raCb = hqP->hqE->raCb;
11278       node = node->next;
11279       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
11280       rgSCHCmnDlHqPResetTemp(hqP);
11281    }
11282    return;
11283 }
11284
11285 #ifdef RGR_V1
11286 /**
11287  * @brief This function Processes the Final Allocations
11288  *        made by the RB Allocator against the requested
11289  *        CCCH SDU tx Allocations.
11290  *
11291  * @details
11292  *
11293  *     Function: rgSCHCmnDlCcchSduTxFnlz
11294  *     Purpose:  This function Processes the Final Allocations
11295  *               made by the RB Allocator against the requested
11296  *               CCCH tx Allocations.
11297  *               Scans through the scheduled list of CCCH SDU trans
11298  *               fills the corresponding pdcch, adds the hqProc to
11299  *               the corresponding SubFrm and removes the hqP from
11300  *               cells tx List.
11301  *
11302  *     Invoked by: Common Scheduler
11303  *
11304  *  @param[in]  RgSchCellCb           *cell
11305  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11306  *  @return  Void
11307  *
11308  **/
11309 static Void rgSCHCmnDlCcchSduTxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11310 {
11311    CmLList           *node;
11312    RgSchUeCb         *ueCb;
11313    RgSchDlRbAlloc    *rbAllocInfo;
11314    RgSchDlHqProcCb   *hqP;
11315    RgSchLchAllocInfo  lchSchdData;
11316
11317    /* Traverse through the Scheduled Retx List */
11318    node = allocInfo->ccchSduAlloc.schdCcchSduTxLst.first;
11319    while (node)
11320    {
11321       hqP = (RgSchDlHqProcCb *)(node->node);
11322       ueCb = hqP->hqE->ue;
11323       node = node->next;
11324       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
11325
11326       /* fill the pdcch and HqProc */
11327       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11328
11329       /* Remove the raCb from cell's toBeSchdLst */
11330       cmLListDelFrm(&cell->ccchSduUeLst, &ueCb->ccchSduLnk);
11331       ueCb->ccchSduLnk.node = (PTR)NULLP;
11332
11333       /* Fix : Resetting this required to avoid complication
11334        * in reestablishment case */
11335       ueCb->dlCcchInfo.bo = 0;
11336
11337       /* Indicate DHM of the CCCH LC scheduling */
11338       hqP->tbInfo[0].contResCe = NOTPRSNT;
11339       lchSchdData.lcId     = 0;
11340       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
11341                              (RGSCH_MSG4_HDRSIZE);
11342       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
11343
11344       /* Fix: syed dlAllocCb reset should be performed.
11345        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11346       rgSCHCmnDlUeResetTemp(ueCb, hqP);
11347    }
11348    /* Fix: syed dlAllocCb reset should be performed.
11349     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11350    node = allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst.first;
11351    while(node)
11352    {
11353       hqP = (RgSchDlHqProcCb *)(node->node);
11354       ueCb = hqP->hqE->ue;
11355       node = node->next;
11356       /* Release HqProc */
11357       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
11358       /*Fix: Removing releasing of TB1 as it will not exist for CCCH SDU and hence caused a crash*/
11359       /*rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
11360       /* reset the UE allocation Information */
11361       rgSCHCmnDlUeResetTemp(ueCb, hqP);
11362    }
11363    return;
11364 }
11365
11366 #endif
11367 /**
11368  * @brief This function Processes the Final Allocations
11369  *        made by the RB Allocator against the requested
11370  *        CCCH tx Allocations.
11371  *
11372  * @details
11373  *
11374  *     Function: rgSCHCmnDlCcchTxFnlz
11375  *     Purpose:  This function Processes the Final Allocations
11376  *               made by the RB Allocator against the requested
11377  *               CCCH tx Allocations.
11378  *               Scans through the scheduled list of msg4 trans
11379  *               fills the corresponding pdcch, adds the hqProc to
11380  *               the corresponding SubFrm and removes the hqP from
11381  *               cells tx List.
11382  *
11383  *     Invoked by: Common Scheduler
11384  *
11385  *  @param[in]  RgSchCellCb           *cell
11386  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11387  *  @return  Void
11388  *
11389  **/
11390 static Void rgSCHCmnDlCcchTxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11391 {
11392    CmLList           *node;
11393    RgSchRaCb         *raCb;
11394    RgSchDlRbAlloc    *rbAllocInfo;
11395    RgSchDlHqProcCb   *hqP;
11396    RgSchLchAllocInfo  lchSchdData;
11397
11398    /* Traverse through the Scheduled Retx List */
11399    node = allocInfo->msg4Alloc.schdMsg4TxLst.first;
11400    while (node)
11401    {
11402       hqP = (RgSchDlHqProcCb *)(node->node);
11403       raCb = hqP->hqE->raCb;
11404       node = node->next;
11405       rbAllocInfo = &raCb->rbAllocInfo;
11406
11407       /* fill the pdcch and HqProc */
11408       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11409       /* MSG4 Fix Start */
11410      
11411       rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
11412       /* MSG4 Fix End */     
11413
11414       /* Indicate DHM of the CCCH LC scheduling */
11415       lchSchdData.lcId     = 0;
11416       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
11417          (RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE);
11418       /* TRansmitting presence of cont Res CE across MAC-SCH interface to
11419        * identify CCCH SDU transmissions which need to be done
11420        * without the
11421        * contention resolution CE*/
11422       hqP->tbInfo[0].contResCe = PRSNT_NODEF;
11423       /*Dont add lc if only cont res CE is being transmitted*/
11424       if(raCb->dlCcchInfo.bo)
11425       {
11426          rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
11427       }
11428       else
11429       {
11430       }
11431       /* Fix: syed dlAllocCb reset should be performed.
11432        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11433       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
11434       rgSCHCmnDlHqPResetTemp(hqP);
11435    }
11436    node = allocInfo->msg4Alloc.nonSchdMsg4TxLst.first;
11437    while(node)
11438    {
11439       hqP = (RgSchDlHqProcCb *)(node->node);
11440       raCb = hqP->hqE->raCb;
11441       node = node->next;
11442       rbAllocInfo = &raCb->rbAllocInfo;
11443       /* Release HqProc */
11444       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
11445       /*Fix: Removing releasing of TB1 as it will not exist for MSG4 and hence caused a crash*/
11446       /*      rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
11447       /* reset the UE allocation Information */
11448       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
11449       rgSCHCmnDlHqPResetTemp(hqP);
11450    }
11451
11452    return;
11453 }
11454 /* R8 Upgrade */
11455 /**
11456  * @brief This function calculates the BI Index to be sent in the Bi header
11457  * field.
11458  *
11459  * @details
11460  *     Function: rgSCHCmnGetBiIndex
11461  *     Purpose:  This function Processes utilizes the previous BI time value
11462  *     calculated and the difference last BI sent time and current time. To
11463  *     calculate the latest BI Index. It also considers the how many UE's
11464  *     Unserved in this subframe.
11465  *
11466  *     Invoked by: Common Scheduler
11467  *
11468  *  @param[in]  RgSchCellCb           *cell
11469  *  @param[in]  uint32_t                   ueCount
11470  *  @return  uint8_t
11471  *
11472  **/
11473 uint8_t rgSCHCmnGetBiIndex(RgSchCellCb *cell,uint32_t ueCount)
11474 {
11475    S16  prevVal = 0;      /* To Store Intermediate Value */
11476    uint16_t  newBiVal = 0;     /* To store Bi Value in millisecond */
11477    uint8_t   idx = 0;
11478    uint16_t  timeDiff = 0;
11479
11480
11481    if (cell->biInfo.prevBiTime != 0)
11482    {
11483 #ifdef EMTC_ENABLE
11484       if(cell->emtcEnable == TRUE)
11485       {
11486          timeDiff =(RGSCH_CALC_SF_DIFF_EMTC(cell->crntTime, cell->biInfo.biTime));
11487       }
11488       else
11489 #endif
11490       {
11491          timeDiff =(RGSCH_CALC_SF_DIFF(cell->crntTime, cell->biInfo.biTime));
11492       }
11493
11494       prevVal = cell->biInfo.prevBiTime - timeDiff;
11495    }
11496    if (prevVal < 0)
11497    {
11498       prevVal = 0;
11499    }
11500    newBiVal = RG_SCH_CMN_GET_BI_VAL(prevVal,ueCount);
11501    /* To be used next time when BI is calculated */
11502 #ifdef EMTC_ENABLE
11503    if(cell->emtcEnable == TRUE)
11504    {
11505       RGSCHCPYTIMEINFO_EMTC(cell->crntTime, cell->biInfo.biTime)
11506    }
11507    else
11508 #endif
11509    {
11510       RGSCHCPYTIMEINFO(cell->crntTime, cell->biInfo.biTime)
11511    }
11512
11513   /* Search the actual BI Index from table Backoff Parameters Value  and
11514    * return that Index */
11515    do
11516    {
11517       if (rgSchCmnBiTbl[idx] > newBiVal)
11518       {
11519          break;
11520       }
11521       idx++;
11522    }while(idx < RG_SCH_CMN_NUM_BI_VAL-1);
11523    cell->biInfo.prevBiTime = rgSchCmnBiTbl[idx];
11524    /* For 16 Entries in Table 7.2.1 36.321.880 - 3 reserved so total 13 Entries */
11525    return (idx); /* Returning reserved value from table UE treats it has 960 ms */
11526 } /* rgSCHCmnGetBiIndex */
11527
11528
11529 /**
11530  * @brief This function Processes the Final Allocations
11531  *        made by the RB Allocator against the requested
11532  *        RAR allocations. Assumption: The reuqested
11533  *        allocations are always satisfied completely.
11534  *        Hence no roll back.
11535  *
11536  * @details
11537  *
11538  *     Function: rgSCHCmnDlRaRspFnlz
11539  *     Purpose:  This function Processes the Final Allocations
11540  *               made by the RB Allocator against the requested.
11541  *               Takes care of PDCCH filling.
11542  *
11543  *     Invoked by: Common Scheduler
11544  *
11545  *  @param[in]  RgSchCellCb           *cell
11546  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11547  *  @return  Void
11548  *
11549  **/
11550 static Void rgSCHCmnDlRaRspFnlz(RgSchCellCb  *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11551 {
11552    uint32_t       rarCnt = 0;
11553    RgSchDlRbAlloc *raRspAlloc;
11554    RgSchDlSf      *subFrm = NULLP;
11555    RgSchRaCb      *raCb;
11556    RgSchErrInfo   err;
11557    CmLListCp      *reqLst;
11558    RgSchRaReqInfo *raReq;
11559    Bool           preamGrpA;
11560    RgSchUlAlloc   *ulAllocRef=NULLP;
11561    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11562    uint8_t        allocRapidCnt = 0;
11563 #ifdef LTE_TDD
11564    uint32_t       msg3SchdIdx = 0;
11565    uint8_t        ulDlCfgIdx = cell->ulDlCfgIdx;
11566    uint8_t        msg3Subfrm;
11567 #endif
11568
11569
11570    for (rarCnt=0; rarCnt<RG_SCH_CMN_MAX_CMN_PDCCH; rarCnt++)
11571    {
11572       raRspAlloc = &allocInfo->raRspAlloc[rarCnt];
11573       /* Having likely condition first for optimization */
11574       if (!raRspAlloc->pdcch)
11575       {
11576          continue;
11577       }
11578       else
11579       {
11580          subFrm = raRspAlloc->dlSf;
11581          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
11582          /* Corrected RACH handling for multiple RAPIDs per RARNTI */
11583          allocRapidCnt = raRspAlloc->numRapids;
11584          while (allocRapidCnt)
11585          {
11586             raReq = (RgSchRaReqInfo *)(reqLst->first->node);
11587             /* RACHO: If dedicated preamble, then allocate UL Grant
11588              * (consequence of handover/pdcchOrder) and continue */
11589             if (RGSCH_IS_DEDPRM(cell, raReq->raReq.rapId))
11590             {
11591                rgSCHCmnHdlHoPo(cell, &subFrm->raRsp[rarCnt].contFreeUeLst,
11592                      raReq);
11593                cmLListDelFrm(reqLst, reqLst->first);
11594                allocRapidCnt--;
11595                /* ccpu00117052 - MOD - Passing double pointer
11596                for proper NULLP assignment*/
11597                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11598                      sizeof(RgSchRaReqInfo));
11599                continue;
11600             }
11601             /* ccpu00139815 */
11602             if(cell->overLoadBackOffEnab)
11603             {/* rach Overlaod conrol is triggerd, Skipping this rach */
11604                cmLListDelFrm(reqLst, reqLst->first);
11605                allocRapidCnt--;
11606                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11607                      sizeof(RgSchRaReqInfo));
11608                continue;
11609             }
11610             /* Attempt to include each RA request into the RSP */
11611             /* Any failure in the procedure is considered to   */
11612             /* affect futher allocations in the same TTI. When */
11613             /* a failure happens, we break out and complete    */
11614             /* the processing for random access                */
11615             if (rgSCHRamCreateRaCb(cell, &raCb, &err) != ROK)
11616             {
11617                break;
11618             }
11619             /* Msg3 allocation request to USM */
11620             if (raReq->raReq.rapId < cell->rachCfg.sizeRaPreambleGrpA)
11621                preamGrpA = TRUE;
11622             else
11623                preamGrpA = FALSE;
11624             /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
11625             rgSCHCmnMsg3GrntReq(cell, raCb->tmpCrnti, preamGrpA, \
11626                   &(raCb->msg3HqProc), &ulAllocRef, &raCb->msg3HqProcId);
11627             if (ulAllocRef == NULLP)
11628             {
11629                rgSCHRamDelRaCb(cell, raCb, TRUE);
11630                break;
11631             }
11632             if (raReq->raReq.cqiPres)
11633             {
11634                raCb->ccchCqi = raReq->raReq.cqiIdx;
11635             }
11636             else
11637             {
11638                raCb->ccchCqi = cellDl->ccchCqi;
11639             }
11640             raCb->rapId = raReq->raReq.rapId;
11641             raCb->ta.pres    = TRUE;
11642             raCb->ta.val = raReq->raReq.ta;
11643             raCb->msg3Grnt = ulAllocRef->grnt;
11644             /* Populating the tpc value received */
11645             raCb->msg3Grnt.tpc = raReq->raReq.tpc;
11646             /* PHR handling for MSG3 */
11647             ulAllocRef->raCb = raCb;
11648 #ifndef LTE_TDD
11649             /* To the crntTime, add the MIN time at which UE will
11650              * actually send MSG3 i.e DL_DELTA+6 */
11651             raCb->msg3AllocTime = cell->crntTime;
11652             RGSCH_INCR_SUB_FRAME(raCb->msg3AllocTime, RG_SCH_CMN_MIN_MSG3_RECP_INTRVL);
11653 #else
11654             msg3SchdIdx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % 
11655                                  RGSCH_NUM_SUB_FRAMES;
11656             /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
11657               special subframe */                       
11658             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][msg3SchdIdx] != 
11659                         RG_SCH_TDD_UL_SUBFRAME)
11660             {
11661                RGSCHCMNADDTOCRNTTIME(cell->crntTime,raCb->msg3AllocTime,
11662                                        RG_SCH_CMN_DL_DELTA)
11663                msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][
11664                                        raCb->msg3AllocTime.slot];
11665                RGSCHCMNADDTOCRNTTIME(raCb->msg3AllocTime, raCb->msg3AllocTime, 
11666                                  msg3Subfrm);
11667             }
11668 #endif
11669             cmLListAdd2Tail(&subFrm->raRsp[rarCnt].raRspLst, &raCb->rspLnk);
11670             raCb->rspLnk.node = (PTR)raCb;
11671             cmLListDelFrm(reqLst, reqLst->first);
11672             allocRapidCnt--;
11673             /* ccpu00117052 - MOD - Passing double pointer
11674             for proper NULLP assignment*/
11675             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11676                   sizeof(RgSchRaReqInfo));
11677
11678             /* SR_RACH_STATS : RAR scheduled */
11679             rgNumRarSched++;
11680
11681          }
11682          /* R8 Upgrade */
11683          /* Fill subframe data members */
11684          subFrm->raRsp[rarCnt].raRnti = raRspAlloc->rnti;
11685          subFrm->raRsp[rarCnt].pdcch  = raRspAlloc->pdcch;
11686          subFrm->raRsp[rarCnt].tbSz   = raRspAlloc->tbInfo[0].bytesAlloc;
11687          /* Fill PDCCH data members */
11688          rgSCHCmnFillPdcch(cell, subFrm->raRsp[rarCnt].pdcch, raRspAlloc);
11689
11690          /* ccpu00139815 */
11691          if(cell->overLoadBackOffEnab)
11692          {/* rach Overlaod conrol is triggerd, Skipping this rach */
11693             subFrm->raRsp[rarCnt].backOffInd.pres = PRSNT_NODEF;
11694             subFrm->raRsp[rarCnt].backOffInd.val  = cell->overLoadBackOffval;
11695             continue;
11696          }
11697          else
11698          {
11699             subFrm->raRsp[rarCnt].backOffInd.pres = NOTPRSNT;
11700          }
11701
11702          /*[ccpu00125212] Avoiding sending of empty RAR in case of RAR window
11703            is short and UE is sending unauthorised preamble.*/
11704          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
11705          if ((raRspAlloc->biEstmt) && (reqLst->count))
11706          {
11707             subFrm->raRsp[0].backOffInd.pres = PRSNT_NODEF;
11708             /* Added as part of Upgrade */
11709             subFrm->raRsp[0].backOffInd.val =
11710             rgSCHCmnGetBiIndex(cell, reqLst->count);
11711
11712             /* SR_RACH_STATS : Back Off Inds */
11713             rgNumBI++;
11714
11715          }
11716          else if ((subFrm->raRsp[rarCnt].raRspLst.first == NULLP) &&
11717                (subFrm->raRsp[rarCnt].contFreeUeLst.first == NULLP))
11718          {
11719             /* Return the grabbed PDCCH */
11720             rgSCHUtlPdcchPut(cell, &subFrm->pdcchInfo, raRspAlloc->pdcch);
11721             subFrm->raRsp[rarCnt].pdcch = NULLP;
11722             DU_LOG("\nERROR  -->  SCH : rgSCHCmnRaRspAlloc(): "
11723                   "Not even one RaReq.");
11724             return;
11725          }
11726       }
11727       DU_LOG("\nDEBUG  -->  SCH : RNTI:%d Scheduled RAR @ (%u,%u) ",
11728             raRspAlloc->rnti, 
11729             cell->crntTime.sfn,
11730             cell->crntTime.slot);
11731    }
11732    return;
11733 }
11734
11735 /**
11736  * @brief This function computes rv.
11737  *
11738  * @details
11739  *
11740  *     Function: rgSCHCmnDlCalcRvForBcch
11741  *     Purpose:  This function computes rv.
11742  *
11743  *     Invoked by: Common Scheduler
11744  *
11745  *  @param[in]   RgSchCellCb     *cell
11746  *  @param[in]   Bool            si
11747  *  @param[in]   uint16_t             i
11748  *  @return  uint8_t
11749  *
11750  **/
11751 static uint8_t rgSCHCmnDlCalcRvForBcch(RgSchCellCb *cell,Bool si,uint16_t i)
11752 {
11753    uint8_t k, rv;
11754    CmLteTimingInfo   frm;
11755
11756    frm   = cell->crntTime;
11757    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
11758
11759    if(si)
11760    {
11761       k = i % 4;
11762    }
11763    else
11764    {
11765       k = (frm.sfn/2) % 4;
11766    }
11767    rv = RGSCH_CEIL(3*k, 2) % 4;
11768    return (rv);
11769 }
11770
11771 /**
11772  * @brief This function Processes the Final Allocations
11773  *        made by the RB Allocator against the requested
11774  *        BCCH/PCCH allocations. Assumption: The reuqested
11775  *        allocations are always satisfied completely.
11776  *        Hence no roll back.
11777  *
11778  * @details
11779  *
11780  *     Function: rgSCHCmnDlBcchPcchFnlz
11781  *     Purpose:  This function Processes the Final Allocations
11782  *               made by the RB Allocator against the requested.
11783  *               Takes care of PDCCH filling.
11784  *
11785  *     Invoked by: Common Scheduler
11786  *
11787  *  @param[in]  RgSchCellCb           *cell
11788  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11789  *  @return  Void
11790  *
11791  **/
11792 static Void rgSCHCmnDlBcchPcchFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11793 {
11794    RgSchDlRbAlloc *rbAllocInfo;
11795    RgSchDlSf      *subFrm;
11796
11797 #ifdef LTE_TDD
11798    uint8_t        nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
11799 #else
11800 #ifdef LTEMAC_HDFDD
11801    uint8_t        nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11802 #else
11803    uint8_t        nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11804 #endif
11805 #endif
11806
11807    /*  Moving variables to available scope for optimization */
11808    RgSchClcDlLcCb *pcch;
11809    RgSchClcBoRpt  *bo;
11810 #ifndef RGR_SI_SCH
11811    RgSchClcDlLcCb  *bcch;
11812    Bool           sendInd=TRUE;
11813 #endif
11814    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11815
11816
11817    /* handle PCCH */
11818    rbAllocInfo = &allocInfo->pcchAlloc;
11819    if (rbAllocInfo->pdcch)
11820    {
11821       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
11822
11823       /* Added sfIdx calculation for TDD as well */
11824 #ifndef LTE_TDD
11825 #ifdef LTEMAC_HDFDD
11826       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11827 #else
11828       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11829 #endif
11830 #endif
11831       subFrm = rbAllocInfo->dlSf;
11832       pcch = rgSCHDbmGetPcch(cell);
11833       if(pcch == NULLP)
11834       {
11835          DU_LOG("\nERROR  -->  SCH : rgSCHCmnDlBcchPcchFnlz( ): "
11836                "No Pcch Present");
11837          return;
11838       }
11839
11840       /* Added Dl TB count for paging message transmission*/
11841 #ifdef LTE_L2_MEAS
11842       cell->dlUlTbCnt.tbTransDlTotalCnt++;
11843 #endif      
11844       bo = (RgSchClcBoRpt *)pcch->boLst.first->node;
11845       cmLListDelFrm(&pcch->boLst, &bo->boLstEnt);
11846       /* ccpu00117052 - MOD - Passing double pointer
11847          for proper NULLP assignment*/
11848       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
11849       /* Fill subframe data members */
11850       subFrm->pcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
11851       subFrm->pcch.pdcch  = rbAllocInfo->pdcch;
11852       /* Fill PDCCH data members */
11853       rgSCHCmnFillPdcch(cell, subFrm->pcch.pdcch, rbAllocInfo);
11854       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, pcch->lcId, TRUE);
11855       /* ccpu00132314-ADD-Update the tx power allocation info  
11856          TODO-Need to add a check for max tx power per symbol */ 
11857       subfrmAlloc->cmnLcInfo.pcchInfo.txPwrOffset = cellDl->pcchTxPwrOffset;   
11858    }
11859
11860    /* handle BCCH */
11861    rbAllocInfo = &allocInfo->bcchAlloc;
11862    if (rbAllocInfo->pdcch)
11863    {
11864       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
11865 #ifndef LTE_TDD
11866 #ifdef LTEMAC_HDFDD
11867       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11868 #else
11869       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11870 #endif
11871 #endif
11872       subFrm = rbAllocInfo->dlSf;
11873
11874       /* Fill subframe data members */
11875       subFrm->bcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
11876       subFrm->bcch.pdcch  = rbAllocInfo->pdcch;
11877       /* Fill PDCCH data members */
11878       rgSCHCmnFillPdcch(cell, subFrm->bcch.pdcch, rbAllocInfo);
11879
11880       if(rbAllocInfo->schdFirst)
11881       {
11882 #ifndef RGR_SI_SCH
11883          bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
11884          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
11885 #else
11886          /*Copy the SIB1 msg buff into interface buffer */
11887          SCpyMsgMsg(cell->siCb.crntSiInfo.sib1Info.sib1,
11888                rgSchCb[cell->instIdx].rgSchInit.region,
11889                rgSchCb[cell->instIdx].rgSchInit.pool,
11890                &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11891 #endif/*RGR_SI_SCH*/
11892          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
11893             rgSCHCmnDlCalcRvForBcch(cell, FALSE, 0);
11894       }
11895       else
11896       {
11897          uint16_t   i;
11898 #ifdef RGR_SI_SCH
11899          Buffer    *pdu;
11900
11901          i = cell->siCb.siCtx.i;
11902          /*Decrement the retransmission count */
11903          cell->siCb.siCtx.retxCntRem--;
11904
11905          /*Copy the SI msg buff into interface buffer */
11906          if(cell->siCb.siCtx.warningSiFlag == FALSE)
11907          {
11908             SCpyMsgMsg(cell->siCb.siArray[cell->siCb.siCtx.siId-1].si,
11909                   rgSchCb[cell->instIdx].rgSchInit.region,
11910                   rgSchCb[cell->instIdx].rgSchInit.pool,
11911                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11912          }
11913          else
11914          {
11915             pdu = rgSCHUtlGetWarningSiPdu(cell);
11916             RGSCH_NULL_CHECK(cell->instIdx, pdu);
11917             SCpyMsgMsg(pdu,
11918                   rgSchCb[cell->instIdx].rgSchInit.region,
11919                   rgSchCb[cell->instIdx].rgSchInit.pool,
11920                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11921             if(cell->siCb.siCtx.retxCntRem == 0)
11922             {  
11923                rgSCHUtlFreeWarningSiPdu(cell);
11924                cell->siCb.siCtx.warningSiFlag  = FALSE;
11925
11926             }
11927          }
11928 #else
11929          bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
11930          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
11931          bo->retxCnt--;
11932          if(bo->retxCnt != cell->siCfg.retxCnt-1)
11933          {
11934             sendInd=FALSE;
11935          }
11936          i = bo->i;
11937 #endif/*RGR_SI_SCH*/
11938          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
11939             rgSCHCmnDlCalcRvForBcch(cell, TRUE, i);
11940       }
11941
11942       /* Added Dl TB count for SIB1 and SI messages transmission.
11943        * This counter will be incremented only for the first transmission
11944        * (with RV 0) of these messages*/
11945 #ifdef LTE_L2_MEAS
11946       if(subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv == 0)
11947       {   
11948          cell->dlUlTbCnt.tbTransDlTotalCnt++;
11949       }
11950 #endif      
11951 #ifndef RGR_SI_SCH
11952       if(bo->retxCnt == 0)
11953       {
11954          cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
11955          /* ccpu00117052 - MOD - Passing double pointer
11956             for proper NULLP assignment*/
11957          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
11958       }
11959       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, bcch->lcId, sendInd);
11960 #else
11961       /*Fill the interface info */
11962       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, NULLD, NULLD);
11963
11964       /* ccpu00132314-ADD-Update the tx power allocation info  
11965          TODO-Need to add a check for max tx power per symbol */ 
11966       subfrmAlloc->cmnLcInfo.bcchInfo.txPwrOffset = cellDl->bcchTxPwrOffset;   
11967
11968       /*mBuf has been already copied above */
11969 #endif/*RGR_SI_SCH*/
11970    }
11971
11972    return;
11973 }
11974
11975
11976 #if RG_UNUSED
11977 /**
11978  * @brief
11979  *
11980  * @details
11981  *
11982  *     Function: rgSCHCmnUlSetAllUnSched
11983  *     Purpose:
11984  *
11985  *     Invoked by: Common Scheduler
11986  *
11987  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
11988  *  @return  Void
11989  *
11990  **/
11991 static Void rgSCHCmnUlSetAllUnSched(RgSchCmnUlRbAllocInfo *allocInfo)
11992 {
11993    CmLList            *node;
11994
11995
11996    node = allocInfo->contResLst.first;
11997    while (node)
11998    {
11999       rgSCHCmnUlMov2NonSchdCntResLst(allocInfo, (RgSchUeCb *)node->node);
12000       node = allocInfo->contResLst.first;
12001    }
12002
12003    node = allocInfo->retxUeLst.first;
12004    while (node)
12005    {
12006       rgSCHCmnUlMov2NonSchdRetxUeLst(allocInfo, (RgSchUeCb *)node->node);
12007       node = allocInfo->retxUeLst.first;
12008    }
12009
12010    node = allocInfo->ueLst.first;
12011    while (node)
12012    {
12013       rgSCHCmnUlMov2NonSchdUeLst(allocInfo, (RgSchUeCb *)node->node);
12014       node = allocInfo->ueLst.first;
12015    }
12016
12017    return;
12018 }
12019 #endif
12020
12021 /**
12022  * @brief
12023  *
12024  * @details
12025  *
12026  *     Function: rgSCHCmnUlAdd2CntResLst
12027  *     Purpose:
12028  *
12029  *     Invoked by: Common Scheduler
12030  *
12031  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
12032  *  @param[in]  RgSchUeCb             *ue
12033  *  @return  Void
12034  *
12035  **/
12036 Void rgSCHCmnUlAdd2CntResLst(RgSchCmnUlRbAllocInfo *allocInfo,RgSchUeCb *ue)
12037 {
12038    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,ue->cell))->alloc);
12039    cmLListAdd2Tail(&allocInfo->contResLst, &ulAllocInfo->reqLnk);
12040    ulAllocInfo->reqLnk.node = (PTR)ue;
12041    return;
12042 }
12043
12044 /**
12045  * @brief
12046  *
12047  * @details
12048  *
12049  *     Function: rgSCHCmnUlAdd2UeLst
12050  *     Purpose:
12051  *
12052  *     Invoked by: Common Scheduler
12053  *
12054  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
12055  *  @param[in]  RgSchUeCb             *ue
12056  *  @return  Void
12057  *
12058  **/
12059 Void rgSCHCmnUlAdd2UeLst(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUeCb *ue)
12060 {
12061    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,cell))->alloc);
12062    if (ulAllocInfo->reqLnk.node == NULLP)
12063    {
12064       cmLListAdd2Tail(&allocInfo->ueLst, &ulAllocInfo->reqLnk);
12065       ulAllocInfo->reqLnk.node = (PTR)ue;
12066    }
12067    return;
12068 }
12069
12070 /**
12071  * @brief
12072  *
12073  * @details
12074  *
12075  *     Function: rgSCHCmnAllocUlRb
12076  *     Purpose:  To do RB allocations for uplink
12077  *
12078  *     Invoked by: Common Scheduler
12079  *
12080  *  @param[in]  RgSchCellCb           *cell
12081  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12082  *  @return  Void
12083  **/
12084 Void rgSCHCmnAllocUlRb(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
12085 {
12086    RgSchUlSf         *sf = allocInfo->sf;
12087
12088    /* Schedule for new transmissions */
12089    rgSCHCmnUlRbAllocForLst(cell, sf, allocInfo->ueLst.count,
12090          &allocInfo->ueLst, &allocInfo->schdUeLst,
12091          &allocInfo->nonSchdUeLst, (Bool)TRUE);
12092    return;
12093 }
12094
12095 /***********************************************************
12096  *
12097  *     Func : rgSCHCmnUlRbAllocForLst
12098  *
12099  *     Desc : Allocate for a list in cmn rb alloc information passed
12100  *            in a subframe.
12101  *
12102  *     Ret  :
12103  *
12104  *     Notes:
12105  *
12106  *     File :
12107  *
12108  **********************************************************/
12109 static Void rgSCHCmnUlRbAllocForLst
12110 (
12111 RgSchCellCb  *cell,
12112 RgSchUlSf    *sf,
12113 uint32_t     count,
12114 CmLListCp    *reqLst,
12115 CmLListCp    *schdLst,
12116 CmLListCp    *nonSchdLst,
12117 Bool         isNewTx
12118 )
12119 {
12120    CmLList          *lnk;
12121    RgSchUlHole      *hole;
12122 #ifdef LTE_L2_MEAS
12123 #ifdef LTE_TDD
12124    uint8_t               k;
12125    CmLteTimingInfo  timeInfo;
12126 #endif    
12127 #endif    
12128
12129    if(schdLst->count == 0)
12130    {
12131       cmLListInit(schdLst);
12132    }
12133
12134    cmLListInit(nonSchdLst);
12135 #ifdef LTE_L2_MEAS
12136    if(isNewTx == TRUE)
12137    {
12138       cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.numUes = (uint8_t) count;
12139 #ifdef LTE_TDD
12140       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timeInfo, TFU_ULCNTRL_DLDELTA);
12141       k = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][timeInfo.subframe];
12142       RG_SCH_ADD_TO_CRNT_TIME(timeInfo,
12143           cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, k);
12144 #else
12145       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime,cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo,
12146                             (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
12147 #endif
12148    }
12149 #endif
12150
12151    for (lnk = reqLst->first; count; lnk = lnk->next, --count)
12152    {
12153       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
12154       RgSchCmnUlUe          *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
12155       S16                   ret;
12156       uint8_t                    maxRb;
12157
12158
12159       if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
12160       {
12161          break;
12162       }
12163
12164       ueUl->subbandShare = ueUl->subbandRequired;
12165       if(isNewTx == TRUE)
12166       {
12167          maxRb = RGSCH_MIN((ueUl->subbandRequired * MAX_5GTF_VRBG_SIZE), ue->ue5gtfCb.maxPrb);
12168       } 
12169       ret = rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole);
12170       if (ret == ROK)
12171       {
12172          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, schdLst);
12173          rgSCHCmnUlUeFillAllocInfo(cell, ue);
12174       }
12175       else
12176       {
12177          gUl5gtfRbAllocFail++;
12178 #if defined (TENB_STATS) && defined (RG_5GTF)
12179          cell->tenbStats->sch.ul5gtfRbAllocFail++;
12180 #endif
12181          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
12182          ue->isMsg4PdcchWithCrnti = FALSE;
12183          ue->isSrGrant = FALSE;
12184       }
12185 #ifdef LTE_L2_MEAS
12186       if(isNewTx == TRUE)
12187       {
12188          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
12189          ulAllocInfo[count - 1].rnti   = ue->ueId;
12190          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
12191          ulAllocInfo[count - 1].numPrb = ue->ul.nPrb;
12192       }
12193 #endif
12194       ueUl->subbandShare = 0; /* This reset will take care of
12195                                   * all scheduler types */
12196    }
12197    for (; count; lnk = lnk->next, --count)
12198    {
12199       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
12200       rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
12201       ue->isMsg4PdcchWithCrnti = FALSE;
12202    }
12203    return;
12204 }
12205
12206 #ifdef UNUSED_FUNC
12207 #ifdef TFU_UPGRADE
12208 /***********************************************************
12209  *
12210  *     Func : rgSCHCmnUlMdfyGrntForCqi
12211  *
12212  *     Desc : Modify UL Grant to consider presence of 
12213  *            CQI along with PUSCH Data.
12214  *
12215  *     Ret  :
12216  *
12217  *     Notes: 
12218  *          -  Scale down iTbs based on betaOffset and
12219  *             size of Acqi Size.
12220  *          -  Optionally attempt to increase numSb by 1
12221  *             if input payload size does not fit in due 
12222  *             to reduced tbSz as a result of iTbsNew.
12223  *
12224  *     File :
12225  *
12226  **********************************************************/
12227 static S16 rgSCHCmnUlMdfyGrntForCqi
12228 (
12229 RgSchCellCb  *cell,
12230 RgSchUeCb    *ue,
12231 uint32_t     maxRb,
12232 uint32_t     *numSb,
12233 uint8_t      *iTbs,
12234 uint32_t     hqSz,
12235 uint32_t     stepDownItbs,
12236 uint32_t     effTgt
12237 )
12238 {
12239    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(ue->cell);
12240    uint32_t  nPrb;
12241    uint32_t  totREs;
12242    uint32_t  cqiRiREs;
12243    uint32_t  hqREs;
12244    uint32_t  remREsForPusch;
12245    uint32_t  bitsPerRe;
12246    uint32_t  tbSz;
12247    uint32_t  betaOffVal = ue->ul.betaOffstVal;
12248    uint32_t  cqiRiRptSz = ue->ul.cqiRiSz;
12249    uint32_t  betaOffHqVal = rgSchCmnBetaHqOffstTbl[ue->ul.betaHqOffst];
12250    uint32_t  resNumSb = *numSb;
12251    uint32_t  puschEff = 1000;
12252    uint8_t   modOdr;
12253    uint8_t   iMcs;
12254    Bool mdfyiTbsFlg = FALSE;
12255    uint8_t   resiTbs = *iTbs;
12256
12257
12258    
12259    do
12260    {
12261       iMcs  = rgSCHCmnUlGetIMcsFrmITbs(resiTbs, RG_SCH_CMN_GET_UE_CTGY(ue));
12262       RG_SCH_UL_MCS_TO_MODODR(iMcs, modOdr);
12263       if (RG_SCH_CMN_GET_UE_CTGY(ue) != CM_LTE_UE_CAT_5)
12264       {
12265          modOdr = RGSCH_MIN(RGSCH_QM_QPSK, modOdr);
12266       }
12267       else
12268       {
12269          modOdr = RGSCH_MIN(RGSCH_QM_64QAM, modOdr);
12270       }
12271       nPrb = resNumSb * cellUl->sbSize;
12272       /* Restricting the minumum iTbs requried to modify to 10 */
12273       if ((nPrb >= maxRb) && (resiTbs <= 10))
12274       {
12275          /* Could not accomodate ACQI */
12276          return RFAILED;
12277       }
12278       totREs = nPrb * RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
12279       tbSz = rgTbSzTbl[0][resiTbs][nPrb-1];
12280       /*  totalREs/tbSz = num of bits perRE.  */
12281       cqiRiREs = (totREs * betaOffVal * cqiRiRptSz)/(1000 * tbSz); /* betaOffVal is represented 
12282                                                                    as parts per 1000 */
12283       hqREs = (totREs * betaOffHqVal * hqSz)/(1000 * tbSz);
12284       if ((cqiRiREs + hqREs) < totREs)
12285       {
12286          remREsForPusch = totREs - cqiRiREs - hqREs;
12287          bitsPerRe = (tbSz * 1000)/remREsForPusch; /* Multiplying by 1000 for Interger Oper */
12288          puschEff = bitsPerRe/modOdr;
12289       }
12290       if (puschEff < effTgt)
12291       {
12292           /* ensure resultant efficiency for PUSCH Data is within 0.93*/
12293           break;
12294       }
12295       else
12296       {
12297          /* Alternate between increasing SB or decreasing iTbs until eff is met */
12298          if (mdfyiTbsFlg == FALSE)
12299          {
12300             if (nPrb < maxRb)
12301             {
12302               resNumSb = resNumSb + 1;
12303             }
12304             mdfyiTbsFlg = TRUE;
12305          }
12306          else
12307          {
12308             if (resiTbs > 10)
12309             {
12310                resiTbs-= stepDownItbs;
12311             }
12312             mdfyiTbsFlg = FALSE;
12313          }
12314       }
12315    }while (1); /* Loop breaks if efficency is met 
12316                   or returns RFAILED if not able to meet the efficiency */
12317               
12318    *numSb = resNumSb;
12319    *iTbs = resiTbs;
12320
12321    return ROK;
12322 }
12323 #endif
12324 #endif
12325 /***********************************************************
12326  *
12327  *     Func : rgSCHCmnUlRbAllocForUe
12328  *
12329  *     Desc : Do uplink RB allocation for an UE.
12330  *
12331  *     Ret  :
12332  *
12333  *     Notes: Note that as of now, for retx, maxRb
12334  *            is not considered. Alternatives, such
12335  *            as dropping retx if it crosses maxRb
12336  *            could be considered.
12337  *
12338  *     File :
12339  *
12340  **********************************************************/
12341 static S16 rgSCHCmnUlRbAllocForUe
12342 (
12343 RgSchCellCb  *cell,
12344 RgSchUlSf    *sf,
12345 RgSchUeCb    *ue,
12346 uint8_t      maxRb,
12347 RgSchUlHole  *hole
12348 )
12349 {
12350    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
12351    RgSchCmnUlUe   *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
12352    RgSchUlAlloc   *alloc = NULLP;
12353    uint32_t       nPrb = 0;
12354    uint8_t        numVrbg;
12355    uint8_t        iMcs;
12356    uint8_t        iMcsCrnt;
12357 #ifndef RG_5GTF
12358    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->schdHqProcIdx];
12359 #else
12360    RgSchUlHqProcCb  *proc = NULLP;
12361 #endif
12362    RgSchPdcch       *pdcch;
12363    uint32_t              reqVrbg;
12364    uint8_t               numVrbgTemp;
12365 #ifdef RG_5GTF
12366    TfuDciFormat     dciFrmt;
12367    uint8_t               numLyr;
12368 #endif
12369
12370 #ifdef RG_5GTF
12371    rgSCHUhmGetAvlHqProc(cell, ue, &proc);
12372    if (proc == NULLP)
12373    {
12374       //DU_LOG("\nINFO   -->  SCH : UE [%d] HQ Proc unavailable\n", ue->ueId);
12375       return RFAILED;
12376    }
12377 #endif
12378
12379    if (ue->ue5gtfCb.rank == 2)
12380    {
12381       dciFrmt = TFU_DCI_FORMAT_A2;
12382       numLyr = 2;
12383    }
12384    else
12385    {
12386       dciFrmt = TFU_DCI_FORMAT_A1;
12387       numLyr = 1;
12388    }
12389    /* 5gtf TODO : To pass dci frmt to this function */
12390    pdcch = rgSCHCmnPdcchAllocCrntSf(cell, ue);
12391    if(pdcch == NULLP)
12392    {
12393       DU_LOG("\nDEBUG  -->  SCH : rgSCHCmnUlRbAllocForUe(): Could not get PDCCH for CRNTI:%d",ue->ueId);
12394       return RFAILED;
12395    }
12396         gUl5gtfPdcchSchd++;
12397 #if defined (TENB_STATS) && defined (RG_5GTF)
12398    cell->tenbStats->sch.ul5gtfPdcchSchd++;
12399 #endif
12400
12401    //TODO_SID using configured prb as of now
12402    nPrb = ue->ue5gtfCb.maxPrb;
12403    reqVrbg = nPrb/MAX_5GTF_VRBG_SIZE;
12404    iMcs  = ue->ue5gtfCb.mcs; //gSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
12405    iMcsCrnt = iMcs;
12406    numVrbg = reqVrbg;
12407
12408    if((sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart > MAX_5GTF_VRBG)
12409          || (sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated > MAX_5GTF_VRBG))
12410    {
12411       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR vrbg > 25 valstart = %d valalloc %d\n", sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart
12412             , sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated);
12413       int *p=NULLP;
12414       *p = 10;
12415    }
12416
12417    /*TODO_SID: Workaround for alloc. Currently alloc is ulsf based. To handle multiple beams, we need a different
12418      design. Now alloc are formed based on MAX_5GTF_UE_SCH macro. */
12419    numVrbgTemp = MAX_5GTF_VRBG/MAX_5GTF_UE_SCH;
12420    if(numVrbg)
12421    {
12422       alloc = rgSCHCmnUlSbAlloc(sf, numVrbgTemp,\
12423                                 hole);
12424    }
12425    if (alloc == NULLP)
12426    {
12427       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForUe(): Could not get UlAlloc %d CRNTI:%d",numVrbg,ue->ueId);
12428       rgSCHCmnPdcchRlsCrntSf(cell, pdcch);
12429       return RFAILED;
12430    }
12431    gUl5gtfAllocAllocated++;
12432 #if defined (TENB_STATS) && defined (RG_5GTF)
12433    cell->tenbStats->sch.ul5gtfAllocAllocated++;
12434 #endif
12435    alloc->grnt.vrbgStart = sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart;
12436    alloc->grnt.numVrbg = numVrbg;
12437    alloc->grnt.numLyr = numLyr;
12438    alloc->grnt.dciFrmt = dciFrmt;
12439
12440    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart += numVrbg;
12441    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated += numVrbg;
12442
12443    //rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
12444 #ifdef LTE_L2_MEAS
12445    sf->totPrb  += alloc->grnt.numRb;
12446    ue->ul.nPrb = alloc->grnt.numRb;
12447 #endif
12448    if (ue->csgMmbrSta != TRUE)
12449    {
12450       cellUl->ncsgPrbCnt += alloc->grnt.numRb;
12451    }
12452    cellUl->totPrbCnt += (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
12453    alloc->pdcch = pdcch;
12454    alloc->grnt.iMcs = iMcs;
12455    alloc->grnt.iMcsCrnt = iMcsCrnt;
12456    alloc->grnt.hop = 0;
12457    /* Initial Num RBs support for UCI on PUSCH */
12458 #ifdef TFU_UPGRADE
12459    ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
12460 #endif
12461    alloc->forMsg3 = FALSE;
12462    //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTb5gtfSzTbl[0], (iTbs)); 
12463
12464    //ueUl->alloc.allocdBytes = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
12465    /* TODO_SID Allocating based on configured MCS as of now.
12466          Currently for format A2. When doing multi grp per tti, need to update this. */
12467    ueUl->alloc.allocdBytes = (rgSch5gtfTbSzTbl[iMcs]/8) * ue->ue5gtfCb.rank;
12468
12469    alloc->grnt.datSz = ueUl->alloc.allocdBytes;
12470    //TODO_SID Need to check mod order.
12471    RG_SCH_CMN_TBS_TO_MODODR(iMcs, alloc->grnt.modOdr);
12472         //alloc->grnt.modOdr = 6;
12473    alloc->grnt.isRtx = FALSE;
12474
12475    alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
12476    alloc->grnt.SCID = 0;
12477    alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
12478    alloc->grnt.PMI = 0;
12479    alloc->grnt.uciOnxPUSCH = 0;
12480    alloc->grnt.hqProcId = proc->procId;
12481
12482    alloc->hqProc = proc;
12483    alloc->hqProc->ulSfIdx = cellUl->schdIdx;
12484    alloc->ue = ue;
12485    /*commenting to retain the rnti used for transmission SPS/c-rnti */
12486    alloc->rnti = ue->ueId;
12487    ueUl->alloc.alloc = alloc;
12488    /*rntiwari-Adding the debug for generating the graph.*/
12489    /* No grant attr recorded now */
12490    return ROK;
12491 }
12492
12493 /***********************************************************
12494  *
12495  *     Func : rgSCHCmnUlRbAllocAddUeToLst
12496  *
12497  *     Desc : Add UE to list (scheduled/non-scheduled list)
12498  *            for UL RB allocation information.
12499  *
12500  *     Ret  :
12501  *
12502  *     Notes:
12503  *
12504  *     File :
12505  *
12506  **********************************************************/
12507 Void rgSCHCmnUlRbAllocAddUeToLst(RgSchCellCb *cell,RgSchUeCb *ue,CmLListCp *lst)
12508 {
12509    RgSchCmnUlUe   *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
12510    UNUSED(cell);
12511
12512    gUl5gtfUeRbAllocDone++;
12513 #if defined (TENB_STATS) && defined (RG_5GTF)
12514    cell->tenbStats->sch.ul5gtfUeRbAllocDone++;
12515 #endif
12516    cmLListAdd2Tail(lst, &ueUl->alloc.schdLstLnk);
12517    ueUl->alloc.schdLstLnk.node = (PTR)ue;
12518 }
12519
12520
12521 /**
12522  * @brief This function Processes the Final Allocations
12523  *        made by the RB Allocator against the requested.
12524  *
12525  * @details
12526  *
12527  *     Function: rgSCHCmnUlAllocFnlz
12528  *     Purpose:  This function Processes the Final Allocations
12529  *               made by the RB Allocator against the requested.
12530  *
12531  *     Invoked by: Common Scheduler
12532  *
12533  *  @param[in]  RgSchCellCb           *cell
12534  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12535  *  @return  Void
12536  *
12537  **/
12538 static Void rgSCHCmnUlAllocFnlz(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
12539 {
12540    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12541
12542    /* call scheduler specific Finalization */
12543    cellSch->apisUl->rgSCHUlAllocFnlz(cell, allocInfo);
12544
12545    return;
12546 }
12547
12548 /**
12549  * @brief This function Processes the Final Allocations
12550  *        made by the RB Allocator against the requested.
12551  *
12552  * @details
12553  *
12554  *     Function: rgSCHCmnDlAllocFnlz
12555  *     Purpose:  This function Processes the Final Allocations
12556  *               made by the RB Allocator against the requested.
12557  *
12558  *     Invoked by: Common Scheduler
12559  *
12560  *  @param[in]  RgSchCellCb           *cell
12561  *  @return  Void
12562  *
12563  **/
12564 Void rgSCHCmnDlAllocFnlz(RgSchCellCb  *cell)
12565 {
12566    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
12567    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo; 
12568
12569
12570    rgSCHCmnDlCcchRetxFnlz(cell, allocInfo);
12571    rgSCHCmnDlCcchTxFnlz(cell, allocInfo);
12572 #ifdef RGR_V1
12573    /* Added below functions for handling CCCH SDU transmission received
12574     * after
12575     *     * guard timer expiry*/
12576    rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo);
12577    rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo);
12578 #endif
12579    rgSCHCmnDlRaRspFnlz(cell, allocInfo);
12580       /* call scheduler specific Finalization */
12581    cellSch->apisDl->rgSCHDlAllocFnlz(cell, allocInfo);
12582
12583    /* Stack Crash problem for TRACE5 Changes. Added the return below */
12584    return;
12585
12586 }
12587
12588 #ifdef RG_UNUSED
12589 /**
12590  * @brief Update an uplink subframe.
12591  *
12592  * @details
12593  *
12594  *     Function : rgSCHCmnUlUpdSf
12595  *
12596  *     For each allocation
12597  *      - if no more tx needed
12598  *         - Release allocation
12599  *      - else
12600  *         - Perform retransmission
12601  *
12602  *  @param[in]  RgSchUlSf *sf
12603  *  @return  Void
12604  **/
12605 static Void rgSCHCmnUlUpdSf(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUlSf *sf)
12606 {
12607    CmLList        *lnk;
12608
12609    while ((lnk = sf->allocs.first))
12610    {
12611       RgSchUlAlloc  *alloc = (RgSchUlAlloc *)lnk->node;
12612       lnk = lnk->next;
12613
12614       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
12615       {
12616       }
12617       else
12618       {
12619          /* If need to handle all retx together, run another loop separately */
12620          rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc);
12621       }
12622       rgSCHCmnUlRlsUlAlloc(cell, sf, alloc);
12623    }
12624
12625    /* By this time, all allocs would have been cleared and
12626     * SF is reset to be made ready for new allocations. */
12627    rgSCHCmnUlSfReset(cell, sf);
12628    /* In case there are timing problems due to msg3
12629     * allocations being done in advance, (which will
12630     * probably happen with the current FDD code that
12631     * handles 8 subframes) one solution
12632     * could be to hold the (recent) msg3 allocs in a separate
12633     * list, and then possibly add that to the actual
12634     * list later. So at this time while allocations are
12635     * traversed, the recent msg3 ones are not seen. Anytime after
12636     * this (a good time is when the usual allocations
12637     * are made), msg3 allocations could be transferred to the
12638     * normal list. Not doing this now as it is assumed
12639     * that incorporation of TDD shall take care of this.
12640     */
12641
12642
12643    return;
12644 }
12645
12646 /**
12647  * @brief Handle uplink allocation for retransmission.
12648  *
12649  * @details
12650  *
12651  *     Function : rgSCHCmnUlHndlAllocRetx
12652  *
12653  *     Processing Steps:
12654  *     - Add to queue for retx.
12655  *     - Do not release here, release happends as part
12656  *       of the loop that calls this function.
12657  *
12658  *  @param[in]  RgSchCellCb           *cell
12659  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12660  *  @param[in]  RgSchUlSf *sf
12661  *  @param[in]  RgSchUlAlloc  *alloc
12662  *  @return  Void
12663  **/
12664 static Void rgSCHCmnUlHndlAllocRetx(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUlSf *sf,RgSchUlAlloc  *alloc)
12665 {
12666    uint32_t       bytes;
12667    RgSchCmnUlUe   *ueUl;
12668    bytes = \
12669       rgTbSzTbl[0][rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs)]\
12670                                      [alloc->grnt.numRb-1]/8;
12671    if (!alloc->forMsg3)
12672    {
12673       ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue);
12674       ueUl->alloc.reqBytes = bytes;
12675       rgSCHUhmRetx(alloc->hqProc);
12676       rgSCHCmnUlAdd2RetxUeLst(allocInfo, alloc->ue);
12677    }
12678    else
12679    {
12680       /* RACHO msg3 retx handling. Part of RACH procedure changes. */
12681       retxAlloc = rgSCHCmnUlGetUlAlloc(cell, sf, alloc->numSb);
12682       if (retxAlloc == NULLP)
12683       {
12684          DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForUe():Could not get UlAlloc for msg3Retx RNTI:%d",
12685                alloc->rnti);
12686          return;
12687       }
12688       retxAlloc->grnt.iMcs = alloc->grnt.iMcs;
12689       retxAlloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl\
12690                                  [alloc->hqProc->rvIdx];
12691       retxAlloc->grnt.nDmrs    = 0;
12692       retxAlloc->grnt.hop      = 0;
12693       retxAlloc->grnt.delayBit = 0;
12694       retxAlloc->rnti          = alloc->rnti;
12695       retxAlloc->ue            = NULLP;
12696       retxAlloc->pdcch         = FALSE;
12697       retxAlloc->forMsg3       = TRUE;
12698       retxAlloc->raCb          = alloc->raCb;
12699       retxAlloc->hqProc        = alloc->hqProc;
12700       rgSCHUhmRetx(retxAlloc->hqProc);
12701    }
12702    return;
12703 }
12704 #endif
12705
12706 /**
12707  * @brief Uplink Scheduling Handler.
12708  *
12709  * @details
12710  *
12711  *     Function: rgSCHCmnUlAlloc
12712  *     Purpose:  This function Handles Uplink Scheduling.
12713  *
12714  *     Invoked by: Common Scheduler
12715  *
12716  *  @param[in]  RgSchCellCb *cell
12717  *  @return  Void
12718  **/
12719 /* ccpu00132653- The definition of this function made common for TDD and FDD*/
12720 static Void rgSCHCmnUlAlloc(RgSchCellCb  *cell)
12721 {
12722    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
12723    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
12724    RgSchCmnDlCell         *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12725    RgSchCmnUlRbAllocInfo  allocInfo;
12726    RgSchCmnUlRbAllocInfo  *allocInfoRef = &allocInfo;
12727 #ifdef RG_5GTF
12728    uint8_t idx;
12729
12730 #endif
12731
12732
12733    /* Initializing RgSchCmnUlRbAllocInfo structure */
12734    rgSCHCmnInitUlRbAllocInfo(allocInfoRef);
12735
12736    /* Get Uplink Subframe */
12737    allocInfoRef->sf = &cellUl->ulSfArr[cellUl->schdIdx];
12738 #ifdef LTE_L2_MEAS
12739    /* initializing the UL PRB count */
12740    allocInfoRef->sf->totPrb = 0;
12741 #endif
12742
12743 #ifdef LTEMAC_SPS
12744    rgSCHCmnSpsUlTti(cell, allocInfoRef);
12745 #endif
12746
12747    if(*allocInfoRef->sf->allocCountRef == 0)
12748    {            
12749       RgSchUlHole     *hole;
12750
12751       if ((hole = rgSCHUtlUlHoleFirst(allocInfoRef->sf)) != NULLP)
12752       {
12753          /* Sanity check of holeDb */
12754          if (allocInfoRef->sf->holeDb->count == 1 && hole->start == 0) 
12755          {
12756             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
12757             /* Re-Initialize available subbands because of CFI change*/
12758             allocInfoRef->sf->availSubbands = cell->dynCfiCb.\
12759                                               bwInfo[cellDl->currCfi].numSb;
12760             /*Currently initializing 5gtf ulsf specific initialization here.
12761               need to do at proper place */
12762 #ifdef RG_5GTF
12763        allocInfoRef->sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
12764        allocInfoRef->sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
12765             for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
12766             {
12767                allocInfoRef->sf->sfBeamInfo[idx].totVrbgAllocated = 0;
12768                allocInfoRef->sf->sfBeamInfo[idx].totVrbgRequired = 0;
12769                allocInfoRef->sf->sfBeamInfo[idx].vrbgStart = 0;
12770             }    
12771 #endif
12772          }
12773          else
12774          {
12775             DU_LOG("\nERROR  -->  SCH :  holeDb sanity check failed");
12776          }
12777       }
12778    }
12779
12780    /* Fix: Adaptive re-transmissions prioritised over other transmissions */
12781    /* perform adaptive retransmissions */
12782    rgSCHCmnUlSfReTxAllocs(cell, allocInfoRef->sf);
12783
12784         g5gtfTtiCnt++;
12785
12786    /* Fix: syed Adaptive Msg3 Retx crash. Release all
12787     Harq processes for which adap Retx failed, to avoid 
12788     blocking. This step should be done before New TX 
12789     scheduling to make hqProc available. Right now we
12790     dont check if proc is in adap Retx list for considering
12791     it to be available. But now with this release that 
12792     functionality would be correct. */
12793 #ifndef RG_5GTF
12794    rgSCHCmnUlSfRlsRetxProcs(cell, allocInfoRef->sf);  
12795 #endif
12796
12797    /* Specific UL scheduler to perform UE scheduling */
12798    cellSch->apisUl->rgSCHUlSched(cell, allocInfoRef);
12799
12800    /* Call UL RB allocator module */
12801    rgSCHCmnAllocUlRb(cell, allocInfoRef);
12802
12803    /* Do group power control for PUSCH */
12804    rgSCHCmnGrpPwrCntrlPusch(cell, allocInfoRef->sf);
12805
12806    cell->sc.apis->rgSCHDrxStrtInActvTmrInUl(cell);
12807
12808    rgSCHCmnUlAllocFnlz(cell, allocInfoRef);
12809         if(5000 == g5gtfTtiCnt)
12810         {
12811       ul5gtfsidDlAlreadyMarkUl = 0;
12812                 ul5gtfsidDlSchdPass = 0;
12813                 ul5gtfsidUlMarkUl = 0;
12814       ul5gtfTotSchdCnt = 0;
12815                 g5gtfTtiCnt = 0;
12816         }
12817
12818    return;
12819 }
12820
12821 /**
12822  * @brief send Subframe Allocations.
12823  *
12824  * @details
12825  *
12826  *     Function: rgSCHCmnSndCnsldtInfo
12827  *     Purpose:  Send the scheduled
12828  *     allocations to MAC for StaInd generation to Higher layers and
12829  *     for MUXing. PST's RgInfSfAlloc to MAC instance.
12830  *
12831  *     Invoked by: Common Scheduler
12832  *
12833  *  @param[in]  RgSchCellCb *cell
12834  *  @return  Void
12835  **/
12836 Void rgSCHCmnSndCnsldtInfo(RgSchCellCb *cell)
12837 {
12838    RgInfSfAlloc  *subfrmAlloc;
12839    Pst           pst;
12840    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
12841
12842
12843    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
12844
12845    /* Send the allocations to MAC for MUXing */
12846    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
12847    subfrmAlloc->cellId = cell->cellId;
12848    /* Populate the List of UEs needing PDB-based Flow control */
12849    cellSch->apisDl->rgSCHDlFillFlwCtrlInfo(cell, subfrmAlloc);
12850 #ifdef LTE_L2_MEAS
12851    if((subfrmAlloc->rarInfo.numRaRntis) ||
12852 #ifdef EMTC_ENABLE
12853       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
12854       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
12855       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
12856 #endif
12857       (subfrmAlloc->ueInfo.numUes)      ||
12858       (subfrmAlloc->cmnLcInfo.bitMask)  ||
12859          (subfrmAlloc->ulUeInfo.numUes)    ||
12860          (subfrmAlloc->flowCntrlInfo.numUes))
12861 #else
12862    if((subfrmAlloc->rarInfo.numRaRntis) ||
12863 #ifdef EMTC_ENABLE
12864       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
12865       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
12866       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
12867 #endif
12868       (subfrmAlloc->ueInfo.numUes)      ||
12869             (subfrmAlloc->cmnLcInfo.bitMask)  ||
12870             (subfrmAlloc->flowCntrlInfo.numUes))
12871 #endif
12872    {
12873       RgSchMacSfAlloc(&pst, subfrmAlloc);
12874    }
12875 #ifndef LTE_TDD
12876    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
12877 #else
12878    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_SF_ALLOC_SIZE;
12879 #endif
12880    
12881    return;
12882 }
12883 /**
12884  * @brief Consolidate Subframe Allocations.
12885  *
12886  * @details
12887  *
12888  *     Function: rgSCHCmnCnsldtSfAlloc
12889  *     Purpose:  Consolidate Subframe Allocations.
12890  *
12891  *     Invoked by: Common Scheduler
12892  *
12893  *  @param[in]  RgSchCellCb *cell
12894  *  @return  Void
12895  **/
12896 Void rgSCHCmnCnsldtSfAlloc(RgSchCellCb  *cell)
12897 {
12898    RgInfSfAlloc     *subfrmAlloc;
12899    CmLteTimingInfo  frm;
12900    RgSchDlSf        *dlSf;
12901    CmLListCp        dlDrxInactvTmrLst;
12902    CmLListCp        dlInActvLst;
12903    CmLListCp        ulInActvLst;
12904    RgSchCmnCell     *cellSch = NULLP;
12905
12906
12907    cmLListInit(&dlDrxInactvTmrLst);
12908    cmLListInit(&dlInActvLst);
12909    cmLListInit(&ulInActvLst);
12910
12911    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
12912
12913    /* Get Downlink Subframe */
12914    frm   = cell->crntTime;
12915    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
12916    dlSf = rgSCHUtlSubFrmGet(cell, frm);
12917
12918    /* Fill the allocation Info */
12919    rgSCHUtlFillRgInfRarInfo(dlSf, subfrmAlloc, cell);
12920
12921   /* CA dev Start */
12922    rgSCHUtlFillRgInfUeInfo(dlSf, cell, &dlDrxInactvTmrLst, 
12923                            &dlInActvLst, &ulInActvLst);
12924 #ifdef RG_PFS_STATS
12925    cell->totalPrb += dlSf->bwAssigned;
12926 #endif
12927    /* Mark the following Ues inactive for UL*/
12928    cellSch = RG_SCH_CMN_GET_CELL(cell);
12929
12930    /* Calling Scheduler specific function with DRX inactive UE list*/
12931    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInActvLst);
12932    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInActvLst);
12933     
12934   /* CA dev End */
12935    /*re/start DRX inactivity timer for the UEs*/
12936    (Void)rgSCHDrxStrtInActvTmr(cell,&dlDrxInactvTmrLst,RG_SCH_DRX_DL);
12937
12938    return;
12939 }
12940
12941 /**
12942  * @brief Initialize the DL Allocation Information Structure.
12943  *
12944  * @details
12945  *
12946  *     Function: rgSCHCmnInitDlRbAllocInfo
12947  *     Purpose:  Initialize the DL Allocation Information Structure.
12948  *
12949  *     Invoked by: Common Scheduler
12950  *
12951  *  @param[out]  RgSchCmnDlRbAllocInfo  *allocInfo
12952  *  @return  Void
12953  **/
12954 static Void rgSCHCmnInitDlRbAllocInfo(RgSchCmnDlRbAllocInfo  *allocInfo)
12955 {
12956    memset(&allocInfo->pcchAlloc, 0, sizeof(RgSchDlRbAlloc));
12957    memset(&allocInfo->bcchAlloc, 0, sizeof(RgSchDlRbAlloc));
12958    memset(allocInfo->raRspAlloc, 0, RG_SCH_CMN_MAX_CMN_PDCCH*sizeof(RgSchDlRbAlloc));
12959
12960    allocInfo->msg4Alloc.msg4DlSf = NULLP;
12961    cmLListInit(&allocInfo->msg4Alloc.msg4TxLst);
12962    cmLListInit(&allocInfo->msg4Alloc.msg4RetxLst);
12963    cmLListInit(&allocInfo->msg4Alloc.schdMsg4TxLst);
12964    cmLListInit(&allocInfo->msg4Alloc.schdMsg4RetxLst);
12965    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4TxLst);
12966    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4RetxLst);
12967 #ifdef RGR_V1
12968    allocInfo->ccchSduAlloc.ccchSduDlSf = NULLP;
12969    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduTxLst);
12970    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduRetxLst);
12971    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduTxLst);
12972    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduRetxLst);
12973    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst);
12974    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst);
12975 #endif
12976
12977    allocInfo->dedAlloc.dedDlSf = NULLP;
12978    cmLListInit(&allocInfo->dedAlloc.txHqPLst);
12979    cmLListInit(&allocInfo->dedAlloc.retxHqPLst);
12980    cmLListInit(&allocInfo->dedAlloc.schdTxHqPLst);
12981    cmLListInit(&allocInfo->dedAlloc.schdRetxHqPLst);
12982    cmLListInit(&allocInfo->dedAlloc.nonSchdTxHqPLst);
12983    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxHqPLst);
12984
12985    cmLListInit(&allocInfo->dedAlloc.txRetxHqPLst);
12986    cmLListInit(&allocInfo->dedAlloc.schdTxRetxHqPLst);
12987    cmLListInit(&allocInfo->dedAlloc.nonSchdTxRetxHqPLst);
12988 #ifdef LTEMAC_SPS
12989    cmLListInit(&allocInfo->dedAlloc.txSpsHqPLst);
12990    cmLListInit(&allocInfo->dedAlloc.retxSpsHqPLst);
12991    cmLListInit(&allocInfo->dedAlloc.schdTxSpsHqPLst);
12992    cmLListInit(&allocInfo->dedAlloc.schdRetxSpsHqPLst);
12993    cmLListInit(&allocInfo->dedAlloc.nonSchdTxSpsHqPLst);
12994    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxSpsHqPLst);
12995 #endif
12996
12997 #ifdef LTE_ADV
12998    rgSCHLaaCmnInitDlRbAllocInfo (allocInfo);
12999 #endif
13000
13001    cmLListInit(&allocInfo->dedAlloc.errIndTxHqPLst);
13002    cmLListInit(&allocInfo->dedAlloc.schdErrIndTxHqPLst);
13003    cmLListInit(&allocInfo->dedAlloc.nonSchdErrIndTxHqPLst);
13004    return;
13005 }
13006
13007 /**
13008  * @brief Initialize the UL Allocation Information Structure.
13009  *
13010  * @details
13011  *
13012  *     Function: rgSCHCmnInitUlRbAllocInfo
13013  *     Purpose:  Initialize the UL Allocation Information Structure.
13014  *
13015  *     Invoked by: Common Scheduler
13016  *
13017  *  @param[out]  RgSchCmnUlRbAllocInfo  *allocInfo
13018  *  @return  Void
13019  **/
13020 Void rgSCHCmnInitUlRbAllocInfo(RgSchCmnUlRbAllocInfo  *allocInfo)
13021 {
13022    allocInfo->sf = NULLP;
13023    cmLListInit(&allocInfo->contResLst);
13024    cmLListInit(&allocInfo->schdContResLst);
13025    cmLListInit(&allocInfo->nonSchdContResLst);
13026    cmLListInit(&allocInfo->ueLst);
13027    cmLListInit(&allocInfo->schdUeLst);
13028    cmLListInit(&allocInfo->nonSchdUeLst);
13029
13030    return;
13031 }
13032
13033 /**
13034  * @brief Scheduling for PUCCH group power control.
13035  *
13036  * @details
13037  *
13038  *     Function: rgSCHCmnGrpPwrCntrlPucch
13039  *     Purpose: This function does group power control for PUCCH
13040  *     corresponding to the subframe for which DL UE allocations
13041  *     have happended.
13042  *
13043  *     Invoked by: Common Scheduler
13044  *
13045  *  @param[in]  RgSchCellCb *cell
13046  *  @return  Void
13047  **/
13048 static Void rgSCHCmnGrpPwrCntrlPucch(RgSchCellCb *cell,RgSchDlSf *dlSf)
13049 {
13050    rgSCHPwrGrpCntrlPucch(cell, dlSf);
13051    return;
13052 }
13053
13054 /**
13055  * @brief Scheduling for PUSCH group power control.
13056  *
13057  * @details
13058  *
13059  *     Function: rgSCHCmnGrpPwrCntrlPusch
13060  *     Purpose: This function does group power control, for
13061  *     the subframe for which UL allocation has (just) happened.
13062  *
13063  *     Invoked by: Common Scheduler
13064  *
13065  *  @param[in]  RgSchCellCb *cell
13066  *  @param[in]  RgSchUlSf   *ulSf
13067  *  @return  Void
13068  **/
13069 static Void rgSCHCmnGrpPwrCntrlPusch(RgSchCellCb *cell,RgSchUlSf *ulSf)
13070 {
13071    /*removed unused variable *cellSch*/
13072    CmLteTimingInfo        frm;
13073    RgSchDlSf              *dlSf;
13074
13075
13076    /* Got to pass DL SF corresponding to UL SF, so get that first.
13077     * There is no easy way of getting dlSf by having the RgSchUlSf*,
13078     * so use the UL delta from current time to get the DL SF. */
13079    frm   = cell->crntTime;
13080
13081 #ifdef EMTC_ENABLE
13082    if(cell->emtcEnable == TRUE)
13083    {
13084       RGSCH_INCR_SUB_FRAME_EMTC(frm, TFU_DLCNTRL_DLDELTA);
13085    }
13086    else
13087 #endif
13088    {
13089       RGSCH_INCR_SUB_FRAME(frm, TFU_DLCNTRL_DLDELTA);
13090    }
13091    /* Del filling of dl.time */
13092    dlSf = rgSCHUtlSubFrmGet(cell, frm);
13093
13094    rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf);
13095
13096    return;
13097 }
13098
13099 /* Fix: syed align multiple UEs to refresh at same time */
13100 /***********************************************************
13101  *
13102  *     Func : rgSCHCmnApplyUeRefresh 
13103  *
13104  *     Desc : Apply UE refresh in CMN and Specific 
13105  *     schedulers. Data rates and corresponding 
13106  *     scratchpad variables are updated.
13107  *
13108  *     Ret  :
13109  *
13110  *     Notes:
13111  *
13112  *     File :
13113  *
13114  **********************************************************/
13115 static S16 rgSCHCmnApplyUeRefresh(RgSchCellCb *cell,RgSchUeCb  *ue)
13116 {
13117    RgSchCmnCell *cellSch     = RG_SCH_CMN_GET_CELL(cell);
13118    uint32_t     effGbrBsr    = 0;
13119    uint32_t     effNonGbrBsr = 0;
13120    uint32_t     lcgId;
13121
13122
13123    /* Reset the refresh cycle variableCAP */
13124    ue->ul.effAmbr = ue->ul.cfgdAmbr;
13125
13126    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
13127    {
13128       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
13129       {
13130          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
13131
13132          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
13133          {
13134             cmnLcg->effGbr = cmnLcg->cfgdGbr;
13135             cmnLcg->effDeltaMbr = cmnLcg->deltaMbr;
13136             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
13137             /* Considering GBR LCG will be prioritised by UE */
13138             effGbrBsr += cmnLcg->bs;
13139          }/* Else no remaing BS so nonLcg0 will be updated when BSR will be received */
13140          else
13141          {
13142             effNonGbrBsr += cmnLcg->reportedBs;
13143             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
13144          }
13145       }
13146    }
13147    effNonGbrBsr = RGSCH_MIN(effNonGbrBsr,ue->ul.effAmbr);
13148    ue->ul.nonGbrLcgBs = effNonGbrBsr;
13149
13150    ue->ul.nonLcg0Bs = effGbrBsr + effNonGbrBsr;
13151    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
13152                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
13153
13154
13155    /* call scheduler specific event handlers
13156     * for refresh timer expiry */
13157    cellSch->apisUl->rgSCHUlUeRefresh(cell, ue);
13158    cellSch->apisDl->rgSCHDlUeRefresh(cell, ue);
13159
13160    return ROK;
13161 }
13162
13163 /***********************************************************
13164  *
13165  *     Func : rgSCHCmnTmrExpiry
13166  *
13167  *     Desc : Adds an UE to refresh queue, so that the UE is
13168  *            periodically triggered to refresh it's GBR and
13169  *            AMBR values.
13170  *
13171  *     Ret  :
13172  *
13173  *     Notes:
13174  *
13175  *     File :
13176  *
13177  **********************************************************/
13178 static S16 rgSCHCmnTmrExpiry
13179 (
13180 PTR cb,               /* Pointer to timer control block */
13181 S16 tmrEvnt           /* Timer Event */
13182 )
13183 {
13184    RgSchUeCb       *ue = (RgSchUeCb *)cb;
13185    RgSchCellCb     *cell = ue->cell;
13186 #if (ERRCLASS & ERRCLS_DEBUG)
13187 #endif
13188
13189
13190 #if (ERRCLASS & ERRCLS_DEBUG)
13191    if (tmrEvnt != RG_SCH_CMN_EVNT_UE_REFRESH)
13192    {
13193       DU_LOG("\nERROR  -->  SCH : rgSCHCmnTmrExpiry(): Invalid "
13194          "timer event CRNTI:%d",ue->ueId);
13195       return RFAILED;
13196    }
13197 #else
13198    UNUSED(tmrEvnt);
13199 #endif
13200
13201    rgSCHCmnApplyUeRefresh(cell, ue);
13202
13203    rgSCHCmnAddUeToRefreshQ(cell, ue, RG_SCH_CMN_REFRESH_TIME);
13204
13205    return ROK;
13206 }
13207
13208 /***********************************************************
13209  *
13210  *     Func : rgSCHCmnTmrProc
13211  *
13212  *     Desc : Timer entry point per cell. Timer
13213  *            processing is triggered at every frame boundary
13214  *            (every 10 ms).
13215  *
13216  *     Ret  :
13217  *
13218  *     Notes:
13219  *
13220  *     File :
13221  *
13222  **********************************************************/
13223 static S16 rgSCHCmnTmrProc(RgSchCellCb *cell)
13224 {
13225    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
13226    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
13227    /* Moving the assignment of scheduler pointer
13228      to available scope for optimization */
13229
13230    if ((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES_5G) == 0)
13231    {
13232       /* Reset the counters periodically */
13233       if ((cell->crntTime.sfn % RG_SCH_CMN_CSG_REFRESH_TIME) == 0)
13234       {
13235          RG_SCH_RESET_HCSG_DL_PRB_CNTR(cmnDlCell);
13236          RG_SCH_RESET_HCSG_UL_PRB_CNTR(cmnUlCell);
13237       }
13238       if ((cell->crntTime.sfn % RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME) == 0)
13239       {
13240
13241          cell->measurements.ulTpt =  ((cell->measurements.ulTpt * 95) + ( cell->measurements.ulBytesCnt * 5))/100;
13242          cell->measurements.dlTpt =  ((cell->measurements.dlTpt * 95) + ( cell->measurements.dlBytesCnt * 5))/100;
13243
13244          rgSCHUtlCpuOvrLdAdjItbsCap(cell);
13245          /* reset cell level tpt measurements for next cycle */
13246          cell->measurements.ulBytesCnt = 0;
13247          cell->measurements.dlBytesCnt = 0;
13248       }
13249       /* Comparing with Zero instead of % is being done for efficiency.
13250        * If Timer resolution changes then accordingly update the
13251        * macro RG_SCH_CMN_REFRESH_TIMERES */    
13252       RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
13253       cmPrcTmr(&sched->tmrTqCp, sched->tmrTq, (PFV)rgSCHCmnTmrExpiry);
13254    }
13255
13256    return ROK;
13257 }
13258
13259
13260 /***********************************************************
13261  *
13262  *     Func : rgSchCmnUpdCfiVal 
13263  *
13264  *     Desc : Update the CFI value if CFI switch was done 
13265  *
13266  *     Ret  :
13267  *
13268  *     Notes:
13269  *
13270  *     File :
13271  *
13272  **********************************************************/
13273 static Void rgSchCmnUpdCfiVal(RgSchCellCb *cell,uint8_t delta)
13274 {
13275    RgSchDlSf        *dlSf;
13276    CmLteTimingInfo  pdsch;
13277    RgSchCmnDlCell   *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); 
13278    uint8_t          dlIdx;
13279 #ifdef LTE_TDD
13280    uint8_t          mPhich;
13281    RgSchDlSf        *tddSf;
13282    uint8_t          idx;
13283    uint8_t          splSfCfi = 0;
13284 #endif    
13285
13286
13287    pdsch  = cell->crntTime;
13288    RGSCH_INCR_SUB_FRAME(pdsch, delta);
13289    dlSf = rgSCHUtlSubFrmGet(cell, pdsch);
13290    /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
13291     *change happens in that SF then UL PDCCH allocation happens with old CFI
13292     *but CFI in control Req goes updated one since it was stored in the CELL
13293     */
13294    dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
13295    if(cell->dynCfiCb.pdcchSfIdx != 0xFF) 
13296    {
13297 #ifdef LTE_TDD
13298       dlIdx = rgSCHUtlGetDlSfIdx(cell, &pdsch);
13299 #else
13300       dlIdx = (((pdsch.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (pdsch.slot % RGSCH_NUM_SUB_FRAMES));
13301       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
13302 #endif  
13303       /* If current downlink subframe index is same as pdcch SF index,
13304        * perform the switching of CFI in this subframe */
13305       if(cell->dynCfiCb.pdcchSfIdx == dlIdx)
13306       {
13307          cellCmnDl->currCfi  = cellCmnDl->newCfi;
13308          cell->dynCfiCb.pdcchSfIdx = 0xFF;
13309
13310          /* Updating the nCce value based on the new CFI */
13311 #ifdef LTE_TDD
13312          splSfCfi = cellCmnDl->newCfi;
13313          for(idx = 0; idx < cell->numDlSubfrms; idx++)
13314          {   
13315             tddSf = cell->subFrms[idx];
13316
13317             mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][tddSf->sfNum];
13318
13319             if(tddSf->sfType == RG_SCH_SPL_SF_DATA)
13320             {
13321                RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
13322
13323                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
13324             }
13325             else
13326             {   
13327                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][cellCmnDl->currCfi];
13328             }
13329          }
13330          /* Setting the switch over window length based on config index.
13331           * During switch over period all the UL trnsmissions are Acked 
13332           * to UEs */
13333          cell->dynCfiCb.switchOvrWinLen = 
13334                rgSchCfiSwitchOvrWinLen[cell->ulDlCfgIdx];
13335 #else
13336          cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCmnDl->currCfi];
13337          /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
13338           *change happens in that SF then UL PDCCH allocation happens with old CFI
13339           *but CFI in control Req goes updated one since it was stored in the CELL
13340           */
13341          dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
13342          cell->dynCfiCb.switchOvrWinLen = rgSchCfiSwitchOvrWinLen[7];
13343 #endif
13344       }   
13345    }   
13346
13347    return;
13348 }
13349
13350 /***********************************************************
13351  *
13352  *     Func : rgSchCmnUpdtPdcchSfIdx 
13353  *
13354  *     Desc : Update the switch over window length
13355  *
13356  *     Ret  : void
13357  *
13358  *     Notes:
13359  *
13360  *     File :
13361  *
13362  **********************************************************/
13363 #ifdef LTE_TDD
13364 static Void rgSchCmnUpdtPdcchSfIdx(RgSchCellCb *cell,uint8_t dlIdx,uint8_t sfNum)
13365 #else
13366 static Void rgSchCmnUpdtPdcchSfIdx(RgSchCellCb *cell,uint8_t dlIdx)
13367 #endif
13368 {
13369    uint8_t  idx;
13370
13371
13372    /* Resetting the parameters on CFI switching */
13373    cell->dynCfiCb.cceUsed = 0;
13374    cell->dynCfiCb.lowCceCnt = 0;
13375
13376    cell->dynCfiCb.cceFailSum = 0;
13377    cell->dynCfiCb.cceFailCnt = 0;
13378    cell->dynCfiCb.prevCceFailIdx = 0;
13379
13380    cell->dynCfiCb.switchOvrInProgress = TRUE;
13381
13382    for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++)
13383    {
13384       cell->dynCfiCb.cceFailSamples[idx] = 0;
13385    }   
13386
13387    cell->dynCfiCb.ttiCnt = 0;
13388
13389    cell->dynCfiCb.cfiSwitches++;
13390    cfiSwitchCnt = cell->dynCfiCb.cfiSwitches;
13391
13392 #ifdef LTE_TDD 
13393    cell->dynCfiCb.pdcchSfIdx = (dlIdx + 
13394       rgSchTddPdcchSfIncTbl[cell->ulDlCfgIdx][sfNum]) % cell->numDlSubfrms;
13395 #else
13396    cell->dynCfiCb.pdcchSfIdx = (dlIdx + RG_SCH_CFI_APPLY_DELTA) % \
13397         RGSCH_NUM_DL_slotS;
13398 #endif
13399 }
13400
13401 /***********************************************************
13402  *
13403  *     Func : rgSchCmnUpdCfiDb 
13404  *
13405  *     Desc : Update the counters related to dynamic
13406  *            CFI feature in cellCb. 
13407  *
13408  *     Ret  :
13409  *
13410  *     Notes:
13411  *
13412  *     File :
13413  *
13414  **********************************************************/
13415 Void rgSchCmnUpdCfiDb(RgSchCellCb *cell,uint8_t delta)
13416 {
13417    CmLteTimingInfo   frm;
13418    RgSchDlSf         *dlSf;
13419 #ifdef LTE_TDD
13420    uint8_t           mPhich;
13421    Bool              isHiDci0; 
13422 #endif      
13423    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell); 
13424    uint8_t           nCceLowerCfi = 0;
13425    uint8_t           currCfi;
13426    uint8_t           cceFailIdx;
13427    uint32_t          totalCce;
13428    uint8_t           dlIdx;
13429    uint16_t          ttiMod;
13430
13431
13432    /* Get Downlink Subframe */   
13433    frm   = cell->crntTime;
13434    RGSCH_INCR_SUB_FRAME(frm, delta);
13435
13436 #ifdef LTE_TDD
13437    dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
13438    dlSf = cell->subFrms[dlIdx];
13439    isHiDci0 = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][dlSf->sfNum];
13440 #else
13441    /* Changing the idexing
13442       so that proper subframe is selected */
13443    dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
13444    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
13445    dlSf = cell->subFrms[dlIdx];
13446 #endif 
13447
13448    currCfi = cellSch->dl.currCfi;
13449
13450    if(!cell->dynCfiCb.switchOvrInProgress)
13451    {   
13452       do{
13453          if(!cell->dynCfiCb.isDynCfiEnb)
13454          {
13455             if(currCfi != cellSch->cfiCfg.cfi)
13456             {
13457                if(currCfi < cellSch->cfiCfg.cfi)
13458                {
13459                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
13460                   cfiIncr = cell->dynCfiCb.cfiIncr;   
13461                }
13462                else
13463                {
13464                   RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
13465                   cfiDecr = cell->dynCfiCb.cfiDecr;
13466                }
13467             }
13468             break;
13469          }
13470
13471 #ifdef LTE_TDD         
13472          /* Setting ttiMod to 0 for ttiCnt > 1000 in case if this 
13473           * function was not called in UL subframe*/
13474          if(cell->dynCfiCb.ttiCnt > RGSCH_CFI_TTI_MON_INTRVL)
13475          {   
13476             ttiMod = 0;
13477          }
13478          else
13479 #endif
13480          {   
13481             ttiMod = cell->dynCfiCb.ttiCnt % RGSCH_CFI_TTI_MON_INTRVL;
13482          }
13483
13484          dlSf->dlUlBothCmplt++;
13485 #ifdef LTE_TDD      
13486          if((dlSf->dlUlBothCmplt == 2) || (!isHiDci0))
13487 #else
13488          if(dlSf->dlUlBothCmplt == 2)
13489 #endif         
13490          {
13491             /********************STEP UP CRITERIA********************/
13492             /* Updating the CCE failure count parameter */
13493             cell->dynCfiCb.cceFailCnt += dlSf->isCceFailure;
13494             cell->dynCfiCb.cceFailSum += dlSf->isCceFailure;
13495
13496             /* Check if cfi step up can be performed */
13497             if(currCfi < cell->dynCfiCb.maxCfi)
13498             {
13499                if(cell->dynCfiCb.cceFailSum >= cell->dynCfiCb.cfiStepUpTtiCnt) 
13500                {
13501                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
13502                   cfiIncr = cell->dynCfiCb.cfiIncr;   
13503                   break;
13504                }
13505             } 
13506
13507             /********************STEP DOWN CRITERIA********************/
13508
13509             /* Updating the no. of CCE used in this dl subframe */
13510             cell->dynCfiCb.cceUsed += dlSf->cceCnt;
13511
13512             if(currCfi > RGSCH_MIN_CFI_VAL)
13513             {   
13514                /* calculating the number of CCE for next lower CFI */
13515 #ifdef LTE_TDD      
13516                mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][dlSf->sfNum];
13517                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[mPhich][currCfi-1];
13518 #else
13519                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[0][currCfi-1];
13520 #endif     
13521                if(dlSf->cceCnt < nCceLowerCfi)
13522                {
13523                   /* Updating the count of TTIs in which no. of CCEs
13524                    * used were less than the CCEs of next lower CFI */
13525                   cell->dynCfiCb.lowCceCnt++;
13526                }   
13527
13528                if(ttiMod == 0)
13529                {
13530                   totalCce = (nCceLowerCfi * cell->dynCfiCb.cfiStepDownTtiCnt * 
13531                         RGSCH_CFI_CCE_PERCNTG)/100;
13532
13533                   if((!cell->dynCfiCb.cceFailSum) && 
13534                         (cell->dynCfiCb.lowCceCnt >= 
13535                          cell->dynCfiCb.cfiStepDownTtiCnt) && 
13536                         (cell->dynCfiCb.cceUsed < totalCce))  
13537                   {
13538                      RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
13539                      cfiDecr = cell->dynCfiCb.cfiDecr; 
13540                      break;
13541                   }
13542                }   
13543             }
13544
13545             cceFailIdx = ttiMod/cell->dynCfiCb.failSamplePrd;
13546
13547             if(cceFailIdx != cell->dynCfiCb.prevCceFailIdx)
13548             {   
13549                /* New sample period has started. Subtract the old count  
13550                 * from the new sample period */
13551                cell->dynCfiCb.cceFailSum -= cell->dynCfiCb.cceFailSamples[cceFailIdx];
13552
13553                /* Store the previous sample period data */
13554                cell->dynCfiCb.cceFailSamples[cell->dynCfiCb.prevCceFailIdx]
13555                   = cell->dynCfiCb.cceFailCnt;
13556
13557                cell->dynCfiCb.prevCceFailIdx = cceFailIdx;
13558
13559                /* Resetting the CCE failure count as zero for next sample period */
13560                cell->dynCfiCb.cceFailCnt = 0;  
13561             }
13562
13563             if(ttiMod == 0)
13564             {   
13565                /* Restting the parametrs after Monitoring Interval expired */
13566                cell->dynCfiCb.cceUsed = 0;
13567                cell->dynCfiCb.lowCceCnt = 0;
13568                cell->dynCfiCb.ttiCnt = 0;
13569             }
13570
13571             cell->dynCfiCb.ttiCnt++;
13572          }
13573       }while(0);
13574
13575       if(cellSch->dl.newCfi != cellSch->dl.currCfi)
13576       {
13577 #ifdef LTE_TDD      
13578          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, dlSf->sfNum);
13579 #else
13580          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx);
13581 #endif      
13582       }  
13583    }
13584 }   
13585
13586 /**
13587  * @brief Dl Scheduler for Broadcast and Common channel scheduling.
13588  *
13589  * @details
13590  *
13591  *     Function: rgSCHCmnDlCommonChSch
13592  *     Purpose:  This function schedules DL Common channels for LTE. 
13593  *               Invoked by TTI processing in TOM. Scheduling is done for 
13594  *               BCCH, PCCH, Msg4, CCCH SDU, RAR in that order 
13595  *
13596  *     Invoked by: TOM (TTI processing)
13597  *
13598  *  @param[in]  RgSchCellCb *cell
13599  *  @return  Void
13600  **/
13601 Void rgSCHCmnDlCommonChSch(RgSchCellCb  *cell)
13602 {
13603    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
13604
13605
13606    cellSch->apisDl->rgSCHDlTickForPdbTrkng(cell);
13607    rgSchCmnUpdCfiVal(cell, RG_SCH_CMN_DL_DELTA);
13608
13609    /* handle Inactive UEs for DL */
13610    rgSCHCmnHdlDlInactUes(cell);
13611
13612    /* Send a Tick to Refresh Timer */
13613    rgSCHCmnTmrProc(cell);
13614
13615    if (cell->isDlDataAllwd && (cell->stopSiSch == FALSE)) 
13616    {
13617       rgSCHCmnInitRbAlloc(cell); 
13618       /* Perform DL scheduling of BCCH, PCCH */
13619       rgSCHCmnDlBcchPcchAlloc(cell);
13620    }
13621    else
13622    {
13623       if(cell->siCb.inWindow != 0)
13624       {
13625          cell->siCb.inWindow--;
13626       }
13627    }
13628    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
13629    {
13630       rgSCHCmnDlCcchRarAlloc(cell);
13631    }
13632    return;
13633 }
13634
13635 /**
13636  * @brief Scheduler invocation per TTI.
13637  *
13638  * @details
13639  *
13640  *     Function: rgSCHCmnUlSch
13641  *     Purpose:  This function implements UL scheduler alone. This is to
13642  *               be able to perform scheduling with more flexibility.
13643  *
13644  *     Invoked by: TOM (TTI processing)
13645  *
13646  *  @param[in]  RgSchCellCb *cell
13647  *  @return  Void
13648  **/
13649 Void rgSCHCmnUlSch(RgSchCellCb  *cell)
13650 {
13651    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
13652    
13653
13654 #ifdef LTE_ADV
13655    /* LAA_SCELL: */
13656    if(TRUE == rgSCHLaaSCellEnabled(cell))
13657    {
13658       return;   
13659    }
13660 #endif
13661    
13662    if(cellSch->ul.schdIdx != RGSCH_INVALID_INFO)
13663    {   
13664       rgSchCmnUpdCfiVal(cell, TFU_ULCNTRL_DLDELTA);
13665
13666       /* Handle Inactive UEs for UL */
13667       rgSCHCmnHdlUlInactUes(cell);
13668       /* Perform UL Scheduling EVERY TTI */
13669       rgSCHCmnUlAlloc(cell);
13670
13671       /* Calling function to update CFI parameters*/
13672       rgSchCmnUpdCfiDb(cell, TFU_ULCNTRL_DLDELTA);   
13673
13674       if(cell->dynCfiCb.switchOvrWinLen > 0)
13675       {
13676          /* Decrementing the switchover window length */
13677          cell->dynCfiCb.switchOvrWinLen--;
13678
13679          if(!cell->dynCfiCb.switchOvrWinLen)
13680          {   
13681             if(cell->dynCfiCb.dynCfiRecfgPend)
13682             {  
13683                /* Toggling the Dynamic CFI enabling */
13684                cell->dynCfiCb.isDynCfiEnb ^= 1;
13685                rgSCHDynCfiReCfg(cell, cell->dynCfiCb.isDynCfiEnb); 
13686                cell->dynCfiCb.dynCfiRecfgPend = FALSE;
13687             }   
13688             cell->dynCfiCb.switchOvrInProgress = FALSE;
13689          }
13690       }
13691    }
13692 #ifdef LTE_TDD
13693 #ifdef LTEMAC_SPS
13694    else
13695    {
13696       rgSCHCmnSpsUlTti(cell, NULLP); 
13697    }
13698 #endif
13699 #endif
13700
13701    return;
13702 }
13703
13704 \f
13705 /**
13706  * @brief This function updates the scheduler with service for an UE.
13707  *
13708  * @details
13709  *
13710  *     Function: rgSCHCmnDlDedBoUpd
13711  *     Purpose:  This function should be called whenever there is a
13712  *               change BO for a service.
13713  *
13714  *     Invoked by: BO and Scheduler
13715  *
13716  *  @param[in]  RgSchCellCb*  cell
13717  *  @param[in]  RgSchUeCb*    ue
13718  *  @param[in]  RgSchDlLcCb*  svc
13719  *  @return  Void
13720  *
13721  **/
13722 Void rgSCHCmnDlDedBoUpd(RgSchCellCb *cell,RgSchUeCb   *ue,RgSchDlLcCb *svc)
13723 {
13724    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13725
13726    /* RACHO : if UEs idle time exceeded and a BO update
13727     * is received, then add UE to the pdcch Order Q */
13728    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
13729    {
13730       RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
13731       /* If PDCCH order is already triggered and we are waiting for
13732        * RACH from UE then do not add to PdcchOdrQ. */
13733       if (ueDl->rachInfo.rapIdLnk.node == NULLP)
13734       {
13735          rgSCHCmnDlAdd2PdcchOdrQ(cell, ue);
13736       }
13737    }
13738
13739 #ifdef LTEMAC_SPS
13740
13741    /* If SPS service, invoke SPS module */
13742    if (svc->dlLcSpsCfg.isSpsEnabled)
13743    {
13744       rgSCHCmnSpsDlDedBoUpd(cell, ue, svc);
13745       /* Note: Retrun from here, no update needed in other schedulers */
13746       return;
13747    }
13748 #endif
13749 #ifdef EMTC_ENABLE
13750    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
13751    {
13752       cellSch->apisEmtcDl->rgSCHDlDedBoUpd(cell, ue, svc);
13753       //DU_LOG("\nINFO   -->  SCH : rgSCHEMTCDlDedBoUpd\n");
13754    }
13755    else
13756 #endif
13757    {
13758       cellSch->apisDl->rgSCHDlDedBoUpd(cell, ue, svc);
13759    }
13760 #ifdef LTE_ADV
13761    if (ue->numSCells)
13762    {
13763       rgSCHSCellDlDedBoUpd(cell, ue, svc);
13764    }
13765 #endif
13766    return;
13767 }
13768
13769 \f
13770 /**
13771  * @brief Removes an UE from Cell's TA List.
13772  *
13773  * @details
13774  *
13775  *     Function: rgSCHCmnRmvFrmTaLst
13776  *     Purpose:  Removes an UE from Cell's TA List.
13777  *
13778  *     Invoked by: Specific Scheduler
13779  *
13780  *  @param[in]  RgSchCellCb*     cell
13781  *  @param[in]  RgSchUeCb*       ue
13782  *  @return  Void
13783  *
13784  **/
13785 Void rgSCHCmnRmvFrmTaLst(RgSchCellCb *cell,RgSchUeCb *ue)
13786 {
13787    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
13788
13789 #ifdef EMTC_ENABLE
13790    if(cell->emtcEnable && ue->isEmtcUe)
13791    {
13792       rgSCHEmtcRmvFrmTaLst(cellCmnDl,ue);
13793    }
13794    else
13795 #endif
13796    {
13797       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
13798       ue->dlTaLnk.node = (PTR)NULLP;
13799    }
13800    return;
13801 }
13802
13803 /* Fix: syed Remove the msg4Proc from cell
13804  * msg4Retx Queue. I have used CMN scheduler function
13805  * directly. Please define a new API and call this
13806  * function through that. */        
13807 \f
13808 /**
13809  * @brief This function removes MSG4 HARQ process from cell RETX Queues.
13810  *
13811  * @details
13812  *
13813  *     Function: rgSCHCmnDlMsg4ProcRmvFrmRetx
13814  *     Purpose:  This function removes MSG4 HARQ process from cell RETX Queues.
13815  *
13816  *     Invoked by: UE/RACB deletion. 
13817  *
13818  *  @param[in]  RgSchCellCb*     cell
13819  *  @param[in]  RgSchDlHqProc*   hqP
13820  *  @return  Void
13821  *
13822  **/
13823 Void rgSCHCmnDlMsg4ProcRmvFrmRetx(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
13824 {
13825    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13826
13827    if (hqP->tbInfo[0].ccchSchdInfo.retxLnk.node)
13828    {
13829       if (hqP->hqE->msg4Proc == hqP)
13830       {
13831          cmLListDelFrm(&cellSch->dl.msg4RetxLst, \
13832                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13833          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
13834       }
13835 #ifdef RGR_V1
13836       else if(hqP->hqE->ccchSduProc == hqP)
13837       {
13838          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
13839                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13840          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
13841       }
13842 #endif
13843    }
13844    return;
13845 }
13846
13847 \f
13848 /**
13849  * @brief This function adds a HARQ process for retx.
13850  *
13851  * @details
13852  *
13853  *     Function: rgSCHCmnDlProcAddToRetx
13854  *     Purpose:  This function adds a HARQ process to retransmission
13855  *               queue. This may be performed when a HARQ ack is
13856  *               unsuccessful.
13857  *
13858  *     Invoked by: HARQ feedback processing
13859  *
13860  *  @param[in]  RgSchCellCb*     cell
13861  *  @param[in]  RgSchDlHqProc*   hqP
13862  *  @return  Void
13863  *
13864  **/
13865 Void rgSCHCmnDlProcAddToRetx(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
13866 {
13867    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13868
13869    if (hqP->hqE->msg4Proc == hqP) /* indicating msg4 transmission */
13870    {
13871       cmLListAdd2Tail(&cellSch->dl.msg4RetxLst, \
13872             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13873       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
13874    }
13875 #ifdef RGR_V1
13876    else if(hqP->hqE->ccchSduProc == hqP)
13877    {
13878       /*If CCCH SDU being transmitted without cont res CE*/
13879       cmLListAdd2Tail(&cellSch->dl.ccchSduRetxLst,
13880             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13881       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
13882    }
13883 #endif
13884    else
13885    {
13886 #ifdef LTEMAC_SPS
13887       if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
13888       {
13889          /* Invoke SPS module for SPS HARQ proc re-transmission handling */
13890          rgSCHCmnSpsDlProcAddToRetx(cell, hqP);
13891          return;
13892       }
13893 #endif /* LTEMAC_SPS */
13894 #ifdef EMTC_ENABLE      
13895       if((TRUE == cell->emtcEnable)
13896          && (TRUE == hqP->hqE->ue->isEmtcUe))
13897       {
13898          cellSch->apisEmtcDl->rgSCHDlProcAddToRetx(cell, hqP);
13899       }
13900       else
13901 #endif         
13902       {
13903          cellSch->apisDl->rgSCHDlProcAddToRetx(cell, hqP);
13904       }
13905    }
13906    return;
13907 }
13908
13909 \f
13910 /**
13911  * @brief This function performs RI validation and
13912  *        updates it to the ueCb.
13913  *
13914  * @details
13915  *
13916  *     Function: rgSCHCmnDlSetUeRi
13917  *     Purpose:  This function performs RI validation and
13918  *        updates it to the ueCb.
13919  *
13920  *     Invoked by: rgSCHCmnDlCqiInd
13921  *
13922  *  @param[in]  RgSchCellCb        *cell
13923  *  @param[in]  RgSchUeCb          *ue
13924  *  @param[in]  uint8_t                 ri
13925  *  @param[in]  Bool               isPeriodic
13926  *  @return  Void
13927  *
13928  **/
13929 static Void rgSCHCmnDlSetUeRi(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t ri,Bool isPer)
13930 {
13931    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
13932    RgSchCmnUeInfo *ueSchCmn = RG_SCH_CMN_GET_CMN_UE(ue);
13933    
13934 #ifdef TFU_UPGRADE
13935    RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell);
13936    UNUSED(isPer);
13937 #endif
13938
13939
13940    /* FIX for RRC Reconfiguration issue */
13941    /* ccpu00140894- During Tx Mode transition RI report will not entertained for 
13942     * specific during which SCH expecting UE can complete TX mode transition*/
13943    if (ue->txModeTransCmplt == FALSE)
13944    {
13945       return;
13946    }
13947
13948    /* Restrict the Number of TX layers to cell->numTxAntPorts.
13949     * Protection from invalid RI values. */
13950    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
13951    
13952    /* Special case of converting PMI to sane value when
13953     * there is a switch in RI from 1 to 2 and PMI reported 
13954     * for RI=1 is invalid for RI=2 */
13955    if ((cell->numTxAntPorts == 2) && (ue->mimoInfo.txMode == RGR_UE_TM_4))
13956    {
13957       if ((ri == 2) && ( ueDl->mimoInfo.ri == 1))
13958       {
13959          ueDl->mimoInfo.pmi = (ueDl->mimoInfo.pmi < 2)? 1:2;
13960       }
13961    }
13962
13963    /* Restrict the Number of TX layers according to the UE Category */
13964    ueDl->mimoInfo.ri = RGSCH_MIN(ri, rgUeCatTbl[ueSchCmn->ueCat].maxTxLyrs);
13965 #ifdef TENB_STATS
13966    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].riCnt[ueDl->mimoInfo.ri-1]++;
13967    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
13968 #endif
13969
13970 #ifdef TENB_STATS
13971    ue->tenbStats->stats.nonPersistent.sch[0].riCnt[ueDl->mimoInfo.ri-1]++;
13972    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
13973 #endif
13974
13975 #ifdef TFU_UPGRADE
13976    if (isPer)
13977    {
13978       /* If RI is from Periodic CQI report */
13979       cqiCb->perRiVal = ueDl->mimoInfo.ri;
13980       /* Reset at every Periodic RI Reception */ 
13981       cqiCb->invalidateCqi = FALSE;
13982    }
13983    else
13984    {
13985       /* If RI is from Aperiodic CQI report */
13986       if (cqiCb->perRiVal != ueDl->mimoInfo.ri)
13987       {
13988          /* if this aperRI is different from last reported
13989           * perRI then invalidate all CQI reports till next
13990           * perRI */
13991          cqiCb->invalidateCqi = TRUE;
13992       }
13993       else
13994       {
13995          cqiCb->invalidateCqi = FALSE;
13996       }
13997    }
13998 #endif   
13999
14000    if (ueDl->mimoInfo.ri > 1)
14001    {
14002       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
14003    }
14004    else if (ue->mimoInfo.txMode == RGR_UE_TM_3) /* ri == 1 */
14005    {
14006       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
14007    }
14008
14009    return;
14010 }
14011
14012 \f
14013 /**
14014  * @brief This function performs PMI validation and
14015  *        updates it to the ueCb.
14016  *
14017  * @details
14018  *
14019  *     Function: rgSCHCmnDlSetUePmi
14020  *     Purpose:  This function performs PMI validation and
14021  *        updates it to the ueCb.
14022  *
14023  *     Invoked by: rgSCHCmnDlCqiInd
14024  *
14025  *  @param[in]  RgSchCellCb        *cell
14026  *  @param[in]  RgSchUeCb          *ue
14027  *  @param[in]  uint8_t                 pmi
14028  *  @return  Void
14029  *
14030  **/
14031 static S16 rgSCHCmnDlSetUePmi(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t pmi)
14032 {
14033    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14034
14035    if (ue->txModeTransCmplt == FALSE)
14036    {
14037        return RFAILED;
14038    }
14039  
14040    if (cell->numTxAntPorts == 2)
14041    {
14042       if (pmi > 3)
14043       {
14044          return RFAILED;
14045       }
14046       if (ueDl->mimoInfo.ri == 2)
14047       {
14048          /*ccpu00118150 - MOD - changed pmi value validation from 0 to 2*/
14049          /* PMI 2 and 3 are invalid incase of 2 TxAnt and 2 Layered SM */
14050          if (pmi == 2 || pmi == 3)
14051          {
14052             return RFAILED;
14053          }
14054          ueDl->mimoInfo.pmi = pmi+1;
14055       }
14056       else
14057       {
14058          ueDl->mimoInfo.pmi = pmi;
14059       }
14060    }
14061    else if (cell->numTxAntPorts == 4)
14062    {
14063       if (pmi > 15)
14064       {
14065          return RFAILED;
14066       }
14067       ueDl->mimoInfo.pmi = pmi;
14068    }
14069    /* Reset the No PMI Flag in forceTD */
14070    RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
14071    return ROK;
14072 }
14073
14074 /**
14075  * @brief This function Updates the DL CQI on PUCCH for the UE.
14076  *
14077  * @details
14078  *
14079  *     Function: rgSCHCmnDlProcCqiMode10
14080  *
14081  *     This function updates the DL CQI on PUCCH for the UE.
14082  *
14083  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14084  *
14085  *     Processing Steps:
14086  *
14087  *  @param[in] RgSchCellCb     *cell
14088  *  @param[in] RgSchUeCb       *ue
14089  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14090  *  @return  S16
14091  *      -# ROK
14092  *      -# RFAILED
14093  **/
14094 #ifdef RGR_CQI_REPT
14095 static inline Void rgSCHCmnDlProcCqiMode10
14096 (
14097 RgSchCellCb   *cell,
14098 RgSchUeCb     *ue,
14099 TfuDlCqiPucch *pucchCqi,
14100 Bool          *isCqiAvail
14101 )
14102 #else
14103 static inline Void rgSCHCmnDlProcCqiMode10
14104 (
14105 RgSchCellCb   *cell,
14106 RgSchUeCb     *ue,
14107 TfuDlCqiPucch *pucchCqi
14108 )
14109 #endif
14110 {
14111    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14112
14113    if (pucchCqi->u.mode10Info.type == TFU_RPT_CQI)
14114    {
14115       /*ccpu00109787 - ADD - Check for non-zero CQI*/
14116       /* Checking whether the decoded CQI is a value between 1 and 15*/
14117       if((pucchCqi->u.mode10Info.u.cqi) && (pucchCqi->u.mode10Info.u.cqi
14118                < RG_SCH_CMN_MAX_CQI))
14119       {
14120          ueDl->cqiFlag = TRUE;
14121          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode10Info.u.cqi;
14122          ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14123          /* ccpu00117452 - MOD - Changed macro name from
14124             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14125 #ifdef RGR_CQI_REPT
14126          *isCqiAvail = TRUE;
14127 #endif
14128       }
14129       else
14130       {
14131          return;
14132       }
14133    }
14134    else if (pucchCqi->u.mode10Info.type == TFU_RPT_RI)
14135    {
14136       if ( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode10Info.u.ri) )
14137       {
14138          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode10Info.u.ri,
14139                            TRUE);
14140       }
14141       else
14142       {
14143          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14144             pucchCqi->u.mode10Info.u.ri,ue->ueId);
14145          return;
14146       }
14147    }
14148 }
14149
14150 /**
14151  * @brief This function Updates the DL CQI on PUCCH for the UE.
14152  *
14153  * @details
14154  *
14155  *     Function: rgSCHCmnDlProcCqiMode11
14156  *
14157  *     This function updates the DL CQI on PUCCH for the UE.
14158  *
14159  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14160  *
14161  *     Processing Steps:
14162  *       Process CQI MODE 11
14163  *  @param[in] RgSchCellCb     *cell
14164  *  @param[in] RgSchUeCb       *ue
14165  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14166  *  @return  S16
14167  *      -# ROK
14168  *      -# RFAILED
14169  **/
14170 #ifdef RGR_CQI_REPT
14171 static inline Void rgSCHCmnDlProcCqiMode11
14172 (
14173 RgSchCellCb    *cell,
14174 RgSchUeCb      *ue,
14175 TfuDlCqiPucch  *pucchCqi,
14176 Bool           *isCqiAvail,
14177 Bool           *is2ndCwCqiAvail
14178 )
14179 #else
14180 static inline Void rgSCHCmnDlProcCqiMode11
14181 (
14182 RgSchCellCb    *cell,
14183 RgSchUeCb      *ue,
14184 TfuDlCqiPucch  *pucchCqi
14185 )
14186 #endif
14187 {
14188    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14189
14190    if (pucchCqi->u.mode11Info.type == TFU_RPT_CQI)
14191    {
14192       ue->mimoInfo.puschFdbkVld  = FALSE;
14193       /*ccpu00109787 - ADD - Check for non-zero CQI*/
14194       if((pucchCqi->u.mode11Info.u.cqi.cqi) &&
14195             (pucchCqi->u.mode11Info.u.cqi.cqi < RG_SCH_CMN_MAX_CQI))
14196       {
14197          ueDl->cqiFlag = TRUE;
14198          /* ccpu00117452 - MOD - Changed macro name from
14199             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14200 #ifdef RGR_CQI_REPT
14201          *isCqiAvail = TRUE;
14202 #endif
14203          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode11Info.u.cqi.cqi;
14204          if (pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.pres)
14205          {
14206             RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
14207                                      ueDl->mimoInfo.cwInfo[1].cqi, \
14208                                      pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.val);
14209 #ifdef RGR_CQI_REPT
14210             /* ccpu00117259 - ADD - Considering second codeword CQI info
14211                incase of MIMO for CQI Reporting */
14212             *is2ndCwCqiAvail = TRUE;
14213 #endif
14214          }
14215       }
14216       else
14217       {
14218          return;
14219       }
14220       rgSCHCmnDlSetUePmi(cell, ue, \
14221             pucchCqi->u.mode11Info.u.cqi.pmi);
14222    }
14223    else if (pucchCqi->u.mode11Info.type == TFU_RPT_RI)
14224    {
14225       if( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode11Info.u.ri))
14226       {
14227          rgSCHCmnDlSetUeRi(cell, ue,  pucchCqi->u.mode11Info.u.ri,
14228                            TRUE);
14229       }
14230       else
14231       {
14232          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14233             pucchCqi->u.mode11Info.u.ri,ue->ueId);
14234          return;
14235       }
14236    }
14237 }
14238
14239 /**
14240  * @brief This function Updates the DL CQI on PUCCH for the UE.
14241  *
14242  * @details
14243  *
14244  *     Function: rgSCHCmnDlProcCqiMode20
14245  *
14246  *     This function updates the DL CQI on PUCCH for the UE.
14247  *
14248  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14249  *
14250  *     Processing Steps:
14251  *       Process CQI MODE 20
14252  *  @param[in] RgSchCellCb     *cell
14253  *  @param[in] RgSchUeCb       *ue
14254  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14255  *  @return  S16
14256  *      -# ROK
14257  *      -# RFAILED
14258  **/
14259 #ifdef RGR_CQI_REPT
14260 static inline Void rgSCHCmnDlProcCqiMode20
14261 (
14262 RgSchCellCb   *cell,
14263 RgSchUeCb     *ue,
14264 TfuDlCqiPucch *pucchCqi,
14265 Bool          *isCqiAvail
14266 )
14267 #else
14268 static inline Void rgSCHCmnDlProcCqiMode20
14269 (
14270 RgSchCellCb   *cell,
14271 RgSchUeCb     *ue,
14272 TfuDlCqiPucch *pucchCqi
14273 )
14274 #endif
14275 {
14276    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14277
14278    if (pucchCqi->u.mode20Info.type == TFU_RPT_CQI)
14279    {
14280       if (pucchCqi->u.mode20Info.u.cqi.isWideband)
14281       {
14282          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14283          if((pucchCqi->u.mode20Info.u.cqi.u.wideCqi) &&
14284                (pucchCqi->u.mode20Info.u.cqi.u.wideCqi < RG_SCH_CMN_MAX_CQI))
14285          {
14286             ueDl->cqiFlag = TRUE;
14287             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode20Info.u.cqi.\
14288                                            u.wideCqi;
14289             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14290             /* ccpu00117452 - MOD - Changed macro name from
14291                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14292 #ifdef RGR_CQI_REPT
14293             *isCqiAvail = TRUE;
14294 #endif
14295          }
14296          else
14297          {
14298             return;
14299          }
14300       }
14301    }
14302    else if (pucchCqi->u.mode20Info.type == TFU_RPT_RI)
14303    {
14304       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode20Info.u.ri))
14305       {
14306          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode20Info.u.ri, 
14307                            TRUE);
14308       }
14309       else
14310       {
14311          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14312             pucchCqi->u.mode20Info.u.ri,ue->ueId);
14313          return;
14314       }
14315    }
14316 }
14317
14318
14319 /**
14320  * @brief This function Updates the DL CQI on PUCCH for the UE.
14321  *
14322  * @details
14323  *
14324  *     Function: rgSCHCmnDlProcCqiMode21
14325  *
14326  *     This function updates the DL CQI on PUCCH for the UE.
14327  *
14328  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14329  *
14330  *     Processing Steps:
14331  *       Process CQI MODE 21
14332  *  @param[in] RgSchCellCb     *cell
14333  *  @param[in] RgSchUeCb       *ue
14334  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14335  *  @return  S16
14336  *      -# ROK
14337  *      -# RFAILED
14338  **/
14339 #ifdef RGR_CQI_REPT
14340 static inline Void rgSCHCmnDlProcCqiMode21
14341 (
14342 RgSchCellCb   *cell,
14343 RgSchUeCb     *ue,
14344 TfuDlCqiPucch *pucchCqi,
14345 Bool          *isCqiAvail,
14346 Bool          *is2ndCwCqiAvail
14347 )
14348 #else
14349 static inline Void rgSCHCmnDlProcCqiMode21
14350 (
14351 RgSchCellCb   *cell,
14352 RgSchUeCb     *ue,
14353 TfuDlCqiPucch *pucchCqi
14354 )
14355 #endif
14356 {
14357    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14358
14359    if (pucchCqi->u.mode21Info.type == TFU_RPT_CQI)
14360    {
14361       ue->mimoInfo.puschFdbkVld  = FALSE;
14362       if (pucchCqi->u.mode21Info.u.cqi.isWideband)
14363       {
14364          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14365          if((pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi) &&
14366                (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi < RG_SCH_CMN_MAX_CQI))
14367          {
14368             ueDl->cqiFlag = TRUE;
14369             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode21Info.u.cqi.\
14370                                            u.wideCqi.cqi;
14371             if (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.pres)
14372             {
14373                RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
14374                                      ueDl->mimoInfo.cwInfo[1].cqi, \
14375                                      pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.val);
14376 #ifdef RGR_CQI_REPT
14377                /* ccpu00117259 - ADD - Considering second codeword CQI info
14378                   incase of MIMO for CQI Reporting */
14379                *is2ndCwCqiAvail = TRUE;
14380 #endif
14381             }
14382             /* ccpu00117452 - MOD - Changed macro name from
14383                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14384 #ifdef RGR_CQI_REPT
14385             *isCqiAvail = TRUE;
14386 #endif
14387          }
14388          else
14389          {
14390             return;
14391          }
14392          rgSCHCmnDlSetUePmi(cell, ue, \
14393                pucchCqi->u.mode21Info.u.cqi.u.wideCqi.pmi);
14394       }
14395    }
14396    else if (pucchCqi->u.mode21Info.type == TFU_RPT_RI)
14397    {
14398       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode21Info.u.ri))
14399       {
14400          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode21Info.u.ri,
14401                            TRUE);
14402       }
14403       else
14404       {
14405          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14406             pucchCqi->u.mode21Info.u.ri,ue->ueId);
14407          return;
14408       }
14409    }
14410 }
14411
14412
14413 /**
14414  * @brief This function Updates the DL CQI on PUCCH for the UE.
14415  *
14416  * @details
14417  *
14418  *     Function: rgSCHCmnDlCqiOnPucchInd
14419  *
14420  *     This function updates the DL CQI on PUCCH for the UE.
14421  *
14422  *     Invoked by: rgSCHCmnDlCqiInd
14423  *
14424  *     Processing Steps:
14425  *     - Depending on the reporting mode of the PUCCH, the CQI/PMI/RI values
14426  *       are updated and stored for each UE
14427  *
14428  *  @param[in] RgSchCellCb     *cell
14429  *  @param[in] RgSchUeCb       *ue
14430  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14431  *  @return  S16
14432  *      -# ROK
14433  *      -# RFAILED
14434  **/
14435 #ifdef RGR_CQI_REPT
14436 static Void rgSCHCmnDlCqiOnPucchInd
14437 (
14438 RgSchCellCb   *cell,
14439 RgSchUeCb     *ue,
14440 TfuDlCqiPucch *pucchCqi,
14441 RgrUeCqiRept  *ueCqiRept,
14442 Bool          *isCqiAvail,
14443 Bool          *is2ndCwCqiAvail
14444 )
14445 #else
14446 static Void rgSCHCmnDlCqiOnPucchInd
14447 (
14448 RgSchCellCb   *cell,
14449 RgSchUeCb     *ue,
14450 TfuDlCqiPucch *pucchCqi
14451 )
14452 #endif
14453 {
14454    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14455
14456    /* ccpu00117452 - MOD - Changed
14457       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14458 #ifdef RGR_CQI_REPT
14459    /* Save CQI mode information in the report */
14460    ueCqiRept->cqiMode = pucchCqi->mode;
14461 #endif
14462
14463    switch(pucchCqi->mode)
14464    {
14465       case TFU_PUCCH_CQI_MODE10:
14466 #ifdef RGR_CQI_REPT
14467          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail);
14468 #else
14469          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi);
14470 #endif
14471          ueDl->cqiFlag = TRUE;
14472          break;
14473       case TFU_PUCCH_CQI_MODE11:
14474 #ifdef RGR_CQI_REPT
14475          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail,
14476                 is2ndCwCqiAvail);
14477 #else
14478          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi);
14479 #endif
14480          ueDl->cqiFlag = TRUE;
14481          break;
14482       case TFU_PUCCH_CQI_MODE20:
14483 #ifdef RGR_CQI_REPT
14484          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail);
14485 #else
14486          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi);
14487 #endif
14488          ueDl->cqiFlag = TRUE;
14489          break;
14490       case TFU_PUCCH_CQI_MODE21:
14491 #ifdef RGR_CQI_REPT
14492          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail,
14493                 is2ndCwCqiAvail);
14494 #else
14495          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi);
14496 #endif
14497          ueDl->cqiFlag = TRUE;
14498          break;
14499       default:
14500          {
14501             DU_LOG("\nERROR  -->  SCH : Unknown CQI Mode %d of UE %d",
14502                pucchCqi->mode,ue->ueId);
14503             /* ccpu00117452 - MOD - Changed macro name from
14504                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14505 #ifdef RGR_CQI_REPT
14506             *isCqiAvail = FALSE;
14507 #endif
14508          }
14509          break;
14510    }
14511
14512   return;
14513 }  /* rgSCHCmnDlCqiOnPucchInd */
14514
14515
14516 /**
14517  * @brief This function Updates the DL CQI on PUSCH for the UE.
14518  *
14519  * @details
14520  *
14521  *     Function: rgSCHCmnDlCqiOnPuschInd
14522  *
14523  *     This function updates the DL CQI on PUSCH for the UE.
14524  *
14525  *     Invoked by: rgSCHCmnDlCqiInd
14526  *
14527  *     Processing Steps:
14528  *     - Depending on the reporting mode of the PUSCH, the CQI/PMI/RI values
14529  *       are updated and stored for each UE
14530  *
14531  *  @param[in] RgSchCellCb     *cell
14532  *  @param[in] RgSchUeCb       *ue
14533  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14534  *  @return  S16
14535  *      -# ROK
14536  *      -# RFAILED
14537  **/
14538 #ifdef RGR_CQI_REPT
14539 static Void rgSCHCmnDlCqiOnPuschInd
14540 (
14541 RgSchCellCb   *cell,
14542 RgSchUeCb     *ue,
14543 TfuDlCqiPusch *puschCqi,
14544 RgrUeCqiRept  *ueCqiRept,
14545 Bool          *isCqiAvail,
14546 Bool          *is2ndCwCqiAvail
14547 )
14548 #else
14549 static Void rgSCHCmnDlCqiOnPuschInd
14550 (
14551 RgSchCellCb   *cell,
14552 RgSchUeCb     *ue,
14553 TfuDlCqiPusch *puschCqi
14554 )
14555 #endif
14556 {
14557    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14558    uint32_t prevRiVal = 0; 
14559    if (puschCqi->ri.pres == PRSNT_NODEF)
14560    {
14561       if (RG_SCH_CMN_IS_RI_VALID(puschCqi->ri.val))
14562       {
14563          /* Saving the previous ri value to revert back
14564             in  case PMI update failed */
14565          if (RGR_UE_TM_4 == ue->mimoInfo.txMode ) /* Cheking for TM4. TM8 check later */
14566          {
14567             prevRiVal = ueDl->mimoInfo.ri;
14568          }
14569          rgSCHCmnDlSetUeRi(cell, ue, puschCqi->ri.val, FALSE);
14570       }
14571       else
14572       {
14573          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14574             puschCqi->ri.val,ue->ueId);
14575          return;
14576       }
14577    }
14578    ue->mimoInfo.puschFdbkVld  = FALSE;
14579    /* ccpu00117452 - MOD - Changed macro name from
14580       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14581 #ifdef RGR_CQI_REPT
14582    /* Save CQI mode information in the report */
14583    ueCqiRept->cqiMode = puschCqi->mode;
14584    /* ccpu00117259 - DEL - removed default setting of isCqiAvail to TRUE */
14585 #endif
14586
14587    switch(puschCqi->mode)
14588    {
14589       case TFU_PUSCH_CQI_MODE_20:
14590          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14591          /* Checking whether the decoded CQI is a value between 1 and 15*/
14592          if((puschCqi->u.mode20Info.wideBandCqi) &&
14593                (puschCqi->u.mode20Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
14594          {
14595             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode20Info.wideBandCqi;
14596             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14597             /* ccpu00117452 - MOD - Changed macro name from
14598                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14599 #ifdef RGR_CQI_REPT
14600            *isCqiAvail = TRUE;
14601 #endif
14602          }
14603          else
14604          {
14605             return;
14606          }
14607          break;
14608       case TFU_PUSCH_CQI_MODE_30:
14609          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14610          if((puschCqi->u.mode30Info.wideBandCqi) &&
14611                (puschCqi->u.mode30Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
14612          {
14613             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode30Info.wideBandCqi;
14614             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14615             /* ccpu00117452 - MOD - Changed macro name from
14616                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14617 #ifdef RGR_CQI_REPT
14618             *isCqiAvail = TRUE;
14619 #endif
14620 #ifdef CA_DBG
14621             {
14622                uint32_t gACqiRcvdCount;
14623                gACqiRcvdCount++;
14624             
14625             }
14626 #endif
14627          }
14628          else
14629          {
14630             return;
14631          }
14632          break;
14633       case TFU_PUSCH_CQI_MODE_12:
14634          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14635          if((puschCqi->u.mode12Info.cqiIdx[0]) &&
14636                (puschCqi->u.mode12Info.cqiIdx[0] < RG_SCH_CMN_MAX_CQI))
14637          {
14638             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode12Info.cqiIdx[0];
14639             /* ccpu00117452 - MOD - Changed macro name from
14640                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14641 #ifdef RGR_CQI_REPT
14642             *isCqiAvail = TRUE;
14643 #endif
14644          }
14645          else
14646          {
14647             return;
14648          }
14649          if((puschCqi->u.mode12Info.cqiIdx[1]) &&
14650                (puschCqi->u.mode12Info.cqiIdx[1] < RG_SCH_CMN_MAX_CQI))
14651          {
14652             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode12Info.cqiIdx[1];
14653             /* ccpu00117452 - MOD - Changed macro name from
14654                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14655 #ifdef RGR_CQI_REPT
14656             /* ccpu00117259 - ADD - Considering second codeword CQI info
14657                incase of MIMO for CQI Reporting */
14658             *is2ndCwCqiAvail = TRUE;
14659 #endif
14660          }
14661          else
14662          {
14663             return;
14664          }
14665          ue->mimoInfo.puschFdbkVld  = TRUE;
14666          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_12;
14667          ue->mimoInfo.puschPmiInfo.u.mode12Info = puschCqi->u.mode12Info;
14668          /*  : resetting this is time based. Make use of CQI reporting
14669           * periodicity, DELTA's in determining the exact time at which this
14670           * need to be reset. */
14671          break;
14672       case TFU_PUSCH_CQI_MODE_22:
14673          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14674          if((puschCqi->u.mode22Info.wideBandCqi[0]) &&
14675                (puschCqi->u.mode22Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
14676          {
14677             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode22Info.wideBandCqi[0];
14678             /* ccpu00117452 - MOD - Changed macro name from
14679                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14680 #ifdef RGR_CQI_REPT
14681             *isCqiAvail = TRUE;
14682 #endif
14683          }
14684          else
14685          {
14686             return;
14687          }
14688          if((puschCqi->u.mode22Info.wideBandCqi[1]) &&
14689                (puschCqi->u.mode22Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
14690          {
14691             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode22Info.wideBandCqi[1];
14692             /* ccpu00117452 - MOD - Changed macro name from
14693                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14694 #ifdef RGR_CQI_REPT
14695             /* ccpu00117259 - ADD - Considering second codeword CQI info
14696                incase of MIMO for CQI Reporting */
14697             *is2ndCwCqiAvail = TRUE;
14698 #endif
14699          }
14700          else
14701          {
14702             return;
14703          }
14704          rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode22Info.wideBandPmi);
14705          ue->mimoInfo.puschFdbkVld  = TRUE;
14706          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_22;
14707          ue->mimoInfo.puschPmiInfo.u.mode22Info = puschCqi->u.mode22Info;
14708          break;
14709       case TFU_PUSCH_CQI_MODE_31:
14710          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14711          if((puschCqi->u.mode31Info.wideBandCqi[0]) &&
14712                (puschCqi->u.mode31Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
14713          {
14714             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode31Info.wideBandCqi[0];
14715             /* ccpu00117452 - MOD - Changed macro name from
14716                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14717 #ifdef RGR_CQI_REPT
14718             *isCqiAvail = TRUE;
14719 #endif
14720          }
14721          if (ueDl->mimoInfo.ri > 1)
14722          {
14723            if((puschCqi->u.mode31Info.wideBandCqi[1]) &&
14724                (puschCqi->u.mode31Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
14725            {
14726              ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode31Info.wideBandCqi[1];
14727             /* ccpu00117452 - MOD - Changed macro name from
14728                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14729 #ifdef RGR_CQI_REPT
14730             /* ccpu00117259 - ADD - Considering second codeword CQI info
14731                incase of MIMO for CQI Reporting */
14732              *is2ndCwCqiAvail = TRUE;
14733 #endif
14734            }
14735          }
14736          if (rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode31Info.pmi) != ROK)
14737          {
14738             /* To avoid Rank and PMI inconsistency */
14739             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
14740                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
14741             {
14742                ueDl->mimoInfo.ri = prevRiVal;
14743             }
14744          }
14745          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_31;
14746          ue->mimoInfo.puschPmiInfo.u.mode31Info = puschCqi->u.mode31Info;
14747          break;
14748       default:
14749          {
14750             DU_LOG("\nERROR  -->  SCH : Unknown CQI Mode %d CRNTI:%d",
14751                puschCqi->mode,ue->ueId);
14752             /*  CQI decoding failed revert the RI to previous value */
14753             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
14754                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
14755             {
14756                ueDl->mimoInfo.ri = prevRiVal;
14757             }
14758             /* ccpu00117452 - MOD - Changed macro name from
14759                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14760 #ifdef RGR_CQI_REPT
14761            *isCqiAvail = FALSE;
14762             /* ccpu00117259 - ADD - Considering second codeword CQI info
14763                incase of MIMO for CQI Reporting */
14764             *is2ndCwCqiAvail = FALSE;
14765 #endif
14766          }
14767          break;
14768    }
14769
14770    return;
14771 }  /* rgSCHCmnDlCqiOnPuschInd */
14772
14773 \f
14774 /**
14775  * @brief This function Updates the DL CQI for the UE.
14776  *
14777  * @details
14778  *
14779  *     Function: rgSCHCmnDlCqiInd
14780  *     Purpose:  Updates the DL CQI for the UE
14781  *
14782  *     Invoked by: TOM
14783  *
14784  *  @param[in]  RgSchCellCb        *cell
14785  *  @param[in]  RgSchUeCb          *ue
14786  *  @param[in]  TfuDlCqiRpt        *dlCqi
14787  *  @return  Void
14788  *
14789  **/
14790 Void rgSCHCmnDlCqiInd
14791 (
14792 RgSchCellCb     *cell,
14793 RgSchUeCb       *ue,
14794 Bool            isPucchInfo,
14795 Void            *dlCqi,
14796 CmLteTimingInfo timingInfo
14797 )
14798 {
14799    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
14800 /* ccpu00117452 - MOD - Changed macro name from
14801    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14802 #ifdef RGR_CQI_REPT
14803    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14804    RgrUeCqiRept   ueCqiRept = {{0}};
14805    Bool           isCqiAvail = FALSE;
14806    /* ccpu00117259 - ADD - Considering second codeword CQI info
14807       incase of MIMO for CQI Reporting */
14808    Bool           is2ndCwCqiAvail = FALSE;
14809 #endif
14810
14811
14812 #ifdef RGR_CQI_REPT
14813    if (isPucchInfo)
14814    {
14815       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail);
14816    }
14817    else
14818    {
14819       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi, &ueCqiRept,  &isCqiAvail, &is2ndCwCqiAvail);
14820    }
14821 #else
14822    if (isPucchInfo)
14823    {
14824       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi);
14825    }
14826    else
14827    {
14828       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi);
14829    }
14830 #endif
14831
14832 #ifdef CQI_CONFBITMASK_DROP
14833    if(!ue->cqiConfBitMask)
14834    {
14835       if (ueDl->mimoInfo.cwInfo[0].cqi >15)
14836       {
14837          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
14838          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
14839       }
14840       else if ( ueDl->mimoInfo.cwInfo[0].cqi >= ue->prevCqi)
14841       {
14842          ue->prevCqi = ueDl->mimoInfo.cwInfo[0].cqi;
14843       }
14844       else
14845       {
14846          uint8_t dlCqiDeltaPrev = 0;
14847          dlCqiDeltaPrev = ue->prevCqi - ueDl->mimoInfo.cwInfo[0].cqi;
14848          if (dlCqiDeltaPrev > 3)
14849             dlCqiDeltaPrev = 3;
14850          if ((ue->prevCqi - dlCqiDeltaPrev) < 6)
14851          {
14852             ue->prevCqi = 6;
14853          }
14854          else 
14855          {
14856             ue->prevCqi = ue->prevCqi - dlCqiDeltaPrev;
14857          }
14858          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
14859          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
14860
14861       }
14862    }
14863 #endif
14864
14865 /* ccpu00117452 - MOD - Changed macro name from
14866    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14867 #ifdef RGR_CQI_REPT
14868    /* ccpu00117259 - ADD - Considering second codeword CQI info
14869       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail\
14870       in 'if' condition*/
14871    if (RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(ue) && (isCqiAvail || is2ndCwCqiAvail))
14872    {
14873       ueCqiRept.cqi[0] = ueDl->mimoInfo.cwInfo[0].cqi;
14874
14875    /* ccpu00117259 - ADD - Considering second codeword CQI info
14876       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail
14877       in 'if' condition*/
14878       ueCqiRept.cqi[1] = 0;
14879       if(is2ndCwCqiAvail)
14880       {
14881          ueCqiRept.cqi[1] = ueDl->mimoInfo.cwInfo[1].cqi;
14882       }
14883       rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, &ueCqiRept);
14884
14885    }
14886 #endif
14887 #ifdef DL_LA
14888    rgSCHCmnDlSetUeAllocLmtLa(cell, ue);
14889    rgSCHCheckAndSetTxScheme(cell, ue);
14890 #else
14891 #ifdef EMTC_ENABLE   
14892    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), ue->isEmtcUe);
14893 #else 
14894    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), FALSE);
14895 #endif   
14896 #endif
14897
14898    if (cellSch->dl.isDlFreqSel)
14899    {
14900       cellSch->apisDlfs->rgSCHDlfsDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo);
14901    }
14902 #ifdef LTEMAC_SPS
14903    /* Call SPS module to update CQI indication */
14904    rgSCHCmnSpsDlCqiIndHndlr(cell, ue, timingInfo);
14905 #endif
14906    /* Call Specific scheduler to process on dlCqiInd */
14907 #ifdef EMTC_ENABLE
14908    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
14909    {
14910       cellSch->apisEmtcDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
14911    }
14912    else
14913 #endif
14914    {
14915       cellSch->apisDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
14916    }
14917
14918 #ifdef RG_PFS_STATS
14919    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].avgCqi += 
14920       ueDl->mimoInfo.cwInfo[0].cqi;
14921    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].totalCqiOcc++; 
14922 #endif
14923
14924 #ifdef SCH_STATS
14925    ueDl->avgCqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14926    ueDl->numCqiOccns++;
14927    if (ueDl->mimoInfo.ri == 1)
14928    {
14929       ueDl->numRi1++;
14930    }
14931    else
14932    {
14933       ueDl->numRi2++;
14934    }
14935 #endif
14936
14937 #ifdef TENB_STATS
14938    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14939    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
14940    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw0Cqi ++;
14941    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw1Cqi ++;
14942    cell->tenbStats->sch.dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14943    cell->tenbStats->sch.dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
14944    cell->tenbStats->sch.dlNumCw0Cqi ++;
14945    cell->tenbStats->sch.dlNumCw1Cqi ++;
14946 #endif
14947    return;
14948 }
14949
14950 #ifdef TFU_UPGRADE
14951 /**
14952  * @brief This function calculates the wideband CQI from SNR
14953  *            reported for each RB.
14954  *
14955  * @details
14956  *
14957  *     Function: rgSCHCmnCalcWcqiFrmSnr
14958  *     Purpose:  Wideband CQI calculation from SNR
14959  *
14960  *     Invoked by: RG SCH
14961  *
14962  *  @param[in]  RgSchCellCb        *cell
14963  *  @param[in]  TfuSrsRpt        *srsRpt,
14964  *  @return  Wideband CQI
14965  *
14966  **/
14967 static uint8_t rgSCHCmnCalcWcqiFrmSnr(RgSchCellCb *cell, TfuSrsRpt *srsRpt)
14968 {
14969    uint8_t wideCqi=1; /*Calculated value from SNR*/
14970    /*Need to map a certain SNR with a WideCQI value.
14971     * The CQI calculation is still primitive. Further, need to
14972     * use a improvized method for calculating WideCQI from SNR*/
14973        if (srsRpt->snr[0] <=50)
14974        {
14975            wideCqi=3;
14976        }
14977        else if (srsRpt->snr[0]>=51 && srsRpt->snr[0] <=100)
14978        {
14979            wideCqi=6;
14980        }
14981        else if (srsRpt->snr[0]>=101 && srsRpt->snr[0] <=150)
14982        {
14983            wideCqi=9;
14984        }
14985        else if (srsRpt->snr[0]>=151 && srsRpt->snr[0] <=200)
14986        {
14987            wideCqi=12;
14988        }
14989        else if (srsRpt->snr[0]>=201 && srsRpt->snr[0] <=250)
14990        {
14991            wideCqi=14;
14992        }
14993        else
14994        {
14995            wideCqi=15;
14996        }
14997    return (wideCqi);
14998 }/*rgSCHCmnCalcWcqiFrmSnr*/
14999
15000
15001 /**
15002  * @brief This function Updates the SRS for the UE.
15003  *
15004  * @details
15005  *
15006  *     Function: rgSCHCmnSrsInd
15007  *     Purpose:  Updates the UL SRS for the UE
15008  *
15009  *     Invoked by: TOM
15010  *
15011  *  @param[in]  RgSchCellCb        *cell
15012  *  @param[in]  RgSchUeCb          *ue
15013  *  @param[in]  TfuSrsRpt        *srsRpt,
15014  *  @return  Void
15015  *
15016  **/
15017 Void rgSCHCmnSrsInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuSrsRpt  *srsRpt,CmLteTimingInfo  timingInfo)
15018 {
15019     uint8_t wideCqi; /*Calculated value from SNR*/
15020     uint32_t recReqTime; /*Received Time in TTI*/
15021
15022     recReqTime = (timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + timingInfo.slot;
15023     ue->srsCb.selectedAnt = (recReqTime/ue->srsCb.peri)%2;
15024     if(srsRpt->wideCqiPres)
15025     {
15026         wideCqi = srsRpt->wideCqi;
15027     }
15028     else
15029     {
15030         wideCqi = rgSCHCmnCalcWcqiFrmSnr(cell, srsRpt);
15031     }
15032     rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi);
15033     return;
15034 }/*rgSCHCmnSrsInd*/
15035 #endif
15036
15037 \f
15038 /**
15039  * @brief This function is a handler for TA report for an UE.
15040  *
15041  * @details
15042  *
15043  *     Function: rgSCHCmnDlTARpt
15044  *     Purpose:  Determine based on UE_IDLE_TIME threshold,
15045  *     whether UE needs to be Linked to the scheduler's TA list OR
15046  *     if it needs a PDCCH Order.
15047  *
15048  *
15049  *     Invoked by: TOM
15050  *
15051  *  @param[in]  RgSchCellCb        *cell
15052  *  @param[in]  RgSchUeCb          *ue
15053  *  @return  Void
15054  *
15055  **/
15056 Void rgSCHCmnDlTARpt(RgSchCellCb *cell,RgSchUeCb *ue)
15057 {
15058    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
15059    RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
15060    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15061    CmLListCp       poInactvLst;
15062
15063
15064    /* RACHO: If UE idle time is more than threshold, then
15065     * set its poInactv pdcch order inactivity  */
15066    /* Fix : syed Ignore if TaTmr is not configured */
15067    if ((ue->dl.taCb.cfgTaTmr) && (rgSCHCmnUeIdleExdThrsld(cell, ue) == ROK))
15068    {
15069       uint32_t prevDlMsk = ue->dl.dlInactvMask;
15070       uint32_t prevUlMsk = ue->ul.ulInactvMask;
15071       ue->dl.dlInactvMask |= RG_PDCCHODR_INACTIVE;
15072       ue->ul.ulInactvMask |= RG_PDCCHODR_INACTIVE;
15073       /* Indicate Specific scheduler for this UEs inactivity */
15074       cmLListInit(&poInactvLst);
15075       cmLListAdd2Tail(&poInactvLst, &ueDl->rachInfo.inActUeLnk);
15076       ueDl->rachInfo.inActUeLnk.node = (PTR)ue;
15077       /* Send inactivate ind only if not already sent */
15078       if (prevDlMsk == 0)
15079       {
15080          cellSch->apisDl->rgSCHDlInactvtUes(cell, &poInactvLst);
15081       }
15082       if (prevUlMsk == 0)
15083       {
15084          cellSch->apisUl->rgSCHUlInactvtUes(cell, &poInactvLst);
15085       }
15086    }
15087    else
15088    {
15089       /* Fix: ccpu00124009 Fix for loop in the linked list "cellDl->taLst" */
15090       if (!ue->dlTaLnk.node)
15091       {
15092 #ifdef EMTC_ENABLE
15093          if(cell->emtcEnable)
15094          {
15095             if(ue->isEmtcUe)
15096             {
15097                rgSCHEmtcAddToTaLst(cellDl,ue);
15098             }
15099          }
15100          else
15101 #endif
15102          {
15103
15104             cmLListAdd2Tail(&cellDl->taLst, &ue->dlTaLnk);
15105             ue->dlTaLnk.node = (PTR)ue;
15106          }
15107       }
15108       else
15109       {
15110          DU_LOG("\nERROR  -->  SCH : <TA>TA duplicate entry attempt failed: UEID:%u", 
15111                ue->ueId);
15112       }
15113    }
15114    return;
15115 }
15116
15117 #ifdef TFU_UPGRADE
15118 /**
15119  * @brief Indication of UL CQI.
15120  *
15121  * @details
15122  *
15123  *     Function : rgSCHCmnFindUlCqiUlTxAnt
15124  *
15125  *     - Finds the Best Tx Antenna amongst the CQIs received
15126  *         from Two Tx Antennas.
15127  *
15128  *  @param[in]  RgSchCellCb         *cell
15129  *  @param[in]  RgSchUeCb           *ue
15130  *  @param[in]   uint8_t                 wideCqi
15131  *  @return  Void
15132  **/
15133 static Void rgSCHCmnFindUlCqiUlTxAnt(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t wideCqi)
15134 {
15135    ue->validTxAnt = 1;
15136    return;
15137 }  /* rgSCHCmnFindUlCqiUlTxAnt */
15138 #endif
15139
15140 /**
15141  * @brief Indication of UL CQI.
15142  *
15143  * @details
15144  *
15145  *     Function : rgSCHCmnUlCqiInd
15146  *
15147  *     - Updates uplink CQI information for the UE. Computes and
15148  *       stores the lowest CQI of CQIs reported in all subbands.
15149  *
15150  *  @param[in]  RgSchCellCb         *cell
15151  *  @param[in]  RgSchUeCb           *ue
15152  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
15153  *  @return  Void
15154  **/
15155 Void rgSCHCmnUlCqiInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuUlCqiRpt *ulCqiInfo)
15156 {
15157    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15158    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
15159 #ifdef UL_LA
15160    uint8_t       iTbsNew;
15161    S32           previTbs;
15162 #endif
15163 #if (defined(SCH_STATS) || defined(TENB_STATS))
15164      CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
15165 #endif   
15166                   
15167    /*  consider inputs from SRS handlers about SRS occassions
15168     * in determining the UL TX Antenna selection */
15169    ueUl->crntUlCqi[0] = ulCqiInfo->wideCqi;
15170 #ifdef TFU_UPGRADE
15171    ueUl->validUlCqi = ueUl->crntUlCqi[0];
15172    ue->validTxAnt = 0;
15173 #ifdef UL_LA
15174    iTbsNew  =  rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][ueUl->validUlCqi];
15175    previTbs =  (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
15176
15177    if (RG_ITBS_DIFF(iTbsNew, previTbs) > 5)
15178    {
15179       /* Ignore this iTBS report and mark that last iTBS report was */
15180       /* ignored so that subsequently we reset the LA algorithm     */
15181       ueUl->ulLaCb.lastiTbsIgnored = TRUE;
15182    }
15183    else
15184    {
15185       if (ueUl->ulLaCb.lastiTbsIgnored != TRUE)
15186       {
15187          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
15188                                        (80 * ueUl->ulLaCb.cqiBasediTbs))/100;
15189       }
15190       else
15191       {
15192          /* Reset the LA as iTbs in use caught up with the value   */
15193          /* reported by UE.                                        */
15194          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
15195                                         (80 * previTbs * 100))/100;
15196          ueUl->ulLaCb.deltaiTbs = 0;
15197          ueUl->ulLaCb.lastiTbsIgnored = FALSE;
15198       }
15199    }
15200 #endif 
15201 #endif
15202    rgSCHPwrUlCqiInd(cell, ue);
15203 #ifdef LTEMAC_SPS
15204    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
15205    {
15206       rgSCHCmnSpsUlCqiInd(cell, ue);
15207    }
15208 #endif
15209    /* Applicable to only some schedulers */
15210 #ifdef EMTC_ENABLE
15211    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
15212    {
15213       cellSch->apisEmtcUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
15214    }
15215    else
15216 #endif
15217    {
15218       cellSch->apisUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
15219    }
15220
15221 #ifdef SCH_STATS
15222    ueUl->numCqiOccns++;
15223    ueUl->avgCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15224 #endif
15225
15226 #ifdef TENB_STATS
15227    {
15228       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15229       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNumCqi ++;
15230       cell->tenbStats->sch.ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15231       cell->tenbStats->sch.ulNumCqi ++;
15232    }
15233 #endif
15234
15235    return;
15236 }  /* rgSCHCmnUlCqiInd */
15237
15238 /**
15239  * @brief Returns HARQ proc for which data expected now.
15240  *
15241  * @details
15242  *
15243  *     Function: rgSCHCmnUlHqProcForUe
15244  *     Purpose:  This function returns the harq process for
15245  *               which data is expected in the current subframe.
15246  *               It does not validate that the HARQ process
15247  *               has an allocation.
15248  *
15249  *     Invoked by: TOM
15250  *
15251  *  @param[in]  RgSchCellCb        *cell
15252  *  @param[in]  CmLteTimingInfo    frm
15253  *  @param[in]  RgSchUeCb          *ue
15254  *  @param[out] RgSchUlHqProcCb    **procRef
15255  *  @return  Void
15256  **/
15257 Void rgSCHCmnUlHqProcForUe
15258 (
15259 RgSchCellCb     *cell,
15260 CmLteTimingInfo frm,
15261 RgSchUeCb       *ue,
15262 RgSchUlHqProcCb **procRef
15263 )
15264 {
15265 #ifndef RG_5GTF
15266    uint8_t procId = rgSCHCmnGetUlHqProcIdx(&frm, cell);
15267 #endif
15268 #ifndef RG_5GTF
15269    *procRef = rgSCHUhmGetUlHqProc(cell, ue, procId);
15270 #else
15271    *procRef = rgSCHUhmGetUlProcByTime(cell, ue, frm);
15272 #endif
15273    return;
15274 }
15275
15276 #ifdef RG_UNUSED
15277 /**
15278  * @brief Update harq process for allocation.
15279  *
15280  * @details
15281  *
15282  *     Function : rgSCHCmnUpdUlHqProc
15283  *
15284  *     This function is invoked when harq process
15285  *     control block is now in a new memory location
15286  *     thus requiring a pointer/reference update.
15287  *
15288  *  @param[in] RgSchCellCb      *cell
15289  *  @param[in] RgSchUlHqProcCb  *curProc
15290  *  @param[in] RgSchUlHqProcCb  *oldProc
15291  *  @return  S16
15292  *      -# ROK
15293  *      -# RFAILED
15294  **/
15295 S16 rgSCHCmnUpdUlHqProc
15296 (
15297 RgSchCellCb      *cell,
15298 RgSchUlHqProcCb  *curProc,
15299 RgSchUlHqProcCb  *oldProc
15300 )
15301 {
15302
15303    UNUSED(cell);
15304    UNUSED(oldProc);
15305 #if (ERRCLASS & ERRCLS_DEBUG)
15306    if (curProc->alloc == NULLP)
15307    {
15308       return RFAILED;
15309    }
15310 #endif
15311    curProc->alloc->hqProc = curProc;
15312    return ROK;
15313 }  /* rgSCHCmnUpdUlHqProc */
15314 #endif
15315
15316 /*MS_WORKAROUND for CR FIXME */
15317 /**
15318  * @brief Hsndles BSR timer expiry
15319  *
15320  * @details
15321  *
15322  *     Function : rgSCHCmnBsrTmrExpry
15323  *
15324  *     This function is invoked when periodic BSR timer expires for a UE.
15325  *
15326  *  @param[in] RgSchUeCb        *ue
15327  *  @return  S16
15328  *      -# ROK
15329  *      -# RFAILED
15330  **/
15331 S16 rgSCHCmnBsrTmrExpry(RgSchUeCb  *ueCb)
15332 {
15333    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ueCb->cell);
15334
15335
15336    ueCb->isSrGrant = TRUE;
15337
15338 #ifdef EMTC_ENABLE
15339    emtcStatsUlBsrTmrTxp++;
15340 #endif
15341
15342 #ifdef EMTC_ENABLE
15343    if(ueCb->cell->emtcEnable)
15344    {
15345       if(ueCb->isEmtcUe)
15346       {
15347          cellSch->apisEmtcUl->rgSCHSrRcvd(ueCb->cell, ueCb);
15348          return ROK;
15349       }
15350    }
15351    else
15352 #endif
15353    {
15354       cellSch->apisUl->rgSCHSrRcvd(ueCb->cell, ueCb);
15355    }
15356
15357    return  (ROK);
15358 }
15359
15360 /**
15361  * @brief Short BSR update.
15362  *
15363  * @details
15364  *
15365  *     Function : rgSCHCmnUpdBsrShort
15366  *
15367  *     This functions does requisite updates to handle short BSR reporting.
15368  *
15369  *  @param[in]  RgSchCellCb  *cell
15370  *  @param[in]  RgSchUeCb    *ue
15371  *  @param[in]  RgSchLcgCb *ulLcg
15372  *  @param[in]  uint8_t           bsr
15373  *  @param[out] RgSchErrInfo *err
15374  *  @return  S16
15375  *      -# ROK
15376  *      -# RFAILED
15377  **/
15378 S16 rgSCHCmnUpdBsrShort
15379 (
15380 RgSchCellCb  *cell,
15381 RgSchUeCb    *ue,
15382 RgSchLcgCb   *ulLcg,
15383 uint8_t      bsr,
15384 RgSchErrInfo *err
15385 )
15386 {
15387    uint8_t  lcgCnt;
15388 #ifdef LTE_L2_MEAS
15389    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15390 #endif
15391    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15392    RgSchCmnLcg  *cmnLcg  = NULLP;
15393
15394 #ifdef LTE_L2_MEAS
15395    uint8_t             idx;
15396 #endif
15397
15398    if (!RGSCH_LCG_ISCFGD(ulLcg))
15399    {
15400       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
15401       return RFAILED;
15402    }
15403    for (lcgCnt=0; lcgCnt<4; lcgCnt++)
15404    {
15405 #ifdef LTE_L2_MEAS
15406       /* Set BS of all other LCGs to Zero.
15407          If Zero BSR is reported in Short BSR include this LCG too */
15408       if ((lcgCnt != ulLcg->lcgId) ||
15409             (!bsr && !ueUl->hqEnt.numBusyHqProcs))
15410       {
15411          /* If old BO is zero do nothing */
15412          if(((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs != 0)
15413          {
15414             for(idx = 0; idx < ue->ul.lcgArr[lcgCnt].numLch; idx++)
15415             {
15416                if((ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount) &&
15417                  (ue->ulActiveLCs & (1 << 
15418                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1))))
15419                {
15420           /* L2_COUNTER */
15421                  ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount--;
15422                  ue->ulActiveLCs &= ~(1 << 
15423                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1));
15424                }
15425             }
15426          }
15427       }
15428 #endif
15429       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgCnt]))
15430       {
15431          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs = 0;
15432          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->reportedBs = 0;
15433       }
15434    }
15435
15436 #ifdef LTE_L2_MEAS
15437    if(ulLcg->lcgId && bsr && (((RgSchCmnLcg *)(ulLcg->sch))->bs == 0))
15438    {
15439       for(idx = 0; idx < ulLcg->numLch; idx++)
15440       {
15441           /* L2_COUNTER */
15442           if (!(ue->ulActiveLCs & (1 << (ulLcg->lcArray[idx]->qciCb->qci -1))))
15443           {
15444              ulLcg->lcArray[idx]->qciCb->ulUeCount++;
15445              ue->ulActiveLCs |= (1 << (ulLcg->lcArray[idx]->qciCb->qci -1));
15446           }
15447       }
15448    }
15449 #endif
15450    /* Resetting the nonGbrLcgBs info here */
15451    ue->ul.nonGbrLcgBs = 0;
15452    ue->ul.nonLcg0Bs = 0;
15453
15454    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
15455    
15456    if (TRUE == ue->ul.useExtBSRSizes)
15457    {
15458       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
15459    }
15460    else
15461    {
15462       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
15463    }
15464    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15465    {
15466       /* TBD check for effGbr != 0 */    
15467       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15468    }
15469    else if (0 == ulLcg->lcgId) 
15470    {
15471       /* This is added for handling LCG0 */
15472       cmnLcg->bs = cmnLcg->reportedBs;
15473    }
15474    else 
15475    {
15476       /* Update non GBR LCG's BS*/
15477       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
15478       cmnLcg->bs     = ue->ul.nonGbrLcgBs;
15479    }
15480    ue->ul.totalBsr = cmnLcg->bs;
15481
15482 #ifdef RGR_V1
15483    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (bsr == 0))
15484    {
15485       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
15486    }
15487 #endif
15488 #ifdef LTEMAC_SPS
15489    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
15490    {
15491       rgSCHCmnSpsBsrRpt(cell, ue, ulLcg);
15492    }
15493 #endif
15494    rgSCHCmnUpdUlCompEffBsr(ue);
15495
15496 #ifdef EMTC_ENABLE
15497    if(cell->emtcEnable)
15498    {
15499       if(ue->isEmtcUe)
15500       {
15501          cellSch->apisEmtcUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
15502          return ROK;
15503       }
15504    }
15505    else
15506 #endif
15507    {
15508    cellSch->apisUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
15509    }
15510
15511 #ifdef LTE_ADV
15512    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15513    {
15514       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
15515       {
15516 #ifndef PAL_ENABLE_UL_CA
15517          if((ue->cellInfo[sCellIdx] != NULLP) &&
15518                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
15519 #else
15520          if(ue->cellInfo[sCellIdx] != NULLP)
15521 #endif
15522          {
15523             cellSch->apisUl->rgSCHUpdBsrShort(ue->cellInfo[sCellIdx]->cell, 
15524                   ue, ulLcg, bsr);
15525          }
15526       }
15527    }
15528 #endif 
15529
15530    return ROK;
15531 }
15532
15533 /**
15534  * @brief Truncated BSR update.
15535  *
15536  * @details
15537  *
15538  *     Function : rgSCHCmnUpdBsrTrunc
15539  *
15540  *     This functions does required updates to handle truncated BSR report.
15541  *
15542  *
15543  *  @param[in]  RgSchCellCb  *cell
15544  *  @param[in]  RgSchUeCb    *ue
15545  *  @param[in]  RgSchLcgCb *ulLcg
15546  *  @param[in]  uint8_t           bsr
15547  *  @param[out] RgSchErrInfo *err
15548  *  @return  S16
15549  *      -# ROK
15550  *      -# RFAILED
15551  **/
15552 S16 rgSCHCmnUpdBsrTrunc
15553 (
15554 RgSchCellCb  *cell,
15555 RgSchUeCb    *ue,
15556 RgSchLcgCb   *ulLcg,
15557 uint8_t      bsr,
15558 RgSchErrInfo *err
15559 )
15560 {
15561    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15562    RgSchCmnLcg  *cmnLcg = NULLP;
15563    S32          cnt;
15564 #ifdef LTE_L2_MEAS
15565    uint8_t     idx;
15566 #endif
15567
15568
15569    if (!RGSCH_LCG_ISCFGD(ulLcg))
15570    {
15571       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
15572       return RFAILED;
15573    }
15574    /* set all higher prio lcgs bs to 0 and update this lcgs bs and
15575       total bsr= sumofall lcgs bs */
15576    if (ulLcg->lcgId)
15577    {
15578       for (cnt = ulLcg->lcgId-1; cnt >= 0; cnt--)
15579       {
15580 #ifdef LTE_L2_MEAS
15581          /* If Existing BO is zero the don't do anything */
15582          if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs != 0)
15583          {
15584             for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
15585             {
15586                /* L2_COUNTERS */
15587                if((ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount) &&
15588                      (ue->ulActiveLCs & (1 << 
15589                                          (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
15590                {
15591                   ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount--;
15592                   ue->ulActiveLCs &= ~(1 << 
15593                         (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
15594                }
15595             }
15596          }
15597 #endif
15598          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs = 0;
15599          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->reportedBs = 0;
15600       }
15601    }
15602
15603 #ifdef LTE_L2_MEAS
15604    for (cnt = ulLcg->lcgId; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
15605    {
15606       if (ulLcg->lcgId == 0)
15607       {
15608          continue;
15609       }
15610       /* If Existing BO is zero the don't do anything */
15611       if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs == 0)
15612       {
15613          for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
15614          {
15615             /* L2_COUNTERS */
15616             if (!(ue->ulActiveLCs & (1 << 
15617                (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
15618             {
15619                ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount++;
15620                ue->ulActiveLCs |= (1 << 
15621                      (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
15622             }
15623          }
15624       }
15625    }
15626 #endif
15627    ue->ul.nonGbrLcgBs = 0;
15628    ue->ul.nonLcg0Bs = 0;
15629    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
15630    if (TRUE == ue->ul.useExtBSRSizes)
15631    {
15632       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
15633    }
15634    else
15635    {
15636       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
15637    }
15638    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15639    {
15640       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15641    }
15642    else if(ulLcg->lcgId == 0)
15643    {
15644       /* This is for handeling LCG0 */
15645       cmnLcg->bs = cmnLcg->reportedBs;
15646    }
15647    else
15648    {
15649       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
15650       cmnLcg->bs = ue->ul.nonGbrLcgBs;
15651    }
15652    ue->ul.totalBsr = cmnLcg->bs;
15653
15654    for (cnt = ulLcg->lcgId+1; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
15655    {
15656       /* TODO: The bs for the other LCGs may be stale because some or all of
15657        * the part of bs may have been already scheduled/data received. Please 
15658        * consider this when truncated BSR is tested/implemented */
15659       ue->ul.totalBsr += ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs;
15660    }
15661
15662    rgSCHCmnUpdUlCompEffBsr(ue);
15663
15664 #ifdef EMTC_ENABLE
15665    if(cell->emtcEnable)
15666    {
15667       if(ue->isEmtcUe)
15668       {
15669          cellSch->apisEmtcUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
15670          return ROK;
15671       }
15672    }
15673    else
15674 #endif
15675    {
15676       cellSch->apisUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
15677    }
15678
15679 #ifdef LTE_ADV
15680    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15681    {
15682       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
15683       {
15684 #ifndef PAL_ENABLE_UL_CA
15685          if((ue->cellInfo[sCellIdx] != NULLP) &&
15686                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
15687 #else
15688          if(ue->cellInfo[sCellIdx] != NULLP)
15689 #endif
15690          {
15691             cellSch->apisUl->rgSCHUpdBsrTrunc(ue->cellInfo[sCellIdx]->cell, ue, ulLcg, bsr);
15692          }
15693       }
15694    }
15695 #endif 
15696
15697    return ROK;
15698 }
15699
15700 /**
15701  * @brief Long BSR update.
15702  *
15703  * @details
15704  *
15705  *     Function : rgSCHCmnUpdBsrLong
15706  *
15707  *     - Update BSRs for all configured LCGs.
15708  *     - Update priority of LCGs if needed.
15709  *     - Update UE's position within/across uplink scheduling queues.
15710  *
15711  *
15712  *  @param[in]  RgSchCellCb  *cell
15713  *  @param[in]  RgSchUeCb    *ue
15714  *  @param[in]  uint8_t bsArr[]
15715  *  @param[out] RgSchErrInfo *err
15716  *  @return  S16
15717  *      -# ROK
15718  *      -# RFAILED
15719  **/
15720 S16 rgSCHCmnUpdBsrLong
15721 (
15722 RgSchCellCb  *cell,
15723 RgSchUeCb    *ue,
15724 uint8_t      *bsArr,
15725 RgSchErrInfo *err
15726 )
15727 {
15728    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15729    uint32_t     tmpBsArr[4] = {0, 0, 0, 0};
15730    uint32_t     nonGbrBs = 0;
15731 #ifdef LTE_L2_MEAS
15732    uint8_t      idx1;
15733    uint8_t      idx2;
15734 #endif
15735    uint32_t     lcgId;
15736
15737 #ifdef LTE_L2_MEAS
15738    for(idx1 = 1; idx1 < RGSCH_MAX_LCG_PER_UE; idx1++)
15739    {
15740      /* If Old BO is non zero then do nothing */
15741      if ((((RgSchCmnLcg *)(ue->ul.lcgArr[idx1].sch))->bs == 0)
15742         && bsArr[idx1] )
15743      {
15744        for(idx2 = 0; idx2 < ue->ul.lcgArr[idx1].numLch; idx2++)
15745        {
15746           /* L2_COUNTERS */
15747           if (!(ue->ulActiveLCs & (1 << 
15748              (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1))))
15749           {
15750              ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->ulUeCount++;
15751              ue->ulActiveLCs |= (1 << 
15752                (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1));
15753           }
15754        }
15755      }
15756    }
15757 #endif
15758    ue->ul.nonGbrLcgBs = 0;
15759    ue->ul.nonLcg0Bs = 0;
15760
15761    if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[0]))
15762    {
15763       if (TRUE == ue->ul.useExtBSRSizes)
15764       {
15765          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnExtBsrTbl[bsArr[0]];
15766          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnExtBsrTbl[bsArr[0]];
15767          tmpBsArr[0] = rgSchCmnExtBsrTbl[bsArr[0]];
15768       }
15769       else
15770       {
15771          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnBsrTbl[bsArr[0]];
15772          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnBsrTbl[bsArr[0]];
15773          tmpBsArr[0] = rgSchCmnBsrTbl[bsArr[0]];
15774       }
15775    }
15776    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
15777    {
15778       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
15779       {
15780          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
15781
15782          if (TRUE == ue->ul.useExtBSRSizes)
15783          {
15784             cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsArr[lcgId]];
15785          }
15786          else
15787          {
15788             cmnLcg->reportedBs = rgSchCmnBsrTbl[bsArr[lcgId]];
15789          }
15790          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15791          {
15792             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15793             tmpBsArr[lcgId] = cmnLcg->bs;
15794          }
15795          else
15796          {
15797             nonGbrBs += cmnLcg->reportedBs;
15798             tmpBsArr[lcgId] = cmnLcg->reportedBs;
15799             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
15800          }
15801       }
15802    }
15803    ue->ul.nonGbrLcgBs = RGSCH_MIN(nonGbrBs,ue->ul.effAmbr);
15804
15805    ue->ul.totalBsr = tmpBsArr[0] + tmpBsArr[1] + tmpBsArr[2] + tmpBsArr[3];
15806 #ifdef RGR_V1
15807    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (ue->ul.totalBsr == 0))
15808    {
15809       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
15810    }
15811 #endif
15812
15813 #ifdef LTEMAC_SPS
15814    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) /* SPS_FIX */
15815    {
15816      if(ue->ul.totalBsr - tmpBsArr[1] == 0)
15817      {/* Updaing the BSR to SPS only if LCG1 BS is present in sps active state */
15818         rgSCHCmnSpsBsrRpt(cell, ue, &ue->ul.lcgArr[1]);
15819      }
15820    }
15821 #endif
15822    rgSCHCmnUpdUlCompEffBsr(ue);
15823
15824 #ifdef EMTC_ENABLE
15825    if(cell->emtcEnable)
15826    {
15827       if(ue->isEmtcUe)
15828       {
15829          cellSch->apisEmtcUl->rgSCHUpdBsrLong(cell, ue, bsArr);
15830          return ROK;
15831       }
15832    }
15833    else
15834 #endif
15835    {
15836    cellSch->apisUl->rgSCHUpdBsrLong(cell, ue, bsArr);
15837    }
15838
15839 #ifdef LTE_ADV
15840    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15841    {
15842       for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
15843       {
15844 #ifndef PAL_ENABLE_UL_CA
15845          if((ue->cellInfo[idx] != NULLP) &&
15846                (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE))
15847 #else
15848          if(ue->cellInfo[idx] != NULLP)
15849 #endif
15850          {
15851             cellSch->apisUl->rgSCHUpdBsrLong(ue->cellInfo[idx]->cell, ue, bsArr);
15852          }
15853       }
15854    }
15855 #endif 
15856
15857    return ROK;
15858 }
15859
15860 /**
15861  * @brief PHR update.
15862  *
15863  * @details
15864  *
15865  *     Function : rgSCHCmnUpdExtPhr
15866  *
15867  *     Updates extended power headroom information for an UE.
15868  *
15869  *  @param[in]  RgSchCellCb  *cell
15870  *  @param[in]  RgSchUeCb    *ue
15871  *  @param[in]  uint8_t           phr
15872  *  @param[out] RgSchErrInfo *err
15873  *  @return  S16
15874  *      -# ROK
15875  *      -# RFAILED
15876  **/
15877 S16 rgSCHCmnUpdExtPhr
15878 (
15879 RgSchCellCb    *cell,
15880 RgSchUeCb      *ue,
15881 RgInfExtPhrCEInfo *extPhr,
15882 RgSchErrInfo   *err
15883 )
15884 {
15885    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15886    RgSchCmnAllocRecord *allRcd;
15887    CmLList             *node = ueUl->ulAllocLst.last;
15888
15889 #ifdef LTEMAC_SPS
15890    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
15891 #endif
15892
15893    UNUSED(err);
15894
15895    while (node)
15896    {
15897       allRcd = (RgSchCmnAllocRecord *)node->node;
15898       node = node->prev;
15899       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
15900       {
15901          rgSCHPwrUpdExtPhr(cell, ue, extPhr, allRcd);
15902          break;
15903       }
15904    }
15905 #ifdef LTEMAC_SPS
15906    if(ulSpsUe->isUlSpsActv)
15907    {
15908       rgSCHCmnSpsPhrInd(cell,ue);
15909    }
15910 #endif
15911
15912    return ROK;
15913 }  /* rgSCHCmnUpdExtPhr */
15914
15915
15916
15917
15918 /**
15919  * @brief PHR update.
15920  *
15921  * @details
15922  *
15923  *     Function : rgSCHCmnUpdPhr
15924  *
15925  *     Updates power headroom information for an UE.
15926  *
15927  *  @param[in]  RgSchCellCb  *cell
15928  *  @param[in]  RgSchUeCb    *ue
15929  *  @param[in]  uint8_t           phr
15930  *  @param[out] RgSchErrInfo *err
15931  *  @return  S16
15932  *      -# ROK
15933  *      -# RFAILED
15934  **/
15935 S16 rgSCHCmnUpdPhr
15936 (
15937 RgSchCellCb    *cell,
15938 RgSchUeCb      *ue,
15939 uint8_t        phr,
15940 RgSchErrInfo   *err
15941 )
15942 {
15943    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15944    RgSchCmnAllocRecord *allRcd;
15945    CmLList             *node = ueUl->ulAllocLst.last;
15946
15947 #ifdef LTEMAC_SPS
15948    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
15949 #endif
15950
15951    UNUSED(err);
15952
15953    while (node)
15954    {
15955       allRcd = (RgSchCmnAllocRecord *)node->node;
15956       node = node->prev;
15957       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
15958       {
15959          rgSCHPwrUpdPhr(cell, ue, phr, allRcd, RG_SCH_CMN_PWR_USE_CFG_MAX_PWR);
15960          break;
15961       }
15962    }
15963 #ifdef LTEMAC_SPS
15964    if(ulSpsUe->isUlSpsActv)
15965    {
15966       rgSCHCmnSpsPhrInd(cell,ue);
15967    }
15968 #endif
15969
15970    return ROK;
15971 }  /* rgSCHCmnUpdPhr */
15972
15973 /**
15974  * @brief UL grant for contention resolution.
15975  *
15976  * @details
15977  *
15978  *     Function : rgSCHCmnContResUlGrant
15979  *
15980  *     Add UE to another queue specifically for CRNTI based contention
15981  *     resolution.
15982  *
15983  *
15984  *  @param[in]  RgSchUeCb    *ue
15985  *  @param[out] RgSchErrInfo *err
15986  *  @return  S16
15987  *      -# ROK
15988  *      -# RFAILED
15989  **/
15990 S16 rgSCHCmnContResUlGrant
15991 (
15992 RgSchCellCb  *cell,
15993 RgSchUeCb    *ue,
15994 RgSchErrInfo *err
15995 )
15996 {
15997    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15998
15999    #ifdef EMTC_ENABLE
16000    if(cell->emtcEnable)
16001    {
16002       if(ue->isEmtcUe)
16003       {
16004          cellSch->apisEmtcUl->rgSCHContResUlGrant(cell, ue);
16005          return ROK;
16006       }
16007    }
16008    else
16009 #endif
16010    {
16011       cellSch->apisUl->rgSCHContResUlGrant(cell, ue);
16012    }
16013    return ROK;
16014 }
16015
16016 /**
16017  * @brief SR reception handling.
16018  *
16019  * @details
16020  *
16021  *     Function : rgSCHCmnSrRcvd
16022  *
16023  *     - Update UE's position within/across uplink scheduling queues
16024  *     - Update priority of LCGs if needed.
16025  *
16026  *  @param[in]  RgSchCellCb  *cell
16027  *  @param[in]  RgSchUeCb    *ue
16028  *  @param[in]  CmLteTimingInfo frm
16029  *  @param[out] RgSchErrInfo *err
16030  *  @return  S16
16031  *      -# ROK
16032  *      -# RFAILED
16033  **/
16034 S16 rgSCHCmnSrRcvd
16035 (
16036 RgSchCellCb  *cell,
16037 RgSchUeCb    *ue,
16038 CmLteTimingInfo frm,
16039 RgSchErrInfo *err
16040 )
16041 {
16042    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
16043    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
16044    CmLList      *node    = ueUl->ulAllocLst.last;
16045
16046
16047 #ifdef EMTC_ENABLE
16048    emtcStatsUlTomSrInd++;
16049 #endif
16050
16051    RGSCH_INCR_SUB_FRAME(frm, 1); /* 1 TTI after the time SR was sent */
16052    while (node)
16053    {
16054       RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)node->node;
16055       if (RGSCH_TIMEINFO_SAME(frm, allRcd->allocTime))
16056       {
16057          break;
16058       }
16059       node = node->prev;
16060    }
16061    //TODO_SID Need to check when it is getting triggered
16062    ue->isSrGrant = TRUE;
16063 #ifdef EMTC_ENABLE
16064    if(cell->emtcEnable)
16065    {
16066       if(ue->isEmtcUe)
16067       {
16068          cellSch->apisEmtcUl->rgSCHSrRcvd(cell, ue);
16069          return ROK;
16070       }
16071    }
16072    else
16073 #endif
16074    {
16075       cellSch->apisUl->rgSCHSrRcvd(cell, ue);
16076    }
16077    return ROK;
16078 }
16079
16080 /**
16081  * @brief Returns first uplink allocation to send reception
16082  *        request to PHY.
16083  *
16084  * @details
16085  *
16086  *     Function: rgSCHCmnFirstRcptnReq(cell)
16087  *     Purpose:  This function returns the first uplink allocation
16088  *               (or NULLP if there is none) in the subframe
16089  *               in which is expected to prepare and send reception
16090  *               request to PHY.
16091  *
16092  *     Invoked by: TOM
16093  *
16094  *  @param[in]  RgSchCellCb      *cell
16095  *  @return  RgSchUlAlloc*
16096  **/
16097 RgSchUlAlloc *rgSCHCmnFirstRcptnReq(RgSchCellCb *cell)
16098 {
16099    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16100 /* ACC_TDD */
16101    RgSchUlAlloc* alloc = NULLP;
16102
16103
16104    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
16105    {
16106            RgSchUlSf* sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16107            alloc = rgSCHUtlUlAllocFirst(sf);
16108
16109            if (alloc && alloc->hqProc == NULLP)
16110            {
16111                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16112            }
16113    }
16114
16115    return (alloc);
16116 }
16117
16118 /**
16119  * @brief Returns first uplink allocation to send reception
16120  *        request to PHY.
16121  *
16122  * @details
16123  *
16124  *     Function: rgSCHCmnNextRcptnReq(cell)
16125  *     Purpose:  This function returns the next uplink allocation
16126  *               (or NULLP if there is none) in the subframe
16127  *               in which is expected to prepare and send reception
16128  *               request to PHY.
16129  *
16130  *     Invoked by: TOM
16131  *
16132  *  @param[in]  RgSchCellCb      *cell
16133  *  @return  RgSchUlAlloc*
16134  **/
16135 RgSchUlAlloc *rgSCHCmnNextRcptnReq(RgSchCellCb *cell,RgSchUlAlloc *alloc)
16136 {
16137    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16138 /* ACC-TDD */
16139    //RgSchUlSf      *sf   = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16140
16141 /* ACC-TDD */
16142    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
16143    {
16144            RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16145
16146            alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16147            if (alloc && alloc->hqProc == NULLP)
16148            {
16149                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16150            }
16151    }
16152    else
16153    {
16154            alloc = NULLP;
16155    }
16156
16157    return (alloc);
16158 }
16159 /**
16160  * @brief Collates DRX enabled UE's scheduled in this SF
16161  *
16162  * @details
16163  *
16164  *     Function: rgSCHCmnDrxStrtInActvTmrInUl(cell)
16165  *     Purpose:  This function collates the link
16166  *               of UE's scheduled in this SF who
16167  *               have drx enabled. It then calls
16168  *               DRX specific function to start/restart
16169  *               inactivity timer in Ul
16170  *
16171  *     Invoked by: TOM
16172  *
16173  *  @param[in]  RgSchCellCb      *cell
16174  *  @return Void
16175  **/
16176 Void rgSCHCmnDrxStrtInActvTmrInUl(RgSchCellCb *cell)
16177 {
16178    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16179    RgSchUlSf      *sf     = &(cellUl->ulSfArr[cellUl->schdIdx]);
16180    RgSchUlAlloc   *alloc  = rgSCHUtlUlAllocFirst(sf);
16181    CmLListCp       ulUeLst;
16182    RgSchUeCb       *ueCb;
16183
16184
16185    cmLListInit(&ulUeLst);
16186
16187    while(alloc)
16188    {
16189       ueCb = alloc->ue;
16190
16191       if (ueCb)
16192       {
16193          if (!(alloc->grnt.isRtx) && ueCb->isDrxEnabled && !(ueCb->isSrGrant)
16194 #ifdef LTEMAC_SPS
16195              /* ccpu00139513- DRX inactivity timer should not be started for 
16196               * UL SPS occasions */
16197              && (alloc->hqProc->isSpsOccnHqP == FALSE) 
16198 #endif
16199              )
16200          {
16201             cmLListAdd2Tail(&ulUeLst,&(ueCb->ulDrxInactvTmrLnk));
16202             ueCb->ulDrxInactvTmrLnk.node = (PTR)ueCb;
16203          }
16204       }
16205
16206       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16207    }/*while(alloc)*/
16208
16209    (Void)rgSCHDrxStrtInActvTmr(cell,&ulUeLst,RG_SCH_DRX_UL);
16210
16211    return;
16212 }
16213
16214
16215 /**
16216  * @brief Returns first uplink allocation to send HARQ feedback
16217  *        request to PHY.
16218  *
16219  * @details
16220  *
16221  *     Function: rgSCHCmnFirstHqFdbkAlloc
16222  *     Purpose:  This function returns the first uplink allocation
16223  *               (or NULLP if there is none) in the subframe
16224  *               for which it is expected to prepare and send HARQ
16225  *               feedback to PHY.
16226  *
16227  *     Invoked by: TOM
16228  *
16229  *  @param[in]  RgSchCellCb      *cell
16230  *  @param[in]  uint8_t               idx
16231  *  @return  RgSchUlAlloc*
16232  **/
16233 RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc(RgSchCellCb  *cell,uint8_t idx)
16234 {
16235    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16236 /* ACC-TDD */
16237    RgSchUlAlloc  *alloc = NULLP;
16238
16239
16240    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
16241    {
16242           RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
16243           alloc    = rgSCHUtlUlAllocFirst(sf);
16244
16245           while (alloc && (alloc->hqProc == NULLP))
16246           {
16247                   alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16248           }
16249    }
16250
16251    return (alloc);
16252 }
16253
16254 /**
16255  * @brief Returns next allocation to send HARQ feedback for.
16256  *
16257  * @details
16258  *
16259  *     Function: rgSCHCmnNextHqFdbkAlloc(cell)
16260  *     Purpose:  This function returns the next uplink allocation
16261  *               (or NULLP if there is none) in the subframe
16262  *               for which HARQ feedback needs to be sent.
16263  *
16264  *     Invoked by: TOM
16265  *
16266  *  @param[in]  RgSchCellCb      *cell
16267  *  @return  RgSchUlAlloc*
16268  **/
16269 RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc(RgSchCellCb *cell,RgSchUlAlloc *alloc,uint8_t idx)
16270 {
16271    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16272
16273    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
16274    {
16275       RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
16276
16277       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16278       while (alloc && (alloc->hqProc == NULLP))
16279       {
16280          alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16281       }
16282    }
16283    else
16284    {
16285           alloc = NULLP;
16286    }
16287    return (alloc);
16288 }
16289
16290 /***********************************************************
16291  *
16292  *     Func : rgSCHCmnUlGetITbsFrmIMcs
16293  *
16294  *     Desc : Returns the Itbs that is mapped to an Imcs
16295  *            for the case of uplink.
16296  *
16297  *     Ret  :
16298  *
16299  *     Notes:
16300  *
16301  *     File :
16302  *
16303  **********************************************************/
16304 uint8_t rgSCHCmnUlGetITbsFrmIMcs(uint8_t iMcs)
16305 {
16306    return (rgUlIMcsTbl[iMcs].iTbs);
16307 }
16308
16309 /***********************************************************
16310  *
16311  *     Func : rgSCHCmnUlGetIMcsFrmITbs
16312  *
16313  *     Desc : Returns the Imcs that is mapped to an Itbs
16314  *            for the case of uplink.
16315  *
16316  *     Ret  :
16317  *
16318  *     Notes: For iTbs 19, iMcs is dependant on modulation order.
16319  *            Refer to 36.213, Table 8.6.1-1 and 36.306 Table 4.1-2
16320  *            for UE capability information
16321  *
16322  *     File :
16323  *
16324  **********************************************************/
16325 uint8_t rgSCHCmnUlGetIMcsFrmITbs(uint8_t iTbs,CmLteUeCategory ueCtg)
16326 {
16327    uint8_t iMcs;
16328
16329    if (iTbs <= 10)
16330    {
16331       iMcs = iTbs;
16332    }
16333    /*a higher layer can force a 64QAM UE to transmit at 16QAM.
16334     * We currently do not support this. Once the support for such
16335     * is added, ueCtg should be replaced by current transmit
16336     * modulation configuration.Refer to 36.213 -8.6.1
16337     */
16338    else if ( iTbs < 19 )
16339    {
16340       iMcs = iTbs + 1;
16341    }
16342    else if ((iTbs == 19) && (ueCtg != CM_LTE_UE_CAT_5))
16343    {
16344       iMcs = iTbs + 1;
16345    }
16346    else
16347    {
16348       iMcs = iTbs + 2;
16349    }
16350
16351 #ifdef LTE_TDD
16352    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
16353       was seen when IMCS exceeds 20  on T2k TDD*/
16354    if (iMcs > 20)
16355    {
16356       iMcs = 20;
16357    }
16358 #endif
16359
16360    return (iMcs);
16361 }
16362
16363 /***********************************************************
16364  *
16365  *     Func : rgSCHCmnUlMinTbBitsForITbs
16366  *
16367  *     Desc : Returns the minimum number of bits that can
16368  *            be given as grant for a specific CQI.
16369  *
16370  *     Ret  :
16371  *
16372  *     Notes:
16373  *
16374  *     File :
16375  *
16376  **********************************************************/
16377 uint32_t rgSCHCmnUlMinTbBitsForITbs(RgSchCmnUlCell *cellUl,uint8_t  iTbs)
16378 {
16379
16380    RGSCH_ARRAY_BOUND_CHECK(0, rgTbSzTbl[0], iTbs); 
16381
16382    return (rgTbSzTbl[0][iTbs][cellUl->sbSize-1]);
16383 }
16384
16385 /***********************************************************
16386  *
16387  *     Func : rgSCHCmnUlSbAlloc
16388  *
16389  *     Desc : Given a required 'number of subbands' and a hole,
16390  *            returns a suitable alloc such that the subband
16391  *            allocation size is valid
16392  *
16393  *     Ret  :
16394  *
16395  *     Notes: Does not assume either passed numSb or hole size
16396  *            to be valid for allocation, and hence arrives at
16397  *            an acceptable value.
16398  *     File :
16399  *
16400  **********************************************************/
16401 RgSchUlAlloc *rgSCHCmnUlSbAlloc
16402 (
16403 RgSchUlSf    *sf,
16404 uint8_t      numSb,
16405 RgSchUlHole  *hole
16406 )
16407 {
16408    uint8_t      holeSz; /* valid hole size */
16409    RgSchUlAlloc *alloc;
16410
16411    if ((holeSz = rgSchCmnMult235Tbl[hole->num].prvMatch) == hole->num)
16412    {
16413       numSb = rgSchCmnMult235Tbl[numSb].match;
16414       if (numSb >= holeSz)
16415       {
16416          alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
16417       }
16418       else
16419       {
16420          alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
16421       }
16422    }
16423    else
16424    {
16425       if (numSb < holeSz)
16426       {
16427          numSb = rgSchCmnMult235Tbl[numSb].match;
16428       }
16429       else
16430       {
16431          numSb = rgSchCmnMult235Tbl[numSb].prvMatch;
16432       }
16433
16434       if ( numSb >= holeSz )
16435       {
16436          numSb = holeSz;
16437       }
16438       alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
16439    }
16440    return (alloc);
16441 }
16442
16443 /**
16444  * @brief To fill the RgSchCmnUeUlAlloc structure of UeCb.
16445  *
16446  * @details
16447  *
16448  *     Function: rgSCHCmnUlUeFillAllocInfo
16449  *     Purpose:  Specific scheduler to call this API to fill the alloc
16450  *               information.
16451  *
16452  *     Invoked by: Scheduler
16453  *
16454  *  @param[in]  RgSchCellCb      *cell
16455  *  @param[out] RgSchUeCb        *ue
16456  *  @return   Void
16457  **/
16458 Void rgSCHCmnUlUeFillAllocInfo(RgSchCellCb *cell,RgSchUeCb *ue)
16459 {
16460    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16461    RgSchCmnUeUlAlloc  *ulAllocInfo;
16462    RgSchCmnUlUe       *ueUl;
16463
16464
16465    ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16466    ulAllocInfo = &ueUl->alloc;
16467
16468    /* Fill alloc structure */
16469    rgSCHCmnUlAllocFillTpc(cell, ue, ulAllocInfo->alloc);
16470    rgSCHCmnUlAllocFillNdmrs(cellUl, ulAllocInfo->alloc);
16471    rgSCHCmnUlAllocLnkHqProc(ue, ulAllocInfo->alloc, ulAllocInfo->alloc->hqProc,
16472                      ulAllocInfo->alloc->hqProc->isRetx);
16473    /* Fill PDCCH */
16474    rgSCHCmnUlFillPdcchWithAlloc(ulAllocInfo->alloc->pdcch,
16475          ulAllocInfo->alloc, ue);
16476    /* Recording information about this allocation */
16477    rgSCHCmnUlRecordUeAlloc(cell, ue);
16478
16479    /* Update the UE's outstanding allocation */
16480    if (!ulAllocInfo->alloc->hqProc->isRetx)
16481    {
16482       rgSCHCmnUlUpdOutStndAlloc(cell, ue, ulAllocInfo->allocdBytes);
16483    }
16484
16485    return;
16486 }
16487
16488 /**
16489  * @brief Update the UEs outstanding alloc based on the BSR report's timing.
16490  *
16491  *
16492  * @details
16493  *
16494  *     Function: rgSCHCmnUpdUlCompEffBsr
16495  *     Purpose:  Clear off all the allocations from outstanding allocation that
16496  *     are later than or equal to BSR timing information (stored in UEs datIndTime).
16497  *
16498  *     Invoked by: Scheduler
16499  *
16500  *  @param[in]  RgSchUeCb *ue
16501  *  @return  Void
16502  **/
16503 static Void rgSCHCmnUpdUlCompEffBsr(RgSchUeCb *ue)
16504 {
16505    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,ue->cell);
16506    CmLList   *node = ueUl->ulAllocLst.last;
16507    RgSchCmnAllocRecord *allRcd;
16508    uint32_t outStndAlloc=0;
16509    uint32_t nonLcg0OutStndAllocBs=0;
16510    uint32_t nonLcg0Bsr=0;
16511    uint8_t  lcgId;
16512    RgSchCmnLcg *cmnLcg = NULLP;
16513
16514    while (node)
16515    {
16516       allRcd = (RgSchCmnAllocRecord *)node->node;
16517       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
16518       {
16519          node = node->next;
16520          break;
16521       }
16522       node = node->prev;
16523    }
16524    while (node)
16525    {
16526       allRcd = (RgSchCmnAllocRecord *)node->node;
16527       node = node->next;
16528       outStndAlloc += allRcd->alloc;
16529    }
16530  
16531    cmnLcg = (RgSchCmnLcg *)(ue->ul.lcgArr[0].sch);
16532    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
16533    if (cmnLcg->bs > outStndAlloc)
16534    {
16535       cmnLcg->bs -= outStndAlloc;
16536       ue->ul.minReqBytes = cmnLcg->bs;
16537       outStndAlloc = 0;
16538    }
16539    else
16540    {
16541       nonLcg0OutStndAllocBs = outStndAlloc - cmnLcg->bs;
16542       cmnLcg->bs = 0;
16543    }
16544
16545    for(lcgId = 1;lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
16546    {
16547       if(RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
16548       {
16549          cmnLcg = ((RgSchCmnLcg *) (ue->ul.lcgArr[lcgId].sch));
16550          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
16551          {
16552             nonLcg0Bsr += cmnLcg->bs;
16553          }
16554       }
16555    }
16556    nonLcg0Bsr += ue->ul.nonGbrLcgBs;  
16557    if (nonLcg0OutStndAllocBs > nonLcg0Bsr)
16558    {
16559       nonLcg0Bsr = 0;
16560    }
16561    else
16562    {
16563       nonLcg0Bsr -= nonLcg0OutStndAllocBs;
16564    }
16565    ue->ul.nonLcg0Bs = nonLcg0Bsr;
16566    /* Cap effBsr with nonLcg0Bsr and append lcg0 bs.
16567     * nonLcg0Bsr limit applies only to lcg1,2,3 */
16568    /* better be handled in individual scheduler */
16569    ue->ul.effBsr = nonLcg0Bsr +\
16570                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16571    return;
16572 }
16573
16574 /**
16575  * @brief  Records information about the current allocation.
16576  *
16577  * @details
16578  *
16579  *     Function: rgSCHCmnUlRecordUeAlloc
16580  *     Purpose:  Records information about the curent allocation.
16581  *               This includes the allocated bytes, as well
16582  *               as some power information.
16583  *
16584  *     Invoked by: Scheduler
16585  *
16586  *  @param[in]  RgSchCellCb *cell
16587  *  @param[in]  RgSchUeCb   *ue
16588  *  @return  Void
16589  **/
16590 Void rgSCHCmnUlRecordUeAlloc(RgSchCellCb *cell,RgSchUeCb   *ue)
16591 {
16592 #ifdef LTE_TDD
16593    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16594 #endif
16595    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16596    CmLListCp           *lst = &ueUl->ulAllocLst;
16597    CmLList             *node = ueUl->ulAllocLst.first;
16598    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
16599    RgSchCmnUeUlAlloc  *ulAllocInfo = &ueUl->alloc;
16600    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
16601
16602    cmLListDelFrm(lst, &allRcd->lnk);
16603 #ifndef LTE_TDD
16604    /* To the crntTime, add the MIN time at which UE will
16605     * actually send the BSR i.e DELTA+4 */
16606    allRcd->allocTime = cell->crntTime;
16607    /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
16608 #ifdef EMTC_ENABLE
16609    if(ue->isEmtcUe == TRUE)
16610    {
16611       RGSCH_INCR_SUB_FRAME_EMTC(allRcd->allocTime,
16612                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
16613    }
16614    else
16615 #endif
16616    {
16617       RGSCH_INCR_SUB_FRAME(allRcd->allocTime,
16618                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
16619    }
16620 #else
16621    allRcd->allocTime = cellUl->schdTime;
16622 #endif
16623    cmLListAdd2Tail(lst, &allRcd->lnk);
16624
16625    /* Filling in the parameters to be recorded */
16626    allRcd->alloc = ulAllocInfo->allocdBytes;
16627    //allRcd->numRb = ulAllocInfo->alloc->grnt.numRb;
16628    allRcd->numRb = (ulAllocInfo->alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
16629    /*Recording the UL CQI derived from the maxUlCqi */
16630    allRcd->cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
16631    allRcd->tpc   = ulAllocInfo->alloc->grnt.tpc;
16632
16633    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
16634
16635    cell->measurements.ulBytesCnt += ulAllocInfo->allocdBytes;
16636
16637    return;
16638 }
16639
16640 /** PHR handling for MSG3
16641  * @brief  Records allocation information of msg3 in the the UE.
16642  *
16643  * @details
16644  *
16645  *     Function: rgSCHCmnUlRecMsg3Alloc
16646  *     Purpose:  Records information about msg3 allocation.
16647  *               This includes the allocated bytes, as well
16648  *               as some power information.
16649  *
16650  *     Invoked by: Scheduler
16651  *
16652  *  @param[in]  RgSchCellCb *cell
16653  *  @param[in]  RgSchUeCb   *ue
16654  *  @param[in]  RgSchRaCb   *raCb
16655  *  @return  Void
16656  **/
16657 Void rgSCHCmnUlRecMsg3Alloc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchRaCb *raCb)
16658 {
16659    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16660    CmLListCp           *lst = &ueUl->ulAllocLst;
16661    CmLList             *node = ueUl->ulAllocLst.first;
16662    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
16663
16664    /* Stack Crash problem for TRACE5 changes */
16665
16666    cmLListDelFrm(lst, node);
16667    allRcd->allocTime = raCb->msg3AllocTime;
16668    cmLListAdd2Tail(lst, node);
16669
16670    /* Filling in the parameters to be recorded */
16671    allRcd->alloc = raCb->msg3Grnt.datSz;
16672    allRcd->numRb = raCb->msg3Grnt.numRb;
16673    allRcd->cqi   = raCb->ccchCqi;
16674    allRcd->tpc   = raCb->msg3Grnt.tpc;
16675
16676    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
16677
16678    return;
16679 }
16680 /**
16681  * @brief Keeps track of the most recent RG_SCH_CMN_MAX_ALLOC_TRACK
16682  * allocations to track. Adds this allocation to the ueUl's ulAllocLst.
16683  *
16684  *
16685  * @details
16686  *
16687  *     Function: rgSCHCmnUlUpdOutStndAlloc
16688  *     Purpose:  Recent Allocation shall be at First Pos'n.
16689  *               Remove the last node, update the fields
16690  *                with the new allocation and add at front.
16691  *
16692  *     Invoked by: Scheduler
16693  *
16694  *  @param[in]  RgSchCellCb *cell
16695  *  @param[in]  RgSchUeCb   *ue
16696  *  @param[in]  uint32_t alloc
16697  *  @return  Void
16698  **/
16699 Void rgSCHCmnUlUpdOutStndAlloc(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t alloc)
16700 {
16701    uint32_t  nonLcg0Alloc=0;
16702
16703    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
16704    if (((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs > alloc)
16705    {
16706       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs -= alloc;
16707    }
16708    else
16709    {
16710       nonLcg0Alloc = alloc - ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16711       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = 0;
16712    }
16713
16714    if (nonLcg0Alloc >= ue->ul.nonLcg0Bs)
16715    {
16716       ue->ul.nonLcg0Bs  = 0;
16717    }
16718    else
16719    {
16720       ue->ul.nonLcg0Bs  -= nonLcg0Alloc;
16721    }
16722    /* Cap effBsr with effAmbr and append lcg0 bs.
16723     * effAmbr limit applies only to lcg1,2,3 non GBR LCG's*/
16724    /* better be handled in individual scheduler */
16725    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
16726                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16727 #ifdef RGR_V1
16728    if (ue->ul.effBsr == 0)
16729    {
16730       if (ue->bsrTmr.tmrEvnt != TMR_NONE)
16731       {
16732          rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
16733       }
16734       /* ccpu00133008 */
16735       if (FALSE == ue->isSrGrant)
16736       {
16737          if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
16738          {
16739             /*
16740             rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR,
16741                   ue->ul.bsrTmrCfg.prdBsrTmr);
16742             */
16743          }
16744       }
16745    }
16746 #endif
16747    /* Resetting UEs lower Cap */
16748    ue->ul.minReqBytes = 0;
16749
16750    return;
16751 }
16752
16753
16754 /**
16755  * @brief Returns the "Itbs" for a given UE.
16756  *
16757  * @details
16758  *
16759  *     Function: rgSCHCmnUlGetITbs
16760  *     Purpose:  This function returns the "Itbs" for a given UE.
16761  *
16762  *     Invoked by: Scheduler
16763  *
16764  *  @param[in]  RgSchUeCb        *ue
16765  *  @return     uint8_t
16766  **/
16767 uint8_t rgSCHCmnUlGetITbs
16768 (
16769 RgSchCellCb *cell,
16770 RgSchUeCb   *ue,
16771 Bool        isEcp
16772 )
16773 {
16774    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
16775    /* CQI will be capped to maxUlCqi for 16qam UEs */
16776    CmLteUeCategory  ueCtgy = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
16777    uint8_t          cqi;
16778 #ifdef UL_LA
16779    S32            iTbs;
16780    uint8_t        maxiTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ueUl->maxUlCqi]; 
16781 #endif
16782
16783
16784    /* #ifdef RG_SCH_CMN_EXT_CP_SUP For ECP pick index 1 */
16785 #ifdef TFU_UPGRADE
16786    if ( (ueCtgy != CM_LTE_UE_CAT_5) &&
16787         (ueUl->validUlCqi > ueUl->maxUlCqi)
16788       )
16789    {
16790       cqi = ueUl->maxUlCqi;
16791    }
16792    else
16793    {
16794       cqi = ueUl->validUlCqi;
16795    }
16796
16797 #ifdef UL_LA
16798    iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
16799
16800    RG_SCH_CHK_ITBS_RANGE(iTbs, maxiTbs); 
16801
16802    iTbs = RGSCH_MIN(iTbs,  ue->cell->thresholds.maxUlItbs);
16803
16804 #ifdef LTE_TDD
16805    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
16806       was seen when IMCS exceeds 20 on T2k TDD */
16807    if (iTbs > 19)
16808    {
16809       iTbs = 19;
16810    }
16811 #endif
16812    return (iTbs);
16813 #endif 
16814 #else
16815    if ( (ueCtgy != CM_LTE_UE_CAT_5) && (ueUl->crntUlCqi[0] > ueUl->maxUlCqi ))
16816    {
16817       cqi = ueUl->maxUlCqi;
16818    }
16819    else
16820    {
16821       cqi = ueUl->crntUlCqi[0];
16822    }
16823 #endif
16824    return (rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][cqi]);
16825 }
16826
16827 /**
16828  * @brief This function adds the UE to DLRbAllocInfo TX lst.
16829  *
16830  * @details
16831  *
16832  *     Function: rgSCHCmnDlRbInfoAddUeTx
16833  *     Purpose:  This function adds the UE to DLRbAllocInfo TX lst.
16834  *
16835  *     Invoked by: Common Scheduler
16836  *
16837  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16838  *  @param[in]  RgSchUeCb             *ue
16839  *  @param[in]  RgSchDlHqProcCb       *hqP
16840  *  @return  Void
16841  *
16842  **/
16843 static Void rgSCHCmnDlRbInfoAddUeTx
16844 (
16845 RgSchCellCb        *cell,
16846 RgSchCmnDlRbAllocInfo *allocInfo,
16847 RgSchUeCb             *ue,
16848 RgSchDlHqProcCb       *hqP
16849 )
16850 {
16851    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
16852
16853
16854    if (hqP->reqLnk.node == NULLP)
16855    {
16856       if (cellSch->dl.isDlFreqSel)
16857       {
16858          cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16859            &allocInfo->dedAlloc.txHqPLst, hqP);
16860       }
16861       else
16862       {
16863          {
16864             cmLListAdd2Tail(&allocInfo->dedAlloc.txHqPLst, &hqP->reqLnk);
16865          }
16866          hqP->reqLnk.node = (PTR)hqP;
16867       }
16868    }
16869    return;
16870 }
16871
16872 /**
16873  * @brief This function adds the UE to DLRbAllocInfo RETX lst.
16874  *
16875  * @details
16876  *
16877  *     Function: rgSCHCmnDlRbInfoAddUeRetx
16878  *     Purpose:  This function adds the UE to DLRbAllocInfo RETX lst.
16879  *
16880  *     Invoked by: Common Scheduler
16881  *
16882  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16883  *  @param[in]  RgSchUeCb             *ue
16884  *  @param[in]  RgSchDlHqProcCb       *hqP
16885  *  @return  Void
16886  *
16887  **/
16888 static Void rgSCHCmnDlRbInfoAddUeRetx
16889 (
16890 RgSchCellCb        *cell,
16891 RgSchCmnDlRbAllocInfo *allocInfo,
16892 RgSchUeCb             *ue,
16893 RgSchDlHqProcCb       *hqP
16894 )
16895 {
16896    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
16897
16898
16899    if (cellSch->dl.isDlFreqSel)
16900    {
16901       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16902         &allocInfo->dedAlloc.retxHqPLst, hqP);
16903    }
16904    else
16905    {
16906       /* checking UE's presence in this lst is unnecessary */
16907       cmLListAdd2Tail(&allocInfo->dedAlloc.retxHqPLst, &hqP->reqLnk);
16908       hqP->reqLnk.node = (PTR)hqP;
16909    }
16910    return;
16911 }
16912
16913 /**
16914  * @brief This function adds the UE to DLRbAllocInfo TX-RETX lst.
16915  *
16916  * @details
16917  *
16918  *     Function: rgSCHCmnDlRbInfoAddUeRetxTx
16919  *     Purpose:  This adds the UE to DLRbAllocInfo TX-RETX lst.
16920  *
16921  *     Invoked by: Common Scheduler
16922  *
16923  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16924  *  @param[in]  RgSchUeCb             *ue
16925  *  @param[in]  RgSchDlHqProcCb       *hqP
16926  *  @return  Void
16927  *
16928  **/
16929 static Void rgSCHCmnDlRbInfoAddUeRetxTx
16930 (
16931 RgSchCellCb        *cell,
16932 RgSchCmnDlRbAllocInfo *allocInfo,
16933 RgSchUeCb             *ue,
16934 RgSchDlHqProcCb       *hqP
16935 )
16936 {
16937    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
16938
16939
16940    if (cellSch->dl.isDlFreqSel)
16941    {
16942       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16943         &allocInfo->dedAlloc.txRetxHqPLst, hqP);
16944    }
16945    else
16946    {
16947       cmLListAdd2Tail(&allocInfo->dedAlloc.txRetxHqPLst, &hqP->reqLnk);
16948       hqP->reqLnk.node = (PTR)hqP;
16949    }
16950    return;
16951 }
16952
16953 /**
16954  * @brief This function adds the UE to DLRbAllocInfo NonSchdRetxLst.
16955  *
16956  * @details
16957  *
16958  *     Function: rgSCHCmnDlAdd2NonSchdRetxLst 
16959  *     Purpose:  During RB estimation for RETX, if allocation fails
16960  *               then appending it to NonSchdRetxLst, the further
16961  *               action is taken as part of Finalization in
16962  *               respective schedulers.
16963  *
16964  *     Invoked by: Common Scheduler
16965  *
16966  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16967  *  @param[in]  RgSchUeCb             *ue
16968  *  @param[in]  RgSchDlHqProcCb       *hqP
16969  *  @return  Void
16970  *
16971  **/
16972 static Void rgSCHCmnDlAdd2NonSchdRetxLst 
16973 (
16974 RgSchCmnDlRbAllocInfo *allocInfo,
16975 RgSchUeCb             *ue,
16976 RgSchDlHqProcCb       *hqP
16977 )
16978 {
16979    CmLList         *schdLnkNode;
16980
16981
16982 #ifdef LTEMAC_SPS
16983    if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && 
16984          (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)))
16985    {
16986       return;
16987    }
16988 #endif
16989
16990    schdLnkNode = &hqP->schdLstLnk;
16991    RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
16992    cmLListAdd2Tail(&allocInfo->dedAlloc.nonSchdRetxHqPLst, schdLnkNode);
16993
16994    return;
16995 }
16996
16997
16998
16999 /**
17000  * @brief This function adds the UE to DLRbAllocInfo NonSchdTxRetxLst.
17001  *
17002  * @details
17003  *
17004  *     Function: rgSCHCmnDlAdd2NonSchdTxRetxLst 
17005  *     Purpose:  During RB estimation for TXRETX, if allocation fails
17006  *               then appending it to NonSchdTxRetxLst, the further
17007  *               action is taken as part of Finalization in
17008  *               respective schedulers.
17009  *
17010  *     Invoked by: Common Scheduler
17011  *
17012  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
17013  *  @param[in]  RgSchUeCb             *ue
17014  *  @param[in]  RgSchDlHqProcCb       *hqP
17015  *  @return  Void
17016  *
17017  **/
17018 #ifdef LTE_TDD
17019 /**
17020  * @brief This function handles the initialisation of DL HARQ/ACK feedback
17021  *        timing information for eaach DL subframe.
17022  *
17023  * @details
17024  *
17025  *     Function: rgSCHCmnDlANFdbkInit
17026  *     Purpose:  Each DL subframe stores the sfn and subframe
17027  *               information of UL subframe in which it expects
17028  *               HARQ ACK/NACK feedback for this subframe.It
17029  *               generates the information based on Downlink
17030  *               Association Set Index table.
17031  *
17032  *     Invoked by: Scheduler
17033  *
17034  *  @param[in]  RgSchCellCb*     cell
17035  *  @return     S16
17036  *
17037  **/
17038 static S16 rgSCHCmnDlANFdbkInit(RgSchCellCb  *cell)
17039 {
17040  uint8_t              sfCount;
17041  uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17042  uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17043  uint8_t              sfNum;
17044  uint8_t              idx;
17045  uint8_t              dlIdx;
17046  uint8_t              calcSfnOffset;
17047  S8                   calcSfNum;
17048  uint8_t              ulSfCnt =0;
17049  RgSchTddSubfrmInfo   ulSubfrmInfo;
17050  uint8_t              maxUlSubfrms;
17051
17052
17053    ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17054    maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17055
17056    /* Generate HARQ ACK/NACK feedback information for each DL sf in a radio frame
17057     * Calculate this information based on DL Association set Index table */
17058    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17059    {
17060       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17061             RG_SCH_TDD_UL_SUBFRAME)
17062       {
17063          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17064       }
17065       ulSfCnt++;
17066
17067       for(idx=0; idx < rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
17068             numFdbkSubfrms; idx++)
17069       {
17070          calcSfNum = sfNum - rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
17071                      subfrmNum[idx];
17072          if(calcSfNum < 0)
17073          {
17074             calcSfnOffset = RGSCH_CEIL(-calcSfNum, RGSCH_NUM_SUB_FRAMES);
17075          }
17076          else
17077          {
17078             calcSfnOffset = 0;
17079          }
17080
17081          calcSfNum = ((RGSCH_NUM_SUB_FRAMES * calcSfnOffset) + calcSfNum)\
17082                      % RGSCH_NUM_SUB_FRAMES;
17083
17084          if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17085          {
17086             dlIdx = calcSfNum;
17087          }
17088          else if((ulSubfrmInfo.switchPoints == 2) && (calcSfNum <= \
17089                   RG_SCH_CMN_SPL_SUBFRM_6))
17090          {
17091             dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17092          }
17093          else
17094          {
17095             dlIdx = calcSfNum - maxUlSubfrms;
17096          }
17097
17098          cell->subFrms[dlIdx]->dlFdbkInfo.subframe = sfNum;
17099          cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = calcSfnOffset;
17100          cell->subFrms[dlIdx]->dlFdbkInfo.m = idx;
17101       }
17102       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17103    }
17104
17105    /* DL subframes in the subsequent radio frames are initialized
17106     * with the previous radio frames  */
17107    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;\
17108          dlIdx++)
17109    {
17110       sfNum = dlIdx - rgSchTddNumDlSubfrmTbl[ulDlCfgIdx]\
17111               [RGSCH_NUM_SUB_FRAMES-1];
17112       cell->subFrms[dlIdx]->dlFdbkInfo.subframe = \
17113                                                   cell->subFrms[sfNum]->dlFdbkInfo.subframe;
17114       cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = \
17115                                                    cell->subFrms[sfNum]->dlFdbkInfo.sfnOffset;
17116       cell->subFrms[dlIdx]->dlFdbkInfo.m = cell->subFrms[sfNum]->dlFdbkInfo.m;
17117    }
17118    return ROK;
17119 }
17120
17121 /**
17122  * @brief This function handles the initialization of uplink association
17123  *        set information for each DL subframe.
17124  *
17125  *
17126  * @details
17127  *
17128  *     Function: rgSCHCmnDlKdashUlAscInit
17129  *     Purpose:  Each DL sf stores the sfn and sf information of UL sf
17130  *               in which it expects HQ ACK/NACK trans. It generates the information
17131  *               based on k` in UL association set index table.
17132  *
17133  *     Invoked by: Scheduler
17134  *
17135  *  @param[in]  RgSchCellCb*     cell
17136  *  @return     S16
17137  *
17138  **/
17139 static S16 rgSCHCmnDlKdashUlAscInit(RgSchCellCb *cell)
17140 {
17141  uint8_t              sfCount;
17142  uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17143  uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17144  uint8_t              sfNum;
17145  uint8_t              dlIdx;
17146  S8                   calcSfnOffset;
17147  S8                   calcSfNum;
17148  uint8_t              ulSfCnt =0;
17149  RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17150  uint8_t              maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17151  uint8_t              dlPres = 0;
17152
17153
17154    /* Generate ACK/NACK offset information for each DL subframe in a radio frame
17155     * Calculate this information based on K` in UL Association Set table */
17156    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17157    {
17158       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17159             RG_SCH_TDD_UL_SUBFRAME)
17160       {
17161          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17162       }
17163       ulSfCnt++;
17164
17165       calcSfNum = (sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum] + \
17166             RGSCH_NUM_SUB_FRAMES) % RGSCH_NUM_SUB_FRAMES;
17167       calcSfnOffset = sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum];
17168       if(calcSfnOffset < 0)
17169       {
17170          calcSfnOffset = RGSCH_CEIL(-calcSfnOffset, RGSCH_NUM_SUB_FRAMES);
17171       }
17172       else
17173       {
17174          calcSfnOffset = 0;
17175       }
17176
17177       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17178       {
17179          dlIdx = calcSfNum;
17180       }
17181       else if((ulSubfrmInfo.switchPoints == 2) &&
17182             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
17183       {
17184          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17185       }
17186       else
17187       {
17188          dlIdx = calcSfNum - maxUlSubfrms;
17189       }
17190
17191       cell->subFrms[dlIdx]->ulAscInfo.subframe = sfNum;
17192       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = calcSfnOffset;
17193
17194       /* set dlIdx for which ulAscInfo is updated */
17195       dlPres = dlPres | (1 << dlIdx);
17196       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17197    }
17198
17199    /* Set Invalid information for which ulAscInfo is not present */
17200    for (sfCount = 0;
17201          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17202          sfCount++)
17203    {
17204       /* If dlPres is 0, ulAscInfo is not present in that DL index */
17205       if(! ((dlPres >> sfCount)&0x01))
17206       {
17207          cell->subFrms[sfCount]->ulAscInfo.sfnOffset =
17208             RGSCH_INVALID_INFO;
17209          cell->subFrms[sfCount]->ulAscInfo.subframe =
17210             RGSCH_INVALID_INFO;
17211       }
17212    }
17213
17214    /* DL subframes in the subsequent radio frames are initialized
17215     * with the previous radio frames  */
17216    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;
17217          dlIdx++)
17218    {
17219       sfNum = dlIdx - \
17220               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17221       cell->subFrms[dlIdx]->ulAscInfo.subframe =
17222          cell->subFrms[sfNum]->ulAscInfo.subframe;
17223       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset =
17224          cell->subFrms[sfNum]->ulAscInfo.sfnOffset;
17225    }
17226    return ROK;
17227 }
17228
17229
17230 /**
17231  * @brief This function initialises the 'Np' value for 'p'
17232  *
17233  * @details
17234  *
17235  *     Function: rgSCHCmnDlNpValInit
17236  *     Purpose:  To initialise the 'Np' value for each 'p'. It is used
17237  *               to find the mapping between nCCE and 'p' and used in
17238  *               HARQ ACK/NACK reception.
17239  *
17240  *     Invoked by: Scheduler
17241  *
17242  *  @param[in]  RgSchCellCb*     cell
17243  *  @return     S16
17244  *
17245  **/
17246 static S16 rgSCHCmnDlNpValInit(RgSchCellCb *cell)
17247 {
17248    uint8_t    idx;
17249    uint16_t   np;
17250
17251    /* Always Np is 0 for p=0 */
17252    cell->rgSchTddNpValTbl[0] = 0;
17253
17254    for(idx=1; idx < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; idx++)
17255    {
17256       np = cell->bwCfg.dlTotalBw * (idx * RG_SCH_CMN_NUM_SUBCAR - 4);
17257       cell->rgSchTddNpValTbl[idx] = (uint8_t) (np/36);
17258    }
17259
17260    return ROK;
17261 }
17262
17263 /**
17264  * @brief This function handles the creation of RACH preamble
17265  *        list to queue the preambles and process at the scheduled
17266  *        time.
17267  *
17268  * @details
17269  *
17270  *     Function: rgSCHCmnDlCreateRachPrmLst
17271  *     Purpose:  To create RACH preamble list based on RA window size.
17272  *               It is used to queue the preambles and process it at the
17273  *               scheduled time.
17274  *
17275  *     Invoked by: Scheduler
17276  *
17277  *  @param[in]  RgSchCellCb*     cell
17278  *  @return     S16
17279  *
17280  **/
17281 static S16 rgSCHCmnDlCreateRachPrmLst(RgSchCellCb *cell)
17282 {
17283    uint8_t   raArrSz;
17284    S16       ret;
17285    uint8_t   lstSize;
17286
17287    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
17288
17289    lstSize = raArrSz * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES;
17290
17291    cell->raInfo.maxRaSize = raArrSz;
17292    ret = rgSCHUtlAllocSBuf(cell->instIdx,
17293          (Data **)(&cell->raInfo.raReqLst), (Size)(lstSize * sizeof(CmLListCp)));
17294    if (ret != ROK)
17295    {
17296       return (ret);
17297    }
17298
17299    cell->raInfo.lstSize = lstSize;
17300
17301    return ROK;
17302 }
17303
17304
17305 /**
17306  * @brief This function handles the initialization of RACH Response
17307  *        information at each DL subframe.
17308  *
17309  * @details
17310  *
17311  *     Function: rgSCHCmnDlRachInfoInit
17312  *     Purpose:  Each DL subframe stores the sfn and subframe information of
17313  *               possible RACH response allowed for UL subframes. It generates
17314  *               the information based on PRACH configuration.
17315  *
17316  *     Invoked by: Scheduler
17317  *
17318  *  @param[in]  RgSchCellCb*     cell
17319  *  @return     S16
17320  *
17321  **/
17322 static S16 rgSCHCmnDlRachInfoInit(RgSchCellCb  *cell)
17323 {
17324    uint8_t                   sfCount;
17325    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
17326    uint8_t                   sfNum;
17327    uint8_t                   ulSfCnt =0;
17328    uint8_t                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
17329                                        [RGSCH_NUM_SUB_FRAMES-1];
17330    uint8_t                   raArrSz;
17331    RgSchTddRachRspLst        rachRspLst[3][RGSCH_NUM_SUB_FRAMES];
17332    uint8_t                   startWin;
17333    uint8_t                   endWin;
17334    uint8_t                   sfnIdx;
17335    uint8_t                   subfrmIdx;
17336    uint8_t                   endSubfrmIdx;
17337    uint8_t                   startSubfrmIdx;
17338    S16                       ret;
17339    RgSchTddRachDelInfo       *delInfo;
17340    S8                        sfnOffset;
17341    uint8_t                   numSubfrms;
17342
17343
17344    memset(rachRspLst, 0, sizeof(rachRspLst));
17345
17346    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
17347
17348    /* Include Special subframes */
17349    maxUlSubfrms = maxUlSubfrms + \
17350                   rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx].switchPoints;
17351    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17352    {
17353       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
17354             RG_SCH_TDD_DL_SUBFRAME)
17355       {
17356          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17357       }
17358       ulSfCnt++;
17359
17360       startWin = (sfNum + RG_SCH_CMN_RARSP_WAIT_PRD + \
17361             ((RgSchCmnCell *)cell->sc.sch)->dl.numRaSubFrms);
17362       endWin = (startWin + cell->rachCfg.raWinSize - 1);
17363       startSubfrmIdx =
17364          rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][startWin%RGSCH_NUM_SUB_FRAMES];
17365       /* Find the next DL subframe starting from Subframe 0 */
17366       if((startSubfrmIdx % RGSCH_NUM_SUB_FRAMES) == 0)
17367       {
17368          startWin = RGSCH_CEIL(startWin, RGSCH_NUM_SUB_FRAMES);
17369          startWin = startWin * RGSCH_NUM_SUB_FRAMES;
17370       }
17371
17372       endSubfrmIdx =
17373          rgSchTddLowDlSubfrmIdxTbl[ulDlCfgIdx][endWin%RGSCH_NUM_SUB_FRAMES];
17374       endWin = (endWin/RGSCH_NUM_SUB_FRAMES) * RGSCH_NUM_SUB_FRAMES \
17375                + endSubfrmIdx;
17376       if(startWin > endWin)
17377       {
17378          continue;
17379       }
17380       /* Find all the possible RACH Response transmission
17381        * time within the RA window size */
17382       startSubfrmIdx = startWin%RGSCH_NUM_SUB_FRAMES;
17383       for(sfnIdx = startWin/RGSCH_NUM_SUB_FRAMES;
17384             sfnIdx <= endWin/RGSCH_NUM_SUB_FRAMES; sfnIdx++)
17385       {
17386          if(sfnIdx == endWin/RGSCH_NUM_SUB_FRAMES)
17387          {
17388             endSubfrmIdx = endWin%RGSCH_NUM_SUB_FRAMES;
17389          }
17390          else
17391          {
17392             endSubfrmIdx = RGSCH_NUM_SUB_FRAMES-1;
17393          }
17394
17395          /* Find all the possible RACH Response transmission
17396           * time within radio frame */
17397          for(subfrmIdx = startSubfrmIdx;
17398                subfrmIdx <= endSubfrmIdx; subfrmIdx++)
17399          {
17400             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][subfrmIdx] ==
17401                   RG_SCH_TDD_UL_SUBFRAME)
17402             {
17403                continue;
17404             }
17405             subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
17406             /* Find the next DL subframe starting from Subframe 0 */
17407             if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
17408             {
17409                break;
17410             }
17411             RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx], subfrmIdx);
17412             numSubfrms =
17413                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
17414             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset = sfnIdx;
17415             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].subframe[numSubfrms]
17416                = sfNum;
17417             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms++;
17418          }
17419          startSubfrmIdx = RG_SCH_CMN_SUBFRM_0;
17420       }
17421       /* Update the subframes to be deleted at this subframe */
17422       /* Get the subframe after the end of RA window size */
17423       endWin++;
17424       endSubfrmIdx++;
17425       sfnOffset = endWin/RGSCH_NUM_SUB_FRAMES;
17426       if(sfnOffset < 0)
17427       {
17428          sfnOffset += raArrSz;
17429       }
17430       sfnIdx = (endWin/RGSCH_NUM_SUB_FRAMES) % raArrSz;
17431
17432       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx],endSubfrmIdx-1);
17433       if((endSubfrmIdx == RGSCH_NUM_SUB_FRAMES) ||
17434             (rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx] ==
17435              RGSCH_NUM_SUB_FRAMES))
17436       {
17437          subfrmIdx =
17438             rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][RG_SCH_CMN_SUBFRM_0];
17439       }
17440       else
17441       {
17442          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx];
17443       }
17444
17445       delInfo = &rachRspLst[sfnIdx][subfrmIdx].delInfo;
17446       delInfo->sfnOffset = sfnOffset;
17447       delInfo->subframe[delInfo->numSubfrms] = sfNum;
17448       delInfo->numSubfrms++;
17449
17450       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17451    }
17452
17453    ret = rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz);
17454    if (ret != ROK)
17455    {
17456       return (ret);
17457    }
17458
17459    return ROK;
17460 }
17461
17462 /**
17463  * @brief This function handles the initialization of PHICH information
17464  *        for each DL subframe based on PHICH table.
17465  *
17466  * @details
17467  *
17468  *     Function: rgSCHCmnDlPhichOffsetInit
17469  *     Purpose:  Each DL subf stores the sfn and subf information of UL subframe
17470  *               for which it trnsmts PHICH in this subframe. It generates the information
17471  *               based on PHICH table.
17472  *
17473  *     Invoked by: Scheduler
17474  *
17475  *  @param[in]  RgSchCellCb*     cell
17476  *  @return     S16
17477  *
17478  **/
17479 static S16 rgSCHCmnDlPhichOffsetInit(RgSchCellCb *cell)
17480 {
17481    uint8_t              sfCount;
17482    uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17483    uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17484    uint8_t              sfNum;
17485    uint8_t              dlIdx;
17486    uint8_t              dlPres = 0;
17487    uint8_t              calcSfnOffset;
17488    uint8_t              calcSfNum;
17489    uint8_t              ulSfCnt =0;
17490    RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17491    uint8_t              maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
17492                                        [RGSCH_NUM_SUB_FRAMES-1];
17493
17494
17495    /* Generate PHICH offset information for each DL subframe in a radio frame
17496     * Calculate this information based on K in PHICH table */
17497    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17498    {
17499       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17500             RG_SCH_TDD_UL_SUBFRAME)
17501       {
17502          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17503       }
17504       ulSfCnt++;
17505
17506       calcSfNum = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) % \
17507                   RGSCH_NUM_SUB_FRAMES;
17508       calcSfnOffset = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) / \
17509                       RGSCH_NUM_SUB_FRAMES;
17510
17511       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17512       {
17513          dlIdx = calcSfNum;
17514       }
17515       else if((ulSubfrmInfo.switchPoints == 2) &&
17516             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
17517       {
17518          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17519       }
17520       else
17521       {
17522          dlIdx = calcSfNum - maxUlSubfrms;
17523       }
17524
17525       cell->subFrms[dlIdx]->phichOffInfo.subframe = sfNum;
17526       cell->subFrms[dlIdx]->phichOffInfo.numSubfrms = 1;
17527
17528       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = calcSfnOffset;
17529
17530       /* set dlIdx for which phich offset is updated */
17531       dlPres = dlPres | (1 << dlIdx);
17532       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17533    }
17534
17535    /* Set Invalid information for which phich offset is not present */
17536    for (sfCount = 0;
17537          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17538          sfCount++)
17539    {
17540       /* If dlPres is 0, phich offset is not present in that DL index */
17541       if(! ((dlPres >> sfCount)&0x01))
17542       {
17543          cell->subFrms[sfCount]->phichOffInfo.sfnOffset =
17544             RGSCH_INVALID_INFO;
17545          cell->subFrms[sfCount]->phichOffInfo.subframe =
17546             RGSCH_INVALID_INFO;
17547          cell->subFrms[sfCount]->phichOffInfo.numSubfrms = 0;
17548       }
17549    }
17550
17551    /* DL subframes in the subsequent radio frames are
17552     * initialized with the previous radio frames  */
17553    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms;
17554          dlIdx < maxDlSubfrms; dlIdx++)
17555    {
17556       sfNum = dlIdx - \
17557               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17558
17559       cell->subFrms[dlIdx]->phichOffInfo.subframe =
17560          cell->subFrms[sfNum]->phichOffInfo.subframe;
17561
17562       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset =
17563          cell->subFrms[sfNum]->phichOffInfo.sfnOffset;
17564    }
17565    return ROK;
17566 }
17567
17568
17569 /**
17570  * @brief Updation of Sch vars per TTI.
17571  *
17572  * @details
17573  *
17574  *     Function: rgSCHCmnUpdVars
17575  *     Purpose:  Updation of Sch vars per TTI.
17576  *
17577  *  @param[in]  RgSchCellCb *cell
17578  *  @return  Void
17579  *
17580  **/
17581 Void rgSCHCmnUpdVars(RgSchCellCb *cell)
17582 {
17583    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
17584    CmLteTimingInfo        timeInfo;
17585    uint8_t                idx;
17586    uint8_t                ulSubframe;
17587    uint8_t                ulDlCfgIdx = cell->ulDlCfgIdx;
17588    uint8_t                msg3Subfrm;
17589    uint8_t                Mval;
17590  
17591    /* ccpu00132654-ADD- Initializing all the indices in every subframe*/ 
17592    rgSCHCmnInitVars(cell);
17593
17594    idx = (cell->crntTime.slot + TFU_ULCNTRL_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
17595    /* Calculate the UL scheduling subframe idx based on the 
17596       Pusch k table */
17597    if(rgSchTddPuschTxKTbl[ulDlCfgIdx][idx] != 0)
17598    {
17599       /* PUSCH transmission is based on offset from DL
17600        * PDCCH scheduling */
17601       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); 
17602       ulSubframe = rgSchTddPuschTxKTbl[ulDlCfgIdx][timeInfo.subframe];
17603       /* Add the DCI-0 to PUSCH time to get the time of UL subframe */
17604       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, ulSubframe);
17605 #ifdef LTEMAC_SPS
17606       cellUl->schdTti = timeInfo.sfn * 10 + timeInfo.subframe;
17607 #endif
17608       /* Fetch the corresponding  UL subframe Idx in UL sf array */ 
17609       cellUl->schdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17610       /* Fetch the corresponding  UL Harq Proc ID */ 
17611       cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
17612       cellUl->schdTime = timeInfo;
17613    }
17614    Mval = rgSchTddPhichMValTbl[ulDlCfgIdx][idx]; 
17615    if(Mval)
17616    {
17617       /* Fetch the tx time for DL HIDCI-0 */
17618       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA);
17619       /* Fetch the corresponding n-k tx time of PUSCH */
17620       cellUl->hqFdbkIdx[0] = rgSCHCmnGetPhichUlSfIdx(&timeInfo, cell);
17621       /* Retx will happen according to the Pusch k table */
17622       cellUl->reTxIdx[0] = cellUl->schdIdx;
17623       
17624       if(ulDlCfgIdx == 0) 
17625       {
17626          /* Calculate the ReTxIdx corresponding to hqFdbkIdx[0] */
17627          cellUl->reTxIdx[0] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
17628                                                 cellUl->hqFdbkIdx[0]);
17629          if(Mval == 2)
17630          {
17631             /* At Idx 1 store the UL SF adjacent(left) to the UL SF
17632                given at idx 0 */  
17633             cellUl->hqFdbkIdx[1] = (cellUl->hqFdbkIdx[0]-1 + 
17634                                    cellUl->numUlSubfrms) % cellUl->numUlSubfrms;
17635             /* Calculate the ReTxIdx corresponding to hqFdbkIdx[1] */
17636             cellUl->reTxIdx[1] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
17637                                                 cellUl->hqFdbkIdx[1]);
17638          }                               
17639       }
17640    }
17641
17642    idx = (cell->crntTime.slot + TFU_RECPREQ_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
17643    if (rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == RG_SCH_TDD_UL_SUBFRAME)
17644    {
17645       RGSCHCMNADDTOCRNTTIME(cell->crntTime, timeInfo, TFU_RECPREQ_DLDELTA)
17646       cellUl->rcpReqIdx   = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17647    }
17648    idx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % RGSCH_NUM_SUB_FRAMES;
17649    
17650    /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
17651      special subframe */                       
17652    if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] != RG_SCH_TDD_UL_SUBFRAME)
17653    {
17654       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
17655       msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
17656       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, msg3Subfrm);
17657       cellUl->msg3SchdIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17658       cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
17659    }
17660 #ifdef LTEMAC_SPS
17661    if(!rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][idx])
17662    {
17663       cellUl->spsUlRsrvIdx = RGSCH_INVALID_INFO;
17664    }
17665    else
17666    {
17667       /* introduce some reuse with above code? */
17668       uint8_t    offst;
17669       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
17670       //offst = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
17671       offst = rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][timeInfo.subframe];
17672       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, offst);
17673       cellUl->spsUlRsrvIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17674       /* The harq proc continues to be accessed and used the same delta before
17675        * actual data occurance, and hence use the same idx */
17676       cellUl->spsUlRsrvHqProcIdx = cellUl->schdHqProcIdx;
17677    }
17678 #endif
17679
17680    /* RACHO: update cmn sched specific RACH variables,
17681     * mainly the prachMaskIndex */
17682    rgSCHCmnUpdRachParam(cell);
17683
17684    return;
17685 }
17686
17687 /**
17688  * @brief To get 'p' value from nCCE.
17689  *
17690  * @details
17691  *
17692  *     Function: rgSCHCmnGetPValFrmCCE
17693  *     Purpose:  Gets 'p' value for HARQ ACK/NACK reception from CCE.
17694  *
17695  *  @param[in]  RgSchCellCb   *cell
17696  *  @param[in]  uint8_t            cce
17697  *  @return uint8_t
17698  *
17699  **/
17700 uint8_t  rgSCHCmnGetPValFrmCCE(RgSchCellCb *cell,uint8_t cce)
17701 {
17702    uint8_t i;
17703
17704    for(i=1; i < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; i++)
17705    {
17706       if(cce < cell->rgSchTddNpValTbl[i])
17707       {
17708          return (i-1);
17709       }
17710    }
17711    return (0);
17712 }
17713 #endif
17714
17715 /***********************************************************
17716  *
17717  *     Func : rgSCHCmnUlAdapRetx
17718  *
17719  *     Desc : Adaptive retransmission for an allocation.
17720  *
17721  *     Ret  :
17722  *
17723  *     Notes:
17724  *
17725  *     File :
17726  *
17727  **********************************************************/
17728 static Void rgSCHCmnUlAdapRetx(RgSchUlAlloc  *alloc,RgSchUlHqProcCb *proc)
17729 {
17730
17731    rgSCHUhmRetx(proc, alloc);
17732 #ifndef RG_5GTF
17733    if (proc->rvIdx != 0)
17734    {
17735       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[proc->rvIdx];
17736    }
17737    else
17738 #endif
17739    {
17740       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
17741    }
17742    return;
17743 }
17744
17745 /**
17746  * @brief Scheduler invocation per TTI.
17747  *
17748  * @details
17749  *
17750  *     Function: rgSCHCmnHdlUlInactUes
17751  *     Purpose:
17752  *
17753  *     Invoked by: Common Scheduler
17754  *
17755  *  @param[in]  RgSchCellCb *cell
17756  *  @return  Void
17757  **/
17758 static Void rgSCHCmnHdlUlInactUes(RgSchCellCb  *cell)
17759 {
17760    RgSchCmnCell  *cellSch  = RG_SCH_CMN_GET_CELL(cell);
17761    CmLListCp     ulInactvLst;
17762    /* Get a List of Inactv UEs for UL*/
17763    cmLListInit(&ulInactvLst);
17764
17765    /* Trigger Spfc Schedulers with Inactive UEs */
17766    rgSCHMeasGapANRepGetUlInactvUe (cell, &ulInactvLst);
17767    /* take care of this in UL retransmission */
17768    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst);
17769
17770    return;
17771 }
17772
17773 /**
17774  * @brief Scheduler invocation per TTI.
17775  *
17776  * @details
17777  *
17778  *     Function: rgSCHCmnHdlDlInactUes
17779  *     Purpose:
17780  *
17781  *     Invoked by: Common Scheduler
17782  *
17783  *  @param[in]  RgSchCellCb *cell
17784  *  @return  Void
17785  **/
17786 static Void rgSCHCmnHdlDlInactUes(RgSchCellCb  *cell)
17787 {
17788    RgSchCmnCell *cellSch  = RG_SCH_CMN_GET_CELL(cell);
17789    CmLListCp    dlInactvLst;
17790    /* Get a List of Inactv UEs for DL */
17791    cmLListInit(&dlInactvLst);
17792
17793    /* Trigger Spfc Schedulers with Inactive UEs */
17794    rgSCHMeasGapANRepGetDlInactvUe (cell, &dlInactvLst);
17795
17796    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst);
17797    return;
17798 }
17799
17800 /* RACHO: Rach handover functions start here */
17801 /***********************************************************
17802  *
17803  *     Func : rgSCHCmnUeIdleExdThrsld
17804  *
17805  *     Desc : RETURN ROK if UE has been idle more
17806  *            than threshold.
17807  *
17808  *     Ret  :
17809  *
17810  *     Notes:
17811  *
17812  *     File :
17813  *
17814  **********************************************************/
17815 static S16 rgSCHCmnUeIdleExdThrsld(RgSchCellCb *cell,RgSchUeCb *ue)
17816 {
17817    /* Time difference in subframes */
17818    uint32_t sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, ue->ul.ulTransTime);
17819
17820    if (sfDiff > (uint32_t)RG_SCH_CMN_UE_IDLE_THRSLD(ue))
17821    {
17822       return ROK;
17823    }
17824    else
17825    {
17826       return RFAILED;
17827    }
17828 }
17829
17830 \f
17831 /**
17832  * @brief Scheduler processing for Ded Preambles on cell configuration.
17833  *
17834  * @details
17835  *
17836  *     Function : rgSCHCmnCfgRachDedPrm
17837  *
17838  *     This function does requisite initialisation
17839  *     for RACH Ded Preambles.
17840  *
17841  *
17842  *  @param[in]  RgSchCellCb   *cell
17843  *  @return  Void
17844  **/
17845 static Void rgSCHCmnCfgRachDedPrm(RgSchCellCb   *cell)
17846 {
17847    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
17848    uint32_t     gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
17849    uint32_t     sfDiff;
17850    uint8_t      cnt;
17851
17852    if (cell->macPreambleSet.pres == NOTPRSNT)
17853    {
17854       return;
17855    }
17856    cellSch->rachCfg.numDedPrm = cell->macPreambleSet.size;
17857    cellSch->rachCfg.dedPrmStart = cell->macPreambleSet.start;
17858    /* Initialize handover List */
17859    cmLListInit(&cellSch->rachCfg.hoUeLst);
17860    /* Initialize pdcch Order List */
17861    cmLListInit(&cellSch->rachCfg.pdcchOdrLst);
17862
17863    /* Intialize the rapId to UE mapping structure */
17864    for (cnt = 0; cnt<cellSch->rachCfg.numDedPrm; cnt++)
17865    {
17866       cellSch->rachCfg.rapIdMap[cnt].rapId = cellSch->rachCfg.dedPrmStart + \
17867                                              cnt;
17868       cmLListInit(&cellSch->rachCfg.rapIdMap[cnt].assgndUes);
17869    }
17870    /* Perform Prach Mask Idx, remDedPrm, applFrm initializations */
17871    /* Set remDedPrm as numDedPrm */
17872    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
17873    /* Initialize applFrm */
17874    cellSch->rachCfg.prachMskIndx = 0;
17875    if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_EVEN)
17876    {
17877       cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + \
17878             (cell->crntTime.sfn % 2)) % RGSCH_MAX_SFN;
17879    }
17880 #ifdef LTE_TDD
17881    else if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ODD)
17882    {
17883       if((cell->crntTime.sfn%2) == 0)
17884       {
17885          cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + 1)\
17886                                         % RGSCH_MAX_SFN;
17887       }
17888    }
17889 #endif
17890    else /* ANY sfn */
17891    {
17892       cellSch->rachCfg.applFrm.sfn = cell->crntTime.sfn;
17893    }
17894    /* Initialize cellSch->rachCfg.applFrm as >= crntTime.
17895     * This is because of RGSCH_CALC_SF_DIFF logic */
17896    if (cellSch->rachCfg.applFrm.sfn == cell->crntTime.sfn)
17897    {
17898       while (cellSch->rachCfg.prachMskIndx < cell->rachCfg.raOccasion.size)
17899       {
17900          if (cell->crntTime.slot <\
17901                cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx])
17902          {
17903             break;
17904          }
17905          cellSch->rachCfg.prachMskIndx++;
17906       }
17907       if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size)
17908       {
17909          if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
17910          {
17911             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) %\
17912                                            RGSCH_MAX_SFN;
17913          }
17914          else
17915          {
17916             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) %\
17917                                            RGSCH_MAX_SFN;
17918          }
17919          cellSch->rachCfg.prachMskIndx = 0;
17920       }
17921       cellSch->rachCfg.applFrm.slot = \
17922                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17923    }
17924    else
17925    {
17926       cellSch->rachCfg.applFrm.slot = \
17927                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17928    }
17929
17930    /* Note first param to this macro should always be the latest in time */
17931    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
17932    while (sfDiff <= gap)
17933    {
17934       rgSCHCmnUpdNxtPrchMskIdx(cell);
17935       sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
17936    }
17937
17938    return;
17939 }
17940
17941 /**
17942  * @brief Updates the PRACH MASK INDEX.
17943  *
17944  * @details
17945  *
17946  *     Function: rgSCHCmnUpdNxtPrchMskIdx
17947  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
17948  *     CFG is always >= "n"+"DELTA", where "n" is the crntTime
17949  *     of the cell. If not, applFrm is updated to the next avl
17950  *     PRACH oppurtunity as per the PRACH Cfg Index configuration.
17951  *
17952  *
17953  *     Invoked by: Common Scheduler
17954  *
17955  *  @param[in]  RgSchCellCb *cell
17956  *  @return  Void
17957  **/
17958 static Void rgSCHCmnUpdNxtPrchMskIdx(RgSchCellCb  *cell)
17959 {
17960    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
17961
17962    /* Determine the next prach mask Index */
17963    if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size - 1)
17964    {
17965       /* PRACH within applFrm.sfn are done, go to next AVL sfn */
17966       cellSch->rachCfg.prachMskIndx = 0;
17967       if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
17968       {
17969          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) % \
17970                                         RGSCH_MAX_SFN;
17971       }
17972       else/* RGR_SFN_EVEN or RGR_SFN_ODD */
17973       {
17974          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) % \
17975                                         RGSCH_MAX_SFN;
17976       }
17977       cellSch->rachCfg.applFrm.slot = cell->rachCfg.raOccasion.\
17978                                           subFrameNum[0];
17979    }
17980    else /* applFrm.sfn is still valid */
17981    {
17982       cellSch->rachCfg.prachMskIndx += 1;
17983       if ( cellSch->rachCfg.prachMskIndx < RGR_MAX_SUBFRAME_NUM )
17984       {
17985          cellSch->rachCfg.applFrm.slot = \
17986                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17987       }
17988    }
17989    return;
17990 }
17991
17992 /**
17993  * @brief Updates the Ded preamble RACH parameters
17994  *        every TTI.
17995  *
17996  * @details
17997  *
17998  *     Function: rgSCHCmnUpdRachParam
17999  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
18000  *     CFG is always >= "n"+"6"+"DELTA", where "n" is the crntTime
18001  *     of the cell. If not, applFrm is updated to the next avl
18002  *     PRACH oppurtunity as per the PRACH Cfg Index configuration,
18003  *     accordingly the "remDedPrm" is reset to "numDedPrm" and
18004  *     "prachMskIdx" field is updated as per "applFrm".
18005  *
18006  *
18007  *     Invoked by: Common Scheduler
18008  *
18009  *  @param[in]  RgSchCellCb *cell
18010  *  @return  Void
18011  **/
18012 static Void rgSCHCmnUpdRachParam(RgSchCellCb  *cell)
18013 {
18014
18015    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18016    uint32_t     gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
18017    uint32_t     sfDiff;
18018
18019    if (cell->macPreambleSet.pres == NOTPRSNT)
18020    {
18021       return;
18022    }
18023    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, \
18024          cell->crntTime);
18025    if (sfDiff > gap)
18026    {
18027       /* applFrm is still a valid next Prach Oppurtunity */
18028       return;
18029    }
18030    rgSCHCmnUpdNxtPrchMskIdx(cell);
18031    /* Reset remDedPrm as numDedPrm */
18032    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
18033
18034    return;
18035 }
18036
18037 /**
18038  * @brief Dedicated Preamble allocation function.
18039  *
18040  * @details
18041  *
18042  *     Function: rgSCHCmnAllocPOParam
18043  *     Purpose:  Allocate pdcch, rapId and PrachMskIdx.
18044  *     Set mapping of UE with the allocated rapId.
18045  *
18046  *     Invoked by: Common Scheduler
18047  *
18048  *  @param[in]   RgSchCellCb *cell
18049  *  @param[in]   RgSchDlSf   *dlSf
18050  *  @param[in]   RgSchUeCb   *ue
18051  *  @param[out]  RgSchPdcch  **pdcch
18052  *  @param[out]  uint8_t          *rapId
18053  *  @param[out]  uint8_t          *prachMskIdx
18054  *  @return  Void
18055  **/
18056 static S16 rgSCHCmnAllocPOParam
18057 (
18058 RgSchCellCb  *cell,
18059 RgSchDlSf    *dlSf,
18060 RgSchUeCb    *ue,
18061 RgSchPdcch   **pdcch,
18062 uint8_t      *rapId,
18063 uint8_t      *prachMskIdx
18064 )
18065 {
18066
18067    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18068    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18069
18070
18071    if (cell->macPreambleSet.pres == PRSNT_NODEF)
18072    {
18073       if (cellSch->rachCfg.remDedPrm == 0)
18074       {
18075          return RFAILED;
18076       }
18077       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
18078       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
18079       {
18080          return RFAILED;
18081       }
18082       /* The stored prachMskIdx is the index of PRACH Oppurtunities in
18083        * raOccasions.subframes[].
18084        * Converting the same to the actual PRACHMskIdx to be transmitted. */
18085       *prachMskIdx = cellSch->rachCfg.prachMskIndx + 1;
18086       /* Distribution starts from dedPrmStart till dedPrmStart + numDedPrm */
18087       *rapId =  cellSch->rachCfg.dedPrmStart +
18088          cellSch->rachCfg.numDedPrm - cellSch->rachCfg.remDedPrm;
18089       cellSch->rachCfg.remDedPrm--;
18090       /* Map UE with the allocated RapId */
18091       ueDl->rachInfo.asgnOppr = cellSch->rachCfg.applFrm;
18092       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, cellSch->rachCfg.rapIdMap, (*rapId - cellSch->rachCfg.dedPrmStart));
18093       cmLListAdd2Tail(&cellSch->rachCfg.rapIdMap[*rapId - cellSch->rachCfg.dedPrmStart].assgndUes, 
18094              &ueDl->rachInfo.rapIdLnk);
18095       ueDl->rachInfo.rapIdLnk.node = (PTR)ue;
18096       ueDl->rachInfo.poRapId = *rapId;
18097    }
18098    else /* if dedicated preambles not configured */
18099    {
18100       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
18101       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
18102       {
18103          return RFAILED;
18104       }
18105       *prachMskIdx = 0;
18106       *rapId       = 0;
18107    }
18108
18109    return ROK;
18110 }
18111
18112 /**
18113  * @brief Dowlink Scheduling Handler.
18114  *
18115  * @details
18116  *
18117  *     Function: rgSCHCmnGenPdcchOrder
18118  *     Purpose:  For each UE in PO Q, grab a PDCCH,
18119  *     get an available ded RapId and fill PDCCH
18120  *     with PO information.
18121  *
18122  *     Invoked by: Common Scheduler
18123  *
18124  *  @param[in]  RgSchCellCb *cell
18125  *  @param[in]  RgSchDlSf   *dlSf
18126  *  @return  Void
18127  **/
18128 static Void rgSCHCmnGenPdcchOrder(RgSchCellCb  *cell,RgSchDlSf    *dlSf)
18129 {
18130    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
18131    CmLList       *node = cellSch->rachCfg.pdcchOdrLst.first;
18132    RgSchUeCb     *ue;
18133    uint8_t       rapId;
18134    uint8_t       prachMskIdx;
18135    RgSchPdcch    *pdcch = NULLP;
18136
18137    while (node)
18138    {
18139       ue = (RgSchUeCb *)node->node;
18140       node = node->next;
18141       /* Skip sending for this subframe is Measuring or inActive in UL due
18142        * to MeasGap or inactie due to DRX
18143        */
18144       if  ((ue->measGapCb.isMeasuring == TRUE) ||
18145            (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) ||
18146            (ue->isDrxEnabled &&
18147              ue->dl.dlInactvMask & RG_DRX_INACTIVE)
18148            )
18149       {
18150          continue;
18151       }
18152       if (rgSCHCmnAllocPOParam(cell, dlSf, ue, &pdcch, &rapId,\
18153                &prachMskIdx) != ROK)
18154       {
18155          /* No More rapIds left for the valid next avl Oppurtunity.
18156           * Unsatisfied UEs here would be given a chance, when the
18157           * prach Mask Index changes as per rachUpd every TTI */
18158
18159          /* PDDCH can also be ordered with rapId=0, prachMskIdx=0
18160           * so that UE triggers a RACH procedure with non-dedicated preamble.
18161           * But the implementation here does not do this. Instead, the "break"
18162           * here implies, that PDCCH Odr always given with valid rapId!=0,
18163           * prachMskIdx!=0 if dedicated preambles are configured.
18164           * If not configured, then trigger a PO with rapId=0,prchMskIdx=0*/
18165          break;
18166       }
18167       /* Fill pdcch with pdcch odr information */
18168       rgSCHCmnFillPdcchOdr2Sf(cell, ue, pdcch, rapId, prachMskIdx);
18169       /* Remove this UE from the PDCCH ORDER QUEUE */
18170       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
18171       /* Reset UE's power state */
18172       rgSCHPwrUeReset(cell, ue);
18173    }
18174    return;
18175 }
18176
18177 \f
18178 /**
18179  * @brief This function add UE to PdcchOdr Q if not already present.
18180  *
18181  * @details
18182  *
18183  *     Function: rgSCHCmnDlAdd2PdcchOdrQ
18184  *     Purpose:
18185  *
18186  *     Invoked by: CMN Scheduler
18187  *
18188  *  @param[in]  RgSchCellCb*  cell
18189  *  @param[in]  RgSchUeCb*    ue
18190  *  @return  Void
18191  *
18192  **/
18193 static Void rgSCHCmnDlAdd2PdcchOdrQ(RgSchCellCb *cell,RgSchUeCb *ue)
18194 {
18195    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18196    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18197
18198
18199    if (ueDl->rachInfo.poLnk.node == NULLP)
18200    {
18201       cmLListAdd2Tail(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
18202       ueDl->rachInfo.poLnk.node = (PTR)ue;
18203    }
18204    return;
18205 }
18206
18207 \f
18208 /**
18209  * @brief This function rmvs UE to PdcchOdr Q if not already present.
18210  *
18211  * @details
18212  *
18213  *     Function: rgSCHCmnDlRmvFrmPdcchOdrQ
18214  *     Purpose:
18215  *
18216  *     Invoked by: CMN Scheduler
18217  *
18218  *  @param[in]  RgSchCellCb*  cell
18219  *  @param[in]  RgSchUeCb*    ue
18220  *  @return  Void
18221  *
18222  **/
18223 static Void rgSCHCmnDlRmvFrmPdcchOdrQ(RgSchCellCb *cell,RgSchUeCb  *ue)
18224 {
18225    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18226    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18227
18228    cmLListDelFrm(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
18229    ueDl->rachInfo.poLnk.node = NULLP;
18230    return;
18231 }
18232
18233 /**
18234  * @brief Fill pdcch with PDCCH order information.
18235  *
18236  * @details
18237  *
18238  *     Function: rgSCHCmnFillPdcchOdr2Sf
18239  *     Purpose:  Fill PDCCH with PDCCH order information,
18240  *
18241  *     Invoked by: Common Scheduler
18242  *
18243  *  @param[in]  RgSchUeCb   *ue
18244  *  @param[in]  RgSchPdcch  *pdcch
18245  *  @param[in]  uint8_t          rapId
18246  *  @param[in]  uint8_t          prachMskIdx
18247  *  @return  Void
18248  **/
18249 static Void rgSCHCmnFillPdcchOdr2Sf
18250 (
18251 RgSchCellCb *cell,
18252 RgSchUeCb   *ue,
18253 RgSchPdcch  *pdcch,
18254 uint8_t     rapId,
18255 uint8_t     prachMskIdx
18256 )
18257 {
18258    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
18259
18260
18261    pdcch->rnti                                         = ue->ueId;
18262    pdcch->dci.dciFormat                                = TFU_DCI_FORMAT_1A;
18263    pdcch->dci.u.format1aInfo.isPdcchOrder = TRUE;
18264    pdcch->dci.u.format1aInfo.t.pdcchOrder.preambleIdx  = rapId;
18265    pdcch->dci.u.format1aInfo.t.pdcchOrder.prachMaskIdx = prachMskIdx;
18266
18267    /* Request for APer CQI immediately after PDCCH Order */
18268    /* CR ccpu00144525 */
18269 #ifdef TFU_UPGRADE
18270    if(ue->dl.ueDlCqiCfg.aprdCqiCfg.pres)
18271    {
18272       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
18273       acqiCb->aCqiTrigWt = 0;
18274    }
18275 #endif   
18276
18277    return;
18278 }
18279
18280 \f
18281 /**
18282  * @brief UE deletion for scheduler.
18283  *
18284  * @details
18285  *
18286  *     Function : rgSCHCmnDelRachInfo
18287  *
18288  *     This functions deletes all scheduler information
18289  *     pertaining to an UE.
18290  *
18291  *  @param[in]  RgSchCellCb  *cell
18292  *  @param[in]  RgSchUeCb    *ue
18293  *  @return  Void
18294  **/
18295 static Void rgSCHCmnDelRachInfo(RgSchCellCb *cell,RgSchUeCb *ue)
18296 {
18297    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18298    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18299    uint8_t            rapIdIdx;
18300
18301
18302    if (ueDl->rachInfo.poLnk.node)
18303    {
18304       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
18305    }
18306    if (ueDl->rachInfo.hoLnk.node)
18307    {
18308       cmLListDelFrm(&cellSch->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
18309       ueDl->rachInfo.hoLnk.node = NULLP;
18310    }
18311    if (ueDl->rachInfo.rapIdLnk.node)
18312    {
18313       rapIdIdx = ueDl->rachInfo.poRapId - cellSch->rachCfg.dedPrmStart;
18314       cmLListDelFrm(&cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes, 
18315           &ueDl->rachInfo.rapIdLnk);
18316       ueDl->rachInfo.rapIdLnk.node = NULLP;
18317    }
18318    return;
18319 }
18320
18321 /**
18322  * @brief This function retrieves the ue which has sent this raReq
18323  * and it allocates grant for UEs undergoing (for which RAR
18324  * is being generated) HandOver/PdcchOrder.
18325  *
18326  *
18327  * @details
18328  *
18329  *     Function: rgSCHCmnHdlHoPo
18330  *     Purpose:  This function  retrieves the ue which has sent this raReq
18331  *               and it allocates grant for UEs undergoing (for which RAR
18332  *               is being generated) HandOver/PdcchOrder.
18333  *
18334  *     Invoked by: Common Scheduler
18335  *
18336  *  @param[in]  RgSchCellCb           *cell
18337  *  @param[out] CmLListCp             *raRspLst
18338  *  @param[in]  RgSchRaReqInfo        *raReq
18339  *  @return  Void
18340  *
18341  **/
18342 static Void rgSCHCmnHdlHoPo
18343 (
18344 RgSchCellCb           *cell,
18345 CmLListCp             *raRspLst,
18346 RgSchRaReqInfo        *raReq
18347 )
18348 {
18349    RgSchUeCb             *ue = raReq->ue;
18350
18351    if ( ue->isDrxEnabled )
18352    {
18353       rgSCHDrxDedRa(cell,ue);
18354    }
18355    rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq);
18356    return;
18357 }
18358
18359 /**
18360  * @brief This function retrieves the UE which has sent this raReq
18361  * for handover case.
18362  *
18363  *
18364  * @details
18365  *
18366  *     Function: rgSCHCmnGetHoUe
18367  *     Purpose:  This function retrieves the UE which has sent this raReq
18368  *     for handover case.
18369  *
18370  *     Invoked by: Common Scheduler
18371  *
18372  *  @param[in]  RgSchCellCb           *cell
18373  *  @param[in]  RgSchRaReqInfo        *raReq
18374  *  @return  RgSchUeCb*
18375  *
18376  **/
18377 RgSchUeCb* rgSCHCmnGetHoUe(RgSchCellCb *cell,uint16_t rapId)
18378 {
18379    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18380    CmLList         *node;
18381    CmLListCp       *ueLst;
18382    RgSchUeCb       *ue;
18383    RgSchCmnDlUe    *ueDl;
18384
18385    ueLst = &cellSch->rachCfg.hoUeLst;
18386    node = ueLst->first;
18387    while (node)
18388    {
18389       ue = (RgSchUeCb *)node->node;
18390       node = node->next;
18391       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18392       if (ueDl->rachInfo.hoRapId == rapId)
18393       {
18394          return (ue);
18395       }
18396    }
18397    return (NULLP);
18398 }
18399
18400 static Void rgSCHCmnDelDedPreamble(RgSchCellCb *cell,uint8_t preambleId)
18401 {
18402    RgSchCmnCell  *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18403    CmLList       *node;
18404    CmLListCp     *ueLst;
18405    RgSchUeCb     *ue;
18406    RgSchCmnDlUe  *ueDl;
18407
18408    ueLst = &cellSch->rachCfg.hoUeLst;
18409    node = ueLst->first;
18410    while (node)
18411    {
18412       ue = (RgSchUeCb *)node->node;
18413       node = node->next;
18414       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18415       if (ueDl->rachInfo.hoRapId == preambleId)
18416       {
18417          cmLListDelFrm(ueLst, &ueDl->rachInfo.hoLnk);
18418          ueDl->rachInfo.hoLnk.node = (PTR)NULLP;
18419       }
18420    }
18421 }
18422
18423 /**
18424  * @brief This function retrieves the UE which has sent this raReq
18425  * for PDCCh Order case.
18426  *
18427  *
18428  * @details
18429  *
18430  *     Function: rgSCHCmnGetPoUe
18431  *     Purpose:  This function retrieves the UE which has sent this raReq
18432  *     for PDCCH Order case.
18433  *
18434  *     Invoked by: Common Scheduler
18435  *
18436  *  @param[in]  RgSchCellCb           *cell
18437  *  @param[in]  RgSchRaReqInfo        *raReq
18438  *  @return  RgSchUeCb*
18439  *
18440  **/
18441 RgSchUeCb* rgSCHCmnGetPoUe
18442 (
18443 RgSchCellCb     *cell,
18444 uint16_t        rapId,
18445 CmLteTimingInfo timingInfo
18446 )
18447 {
18448    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18449    CmLList      *node;
18450    CmLListCp    *ueLst;
18451    RgSchUeCb    *ue;
18452    RgSchCmnDlUe *ueDl;
18453    uint8_t      rapIdIdx;
18454
18455    rapIdIdx = rapId -cellSch->rachCfg.dedPrmStart;
18456    ueLst = &cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes;
18457    node = ueLst->first;
18458    while (node)
18459    {
18460       ue = (RgSchUeCb *)node->node;
18461       node = node->next;
18462       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18463       /* Remove UEs irrespective.
18464        * Old UE associations are removed.*/
18465       cmLListDelFrm(ueLst, &ueDl->rachInfo.rapIdLnk);
18466       ueDl->rachInfo.rapIdLnk.node = (PTR)NULLP;
18467       if (RGSCH_TIMEINFO_SAME(ueDl->rachInfo.asgnOppr, timingInfo))
18468       {
18469          return (ue);
18470       }
18471    }
18472
18473    return (NULLP);
18474 }
18475
18476
18477 /**
18478  * @brief This function returns the valid UL cqi for a given UE.
18479  *
18480  * @details
18481  *
18482  *     Function: rgSCHCmnUlGetCqi
18483  *     Purpose:  This function returns the "valid UL cqi" for a given UE
18484  *               based on UE category
18485  *
18486  *     Invoked by: Scheduler
18487  *     
18488  *  @param[in]  RgSchUeCb        *ue
18489  *  @param[in]  uint8_t               ueCtgy
18490  *  @return     uint8_t 
18491  **/
18492 uint8_t rgSCHCmnUlGetCqi
18493 (
18494 RgSchCellCb      *cell,
18495 RgSchUeCb        *ue,
18496 CmLteUeCategory  ueCtgy
18497 )
18498 {
18499    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18500    uint8_t            cqi;
18501
18502    
18503    cqi = ueUl->maxUlCqi;
18504 #ifdef TFU_UPGRADE
18505    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
18506         (ueUl->validUlCqi > ueUl->maxUlCqi)))
18507    {
18508       cqi = ueUl->validUlCqi;
18509    }
18510 #else   
18511    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
18512          (ueUl->crntUlCqi[0] > ueUl->maxUlCqi )))
18513    {
18514       cqi = ueUl->crntUlCqi[0];
18515    }
18516 #endif    
18517    return (cqi);
18518 }/* End of rgSCHCmnUlGetCqi */
18519
18520 /***********************************************************
18521  *
18522  *     Func : rgSCHCmnUlRbAllocForPoHoUe
18523  *
18524  *     Desc : Do uplink RB allocation for a HO/PO UE.
18525  *
18526  *     Ret  :
18527  *
18528  *     Notes: Note that as of now, for retx, maxRb
18529  *            is not considered. Alternatives, such
18530  *            as dropping retx if it crosses maxRb
18531  *            could be considered.
18532  *
18533  *     File :
18534  *
18535  **********************************************************/
18536 static S16 rgSCHCmnUlRbAllocForPoHoUe
18537 (
18538 RgSchCellCb  *cell,
18539 RgSchUlSf    *sf,
18540 RgSchUeCb    *ue,
18541 uint8_t      maxRb
18542 )
18543 {
18544    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18545    RgSchCmnUlUe      *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18546    uint8_t           sbSize  = cellUl->sbSize;
18547    uint32_t          maxBits = ue->ul.maxBytesPerUePerTti*8;
18548    uint32_t          bits;
18549    RgSchUlAlloc      *alloc;
18550    uint32_t          nPrb;
18551    uint8_t           iTbs;
18552    uint32_t          eff;
18553    uint32_t          numSb;
18554    uint8_t           iMcs;
18555    uint8_t           iMcsCrnt;
18556    uint8_t           cqi;
18557    uint8_t           modOdr;
18558    RgSchUlHole      *hole;
18559    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->msg3SchdHqProcIdx];
18560    CmLteUeCategory  ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
18561
18562    if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
18563    {
18564       return RFAILED;
18565    }
18566    /*MS_WORKAROUND for HO ccpu00121116*/
18567    cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
18568    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend], cqi);
18569    iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
18570    iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
18571    while(iMcs > RG_SCH_CMN_MAX_MSG3_IMCS)
18572    {
18573        cqi--;
18574        iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
18575        iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg);
18576    }
18577    /* Filling the modorder in the grant structure*/
18578    RG_SCH_UL_MCS_TO_MODODR(iMcs,modOdr);
18579    if (!cell->isCpUlExtend)
18580    {
18581       eff   = rgSchCmnNorUlEff[0][iTbs];
18582    }
18583    else
18584    {
18585       eff   = rgSchCmnExtUlEff[0][iTbs];
18586    }
18587
18588    bits = ueUl->alloc.reqBytes * 8;
18589
18590 #if (ERRCLASS & ERRCLS_DEBUG)
18591    if (!bits)
18592    {
18593       return RFAILED;
18594    }
18595 #endif
18596
18597    if (bits < rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs))
18598    {
18599       numSb = 1;
18600       nPrb = numSb * sbSize;
18601    }
18602    else
18603    {
18604       if (bits > maxBits)
18605       {
18606          bits  = maxBits;
18607          nPrb  = bits * 1024 / eff / RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
18608          if (nPrb > maxRb)
18609          {
18610             nPrb = maxRb;
18611          }
18612          numSb = nPrb / sbSize;
18613       }
18614       else
18615       {
18616          /*ccpu00128775:MOD-Change to get upper threshold nPrb*/
18617          nPrb = RGSCH_CEIL((RGSCH_CEIL(bits * 1024, eff)),
18618                   RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl));
18619          if (nPrb > maxRb)
18620          {
18621             nPrb = maxRb;
18622          }
18623          numSb = RGSCH_DIV_ROUND(nPrb, sbSize);
18624       }
18625    }
18626    iMcsCrnt = iMcs;
18627
18628    alloc = rgSCHCmnUlSbAlloc(sf, (uint8_t)RGSCH_MIN(numSb, cellUl->maxSbPerUe),\
18629                              hole);
18630    if (alloc == NULLP)
18631    {
18632       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForPoHoUe(): Could not get UlAlloc");
18633       return RFAILED;
18634    }
18635    rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
18636    
18637    /* Filling the modorder in the grant structure start*/
18638    alloc->grnt.modOdr = (TfuModScheme) modOdr;
18639    alloc->grnt.iMcs = iMcs;
18640    alloc->grnt.iMcsCrnt = iMcsCrnt;
18641    alloc->grnt.hop = 0;
18642    /* Fix for ccpu00123915*/
18643    alloc->forMsg3 = TRUE;
18644    alloc->hqProc = proc;
18645    alloc->hqProc->ulSfIdx = cellUl->msg3SchdIdx;
18646    alloc->ue = ue;
18647    alloc->rnti = ue->ueId;
18648    /* updating initNumRbs in case of HO */
18649 #ifdef TFU_UPGRADE
18650    ue->initNumRbs = alloc->grnt.numRb;
18651 #endif
18652    ueUl->alloc.alloc = alloc;
18653    iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
18654    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs);
18655    alloc->grnt.datSz    = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
18656    /* MS_WORKAROUND for HO ccpu00121124*/
18657    /*[Adi temp change] Need to fil modOdr */
18658    RG_SCH_UL_MCS_TO_MODODR(alloc->grnt.iMcsCrnt,alloc->grnt.modOdr);
18659    rgSCHUhmNewTx(proc, ueUl->hqEnt.maxHqRetx, alloc);
18660    /* No grant attr recorded now */
18661    return ROK;
18662 }
18663
18664 /**
18665  * @brief This function allocates grant for UEs undergoing (for which RAR
18666  * is being generated) HandOver/PdcchOrder.
18667  *
18668  *
18669  * @details
18670  *
18671  *     Function: rgSCHCmnAllocPoHoGrnt
18672  *     Purpose:  This function allocates grant for UEs undergoing (for which RAR
18673  *               is being generated) HandOver/PdcchOrder.
18674  *
18675  *     Invoked by: Common Scheduler
18676  *
18677  *  @param[in]  RgSchCellCb           *cell
18678  *  @param[out] CmLListCp             *raRspLst,
18679  *  @param[in]  RgSchUeCb             *ue
18680  *  @param[in]  RgSchRaReqInfo        *raReq
18681  *  @return  Void
18682  *
18683  **/
18684 static Void rgSCHCmnAllocPoHoGrnt
18685 (
18686 RgSchCellCb     *cell,
18687 CmLListCp       *raRspLst,
18688 RgSchUeCb       *ue,
18689 RgSchRaReqInfo  *raReq
18690 )
18691 {
18692    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18693    RgSchCmnUlUe    *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
18694    RgSchUlGrnt     *grnt;
18695    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
18696
18697
18698    /* Clearing previous allocs if any*/
18699    rgSCHCmnUlUeDelAllocs(cell, ue);
18700    /* Fix : syed allocs are limited */
18701    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
18702    {
18703       return;
18704    }
18705    ueUl->alloc.reqBytes = RG_SCH_MIN_GRNT_HOPO;
18706    if (rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, RGSCH_MAX_UL_RB) != ROK)
18707    {
18708       return;
18709    }
18710
18711    /* Fill grant information */
18712    grnt = &ueUl->alloc.alloc->grnt;
18713
18714    /* KWork fix */
18715    if (grnt == NULLP)
18716    {
18717       DU_LOG("\nERROR  -->  SCH : Failed to get"
18718         "the grant for HO/PDCCH Order. CRNTI:%d",ue->ueId);
18719       return;
18720    }
18721    ue->ul.rarGrnt.rapId = raReq->raReq.rapId;
18722    ue->ul.rarGrnt.hop = grnt->hop;
18723    ue->ul.rarGrnt.rbStart = grnt->rbStart;
18724    ue->ul.rarGrnt.numRb = grnt->numRb;
18725    ue->ul.rarGrnt.tpc = grnt->tpc;
18726    ue->ul.rarGrnt.iMcsCrnt = grnt->iMcsCrnt;
18727    ue->ul.rarGrnt.ta.pres = TRUE;
18728    ue->ul.rarGrnt.ta.val = raReq->raReq.ta;
18729    ue->ul.rarGrnt.datSz = grnt->datSz;
18730    if((sf->numACqiCount < RG_SCH_MAX_ACQI_PER_ULSF) && (RG_SCH_APCQI_NO != ue->dl.reqForCqi)) 
18731    {
18732 #ifdef LTE_ADV
18733       uint8_t    idx = 0; 
18734       /* Send two bits cqireq field if more than one cells are configured else one*/
18735       for (idx = 1;idx < CM_LTE_MAX_CELLS;idx++)
18736       {
18737          if (ue->cellInfo[idx] != NULLP)
18738          {
18739             ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
18740             break;
18741          }
18742       }
18743       if (idx == CM_LTE_MAX_CELLS)
18744 #endif
18745       {
18746          ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
18747       }
18748       ue->dl.reqForCqi = RG_SCH_APCQI_NO;
18749       sf->numACqiCount++;
18750    }
18751    else
18752    {
18753       ue->ul.rarGrnt.cqiReqBit = 0;
18754    }
18755    /* Attach Ho/Po allocation to RAR Rsp cont free Lst */
18756    cmLListAdd2Tail(raRspLst, &ue->ul.rarGrnt.raRspLnk);
18757    ue->ul.rarGrnt.raRspLnk.node = (PTR)ue;
18758
18759    return;
18760 }
18761
18762 /**
18763  * @brief This is a utility function to set the fields in
18764  * an UL harq proc which is identified for non-adaptive retx
18765  *
18766  * @details
18767  *
18768  *     Function: rgSCHCmnUlNonadapRetx 
18769  *     Purpose:  Sets the fields in UL Harq  proc for non-adaptive retx 
18770  *
18771  * @param[in]  RgSchCmnUlCell  *cellUl 
18772  * @param[out] RgSchUlAlloc    *alloc
18773  * @param[in]  uint8_t              idx 
18774  * @return  Void
18775  *
18776  **/
18777 #ifdef UNUSED_FUNC
18778 static Void rgSCHCmnUlNonadapRetx
18779 (
18780 RgSchCmnUlCell  *cellUl,
18781 RgSchUlAlloc    *alloc,
18782 uint8_t         idx
18783 )
18784 {
18785    rgSCHUhmRetx(alloc->hqProc, alloc);
18786
18787    /* Update alloc to retx */
18788    alloc->hqProc->isRetx = TRUE;
18789    alloc->hqProc->ulSfIdx = cellUl->reTxIdx[idx];
18790
18791    if (alloc->hqProc->rvIdx != 0)
18792    {
18793       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[alloc->hqProc->rvIdx];
18794    }
18795    else
18796    {
18797       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
18798    }
18799    alloc->grnt.isRtx = TRUE;
18800    alloc->pdcch = NULLP;
18801    return;
18802 }
18803 /**
18804  * @brief Check if 2 allocs overlap
18805  *
18806  * @details
18807  *
18808  *     Function : rgSCHCmnUlAllocsOvrLap
18809  *
18810  *      - Return TRUE if alloc1 and alloc2 overlap.
18811  *
18812  *  @param[in]  RgSchUlAlloc  *alloc1
18813  *  @param[in]  RgSchUlAlloc  *alloc2
18814  *  @return  Bool
18815  **/
18816 static Bool rgSCHCmnUlAllocsOvrLap(RgSchUlAlloc *alloc1,RgSchUlAlloc *alloc2)
18817 {
18818
18819    if (((alloc1->sbStart >= alloc2->sbStart) &&
18820          (alloc1->sbStart <= alloc2->sbStart + alloc2->numSb-1)) ||
18821         ((alloc2->sbStart >= alloc1->sbStart) &&
18822          (alloc2->sbStart <= alloc1->sbStart + alloc1->numSb-1)))
18823    {
18824       return (TRUE);
18825    }
18826    return (FALSE);
18827 }
18828 /**
18829  * @brief Copy allocation Info from src to dst.
18830  *
18831  * @details
18832  *
18833  *     Function : rgSCHCmnUlCpyAllocInfo
18834  *
18835  *      - Copy allocation Info from src to dst.
18836  *
18837  *  @param[in]  RgSchUlAlloc  *srcAlloc
18838  *  @param[in]  RgSchUlAlloc  *dstAlloc
18839  *  @return  Void
18840  **/
18841 static Void rgSCHCmnUlCpyAllocInfo(RgSchCellCb *cell,RgSchUlAlloc *srcAlloc,RgSchUlAlloc *dstAlloc)
18842 {
18843    RgSchCmnUlUe *ueUl;
18844
18845    dstAlloc->grnt = srcAlloc->grnt;
18846    dstAlloc->hqProc = srcAlloc->hqProc;
18847    /* Fix : syed During UE context release, hqProc->alloc
18848     * was pointing to srcAlloc instead of dstAlloc and
18849     * freeing from incorrect sf->allocDb was
18850     * corrupting the list. */
18851     /* In case of SPS Occasion Allocation is done in advance and 
18852        at a later time Hq Proc is linked. Hence HqProc
18853        pointer in alloc shall be NULL */
18854 #ifdef LTEMAC_SPS
18855    if (dstAlloc->hqProc)
18856 #endif
18857    {
18858       dstAlloc->hqProc->alloc = dstAlloc;
18859    }
18860    dstAlloc->ue = srcAlloc->ue;
18861    dstAlloc->rnti = srcAlloc->rnti;
18862    dstAlloc->forMsg3 = srcAlloc->forMsg3;
18863    dstAlloc->raCb  = srcAlloc->raCb;
18864    dstAlloc->pdcch = srcAlloc->pdcch;
18865    /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
18866    if (dstAlloc->ue)
18867    {
18868       ueUl = RG_SCH_CMN_GET_UL_UE(dstAlloc->ue,cell);
18869       ueUl->alloc.alloc = dstAlloc;
18870 #ifdef LTEMAC_SPS
18871       if (dstAlloc->ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
18872       {
18873          if((dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc != NULLP)
18874                && (dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc == srcAlloc))
18875          {
18876             dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc = dstAlloc;
18877          }
18878       }
18879 #endif
18880    }
18881
18882    return;
18883 }
18884 /**
18885  * @brief Update TX and RETX subframe's allocation
18886  *        markings.
18887  *
18888  * @details
18889  *
18890  *     Function : rgSCHCmnUlInsAllocFrmNewSf2OldSf
18891  *
18892  *      - Release all preassigned allocations of newSf and merge
18893  *        them to oldSf.
18894  *      - If alloc of newSf collide with one or more allocs of oldSf
18895  *        - mark all such allocs of oldSf for Adaptive Retx.
18896  *      - Swap the alloc and hole DB references of oldSf and newSf.
18897  *
18898  *  @param[in]  RgSchCellCb   *cell
18899  *  @param[in]  RgSchUlSf     *newSf
18900  *  @param[in]  RgSchUlSf     *oldSf
18901  *  @param[in]  RgSchUlAlloc  *srcAlloc
18902  *  @return  Void
18903  **/
18904 static Void rgSCHCmnUlInsAllocFrmNewSf2OldSf
18905 (
18906 RgSchCellCb     *cell,
18907 RgSchUlSf       *newSf,
18908 RgSchUlSf       *oldSf,
18909 RgSchUlAlloc    *srcAlloc
18910 )
18911 {
18912    RgSchUlAlloc   *alloc, *dstAlloc, *nxtAlloc;
18913
18914    /* MS_WORKAROUND ccpu00120827 */
18915    RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
18916    uint8_t remAllocs;
18917
18918    if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
18919    {
18920       do
18921       {
18922          nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);
18923          /* If there is an overlap between alloc and srcAlloc
18924           * then alloc is marked for Adaptive retx and it is released
18925           * from txSf */
18926          if (rgSCHCmnUlAllocsOvrLap(alloc, srcAlloc) == TRUE)
18927          {
18928             rgSCHCmnUlUpdAllocRetx(cell, alloc);
18929             rgSCHUtlUlAllocRls(oldSf, alloc);
18930          }
18931          /* No further allocs spanning the srcAlloc subbands */
18932          if (srcAlloc->sbStart + srcAlloc->numSb - 1  <= alloc->sbStart)
18933          {
18934             break;
18935          }
18936       } while ((alloc = nxtAlloc) != NULLP);
18937    }
18938
18939    /* After freeing all the colliding allocs, request for an allocation
18940     * specifying the start and numSb with in txSf. This function should
18941     * always return positively with a nonNULL dstAlloc */
18942     /* MS_WORKAROUND ccpu00120827 */
18943    remAllocs = schCmnCell->ul.maxAllocPerUlSf - *oldSf->allocCountRef;
18944    if (!remAllocs)
18945    {
18946       /* Fix : If oldSf already has max Allocs then release the
18947        * old RETX alloc to make space for new alloc of newSf.
18948        * newSf allocs(i.e new Msg3s) are given higher priority
18949        * over retx allocs. */      
18950       if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
18951       {
18952          do
18953          {
18954             nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);           
18955             if (!alloc->mrgdNewTxAlloc)
18956             {
18957                /* If alloc is for RETX */                   
18958                /* TODO: Incase of this ad also in case of choosing
18959                 * and alloc for ADAP RETX, we need to send ACK for
18960                 * the corresponding alloc in PHICH */               
18961 #ifndef EMTC_ENABLE
18962                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc);
18963 #else
18964                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc,FALSE);
18965 #endif
18966                break;
18967             }               
18968          }while((alloc = nxtAlloc) != NULLP);
18969       }
18970    }
18971    dstAlloc = rgSCHUtlUlGetSpfcAlloc(oldSf, srcAlloc->sbStart, srcAlloc->numSb);
18972 #ifdef ERRCLS_KW
18973    /* This should never happen */
18974    if (dstAlloc == NULLP)
18975    {
18976       DU_LOG("\nERROR  -->  SCH : CRNTI:%d "
18977          "rgSCHUtlUlGetSpfcAlloc failed in rgSCHCmnUlInsAllocFrmNewSf2OldSf",
18978          srcAlloc->rnti);
18979       return;
18980    }
18981 #endif
18982    /* Copy the srcAlloc's state information in to dstAlloc */
18983    rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc);
18984    /* Set new Tx merged Alloc Flag to TRUE, indicating that this
18985     * alloc shall not be processed for non-adaptive retransmission */
18986    dstAlloc->mrgdNewTxAlloc = TRUE;
18987    return;
18988 }
18989 /**
18990  * @brief Merge all allocations of newSf to oldSf.
18991  *
18992  * @details
18993  *
18994  *     Function : rgSCHCmnUlMergeSfAllocs
18995  *
18996  *      - Merge all allocations of newSf to oldSf.
18997  *      - If newSf's alloc collides with oldSf's alloc
18998  *        then oldSf's alloc is marked for adaptive Retx
18999  *        and is released from oldSf to create space for
19000  *        newSf's alloc.
19001  *
19002  *  @param[in]  RgSchCellCb  *cell
19003  *  @param[in]  RgSchUlSf    *oldSf
19004  *  @param[in]  RgSchUlSf    *newSf
19005  *  @return  Void
19006  **/
19007 static Void rgSCHCmnUlMergeSfAllocs(RgSchCellCb *cell,RgSchUlSf  *oldSf,RgSchUlSf  *newSf)
19008 {
19009    RgSchUlAlloc    *alloc, *nxtAlloc;
19010    UNUSED(cell);
19011
19012    /* Merge each alloc of newSf in to oldSf
19013     * and release it from newSf */
19014    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
19015    {
19016       do
19017       {
19018          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
19019          rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, alloc);
19020          rgSCHUtlUlAllocRls(newSf, alloc);
19021       } while((alloc = nxtAlloc) != NULLP);
19022    }
19023    return;
19024 }
19025 /**
19026  * @brief Swap Hole/Alloc DB context of newSf and oldSf.
19027  *
19028  * @details
19029  *
19030  *     Function : rgSCHCmnUlSwapSfAllocs
19031  *
19032  *      - Swap Hole/Alloc DB context of newSf and oldSf.
19033  *
19034  *  @param[in]  RgSchCellCb  *cell
19035  *  @param[in]  RgSchUlSf    *oldSf
19036  *  @param[in]  RgSchUlSf    *newSf
19037  *  @return  Void
19038  **/
19039 static Void rgSCHCmnUlSwapSfAllocs(RgSchCellCb *cell,RgSchUlSf  *oldSf,RgSchUlSf  *newSf)
19040 {
19041    RgSchUlAllocDb *tempAllocDb  = newSf->allocDb;
19042    RgSchUlHoleDb  *tempHoleDb   = newSf->holeDb;
19043    uint8_t        tempAvailSbs = newSf->availSubbands;
19044
19045    UNUSED(cell);
19046
19047    newSf->allocDb       = oldSf->allocDb;
19048    newSf->holeDb        = oldSf->holeDb;
19049    newSf->availSubbands = oldSf->availSubbands;
19050
19051    oldSf->allocDb = tempAllocDb;
19052    oldSf->holeDb  = tempHoleDb;
19053    oldSf->availSubbands = tempAvailSbs;
19054       
19055    /* Fix ccpu00120610*/
19056    newSf->allocCountRef = &newSf->allocDb->count;
19057    oldSf->allocCountRef = &oldSf->allocDb->count;
19058    return;
19059 }
19060 /**
19061  * @brief Perform non-adaptive RETX for non-colliding allocs.
19062  *
19063  * @details
19064  *
19065  *     Function : rgSCHCmnUlPrcNonAdptRetx
19066  *
19067  *      - Perform non-adaptive RETX for non-colliding allocs.
19068  *
19069  *  @param[in]  RgSchCellCb  *cell
19070  *  @param[in]  RgSchUlSf    *newSf
19071  *  @param[in]  uint8_t           idx
19072  *  @return  Void
19073  **/
19074 static Void rgSCHCmnUlPrcNonAdptRetx(RgSchCellCb *cell,RgSchUlSf  *newSf,uint8_t idx)
19075 {
19076    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19077    RgSchUlAlloc    *alloc, *nxtAlloc;
19078
19079    /* perform non-adaptive retx allocation(adjustment) */
19080    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
19081    {
19082       do
19083       {
19084          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
19085          /* A merged new TX alloc, reset the state and skip */
19086          if (alloc->mrgdNewTxAlloc)
19087          {
19088             alloc->mrgdNewTxAlloc = FALSE;
19089             continue;
19090          }
19091          
19092
19093          rgSCHCmnUlNonadapRetx(cellUl, alloc, idx);
19094
19095       } while((alloc = nxtAlloc) != NULLP);
19096    }
19097    return;
19098 }
19099
19100 /**
19101  * @brief Update TX and RETX subframe's allocation
19102  *        markings.
19103  *
19104  * @details
19105  *
19106  *     Function : rgSCHCmnUlPrfmSfMerge
19107  *
19108  *      - Release all preassigned allocations of newSf and merge
19109  *        them to oldSf.
19110  *      - If alloc of newSf collide with one or more allocs of oldSf
19111  *        - mark all such allocs of oldSf for Adaptive Retx.
19112  *      - Swap the alloc and hole DB references of oldSf and newSf.
19113  *      - The allocs which did not collide with pre-assigned msg3
19114  *        allocs are marked for non-adaptive RETX.
19115  *
19116  *  @param[in]  RgSchCellCb  *cell
19117  *  @param[in]  RgSchUlSf    *oldSf
19118  *  @param[in]  RgSchUlSf    *newSf
19119  *  @param[in]  uint8_t           idx 
19120  *  @return  Void
19121  **/
19122 static Void rgSCHCmnUlPrfmSfMerge
19123 (
19124 RgSchCellCb  *cell,
19125 RgSchUlSf    *oldSf,
19126 RgSchUlSf    *newSf,
19127 uint8_t      idx
19128 )
19129 {
19130    /* Preassigned resources for msg3 in newSf.
19131     * Hence do adaptive retx for all NACKED TXs */
19132    rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf);
19133    /* swap alloc and hole DBs of oldSf and newSf. */
19134    rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf);
19135    /* Here newSf has the resultant merged allocs context */
19136    /* Perform non-adaptive RETX for non-colliding allocs */
19137    rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx);
19138    
19139    return;
19140 }
19141 #endif
19142 /**
19143  * @brief Update TX and RETX subframe's allocation
19144  *        markings.
19145  *
19146  * @details
19147  *
19148  *     Function : rgSCHCmnUlRmvCmpltdAllocs
19149  *
19150  *      - Free all Transmission which are ACKED
19151  *        OR for which MAX retransmission have
19152  *        occurred.
19153  *
19154  *
19155  *  @param[in]  RgSchCellCb    *cell,
19156  *  @param[in]  RgSchUlSf      *sf
19157  *  @return  Void
19158  **/
19159 static Void rgSCHCmnUlRmvCmpltdAllocs(RgSchCellCb *cell,RgSchUlSf *sf)
19160 {
19161    RgSchUlAlloc    *alloc, *nxtAlloc;
19162
19163    if ((alloc = rgSCHUtlUlAllocFirst(sf)) == NULLP)
19164    {
19165       return;
19166    }
19167    do
19168    {
19169       nxtAlloc = rgSCHUtlUlAllocNxt(sf, alloc);
19170 #ifdef UL_ADPT_DBG      
19171       DU_LOG("\nDEBUG  -->  SCH : rgSCHCmnUlRmvCmpltdAllocs:time(%d %d) alloc->hqProc->remTx %d hqProcId(%d) \n",cell->crntTime.sfn,cell->crntTime.slot,alloc->hqProc->remTx, alloc->grnt.hqProcId);
19172 #endif
19173       alloc->hqProc->rcvdCrcInd = TRUE;
19174       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
19175       {
19176
19177         /* SR_RACH_STATS : MSG 3 MAX RETX FAIL*/
19178          if ((alloc->forMsg3 == TRUE) && (alloc->hqProc->remTx == 0))
19179          {
19180             rgNumMsg3FailMaxRetx++;
19181 #ifdef TENB_STATS
19182             cell->tenbStats->sch.msg3Fail++;
19183 #endif
19184          }
19185
19186 #ifdef MAC_SCH_STATS
19187     if(alloc->ue != NULLP)
19188     {
19189        /* access from ulHarqProc*/
19190        RgSchUeCb       *ueCb  = alloc->ue;
19191        RgSchCmnUe      *cmnUe = (RgSchCmnUe*)ueCb->sch;
19192        RgSchCmnUlUe    *ulUe  = &(cmnUe->ul);
19193        uint8_t              cqi    = ulUe->crntUlCqi[0];  
19194        uint16_t             numUlRetx = ueCb->ul.hqEnt.maxHqRetx - alloc->hqProc->remTx;
19195
19196        hqRetxStats.ulCqiStat[(cqi - 1)].mcs = alloc->grnt.iMcs;
19197
19198        switch (numUlRetx)
19199        {
19200           case 1:
19201              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1++;
19202              break;
19203           case 2:
19204              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2++;
19205              break;
19206          case 3:
19207             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3++;
19208             break;
19209          case 4:
19210             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4++;
19211             break;
19212       }
19213       hqRetxStats.ulCqiStat[(cqi - 1)].totalTx = \
19214              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1 + \
19215             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
19216             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
19217             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4 * 4);
19218    }
19219
19220 #endif /*MAC_SCH_STATS*/
19221          rgSCHCmnUlFreeAllocation(cell, sf, alloc);
19222       }
19223       /*ccpu00106104 MOD added check for AckNackRep */
19224       /*added check for acknack so that adaptive retx considers ue
19225        inactivity due to ack nack repetition*/
19226       else if((alloc->ue != NULLP) && (TRUE != alloc->forMsg3))
19227       {
19228         rgSCHCmnUlUpdAllocRetx(cell, alloc);
19229         rgSCHUtlUlAllocRls(sf, alloc);
19230       }
19231    } while ((alloc = nxtAlloc) != NULLP);
19232
19233    return;
19234 }
19235
19236 /**
19237  * @brief Update an uplink subframe.
19238  *
19239  * @details
19240  *
19241  *     Function : rgSCHCmnRlsUlSf
19242  *
19243  *     For each allocation
19244  *      - if no more tx needed
19245  *         - Release allocation
19246  *      - else
19247  *         - Perform retransmission
19248  *
19249  *  @param[in]  RgSchUlSf *sf
19250  *  @param[in]  uint8_t        idx 
19251  *  @return  Void
19252  **/
19253 Void rgSCHCmnRlsUlSf(RgSchCellCb *cell,uint8_t idx)
19254 {
19255
19256    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19257    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) 
19258    {
19259       RgSchUlSf   *oldSf  = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
19260
19261       /* Initialize the reTxLst of UL HqProcs for RETX subframe */
19262       if (rgSCHUtlUlAllocFirst(oldSf) == NULLP)
19263       {
19264          return;
19265       }
19266       /* Release all completed TX allocs from sf */
19267       rgSCHCmnUlRmvCmpltdAllocs(cell, oldSf);
19268
19269       oldSf->numACqiCount = 0;
19270    }
19271    return;
19272 }
19273
19274 /**
19275  * @brief Handle uplink allocation for retransmission.
19276  *
19277  * @details
19278  *
19279  *     Function : rgSCHCmnUlUpdAllocRetx
19280  *
19281  *     - Perform adaptive retransmission
19282  *
19283  *  @param[in]  RgSchUlSf *sf
19284  *  @param[in]  RgSchUlAlloc  *alloc
19285  *  @return  Void
19286  **/
19287 static Void rgSCHCmnUlUpdAllocRetx(RgSchCellCb *cell,RgSchUlAlloc *alloc)
19288 {
19289    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
19290
19291    alloc->hqProc->reTxAlloc.rnti    =  alloc->rnti;
19292    alloc->hqProc->reTxAlloc.numSb   =  alloc->numSb;
19293    alloc->hqProc->reTxAlloc.iMcs   =  alloc->grnt.iMcs;
19294 #ifdef RG_5GTF
19295    alloc->hqProc->reTxAlloc.dciFrmt =  alloc->grnt.dciFrmt;
19296    alloc->hqProc->reTxAlloc.numLyr   =  alloc->grnt.numLyr;
19297    alloc->hqProc->reTxAlloc.vrbgStart =  alloc->grnt.vrbgStart;
19298    alloc->hqProc->reTxAlloc.numVrbg   =  alloc->grnt.numVrbg;
19299    alloc->hqProc->reTxAlloc.modOdr   =  alloc->grnt.modOdr;
19300 #endif
19301    //iTbs = rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
19302    //iTbs = alloc->grnt.iMcs;
19303    //RGSCH_ARRAY_BOUND_CHECK( 0, rgTbSzTbl[0], iTbs);
19304    alloc->hqProc->reTxAlloc.tbSz = alloc->grnt.datSz;
19305       //rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1]/8;
19306    alloc->hqProc->reTxAlloc.ue      = alloc->ue;
19307    alloc->hqProc->reTxAlloc.forMsg3 = alloc->forMsg3;
19308    alloc->hqProc->reTxAlloc.raCb = alloc->raCb;
19309
19310    /* Set as retransmission is pending */
19311    alloc->hqProc->isRetx = TRUE;
19312    alloc->hqProc->alloc = NULLP;
19313    alloc->hqProc->ulSfIdx = RGSCH_INVALID_INFO;
19314 #ifdef UL_ADPT_DBG  
19315    DU_LOG("\nDEBUG  -->  SCH : Adding Harq Proc Id in the retx list  hqProcId %d \n",alloc->grnt.hqProcId); 
19316 #endif
19317    cmLListAdd2Tail(&cmnUlCell->reTxLst, &alloc->hqProc->reTxLnk);
19318    alloc->hqProc->reTxLnk.node = (PTR)alloc->hqProc;
19319    return;
19320 }
19321
19322 /**
19323  * @brief Attempts allocation for msg3s for which ADAP retransmissions
19324  *     are required.
19325  *
19326  * @details
19327  *
19328  *     Function : rgSCHCmnUlAdapRetxAlloc
19329  *
19330  *     Attempts allocation for msg3s for which ADAP retransmissions
19331  *     are required.
19332  *
19333  *  @param[in]  RgSchCellCb       *cell
19334  *  @param[in]  RgSchUlSf         *sf
19335  *  @param[in]  RgSchUlHqProcCb   *proc;
19336  *  @param[in]  RgSchUlHole       *hole;
19337  *  @return  uint8_t
19338  **/
19339 static Bool rgSCHCmnUlAdapRetxAlloc
19340 (
19341 RgSchCellCb       *cell,
19342 RgSchUlSf         *sf,
19343 RgSchUlHqProcCb   *proc,
19344 RgSchUlHole       *hole
19345 )
19346 {
19347    uint8_t         numSb = proc->reTxAlloc.numSb;
19348    uint8_t         iMcs  = proc->reTxAlloc.iMcs;
19349    CmLteTimingInfo frm = cell->crntTime;
19350    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19351    RgSchDlSf       *dlSf;
19352    RgSchPdcch      *pdcch;
19353    RgSchUlAlloc    *alloc;
19354
19355    /* Fetch PDCCH for msg3 */
19356    /* ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
19357    /* Introduced timing delta for UL control */
19358    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
19359    dlSf = rgSCHUtlSubFrmGet(cell, frm);
19360    pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
19361    if (pdcch == NULLP)
19362    {
19363       return (FALSE);
19364    }
19365
19366    /* Fetch UL Alloc for msg3 */
19367    if (numSb <= hole->num)
19368    {
19369       alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
19370       
19371       /* KWork fix */
19372          if(alloc == NULLP)
19373          {
19374             rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
19375             DU_LOG("\nERROR  -->  SCH : UL Alloc fail for msg3 retx for rnti: %d\n", 
19376                   proc->reTxAlloc.rnti);
19377             return (FALSE);
19378          }
19379
19380       rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
19381       alloc->grnt.iMcs     = iMcs;
19382       alloc->grnt.datSz    = proc->reTxAlloc.tbSz;
19383 #ifdef RG_5GTF
19384 #else
19385       //RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
19386 #endif
19387       /* Fill UL Alloc for msg3 */
19388       /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
19389       alloc->grnt.nDmrs    = 0;
19390       alloc->grnt.hop      = 0;
19391       alloc->grnt.delayBit = 0;
19392       alloc->grnt.isRtx    = TRUE;
19393       proc->ulSfIdx        = cellUl->schdIdx;
19394 #ifdef RG_5GTF
19395       proc->schdTime = cellUl->schdTime;
19396       alloc->grnt.hqProcId = proc->procId;
19397       alloc->grnt.dciFrmt = proc->reTxAlloc.dciFrmt;
19398       alloc->grnt.numLyr = proc->reTxAlloc.numLyr;
19399       alloc->grnt.vrbgStart = proc->reTxAlloc.vrbgStart;
19400       alloc->grnt.numVrbg = proc->reTxAlloc.numVrbg;
19401       alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
19402       alloc->grnt.modOdr = proc->reTxAlloc.modOdr;
19403
19404       /* TODO : Hardcoding these as of now */
19405       alloc->grnt.hop = 0;
19406       alloc->grnt.SCID = 0;
19407       alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
19408       alloc->grnt.PMI = 0;
19409       alloc->grnt.uciOnxPUSCH = 0;
19410 #endif
19411       alloc->rnti          = proc->reTxAlloc.rnti;
19412       /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
19413       alloc->ue            = proc->reTxAlloc.ue;
19414       alloc->pdcch         = pdcch;
19415       alloc->forMsg3       = proc->reTxAlloc.forMsg3;
19416       alloc->raCb          = proc->reTxAlloc.raCb;
19417       alloc->hqProc        = proc;
19418       alloc->isAdaptive    = TRUE;
19419 #ifdef LTE_L2_MEAS
19420       sf->totPrb  += alloc->grnt.numRb;
19421 #endif
19422       /* FIX : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
19423       if (alloc->raCb)
19424       {
19425          alloc->raCb->msg3Grnt= alloc->grnt;
19426 #ifndef LTE_TDD
19427          /* To the crntTime, add the time at which UE will
19428           * actually send MSG3 */
19429          alloc->raCb->msg3AllocTime = cell->crntTime;
19430          RGSCH_INCR_SUB_FRAME(alloc->raCb->msg3AllocTime, RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL);
19431 #else
19432          alloc->raCb->msg3AllocTime =  cellUl->schdTime;
19433 #endif
19434          rgSCHCmnUlAdapRetx(alloc, proc);
19435          /* Fill PDCCH with alloc info */
19436          pdcch->rnti                           = alloc->rnti;
19437          pdcch->dci.dciFormat                  = TFU_DCI_FORMAT_0;
19438          pdcch->dci.u.format0Info.hoppingEnbld = alloc->grnt.hop;
19439          pdcch->dci.u.format0Info.rbStart      = alloc->grnt.rbStart;
19440          pdcch->dci.u.format0Info.numRb        = alloc->grnt.numRb;
19441          pdcch->dci.u.format0Info.mcs          = alloc->grnt.iMcsCrnt;
19442          pdcch->dci.u.format0Info.ndi          = alloc->hqProc->ndi;
19443          pdcch->dci.u.format0Info.nDmrs        = alloc->grnt.nDmrs;
19444          pdcch->dci.u.format0Info.tpcCmd       = alloc->grnt.tpc;
19445
19446 #ifdef LTE_TDD
19447 #ifdef TFU_TDD
19448          /* ulIdx setting for cfg 0 shall be appropriately fixed thru ccpu00109015 */
19449          pdcch->dci.u.format0Info.ulIdx = RG_SCH_ULIDX_MSB;
19450          pdcch->dci.u.format0Info.dai = RG_SCH_MAX_DAI_IDX;
19451 #endif
19452 #endif
19453          pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_0];
19454       }
19455       else
19456       {
19457          RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(alloc->ue,cell);
19458 #ifdef TFU_UPGRADE
19459          alloc->ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
19460 #endif
19461 #ifdef LTE_L2_MEAS
19462          ue->ul.nPrb = alloc->grnt.numRb;
19463 #endif
19464          ueUl->alloc.alloc = alloc;
19465          /* FIx: Removed the call to rgSCHCmnUlAdapRetx */
19466          rgSCHCmnUlUeFillAllocInfo(cell, alloc->ue);
19467          /* Setting csireq as false for Adaptive Retx*/
19468          ueUl->alloc.alloc->pdcch->dci.u.format0Info.cqiReq = RG_SCH_APCQI_NO;
19469          pdcch->dciNumOfBits = alloc->ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
19470       }
19471       /* Reset as retransmission is done */
19472       proc->isRetx = FALSE;
19473    }
19474    else /* Intg fix */
19475    {
19476       rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
19477       DU_LOG("\nERROR  -->  SCH : Num SB not suffiecient for adap retx for rnti: %d", 
19478                proc->reTxAlloc.rnti);
19479       return (FALSE);
19480    }
19481    return (TRUE);
19482 }
19483
19484 /* Fix: syed Adaptive Msg3 Retx crash. */
19485 /**
19486  * @brief Releases all Adaptive Retx HqProcs which failed for
19487  *        allocations in this scheduling occassion.
19488  *
19489  * @details
19490  *
19491  *     Function : rgSCHCmnUlSfRlsRetxProcs
19492  *
19493  *
19494  *  @param[in]  RgSchCellCb *cell
19495  *  @param[in]  RgSchUlSf   *sf
19496  *  @return  uint8_t
19497  **/
19498 #ifdef UNUSED_FUNC
19499 static Void rgSCHCmnUlSfRlsRetxProcs(RgSchCellCb *cell,RgSchUlSf *sf)
19500 {
19501    CmLListCp         *cp;
19502    CmLList           *node;
19503    RgSchUlHqProcCb   *proc;
19504    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19505
19506    cp = &(cellUl->reTxLst);
19507    node = cp->first;
19508    while (node)
19509    {
19510       proc  = (RgSchUlHqProcCb *)node->node;
19511       node = node->next;
19512       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
19513       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
19514       proc->reTxLnk.node = (PTR)NULLP;
19515    }
19516    return;
19517 }
19518 #endif   
19519
19520 /**
19521  * @brief Attempts allocation for UEs for which retransmissions
19522  *     are required.
19523  *
19524  * @details
19525  *
19526  *     Function : rgSCHCmnUlSfReTxAllocs
19527  *
19528  *     Attempts allocation for UEs for which retransmissions
19529  *     are required.
19530  *
19531  *  @param[in]  RgSchCellCb *cell
19532  *  @param[in]  RgSchUlSf   *sf
19533  *  @return  uint8_t
19534  **/
19535 static Void rgSCHCmnUlSfReTxAllocs(RgSchCellCb *cell,RgSchUlSf  *sf)
19536 {
19537    CmLListCp         *cp;
19538    CmLList           *node;
19539    RgSchUlHqProcCb   *proc;
19540    RgSchUlHole       *hole;
19541    RgSchUeCb         *ue;
19542    RgSchCmnCell      *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
19543    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19544
19545    cp = &(cellUl->reTxLst);
19546    node = cp->first;
19547    while ((node))
19548    {
19549       proc  = (RgSchUlHqProcCb *)node->node;
19550       ue = proc->reTxAlloc.ue;
19551       node = node->next;
19552       /*ccpu00106104 MOD added check for AckNackRep */
19553       /*added check for acknack so that adaptive retx considers ue
19554        inactivity due to ack nack repetition*/
19555       if((ue != NULLP) &&
19556             ((ue->measGapCb.isMeasuring == TRUE)||
19557                (ue->ackNakRepCb.isAckNakRep == TRUE)))
19558       {
19559          continue;
19560       }
19561       /* Fix for ccpu00123917: Check if maximum allocs per UL sf have been exhausted */
19562       if (((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
19563             || (sf->allocDb->count == schCmnCell->ul.maxAllocPerUlSf))
19564       {
19565          /* No more UL BW then return */
19566          break;
19567       }
19568       /* perform adaptive retx for UE's */
19569       if (rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) == FALSE)
19570       {
19571          continue;
19572       }
19573       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
19574       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
19575       /* Fix: syed Adaptive Msg3 Retx crash. */
19576       proc->reTxLnk.node = (PTR)NULLP;
19577    }
19578    return;
19579 }
19580
19581 /**
19582  * @brief Handles RB allocation for downlink.
19583  *
19584  * @details
19585  *
19586  *     Function : rgSCHCmnDlRbAlloc
19587  *
19588  *     Invoking Module Processing:
19589  *     - This function is invoked for DL RB allocation
19590  *
19591  *     Processing Steps:
19592  *     - If cell is frequency selecive,
19593  *       - Call rgSCHDlfsAllocRb().
19594  *     - else,
19595  *       - Call rgSCHCmnNonDlfsRbAlloc().
19596  *
19597  *  @param[in]  RgSchCellCb        *cell
19598  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
19599  *  @return  Void
19600  **/
19601
19602 static Void rgSCHCmnDlRbAlloc(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
19603 {
19604    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
19605
19606    if (cellSch->dl.isDlFreqSel)
19607    {
19608       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR DLFS SCH Enabled\n");
19609       cellSch->apisDlfs->rgSCHDlfsAllocRb(cell, allocInfo);
19610    }
19611    else
19612    {
19613       rgSCHCmnNonDlfsRbAlloc(cell, allocInfo);
19614    }
19615    return;
19616 }
19617
19618 #ifdef LTEMAC_SPS
19619
19620 /**
19621  * @brief Determines number of RBGs and RBG subset sizes for the given DL
19622  * bandwidth and rbgSize
19623  *
19624  * @details
19625  *     Function : rgSCHCmnDlGetRbgInfo
19626  *
19627  *
19628  *     Processing Steps:
19629  *     - Fill-up rbgInfo data structure for given DL bandwidth and rbgSize
19630  *
19631  *   @param[in]  uint8_t             dlTotalBw
19632  *   @param[in]  uint8_t             dlSubsetBw
19633  *   @param[in]  uint8_t             maxRaType1SubsetBw
19634  *   @param[in]  uint8_t             rbgSize
19635  *   @param[out] RgSchBwRbgInfo *rbgInfo
19636  *  @return Void
19637  **/
19638 Void rgSCHCmnDlGetRbgInfo
19639 (
19640 uint8_t        dlTotalBw,
19641 uint8_t        dlSubsetBw,
19642 uint8_t        maxRaType1SubsetBw,
19643 uint8_t        rbgSize,
19644 RgSchBwRbgInfo *rbgInfo
19645 )
19646 {
19647 #ifdef RGSCH_SPS_UNUSED
19648    uint8_t    idx           = 0;
19649    uint8_t    lastRbgIdx    = ((dlTotalBw + rbgSize - 1)/rbgSize) - 1;
19650    uint8_t    currRbgSize   = rbgSize;
19651    uint8_t    subsetSizeIdx = 0;
19652    uint8_t    subsetSize[RG_SCH_NUM_RATYPE1_SUBSETS] = {0};
19653    uint8_t    lastRbgSize = rbgSize - (dlTotalBw - ((dlTotalBw/rbgSize) * rbgSize));
19654    uint8_t    numRaType1Rbgs = (maxRaType1SubsetBw + rbgSize - 1)/rbgSize;
19655 #endif
19656
19657    /* Compute maximum number of SPS RBGs for the cell */
19658    rbgInfo->numRbgs =  ((dlSubsetBw + rbgSize - 1)/rbgSize);
19659
19660 #ifdef RGSCH_SPS_UNUSED
19661    /* Distribute RBGs across subsets except last RBG */
19662    for (;idx < numRaType1Rbgs - 1; ++idx)
19663    {
19664       subsetSize[subsetSizeIdx] += currRbgSize;
19665       subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
19666    }
19667
19668    /* Computation for last RBG */
19669    if (idx == lastRbgIdx)
19670    {
19671       currRbgSize = lastRbgSize;
19672    }
19673    subsetSize[subsetSizeIdx] += currRbgSize;
19674    subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
19675 #endif
19676
19677    /* Update the computed sizes */
19678 #ifdef RGSCH_SPS_UNUSED
19679    rbgInfo->lastRbgSize = currRbgSize;
19680 #endif
19681    rbgInfo->lastRbgSize = rbgSize - 
19682             (dlSubsetBw - ((dlSubsetBw/rbgSize) * rbgSize));
19683 #ifdef RGSCH_SPS_UNUSED
19684    memcpy(rbgInfo->rbgSubsetSize, subsetSize, 4 * sizeof(uint8_t));
19685 #endif
19686    rbgInfo->numRbs = (rbgInfo->numRbgs * rbgSize > dlTotalBw) ?
19687       dlTotalBw:(rbgInfo->numRbgs * rbgSize);
19688    rbgInfo->rbgSize = rbgSize;
19689 }
19690
19691 /**
19692  * @brief Handles RB allocation for Resource allocation type 0
19693  *
19694  * @details
19695  *
19696  *     Function : rgSCHCmnDlRaType0Alloc
19697  *
19698  *     Invoking Module Processing:
19699  *     - This function is invoked for DL RB allocation for resource allocation
19700  *     type 0
19701  *
19702  *     Processing Steps:
19703  *     - Determine the available positions in the rbgMask.
19704  *     - Allocate RBGs in the available positions.
19705  *     - Update RA Type 0, RA Type 1 and RA type 2 masks.
19706  *
19707  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
19708  *  @param[in]   uint8_t             rbsReq
19709  *  @param[in]   RgSchBwRbgInfo *rbgInfo
19710  *  @param[out]  uint8_t             *numAllocRbs
19711  *  @param[out]  RgSchDlSfAllocInfo *resAllocInfo
19712  *  @param[in]   Bool           isPartialAlloc
19713  *
19714  *  @return  Void
19715  **/
19716
19717 uint8_t rgSCHCmnDlRaType0Alloc
19718 (
19719 RgSchDlSfAllocInfo *allocedInfo,
19720 uint8_t            rbsReq,
19721 RgSchBwRbgInfo     *rbgInfo,
19722 uint8_t            *numAllocRbs,
19723 RgSchDlSfAllocInfo *resAllocInfo,
19724 Bool               isPartialAlloc
19725 )
19726 {
19727    /* Note: This function atttempts allocation only full allocation */
19728    uint32_t      remNumRbs, rbgPosInRbgMask, ueRaType2Mask;
19729    uint8_t       type2MaskIdx, cnt, rbIdx;
19730    uint8_t       maskSize, rbg;
19731    uint8_t       bestNumAvailRbs = 0;
19732    uint8_t       usedRbs = 0;
19733    uint8_t       numAllocRbgs = 0;
19734    uint8_t       rbgSize = rbgInfo->rbgSize;
19735    uint32_t      *rbgMask = &(resAllocInfo->raType0Mask);
19736 #ifdef RGSCH_SPS_UNUSED
19737    uint8_t       rbgSubset;
19738    uint32_t      ueRaType1Mask;
19739    uint32_t      *raType1Mask = resAllocInfo->raType1Mask;
19740    uint32_t      *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
19741 #endif
19742    uint32_t      *raType2Mask = resAllocInfo->raType2Mask;
19743
19744    uint32_t      allocedMask = allocedInfo->raType0Mask;
19745
19746    maskSize = rbgInfo->numRbgs;
19747
19748    *numAllocRbs = 0;
19749    RG_SCH_CMN_DL_COUNT_ONES(allocedMask, maskSize, &usedRbs);
19750    if (maskSize == usedRbs)
19751    {
19752       /* All RBGs are allocated, including the last one */
19753       remNumRbs = 0;
19754    }
19755    else
19756    {
19757       remNumRbs = (maskSize - usedRbs - 1) * rbgSize; /* vamsee: removed minus 1 */
19758
19759       /* If last RBG is available, add last RBG size */
19760       if (!(allocedMask & (1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(maskSize - 1))))
19761       {
19762          remNumRbs += rbgInfo->lastRbgSize;
19763       }
19764    }
19765
19766    /* If complete allocation is needed, check if total requested RBs are available else
19767     * check the best available RBs */
19768    if (!isPartialAlloc)
19769    {
19770       if (remNumRbs >= rbsReq)
19771       {
19772          bestNumAvailRbs = rbsReq;
19773       }
19774    }
19775    else
19776    {
19777       bestNumAvailRbs = remNumRbs > rbsReq ? rbsReq : remNumRbs;
19778    }
19779
19780    /* Allocate for bestNumAvailRbs */
19781    if (bestNumAvailRbs)
19782    {
19783       for (rbg = 0; rbg < maskSize - 1; ++rbg)
19784       {
19785          rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
19786          if (!(allocedMask & rbgPosInRbgMask))
19787          {
19788             /* Update RBG mask */
19789             *rbgMask |= rbgPosInRbgMask;
19790
19791             /* Compute RB index of the first RB of the RBG allocated */
19792             rbIdx = rbg * rbgSize;
19793
19794             for (cnt = 0; cnt < rbgSize; ++cnt)
19795             {
19796 #ifdef RGSCH_SPS_UNUSED
19797                ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
19798 #endif
19799                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19800 #ifdef RGSCH_SPS_UNUSED
19801                /* Update RBG mask for RA type 1 */
19802                raType1Mask[rbgSubset] |= ueRaType1Mask;
19803                raType1UsedRbs[rbgSubset]++;
19804 #endif
19805                /* Update RA type 2 mask */
19806                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19807                rbIdx++;
19808             }
19809             *numAllocRbs += rbgSize;
19810             remNumRbs -= rbgSize;
19811             ++numAllocRbgs;
19812             if (*numAllocRbs >= bestNumAvailRbs)
19813             {
19814                break;
19815             }
19816          }
19817       }
19818       /* If last RBG available and allocation is not completed, allocate
19819        * last RBG */
19820       if (*numAllocRbs < bestNumAvailRbs)
19821       {
19822          rbgPosInRbgMask =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
19823          *rbgMask |= rbgPosInRbgMask;
19824          *numAllocRbs += rbgInfo->lastRbgSize;
19825
19826          /* Compute RB index of the first RB of the last RBG */
19827          rbIdx = ((rbgInfo->numRbgs - 1 ) * rbgSize ); /* removed minus 1  vamsee */
19828
19829          for (cnt = 0; cnt < rbgInfo->lastRbgSize; ++cnt)
19830          {
19831 #ifdef RGSCH_SPS_UNUSED
19832             ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
19833 #endif
19834             ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19835 #ifdef RGSCH_SPS_UNUSED
19836             /* Update RBG mask for RA type 1 */
19837             raType1Mask[rbgSubset] |=  ueRaType1Mask;
19838             raType1UsedRbs[rbgSubset]++;
19839 #endif
19840             /* Update RA type 2 mask */
19841             raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19842             rbIdx++;
19843          }
19844          remNumRbs -= rbgInfo->lastRbgSize;
19845          ++numAllocRbgs;
19846       }
19847       /* Note: this should complete allocation, not checking for the
19848        * same */
19849    }
19850
19851    return (numAllocRbgs);
19852 }
19853
19854 #ifdef RGSCH_SPS_UNUSED
19855 /**
19856  * @brief Handles RB allocation for Resource allocation type 1
19857  *
19858  * @details
19859  *
19860  *     Function : rgSCHCmnDlRaType1Alloc
19861  *
19862  *     Invoking Module Processing:
19863  *     - This function is invoked for DL RB allocation for resource allocation
19864  *     type 1
19865  *
19866  *     Processing Steps:
19867  *     - Determine the available positions in the subsets.
19868  *     - Allocate RB in the available subset.
19869  *     - Update RA Type1, RA type 0 and RA type 2 masks.
19870  *
19871  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
19872  *  @param[in]   uint8_t                 rbsReq
19873  *  @param[in]   RgSchBwRbgInfo     *rbgInfo
19874  *  @param[in]   uint8_t                 startRbgSubset
19875  *  @param[in]   uint8_t                 *allocRbgSubset
19876  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
19877  *  @param[in]   Bool               isPartialAlloc
19878  *
19879  *  @return  uint8_t
19880  *  Number of allocated RBs
19881  **/
19882
19883 uint8_t rgSCHCmnDlRaType1Alloc
19884 (
19885 RgSchDlSfAllocInfo *allocedInfo,
19886 uint8_t            rbsReq,
19887 RgSchBwRbgInfo     *rbgInfo,
19888 uint8_t            startRbgSubset,
19889 uint8_t            *allocRbgSubset,
19890 RgSchDlSfAllocInfo *resAllocInfo,
19891 Bool               isPartialAlloc
19892 )
19893 {
19894    /* Note: This function atttempts only full allocation */
19895    uint8_t   *rbgSubsetSzArr;
19896    uint8_t   type2MaskIdx, subsetIdx, rbIdx, rbInSubset, rbgInSubset;
19897    uint8_t   offset, rbg, maskSize, bestSubsetIdx;
19898    uint8_t   startPos = 0;
19899    uint8_t   bestNumAvailRbs = 0;
19900    uint8_t   numAllocRbs = 0;
19901    uint32_t  ueRaType2Mask, ueRaType0Mask, rbPosInSubset;
19902    uint32_t  remNumRbs, allocedMask;
19903    uint8_t   usedRbs = 0;
19904    uint8_t   rbgSize = rbgInfo->rbgSize;
19905    uint8_t   rbgSubset = startRbgSubset;
19906    uint32_t  *rbgMask = &resAllocInfo->raType0Mask;
19907    uint32_t  *raType1Mask = resAllocInfo->raType1Mask;
19908    uint32_t  *raType2Mask = resAllocInfo->raType2Mask;
19909    uint32_t  *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
19910    uint32_t  *allocMask = allocedInfo->raType1Mask;
19911
19912    /* Initialize the subset size Array */
19913    rbgSubsetSzArr = rbgInfo->rbgSubsetSize;
19914
19915    /* Perform allocation for RA type 1 */
19916    for (subsetIdx = 0;subsetIdx < rbgSize; ++subsetIdx)
19917    {
19918       allocedMask = allocMask[rbgSubset];
19919       maskSize = rbgSubsetSzArr[rbgSubset];
19920
19921       /* Determine number of available RBs in the subset */
19922       usedRbs = allocedInfo->raType1UsedRbs[subsetIdx];
19923       remNumRbs = maskSize - usedRbs;
19924
19925       if (remNumRbs >= rbsReq)
19926       {
19927          bestNumAvailRbs = rbsReq;
19928          bestSubsetIdx = rbgSubset;
19929          break;
19930       }
19931       else if (isPartialAlloc && (remNumRbs > bestNumAvailRbs))
19932       {
19933          bestNumAvailRbs = remNumRbs;
19934          bestSubsetIdx = rbgSubset;
19935       }
19936
19937       rbgSubset = (rbgSubset + 1) % rbgSize;
19938    } /* End of for (each rbgsubset) */
19939
19940    if (bestNumAvailRbs)
19941    {
19942       /* Initialize alloced mask and subsetSize depending on the RBG
19943        * subset of allocation */
19944       uint8_t        startIdx = 0;
19945       maskSize = rbgSubsetSzArr[bestSubsetIdx];
19946       allocedMask = allocMask[bestSubsetIdx];
19947       RG_SCH_CMN_DL_GET_START_POS(allocedMask, maskSize,
19948             &startPos);
19949       for (; startIdx < rbgSize; ++startIdx, ++startPos)
19950       {
19951          for (rbInSubset = startPos; rbInSubset < maskSize;
19952                rbInSubset = rbInSubset + rbgSize)
19953          {
19954             rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
19955             if (!(allocedMask & rbPosInSubset))
19956             {
19957                raType1Mask[bestSubsetIdx] |= rbPosInSubset;
19958                raType1UsedRbs[bestSubsetIdx]++;
19959
19960                /* Compute RB index value for the RB being allocated */
19961                rbgInSubset = rbInSubset /rbgSize;
19962                offset = rbInSubset % rbgSize;
19963                rbg = (rbgInSubset * rbgSize) + bestSubsetIdx;
19964                rbIdx = (rbg * rbgSize) + offset;
19965
19966                /* Update RBG mask for RA type 0 allocation */
19967                ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
19968                *rbgMask |= ueRaType0Mask;
19969
19970                /* Update RA type 2 mask */
19971                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19972                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19973
19974                /* Update the counters */
19975                numAllocRbs++;
19976                remNumRbs--;
19977                if (numAllocRbs == bestNumAvailRbs)
19978                {
19979                   break;
19980                }
19981             }
19982          } /* End of for (each position in the subset mask) */
19983          if (numAllocRbs == bestNumAvailRbs)
19984          {
19985             break;
19986          }
19987       } /* End of for startIdx = 0 to rbgSize */
19988
19989       *allocRbgSubset = bestSubsetIdx;
19990    } /* End of if (bestNumAvailRbs) */
19991
19992    return (numAllocRbs);
19993 }
19994 #endif
19995 /**
19996  * @brief Handles RB allocation for Resource allocation type 2
19997  *
19998  * @details
19999  *
20000  *     Function : rgSCHCmnDlRaType2Alloc
20001  *
20002  *     Invoking Module Processing:
20003  *     - This function is invoked for DL RB allocation for resource allocation
20004  *     type 2
20005  *
20006  *     Processing Steps:
20007  *     - Determine the available positions in the mask
20008  *     - Allocate best fit cosecutive RBs.
20009  *     - Update RA Type2, RA type 1 and RA type 0 masks.
20010  *
20011  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
20012  *  @param[in]   uint8_t             rbsReq
20013  *  @param[in]   RgSchBwRbgInfo *rbgInfo
20014  *  @param[out]  uint8_t             *rbStart
20015  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
20016  *  @param[in]   Bool           isPartialAlloc
20017  *
20018  *  @return  uint8_t
20019  *  Number of allocated RBs
20020  **/
20021
20022 uint8_t rgSCHCmnDlRaType2Alloc
20023 (
20024 RgSchDlSfAllocInfo *allocedInfo,
20025 uint8_t            rbsReq,
20026 RgSchBwRbgInfo     *rbgInfo,
20027 uint8_t            *rbStart,
20028 RgSchDlSfAllocInfo *resAllocInfo,
20029 Bool               isPartialAlloc
20030 )
20031 {
20032    uint8_t    numAllocRbs = 0;
20033    uint8_t    rbIdx;
20034    uint8_t    rbgSize = rbgInfo->rbgSize;
20035    uint32_t   *rbgMask = &resAllocInfo->raType0Mask;
20036 #ifdef RGSCH_SPS_UNUSED
20037    uint32_t   *raType1Mask = resAllocInfo->raType1Mask;
20038 #endif
20039    uint32_t   *raType2Mask = resAllocInfo->raType2Mask;
20040 #ifdef RGSCH_SPS_UNUSED
20041    uint32_t   *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
20042 #endif
20043    uint32_t   *allocedMask = allocedInfo->raType2Mask;
20044
20045    /* Note: This function atttempts only full allocation */
20046    rgSCHCmnDlGetBestFitHole(allocedMask, rbgInfo->numRbs,
20047          raType2Mask, rbsReq, rbStart, &numAllocRbs, isPartialAlloc);
20048    if (numAllocRbs)
20049    {
20050       /* Update the allocation in RA type 0 and RA type 1 masks */
20051       uint8_t rbCnt = numAllocRbs;
20052 #ifdef RGSCH_SPS_UNUSED
20053       uint8_t rbgSubset;
20054       uint32_t ueRaType1Mask;
20055 #endif
20056       uint32_t ueRaType0Mask;
20057       rbIdx = *rbStart;
20058
20059       while(rbCnt)
20060       {
20061          /* Update RBG mask for RA type 0 allocation */
20062          ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
20063          *rbgMask |= ueRaType0Mask;
20064
20065 #ifdef RGSCH_SPS_UNUSED
20066          /* Update RBG mask for RA type 1 */
20067          ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
20068          raType1Mask[rbgSubset] |= ueRaType1Mask;
20069          raType1UsedRbs[rbgSubset]++;
20070 #endif
20071          /* Update the counters */
20072          --rbCnt;
20073          rbIdx++;
20074       }
20075    }
20076
20077    return (numAllocRbs);
20078 }
20079
20080 /**
20081  * @brief Determines RA type 0 mask from given RB index.
20082  *
20083  * @details
20084  *
20085  *     Function : rgSCHCmnGetRaType0Mask
20086  *
20087  *
20088  *     Processing Steps:
20089  *     - Determine RA Type 0 mask for given rbIdex and rbg size.
20090  *
20091  *  @param[in]  uint8_t          rbIdx
20092  *  @param[in]  uint8_t          rbgSize
20093  *  @return  uint32_t RA type 0 mask
20094  **/
20095 static uint32_t rgSCHCmnGetRaType0Mask(uint8_t rbIdx,uint8_t rbgSize)
20096 {
20097    uint8_t rbg;
20098    uint32_t rbgPosInRbgMask = 0;
20099
20100    rbg = rbIdx/rbgSize;
20101    rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
20102
20103    return (rbgPosInRbgMask);
20104 }
20105
20106 #ifdef RGSCH_SPS_UNUSED
20107 /**
20108  * @brief Determines RA type 1 mask from given RB index.
20109  *
20110  * @details
20111  *
20112  *     Function : rgSCHCmnGetRaType1Mask
20113  *
20114  *
20115  *     Processing Steps:
20116  *     - Determine RA Type 1 mask for given rbIdex and rbg size.
20117  *
20118  *  @param[in]  uint8_t          rbIdx
20119  *  @param[in]  uint8_t          rbgSize
20120  *  @param[out] uint8_t          *type1Subset
20121  *  @return  uint32_t RA type 1 mask
20122  **/
20123 static uint32_t rgSCHCmnGetRaType1Mask(uint8_t  rbIdx,uint8_t  rbgSize,uint8_t  *type1Subset)
20124 {
20125    uint8_t rbg, rbgSubset, rbgInSubset, offset, rbInSubset;
20126    uint32_t rbPosInSubset;
20127
20128    rbg = rbIdx/rbgSize;
20129    rbgSubset = rbg % rbgSize;
20130    rbgInSubset = rbg/rbgSize;
20131    offset = rbIdx % rbgSize;
20132    rbInSubset = rbgInSubset * rbgSize + offset;
20133    rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
20134
20135    *type1Subset = rbgSubset;
20136    return (rbPosInSubset);
20137
20138 #endif /* RGSCH_SPS_UNUSED */
20139 /**
20140  * @brief Determines RA type 2 mask from given RB index.
20141  *
20142  * @details
20143  *
20144  *     Function : rgSCHCmnGetRaType2Mask
20145  *
20146  *
20147  *     Processing Steps:
20148  *     - Determine RA Type 2 mask for given rbIdx and rbg size.
20149  *
20150  *  @param[in]  uint8_t          rbIdx
20151  *  @param[out] uint8_t          *maskIdx
20152  *  @return  uint32_t RA type 2 mask
20153  **/
20154 static uint32_t rgSCHCmnGetRaType2Mask(uint8_t rbIdx,uint8_t *maskIdx)
20155 {
20156    uint32_t rbPosInType2;
20157
20158    *maskIdx = rbIdx / 32;
20159    rbPosInType2 =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbIdx % 32);
20160
20161    return (rbPosInType2);
20162 }
20163
20164 /**
20165  * @brief Performs resource allocation for a non-SPS UE in SPS bandwidth
20166  *
20167  * @details
20168  *
20169  *     Function : rgSCHCmnAllocUeInSpsBw
20170  *
20171  *
20172  *     Processing Steps:
20173  *       - Determine allocation for the UE.
20174  *       - Use resource allocation type 0, 1 and 2 for allocation
20175  *         within maximum SPS bandwidth.
20176  *
20177  *  @param[in]  RgSchDlSf       *dlSf
20178  *  @param[in]  RgSchCellCb     *cell
20179  *  @param[in]  RgSchUeCb       *ue
20180  *  @param[in]  RgSchDlRbAlloc  *rbAllocInfo
20181  *  @param[in]  Bool            isPartialAlloc
20182  *  @return  Bool
20183  *             ROK      success
20184  *             RFAILED  failed
20185  **/
20186 Bool rgSCHCmnAllocUeInSpsBw
20187 (
20188 RgSchDlSf           *dlSf,
20189 RgSchCellCb         *cell,
20190 RgSchUeCb           *ue,
20191 RgSchDlRbAlloc      *rbAllocInfo,
20192 Bool                isPartialAlloc
20193 )
20194 {
20195    uint8_t            rbgSize = cell->rbgSize;
20196    uint8_t            numAllocRbs = 0;
20197    uint8_t            numAllocRbgs = 0;
20198    uint8_t            rbStart = 0;
20199    uint8_t            idx, noLyr, iTbs;
20200    RgSchCmnDlUe       *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
20201    RgSchDlSfAllocInfo *dlSfAlloc = &rbAllocInfo->dlSf->dlSfAllocInfo;
20202    RgSchBwRbgInfo     *spsRbgInfo = &cell->spsBwRbgInfo;
20203
20204    /* SPS_FIX : Check if this Hq proc is scheduled */
20205    if ((0 == rbAllocInfo->tbInfo[0].schdlngForTb) &&
20206          (0 == rbAllocInfo->tbInfo[1].schdlngForTb))
20207    {
20208       return (TRUE);
20209    }
20210
20211    /* Check if the requirement can be accomodated in SPS BW */
20212    if (dlSf->spsAllocdBw == spsRbgInfo->numRbs)
20213    {
20214       /* SPS Bandwidth has been exhausted: no further allocations possible */
20215       return (FALSE);
20216    }
20217    if (!isPartialAlloc)
20218    {
20219       if((dlSf->spsAllocdBw + rbAllocInfo->rbsReq) > spsRbgInfo->numRbs)
20220       {
20221          return (TRUE);
20222       }
20223    }
20224
20225    /* Perform allocation for RA type 0 if rbsReq is multiple of RBG size (also
20226     * if RBG size = 1) */
20227    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20228    {
20229       rbAllocInfo->rbsReq += (rbgSize - rbAllocInfo->rbsReq % rbgSize);
20230       numAllocRbgs = rgSCHCmnDlRaType0Alloc(dlSfAlloc,
20231             rbAllocInfo->rbsReq, spsRbgInfo, &numAllocRbs,
20232             &rbAllocInfo->resAllocInfo, isPartialAlloc);
20233    }
20234 #ifdef RGSCH_SPS_UNUSED
20235    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
20236    {
20237       /* If no RBS could be allocated, attempt RA TYPE 1 */
20238
20239       numAllocRbs = rgSCHCmnDlRaType1Alloc(dlSfAlloc,
20240             rbAllocInfo->rbsReq, spsRbgInfo, (uint8_t)dlSfAlloc->nxtRbgSubset,
20241             &rbAllocInfo->allocInfo.raType1.rbgSubset,
20242             &rbAllocInfo->resAllocInfo, isPartialAlloc);
20243
20244       if(numAllocRbs)
20245       {
20246          dlSfAlloc->nxtRbgSubset =
20247             (rbAllocInfo->allocInfo.raType1.rbgSubset + 1 ) % rbgSize;
20248       }
20249    }
20250 #endif
20251    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20252    {
20253       numAllocRbs = rgSCHCmnDlRaType2Alloc(dlSfAlloc,
20254             rbAllocInfo->rbsReq, spsRbgInfo,
20255             &rbStart, &rbAllocInfo->resAllocInfo, isPartialAlloc);
20256    }
20257    if (!numAllocRbs)
20258    {
20259       return (TRUE);
20260    }
20261
20262    if (!(rbAllocInfo->pdcch =
20263             rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi,\
20264                rbAllocInfo->dciFormat, FALSE)))
20265    {
20266       /* Note: Returning TRUE since PDCCH might be available for another UE */
20267       return (TRUE);
20268    }
20269
20270    /* Update Tb info for each scheduled TB */
20271    iTbs = rbAllocInfo->tbInfo[0].iTbs;
20272    noLyr = rbAllocInfo->tbInfo[0].noLyr;
20273    rbAllocInfo->tbInfo[0].bytesAlloc =
20274       rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
20275
20276    if (rbAllocInfo->tbInfo[1].schdlngForTb)
20277    {
20278       iTbs = rbAllocInfo->tbInfo[1].iTbs;
20279       noLyr = rbAllocInfo->tbInfo[1].noLyr;
20280       rbAllocInfo->tbInfo[1].bytesAlloc =
20281          rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
20282    }
20283
20284    /* Update rbAllocInfo with the allocation information */
20285    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20286    {
20287       rbAllocInfo->allocInfo.raType0.dlAllocBitMask =
20288          rbAllocInfo->resAllocInfo.raType0Mask;
20289       rbAllocInfo->allocInfo.raType0.numDlAlloc = numAllocRbgs;
20290    }
20291 #ifdef RGSCH_SPS_UNUSED
20292    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
20293    {
20294       rbAllocInfo->allocInfo.raType1.dlAllocBitMask =
20295          rbAllocInfo->resAllocInfo.raType1Mask[rbAllocInfo->allocInfo.raType1.rbgSubset];
20296       rbAllocInfo->allocInfo.raType1.numDlAlloc = numAllocRbs;
20297       rbAllocInfo->allocInfo.raType1.shift = 0;
20298    }
20299 #endif
20300    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20301    {
20302       rbAllocInfo->allocInfo.raType2.isLocal = TRUE;
20303       rbAllocInfo->allocInfo.raType2.rbStart = rbStart;
20304       rbAllocInfo->allocInfo.raType2.numRb = numAllocRbs;
20305    }
20306
20307    rbAllocInfo->rbsAlloc = numAllocRbs;
20308    rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
20309
20310    /* Update allocation masks for RA types 0, 1 and 2 in DL SF */
20311
20312    /* Update type 0 allocation mask */
20313    dlSfAlloc->raType0Mask |= rbAllocInfo->resAllocInfo.raType0Mask;
20314 #ifdef RGSCH_SPS_UNUSED
20315    /* Update type 1 allocation masks */
20316    for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
20317    {
20318       dlSfAlloc->raType1Mask[idx] |= rbAllocInfo->resAllocInfo.raType1Mask[idx];
20319       dlSfAlloc->raType1UsedRbs[idx] +=
20320          rbAllocInfo->resAllocInfo.raType1UsedRbs[idx];
20321    }
20322 #endif
20323    /* Update type 2 allocation masks */
20324    for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
20325    {
20326       dlSfAlloc->raType2Mask[idx] |= rbAllocInfo->resAllocInfo.raType2Mask[idx];
20327    }
20328
20329    dlSf->spsAllocdBw += numAllocRbs;
20330    return (TRUE);
20331 }
20332
20333 /***********************************************************
20334  *
20335  *     Func : rgSCHCmnDlGetBestFitHole
20336  *
20337  *
20338  *     Desc : Converts the best fit hole into allocation and returns the
20339  *     allocation information.
20340  *
20341  *
20342  *     Ret  : Void
20343  *
20344  *
20345  *     Notes:
20346  *
20347  *     File :
20348  *
20349  **********************************************************/
20350 static Void rgSCHCmnDlGetBestFitHole
20351 (
20352 uint32_t  *allocMask,
20353 uint8_t   numMaskRbs,
20354 uint32_t  *crntAllocMask,
20355 uint8_t   rbsReq,
20356 uint8_t   *allocStart,
20357 uint8_t   *allocNumRbs,
20358 Bool      isPartialAlloc
20359 )
20360 {
20361    uint8_t maskSz = (numMaskRbs + 31)/32;
20362    uint8_t maxMaskPos = (numMaskRbs % 32);
20363    uint8_t maskIdx, maskPos;
20364    uint8_t numAvailRbs = 0;
20365    uint8_t bestAvailNumRbs = 0;
20366    S8 bestStartPos = -1;
20367    S8 startPos = -1;
20368    uint32_t tmpMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
20369    uint32_t bestMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
20370
20371    *allocNumRbs = numAvailRbs;
20372    *allocStart = 0;
20373
20374    for (maskIdx = 0; maskIdx < maskSz; ++maskIdx)
20375    {
20376       maxMaskPos = 31;
20377       if (maskIdx == (maskSz - 1))
20378       {
20379          if (numMaskRbs % 32)
20380          {
20381             maxMaskPos = numMaskRbs % 32;
20382          }
20383       }
20384       for (maskPos = 0; maskPos < maxMaskPos; ++maskPos)
20385       {
20386          if (!(allocMask[maskIdx] & (1 << (31 - maskPos))))
20387          {
20388             tmpMask[maskIdx] |= (1 << (31 - maskPos));
20389             if (startPos == -1)
20390             {
20391                startPos = maskIdx * 32 + maskPos;
20392             }
20393             ++numAvailRbs;
20394             if (numAvailRbs == rbsReq)
20395             {
20396                *allocStart = (uint8_t)startPos;
20397                *allocNumRbs = rbsReq;
20398                break;
20399             }
20400          }
20401          else
20402          {
20403             if (numAvailRbs > bestAvailNumRbs)
20404             {
20405                bestAvailNumRbs = numAvailRbs;
20406                bestStartPos = startPos;
20407                memcpy(bestMask, tmpMask, 4 * sizeof(uint32_t));
20408             }
20409             numAvailRbs = 0;
20410             startPos = -1;
20411             memset(tmpMask, 0, 4 * sizeof(uint32_t));
20412          }
20413       }
20414       if (*allocNumRbs == rbsReq)
20415       {
20416          break;
20417       }
20418    }
20419
20420    if (*allocNumRbs == rbsReq)
20421    {
20422       /* Convert the hole into allocation */
20423       memcpy(crntAllocMask, tmpMask, 4 * sizeof(uint32_t));
20424       return;
20425    }
20426    else
20427    {
20428       if (bestAvailNumRbs && isPartialAlloc)
20429       {
20430          /* Partial allocation could have been done */
20431          *allocStart = (uint8_t)bestStartPos;
20432          *allocNumRbs = bestAvailNumRbs;
20433          /* Convert the hole into allocation */
20434          memcpy(crntAllocMask, bestMask, 4 * sizeof(uint32_t));
20435       }
20436    }
20437
20438    return;
20439 }
20440 #endif /* LTEMAC_SPS */
20441
20442 /***************************************************************************
20443  *
20444  * NON-DLFS Allocation functions
20445  *
20446  * *************************************************************************/
20447 #ifndef LTE_TDD
20448 #ifdef DEBUGP
20449 /**
20450  * @brief Function to find out code rate
20451  *
20452  * @details
20453  *
20454  *     Function : rgSCHCmnFindCodeRate
20455  *
20456  *     Processing Steps:
20457  *
20458  *  @param[in]      RgSchCellCb     *cell
20459  *  @param[in]      RgSchDlSf       *dlSf
20460  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20461  *  @return  void
20462  **/
20463 #ifdef UNUSED_FUNC
20464 static Void rgSCHCmnFindCodeRate
20465 (
20466 RgSchCellCb    *cell,
20467 RgSchDlSf      *dlSf,
20468 RgSchDlRbAlloc *allocInfo,
20469 uint8_t        idx
20470 )
20471 {
20472     return;
20473
20474 }
20475 #endif
20476
20477 /* Adjust the Imcs and bytes allocated also with respect to the adjusted
20478    RBs - Here we will find out the Imcs by identifying first Highest
20479    number of bits compared to the original bytes allocated.  */
20480 /**
20481  * @brief Adjust IMCS according to tbSize and ITBS
20482  *
20483  * @details
20484  *
20485  *     Function : rgSCHCmnNonDlfsPbchTbImcsAdj
20486  *
20487  *     Processing Steps:
20488  *      - Adjust Imcs according to tbSize and ITBS.
20489  *
20490  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20491  *  @param[in]      uint8_t              *idx
20492  *  @return  void
20493  **/
20494 static Void rgSCHCmnNonDlfsPbchTbImcsAdj
20495 (
20496 RgSchCellCb     *cell,
20497 RgSchDlRbAlloc  *allocInfo,
20498 uint8_t         idx,
20499 uint8_t         rbsReq
20500 )
20501 {
20502    uint8_t     noLyrs = 0;
20503    uint8_t     tbs = 0;
20504    uint32_t    origBytesReq;
20505    uint8_t     noRbgs = 0;
20506    uint8_t     noRbs = 0;
20507    RgSchDlSf   *dlSf = allocInfo->dlSf;
20508
20509    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
20510    noLyrs = allocInfo->tbInfo[idx].noLyr;
20511
20512    if((allocInfo->raType == RG_SCH_CMN_RA_TYPE0))
20513    {
20514       noRbgs = RGSCH_CEIL((allocInfo->rbsReq + dlSf->lstRbgDfct), cell->rbgSize);
20515       noRbs = (noRbgs * cell->rbgSize) - dlSf->lstRbgDfct;
20516    }
20517    else
20518    {
20519        noRbs = allocInfo->rbsReq;
20520    }
20521
20522    /* This line will help in case if tbs is zero and reduction in MCS is not possible */
20523    if (allocInfo->rbsReq == 0 )
20524    {
20525       return;
20526    }
20527    origBytesReq = rgTbSzTbl[noLyrs - 1][tbs][rbsReq - 1]/8;
20528
20529    /* Find out the ITbs & Imcs by identifying first Highest
20530       number of bits compared to the original bytes allocated.*/
20531    if(tbs > 0)
20532    {
20533       if(((rgTbSzTbl[noLyrs - 1][0][noRbs - 1])/8) < origBytesReq)
20534       {
20535           RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyrs - 1], tbs);
20536           while(((rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1])/8) > origBytesReq)
20537           {
20538               tbs--;
20539           }
20540       }
20541       else
20542       {
20543           tbs = 0;
20544       }
20545       allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1]/8;
20546       allocInfo->tbInfo[idx].iTbs = tbs;
20547       RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
20548    }
20549
20550    return;
20551 }
20552 /* Added funcion to adjust TBSize*/
20553 /**
20554  * @brief Function to adjust the tbsize in case of subframe 0 & 5 when
20555  * we were not able to do RB alloc adjustment by adding extra required Rbs
20556  *
20557  * @details
20558  *
20559  *     Function : rgSCHCmnNonDlfsPbchTbSizeAdj
20560  *
20561  *     Processing Steps:
20562  *
20563  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20564  *  @param[in]      uint8_t            numOvrlapgPbchRb
20565  *  @param[in]      uint8_t            idx
20566  *  @param[in]      uint8_t            pbchSsRsSym
20567  *  @return  void
20568  **/
20569 static Void rgSCHCmnNonDlfsPbchTbSizeAdj
20570 (
20571 RgSchDlRbAlloc  *allocInfo,
20572 uint8_t         numOvrlapgPbchRb,
20573 uint8_t         pbchSsRsSym,
20574 uint8_t         idx,
20575 uint32_t        bytesReq
20576 )
20577 {
20578    uint32_t     reducedTbs = 0;
20579    uint8_t      noLyrs = 0;
20580    uint8_t      tbs = 0;
20581    
20582    noLyrs = allocInfo->tbInfo[idx].noLyr;
20583
20584    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
20585
20586    reducedTbs = bytesReq - (((uint32_t)numOvrlapgPbchRb * (uint32_t)pbchSsRsSym * 6)/8);
20587
20588    /* find out the ITbs & Imcs by identifying first Highest
20589     number of bits compared with reduced bits considering the bits that are
20590     reserved for PBCH/PSS/SSS */
20591    if(((rgTbSzTbl[noLyrs - 1][0][allocInfo->rbsReq - 1])/8) < reducedTbs)
20592    {
20593        while(((rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1])/8) > reducedTbs)
20594        {
20595            tbs--;
20596        }
20597    }
20598    else
20599    {
20600        tbs = 0;
20601    }
20602    allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1]/8;
20603    allocInfo->tbInfo[idx].iTbs = tbs;
20604    RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
20605
20606    return;
20607 }
20608
20609 /* Added this function to find num of ovrlapping PBCH rb*/
20610 /**
20611  * @brief Function to find out how many additional rbs are available
20612  *    in the entire bw which can be allocated to a UE
20613  * @details
20614  *
20615  *     Function : rgSCHCmnFindNumAddtlRbsAvl
20616  *
20617  *     Processing Steps:
20618  *      - Calculates number of additinal rbs available
20619  *
20620  *  @param[in]      RgSchCellCb     *cell
20621  *  @param[in]      RgSchDlSf       *dlSf
20622  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20623  *  @param[out]      uint8_t            addtlRbsAvl
20624  *  @return  void
20625  **/
20626 static uint8_t rgSCHCmnFindNumAddtlRbsAvl(RgSchCellCb *cell,RgSchDlSf *dlSf,RgSchDlRbAlloc *allocInfo)
20627 {
20628     uint8_t addtlRbsAvl = 0;
20629     if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20630     {
20631          addtlRbsAvl = (((dlSf->type0End - dlSf->type2End + 1)*\
20632                         cell->rbgSize) - dlSf->lstRbgDfct) - allocInfo->rbsReq;
20633     }
20634     else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20635     {
20636        addtlRbsAvl = (dlSf->bw - dlSf->bwAlloced) - allocInfo->rbsReq;
20637     }
20638
20639     return (addtlRbsAvl);
20640
20641 }
20642 /* Added this function to find num of ovrlapping PBCH rb*/
20643 /**
20644  * @brief Function to find out how many of the requested RBs are
20645  *        falling in the center 6 RBs of the downlink bandwidth.
20646  * @details
20647  *
20648  *     Function : rgSCHCmnFindNumPbchOvrlapRbs
20649  *
20650  *     Processing Steps:
20651  *      - Calculates number of overlapping rbs
20652  *
20653  *  @param[in]      RgSchCellCb     *cell
20654  *  @param[in]      RgSchDlSf       *dlSf
20655  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20656  *  @param[out]      uint8_t*            numOvrlapgPbchRb
20657  *  @return  void
20658  **/
20659 static Void rgSCHCmnFindNumPbchOvrlapRbs
20660 (
20661 RgSchCellCb    *cell,
20662 RgSchDlSf      *dlSf,
20663 RgSchDlRbAlloc *allocInfo,
20664 uint8_t        *numOvrlapgPbchRb
20665 )
20666 {
20667     *numOvrlapgPbchRb = 0;
20668    /*Find if we have already crossed the start boundary for PBCH 6 RBs,
20669     * if yes then lets find the number of RBs which are getting overlapped
20670     * with this allocation.*/
20671    if(dlSf->bwAlloced <= (cell->pbchRbStart))
20672    {
20673       /*We have not crossed the start boundary of PBCH RBs. Now we need
20674        * to know that if take this allocation then how much PBCH RBs
20675        * are overlapping with this allocation.*/
20676       /* Find out the overlapping RBs in the centre 6 RBs */
20677        if((dlSf->bwAlloced + allocInfo->rbsReq) > cell->pbchRbStart)
20678        {
20679            *numOvrlapgPbchRb = (dlSf->bwAlloced + allocInfo->rbsReq) - (cell->pbchRbStart);
20680            if(*numOvrlapgPbchRb > 6)
20681                 *numOvrlapgPbchRb = 6;
20682        }
20683    }
20684    else if ((dlSf->bwAlloced > (cell->pbchRbStart)) &&
20685          (dlSf->bwAlloced < (cell->pbchRbEnd)))
20686    {
20687       /*We have already crossed the start boundary of PBCH RBs.We need to
20688        * find that if we take this allocation then how much of the RBs for
20689        * this allocation will overlap with PBCH RBs.*/
20690       /* Find out the overlapping RBs in the centre 6 RBs */
20691       if(dlSf->bwAlloced + allocInfo->rbsReq < (cell->pbchRbEnd))
20692       {
20693          /*If we take this allocation then also we are not crossing the
20694           * end boundary of PBCH 6 RBs.*/
20695          *numOvrlapgPbchRb = allocInfo->rbsReq;
20696       }
20697       else
20698       {
20699          /*If we take this allocation then we are crossing the
20700           * end boundary of PBCH 6 RBs.*/
20701          *numOvrlapgPbchRb = (cell->pbchRbEnd) - dlSf->bwAlloced;
20702       }
20703    }
20704     return;
20705
20706 }
20707 /**
20708  * @brief Performs RB allocation adjustment if the requested RBs are
20709  *        falling in the center 6 RBs of the downlink bandwidth.
20710  * @details
20711  *
20712  *     Function : rgSCHCmnNonDlfsPbchRbAllocAdj
20713  *
20714  *     Processing Steps:
20715  *      - Allocate consecutively available RBs.
20716  *
20717  *  @param[in]      RgSchCellCb     *cell
20718  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20719  *  @param[in]      uint8_t               pbchSsRsSym
20720  *  @return  void
20721  **/
20722 static Void rgSCHCmnNonDlfsPbchRbAllocAdj
20723 (
20724 RgSchCellCb      *cell,
20725 RgSchDlRbAlloc   *allocInfo,
20726 uint8_t          pbchSsRsSym,
20727 Bool             isBcchPcch
20728 )
20729 {
20730    RgSchDlSf  *dlSf = allocInfo->dlSf;
20731    uint8_t    numOvrlapgPbchRb = 0;
20732    uint8_t    numOvrlapgAdtlPbchRb = 0;
20733    uint8_t    totSym;
20734    uint8_t    addtlRbsReq = 0;
20735    uint8_t    moreAddtlRbsReq = 0;
20736    uint8_t    addtlRbsAdd = 0;
20737    uint8_t    moreAddtlRbsAdd = 0;
20738    uint8_t    tbs;
20739    uint8_t    origRbsReq = 0;
20740    uint32_t   bytesReq;
20741    uint8_t    noLyr;
20742    uint8_t    divResult;
20743
20744
20745
20746
20747    origRbsReq = allocInfo->rbsReq;
20748    rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20749
20750   totSym =  (cell->isCpDlExtend) ? RGSCH_TOT_NUM_SYM_EXTCP : RGSCH_TOT_NUM_SYM_NORCP;
20751
20752    /* Additional RBs are allocated by considering the loss due to
20753       the reserved symbols for CFICH, PBCH, PSS, SSS and cell specific RS */
20754
20755    divResult = (numOvrlapgPbchRb * pbchSsRsSym)/totSym;
20756    if((numOvrlapgPbchRb * pbchSsRsSym) % totSym)
20757    {
20758       divResult++;
20759    }
20760    addtlRbsReq = divResult;
20761
20762    RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, addtlRbsReq, addtlRbsAdd)
20763
20764    /*Now RBs requires is original requested RBs + these additional RBs to make
20765     * up for PSS/SSS/BCCH.*/
20766    allocInfo->rbsReq = allocInfo->rbsReq + addtlRbsAdd;
20767
20768    /*Check if with these additional RBs we have taken up, these are also falling
20769     * under PBCH RBs range, if yes then we would need to account for
20770     * PSS/BSS/BCCH for these additional RBs too.*/
20771    if(addtlRbsAdd && ((dlSf->bwAlloced + allocInfo->rbsReq - addtlRbsAdd) < (cell->pbchRbEnd)))
20772    {
20773       if((dlSf->bwAlloced + allocInfo->rbsReq) <= (cell->pbchRbEnd))
20774       {
20775       /*With additional RBs taken into account, we are not crossing the
20776        * PBCH RB end boundary.Thus here we need to account just for
20777        * overlapping PBCH RBs for these additonal RBs.*/
20778           divResult = (addtlRbsAdd * pbchSsRsSym)/totSym;
20779           if((addtlRbsAdd * pbchSsRsSym) % totSym)
20780           {
20781             divResult++;
20782           }
20783
20784           moreAddtlRbsReq = divResult;
20785
20786           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
20787
20788           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
20789       }
20790       else
20791       {
20792
20793          /*Here we have crossed the PBCH RB end boundary, thus we need to take
20794           * into account the overlapping RBs for additional RBs which will be
20795           * subset of addtlRbs.*/
20796           numOvrlapgAdtlPbchRb = (cell->pbchRbEnd) - ((dlSf->bwAlloced + allocInfo->rbsReq) -  addtlRbsAdd);
20797
20798           divResult = (numOvrlapgAdtlPbchRb * pbchSsRsSym)/totSym;
20799           if((numOvrlapgAdtlPbchRb * pbchSsRsSym) % totSym)
20800           {
20801              divResult++;
20802           }
20803
20804           moreAddtlRbsReq =  divResult;
20805
20806           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
20807
20808           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
20809       }
20810    }
20811    if (isBcchPcch == TRUE)
20812    {
20813       return;
20814    }
20815
20816    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
20817    if(tbs == 6)
20818    {
20819       /* This case might be for Imcs value 6 and NPrb = 1 case  - Not
20820          Adjusting either RBs or Imcs or Bytes Allocated */
20821       allocInfo->rbsReq = allocInfo->rbsReq - addtlRbsAdd - moreAddtlRbsAdd;
20822    }
20823    else if(tbs && ((0 == addtlRbsAdd) && (moreAddtlRbsAdd == 0)))
20824    {
20825        /*In case of a situation where we the entire bandwidth is already occupied
20826         * and we dont have room to add additional Rbs then in order to decrease the
20827         * code rate we reduce the tbsize such that we reduce the present calculated
20828         * tbsize by number of bytes that would be occupied by PBCH/PSS/SSS in overlapping
20829         * rbs and find the nearest tbsize which would be less than this deduced value*/
20830
20831       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20832
20833       noLyr = allocInfo->tbInfo[0].noLyr;
20834       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyr - 1], tbs);
20835       bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
20836
20837       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,bytesReq);
20838
20839       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20840       {
20841           noLyr = allocInfo->tbInfo[1].noLyr;
20842           bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
20843           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,bytesReq);
20844       }
20845
20846    }
20847    else if(tbs && ((addtlRbsAdd != addtlRbsReq) ||
20848           (addtlRbsAdd && (moreAddtlRbsReq != moreAddtlRbsAdd))))
20849    {
20850        /*In case of a situation where we were not able to add required number of
20851         * additional RBs then we adjust the Imcs based on original RBs requested.
20852         * Doing this would comensate for the few extra Rbs we have added but inorder
20853         * to comensate for number of RBS we couldnt add we again do the TBSize adjustment*/
20854
20855       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
20856
20857       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20858       {
20859           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
20860       }
20861
20862       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20863       numOvrlapgPbchRb = numOvrlapgPbchRb - (addtlRbsAdd + moreAddtlRbsAdd);
20864
20865       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,allocInfo->tbInfo[0].bytesReq);
20866
20867       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20868       {
20869           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,allocInfo->tbInfo[1].bytesReq);
20870       }
20871
20872    }
20873    else
20874    {
20875        /*We hit this code when we were able to add the required additional RBS
20876         * hence we should adjust the IMcs based on orignals RBs requested*/
20877
20878       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
20879
20880       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20881       {
20882           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
20883       }
20884    }
20885
20886    return;
20887 } /* end of rgSCHCmnNonDlfsPbchRbAllocAdj */
20888 #endif
20889 #endif
20890 /**
20891  * @brief Performs RB allocation for frequency non-selective cell.
20892  *
20893  * @details
20894  *
20895  *     Function : rgSCHCmnNonDlfsCmnRbAlloc
20896  *
20897  *     Processing Steps:
20898  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
20899  *
20900  *  @param[in]      RgSchCellCb     *cell
20901  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
20902  *  @return  S16
20903  *      -# ROK
20904  *      -# RFAILED
20905  **/
20906 static S16 rgSCHCmnNonDlfsCmnRbAlloc(RgSchCellCb  *cell,RgSchDlRbAlloc  *allocInfo)
20907 {
20908 #ifndef LTE_TDD
20909 #ifdef LTEMAC_SPS
20910 #endif
20911    uint8_t pbchSsRsSym = 0;
20912    uint8_t pbchFrame = 0;
20913    uint8_t  tbs = 0;
20914    RgSchCmnDlCell   *cellDl    = RG_SCH_CMN_GET_DL_CELL(cell); 
20915 #endif
20916    RgSchDlSf     *dlSf   = allocInfo->dlSf;
20917 #ifdef LTEMAC_SPS
20918    uint8_t                  rbStart = 0;
20919    uint8_t                  spsRbsAlloc = 0;
20920    RgSchDlSfAllocInfo  *dlSfAlloc = &allocInfo->dlSf->dlSfAllocInfo;
20921 #endif
20922
20923    allocInfo->tbInfo[0].noLyr = 1;
20924
20925 #ifdef LTEMAC_SPS
20926    /* Note: Initialize the masks to 0, this might not be needed since alloInfo
20927     * is initialized to 0 at the beginning of allcoation */
20928    allocInfo->resAllocInfo.raType0Mask = 0;
20929    memset(allocInfo->resAllocInfo.raType1Mask, 0,
20930          RG_SCH_NUM_RATYPE1_32BIT_MASK * sizeof (uint32_t));
20931    memset(allocInfo->resAllocInfo.raType2Mask, 0,
20932          RG_SCH_NUM_RATYPE2_32BIT_MASK * sizeof (uint32_t));
20933
20934    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
20935          (dlSf->bwAlloced == dlSf->bw))
20936 #else
20937    if(dlSf->bwAlloced == dlSf->bw)
20938 #endif
20939    {
20940       return RFAILED;
20941    }
20942 #ifndef LTE_TDD
20943    if (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))
20944    {
20945 #ifdef LTEMAC_SPS
20946       if ((allocInfo->tbInfo[0].imcs < 29) && (dlSf->bwAlloced < dlSf->bw))
20947 #else
20948       if(allocInfo->tbInfo[0].imcs < 29)
20949 #endif
20950       {
20951          /* set the remaining RBs for the requested UE */
20952          allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
20953          RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
20954          allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[0][tbs][allocInfo->rbsReq - 1]/8;
20955       }
20956       else
20957       {
20958 #ifdef LTEMAC_SPS
20959          /* Attempt RA Type 2 allocation in SPS Bandwidth */
20960          if (dlSf->spsAllocdBw < cell->spsBwRbgInfo.numRbs) 
20961          {
20962             spsRbsAlloc =
20963                rgSCHCmnDlRaType2Alloc(dlSfAlloc,
20964                      allocInfo->rbsReq, &cell->spsBwRbgInfo, &rbStart,
20965                      &allocInfo->resAllocInfo, FALSE);
20966             /* rbsAlloc assignment moved from line 16671 to here to avoid
20967              * compilation error. Recheck */
20968             dlSf->spsAllocdBw += spsRbsAlloc;
20969          }
20970          if (!spsRbsAlloc)
20971 #endif /* LTEMAC_SPS */
20972          {
20973             return RFAILED;
20974          }
20975       }
20976    }
20977 #endif
20978
20979    /* Update allocation information */
20980    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
20981    if (allocInfo->pdcch == NULLP)
20982    {
20983       return RFAILED;
20984    }
20985    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
20986    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
20987    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
20988    allocInfo->allocInfo.raType2.isLocal = TRUE;
20989 #ifdef LTEMAC_SPS
20990    if (spsRbsAlloc) 
20991    {
20992       allocInfo->allocInfo.raType2.rbStart = rbStart;
20993       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
20994       allocInfo->rbsAlloc = allocInfo->rbsReq;
20995    }
20996 #endif
20997
20998 #ifdef LTEMAC_SPS
20999    if (!spsRbsAlloc)
21000    {
21001 #endif
21002 #ifndef LTE_TDD
21003       if(dlSf->sfNum)
21004       {
21005          if(!(dlSf->sfNum == 5))
21006          {
21007             /* case for subframes 1 to 9 except 5 */
21008 #ifdef LTEMAC_SPS
21009             allocInfo->allocInfo.raType2.rbStart = rbStart;
21010 #else
21011             /*Fix for ccpu00123918*/
21012             allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21013 #endif
21014          }
21015          else
21016          {
21017             pbchFrame = 1; /* case for subframe 5 */
21018             /* In subframe 5, symbols are reserved for PSS and SSS and CFICH
21019                and Cell Specific Reference Signals */
21020             pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PSS_SSS_SYM) *
21021                   RGSCH_NUM_SC_IN_RB + cell->numCellRSPerSf);
21022          }
21023       }
21024       else
21025       {
21026          pbchFrame = 1;
21027          /* In subframe 0, symbols are reserved for PSS, SSS, PBCH, CFICH and
21028             and Cell Specific Reference signals */
21029          pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PBCH_SYM +
21030                   RGSCH_NUM_PSS_SSS_SYM) * RGSCH_NUM_SC_IN_RB +
21031                cell->numCellRSPerSf);
21032       } /* end of outer else */
21033
21034       if((pbchFrame) &&
21035             (((dlSf->bwAlloced + allocInfo->rbsReq) - cell->pbchRbStart) > 0)&&
21036             (dlSf->bwAlloced < cell->pbchRbEnd))
21037       {
21038          if(allocInfo->tbInfo[0].imcs < 29)
21039          {
21040             rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo, pbchSsRsSym, TRUE);
21041          }
21042       }
21043 #endif
21044 #ifdef LTEMAC_SPS
21045    }
21046 #endif
21047
21048 #ifdef LTEMAC_SPS
21049    if (!spsRbsAlloc)
21050    {  
21051 #endif
21052       /*Fix for ccpu00123918*/
21053       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21054       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
21055       allocInfo->rbsAlloc = allocInfo->rbsReq;
21056
21057       /* LTE_ADV_FLAG_REMOVED_START */
21058 #ifndef LTE_TDD
21059       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
21060       {
21061          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
21062                allocInfo->allocInfo.raType2.rbStart, \
21063                allocInfo->allocInfo.raType2.numRb);
21064       }
21065       else
21066 #endif
21067       {
21068          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
21069                allocInfo->allocInfo.raType2.rbStart, \
21070                allocInfo->allocInfo.raType2.numRb);
21071       }
21072
21073 #ifdef LTEMAC_SPS
21074    }
21075 #endif
21076    /* LTE_ADV_FLAG_REMOVED_END */
21077    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21078
21079
21080 #ifdef LTEMAC_SPS
21081    if (spsRbsAlloc)
21082    {
21083       uint8_t    idx;
21084       /* Update type 0, 1 and 2 masks */
21085       dlSfAlloc->raType0Mask    |= allocInfo->resAllocInfo.raType0Mask;
21086 #ifdef RGSCH_SPS_UNUSED
21087       for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
21088       {
21089          dlSfAlloc->raType1Mask[idx] |=
21090             allocInfo->resAllocInfo.raType1Mask[idx];
21091          dlSfAlloc->raType1UsedRbs[idx] +=
21092             allocInfo->resAllocInfo.raType1UsedRbs[idx];
21093       }
21094 #endif
21095       for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
21096       {
21097          dlSfAlloc->raType2Mask[idx] |=
21098             allocInfo->resAllocInfo.raType2Mask[idx];
21099       }
21100    }
21101 #endif
21102
21103    return ROK;
21104 }
21105
21106
21107 /**
21108  * @brief Performs RB allocation for frequency non-selective cell.
21109  *
21110  * @details
21111  *
21112  *     Function : rgSCHCmnNonDlfsCmnRbAllocRar
21113  *
21114  *     Processing Steps:
21115  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
21116  *
21117  *  @param[in]      RgSchCellCb     *cell
21118  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
21119  *  @return  S16
21120  *      -# ROK
21121  *      -# RFAILED
21122  **/
21123 static S16 rgSCHCmnNonDlfsCmnRbAllocRar(RgSchCellCb *cell,RgSchDlRbAlloc *allocInfo)
21124 {
21125    RgSchDlSf     *dlSf   = allocInfo->dlSf;
21126
21127    if(dlSf->bwAlloced == dlSf->bw)
21128    {
21129       return RFAILED;
21130    }
21131
21132    allocInfo->tbInfo[0].noLyr = 1;
21133 #ifndef RG_5GTF
21134    /* Update allocation information */
21135    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
21136    if (allocInfo->pdcch == NULLP)
21137    {
21138       return RFAILED;
21139    }
21140    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
21141    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
21142    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
21143    allocInfo->allocInfo.raType2.isLocal = TRUE;
21144
21145    /*Fix for ccpu00123918*/
21146    allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21147    allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
21148    allocInfo->rbsAlloc = allocInfo->rbsReq;
21149
21150    /* LTE_ADV_FLAG_REMOVED_END */
21151    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21152
21153 #else
21154    allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, NULLP, dlSf, 13, TFU_DCI_FORMAT_B1, FALSE);
21155    if (allocInfo->pdcch == NULLP)
21156    {
21157       return RFAILED;
21158    }
21159    RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
21160    if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
21161    {
21162       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
21163       return RFAILED;
21164    }
21165
21166    allocInfo->tbInfo[0].cmnGrnt.vrbgStart = beamInfo->vrbgStart;
21167    allocInfo->tbInfo[0].cmnGrnt.numVrbg = allocInfo->vrbgReq;
21168
21169    /* Update allocation information */
21170    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
21171
21172    allocInfo->tbInfo[0].cmnGrnt.xPDSCHRange = 1;  
21173    allocInfo->tbInfo[0].cmnGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
21174          allocInfo->tbInfo[0].cmnGrnt.vrbgStart, allocInfo->tbInfo[0].cmnGrnt.numVrbg);
21175
21176    allocInfo->tbInfo[0].cmnGrnt.rbStrt = (allocInfo->tbInfo[0].cmnGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
21177    allocInfo->tbInfo[0].cmnGrnt.numRb = (allocInfo->tbInfo[0].cmnGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
21178
21179    beamInfo->vrbgStart += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
21180    beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
21181    allocInfo->tbInfo[0].cmnGrnt.rv = 0;
21182    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21183
21184 #endif
21185    DU_LOG("\nINFO  -->  SCH : [%s],allocInfo->tbInfo[0].bytesAlloc:%u,vrbgReq:%u\n",
21186          __func__,allocInfo->tbInfo[0].bytesAlloc,allocInfo->vrbgReq);
21187
21188    return ROK;
21189 }
21190
21191
21192 /* LTE_ADV_FLAG_REMOVED_START */
21193 #ifndef LTE_TDD
21194 /**
21195  * @brief To check if DL BW available for non-DLFS allocation.
21196  *
21197  * @details
21198  *
21199  *     Function : rgSCHCmnNonDlfsBwAvlbl
21200  *
21201  *     Processing Steps:
21202  *      - Determine availability based on RA Type.
21203  *
21204  *  @param[in]  RgSchCellCb     *cell
21205  *  @param[in]  RgSchDlSf       *dlSf
21206  *  @param[in]  RgSchDlRbAlloc  *allocInfo
21207  *
21208  *  @return Bool
21209  *      -# TRUE
21210  *      -# FALSE
21211  **/
21212 #ifdef UNUSED_FUNC
21213 static Bool rgSCHCmnNonDlfsSFRBwAvlbl
21214 (
21215 RgSchCellCb      *cell,
21216 RgSchSFRPoolInfo **sfrpoolInfo,
21217 RgSchDlSf        *dlSf,
21218 RgSchDlRbAlloc   *allocInfo,
21219 Bool             isUeCellEdge
21220 )
21221 {
21222    CmLListCp   *l;
21223    CmLListCp   *l1;
21224    CmLList     *n;
21225    CmLList     *n1;
21226    RgSchSFRPoolInfo  *sfrPool;
21227    RgSchSFRPoolInfo  *sfrCEPool;
21228
21229    uint8_t tbs;
21230    uint8_t noLyrs;
21231    RgSchSFRPoolInfo *poolWithMaxAvlblBw = NULLP;
21232    uint32_t bwAvlbl = 0;
21233    uint32_t addtnlPRBs = 0;
21234
21235    if (dlSf->bw <= dlSf->bwAlloced)
21236    {
21237       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for subframe (%d) CRNTI:%d", dlSf->sfNum,allocInfo->rnti);
21238       return FALSE;
21239    }
21240
21241    if (dlSf->sfrTotalPoolInfo.ccBwFull == TRUE)
21242    {
21243       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for CC Pool CRNTI:%d",allocInfo->rnti);
21244       return FALSE;
21245    }
21246
21247    if ((dlSf->sfrTotalPoolInfo.ceBwFull == TRUE) && (isUeCellEdge))
21248    {
21249       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for CE Pool CRNTI:%d",allocInfo->rnti);
21250       return FALSE;
21251    }  
21252
21253    /* We first check if the ue scheduled is a cell edge or cell centre and accordingly check the avaialble
21254       memory in their pool. If the cell centre UE doesnt have Bw available in its pool, then it will check
21255       Bw availability in cell edge pool but the other way around is NOT possible.   */
21256    if(isUeCellEdge)
21257    {   
21258       l = &dlSf->sfrTotalPoolInfo.cePool;
21259    }
21260    else
21261    {
21262       l = &dlSf->sfrTotalPoolInfo.ccPool; 
21263    }     
21264
21265    n = cmLListFirst(l);
21266
21267    while(n)       
21268    {
21269       if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
21270       {
21271          sfrPool = (RgSchSFRPoolInfo*)(n->node);
21272
21273          /* MS_FIX for ccpu00123919 : Number of RBs in case of RETX should be same as that of initial transmission. */
21274          if(allocInfo->tbInfo[0].tbCb->txCntr)
21275          {
21276             /* If RB assignment is being done for RETX. Then if reqRbs are   a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
21277              * not a multiple of rbgSize then check if lsgRbgDfct exists */
21278             if (allocInfo->rbsReq % cell->rbgSize == 0)
21279             {
21280                if ((sfrPool->type2End == dlSf->type2End) && dlSf->lstRbgDfct)
21281                {
21282                   /* In this scenario we are wasting the last RBG for this dlSf */
21283                   sfrPool->type0End--;
21284                   sfrPool->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21285
21286                   dlSf->lstRbgDfct = 0;
21287
21288                   /*ABHINAV To check if these variables need to be taken care of*/
21289                   dlSf->type0End--;
21290                   dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21291                }
21292             }
21293             else
21294             {
21295                if (dlSf->lstRbgDfct)
21296                {
21297                   /* Check if type0 allocation can cater to this RETX requirement */
21298                   if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
21299                   {
21300                      return (FALSE);
21301                   }
21302                   else
21303                   {
21304                      if (sfrPool->type2End != dlSf->type2End)   /*Search again for some pool which has the END RBG of the BandWidth*/
21305                      {
21306                         continue;                                       
21307                      }  
21308                   }
21309                }
21310                else
21311                {
21312                   /* cannot allocate same number of required RBs */
21313                   return (FALSE);                    
21314                }
21315             }
21316          }
21317
21318          /*rg002.301 ccpu00120391 MOD condition is modified approprialtely to find if rbsReq is less than available RBS*/
21319          if(allocInfo->rbsReq <= (((sfrPool->type0End - sfrPool->type2End + 1)*\
21320                      cell->rbgSize) - dlSf->lstRbgDfct))
21321          {
21322             *sfrpoolInfo = sfrPool;
21323             return (TRUE);
21324          }
21325          else
21326          {
21327             if (sfrPool->bw <= sfrPool->bwAlloced + cell->rbgSize)
21328             {
21329                n = cmLListNext(l);
21330                /* If the ue is cell centre then it will simply check the memory available in next pool.
21331                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
21332
21333                if((!isUeCellEdge) && (!n->node))
21334                {
21335                   l = &dlSf->sfrTotalPoolInfo.cePool;
21336                   n = cmLListFirst(l);
21337                }
21338
21339                continue; 
21340             }    
21341
21342             /* MS_FIX: Number of RBs in case of RETX should be same as that of initial transmission */
21343             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21344             {
21345                /*rg002.301 ccpu00120391 MOD setting the remaining RBs  for the requested UE*/
21346                allocInfo->rbsReq = (((sfrPool->type0End - sfrPool->type2End + 1)*\
21347                         cell->rbgSize) - dlSf->lstRbgDfct);
21348                RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21349                noLyrs = allocInfo->tbInfo[0].noLyr;
21350                allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21351                *sfrpoolInfo = sfrPool;
21352                return (TRUE);
21353             }
21354             else
21355             {
21356                n = cmLListNext(l);
21357
21358                /* If the ue is cell centre then it will simply check the memory available in next pool.
21359                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
21360                if((!isUeCellEdge) && (!n->node))
21361                {
21362                   l = &dlSf->sfrTotalPoolInfo.cePool;
21363                   n = cmLListFirst(l);
21364                }
21365
21366                continue;
21367             }
21368
21369          //   return (FALSE);
21370          }
21371       }
21372       else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
21373       {
21374          sfrPool = (RgSchSFRPoolInfo*)(n->node);
21375          /* This is a Case where a UE was CC and had more RBs allocated than present in CE pool.
21376             In case this UE whn become CE with retx going on, then BW is not sufficient for Retx */
21377          if ((isUeCellEdge) &&
21378             (allocInfo->tbInfo[0].tbCb->txCntr != 0))
21379          {
21380             if(allocInfo->rbsReq > (sfrPool->bw - sfrPool->bwAlloced))
21381             {
21382                /* Adjust CE BW such that Retx alloc is successful */
21383                /* Check if merging CE with adjacent CC pool will be sufficient to process Retx */
21384
21385                /* If no Type 0 allocations are made from this pool */
21386                if (sfrPool->type0End == (((sfrPool->poolendRB + 1) / cell->rbgSize) - 1))
21387                {
21388                   if (sfrPool->adjCCPool &&
21389                         (sfrPool->adjCCPool->type2Start == sfrPool->poolendRB + 1) &&
21390                         (allocInfo->rbsReq <= ((sfrPool->bw - sfrPool->bwAlloced) + 
21391                                                ((sfrPool->adjCCPool->bw - sfrPool->adjCCPool->bwAlloced)))))
21392                   {
21393                      addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
21394
21395                      /* Adjusting CE Pool Info */
21396                      sfrPool->bw += addtnlPRBs;
21397                      sfrPool->type0End = ((sfrPool->poolendRB + addtnlPRBs + 1) /
21398                            cell->rbgSize) - 1;
21399
21400                      /* Adjusting CC Pool Info */
21401                      sfrPool->adjCCPool->type2Start += addtnlPRBs;
21402                      sfrPool->adjCCPool->type2End = RGSCH_CEIL(sfrPool->adjCCPool->type2Start, 
21403                            cell->rbgSize);
21404                      sfrPool->adjCCPool->bw -= addtnlPRBs;
21405                      *sfrpoolInfo = sfrPool;
21406                      return (TRUE);
21407                   }
21408                }
21409             }
21410          }
21411
21412          /* Check if CC pool is one of the following:
21413           * 1. |CE| + |CC "CCPool2Exists" = TRUE|
21414           * 2. |CC "CCPool2Exists" = FALSE| + |CE| + |CC "CCPool2Exists" = TRUE|
21415           */ 
21416          if(TRUE == sfrPool->CCPool2Exists)
21417          {
21418             l1 = &dlSf->sfrTotalPoolInfo.cePool;
21419             n1 = cmLListFirst(l1); 
21420             sfrCEPool = (RgSchSFRPoolInfo*)(n1->node);
21421             if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced))
21422             {
21423                *sfrpoolInfo = sfrCEPool;
21424                return (TRUE);
21425             }
21426             else if(allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))  
21427             {
21428                *sfrpoolInfo = sfrPool;
21429                return (TRUE);
21430             }
21431             /* Check if CE and CC boundary has unallocated prbs */
21432             else if ((sfrPool->poolstartRB == sfrPool->type2Start) &&
21433                   (sfrCEPool->type0End  == ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1))
21434             {
21435                if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced) + 
21436                      (sfrPool->bw - sfrPool->bwAlloced))
21437                {
21438                   /* Checking if BW can be allocated partly from CE pool and partly
21439                    * from CC pool
21440                    */
21441                   addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
21442                   /* Updating CE and CC  type2 parametrs based on the RBs allocated
21443                    * from these pools*/
21444                   sfrPool->type2Start -= addtnlPRBs;
21445                   sfrPool->type2End = RGSCH_CEIL(sfrPool->type2Start, cell->rbgSize);
21446                   sfrPool->bw += addtnlPRBs;
21447                   if (addtnlPRBs == (sfrCEPool->bw - sfrCEPool->bwAlloced))
21448                   {
21449                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
21450                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
21451                   }
21452                   else
21453                   {
21454                      sfrCEPool->bw -= addtnlPRBs;
21455                      sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1 - addtnlPRBs) / cell->rbgSize) - 1;
21456                   }
21457                   *sfrpoolInfo = sfrPool;
21458                   return (TRUE);
21459                }
21460                else if ( bwAvlbl < 
21461                      ((sfrCEPool->bw - sfrCEPool->bwAlloced) +
21462                       (sfrPool->bw - sfrPool->bwAlloced)))
21463                {
21464                   /* All the Prbs from CE BW shall be allocated */
21465                   if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21466                   {
21467                      sfrPool->type2Start   = sfrCEPool->type2Start;
21468                      sfrPool->bw          += sfrCEPool->bw - sfrCEPool->bwAlloced;
21469                      sfrCEPool->type2Start = sfrCEPool->poolendRB + 1;
21470                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
21471                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
21472
21473                      /* set the remaining RBs for the requested UE */
21474                      allocInfo->rbsReq = (sfrPool->bw - sfrPool->bwAlloced);
21475                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21476                      noLyrs = allocInfo->tbInfo[0].noLyr;
21477                      allocInfo->tbInfo[0].bytesReq = 
21478                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21479                      *sfrpoolInfo = sfrPool;               
21480                      return (TRUE);
21481                   }
21482                   else
21483                   {
21484                      return (FALSE);
21485                   }
21486                }
21487             }
21488          } 
21489
21490          /* Checking if no. of RBs required can be allocated from
21491           * SFR pool. 
21492           * 1. If available return the SFR pool.
21493           * 2. Else update the RBs required parameter based on the 
21494           *    BW available in the pool 
21495           * 3. Return FALSE if no B/W is available. 
21496           */
21497          if (allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))
21498          {
21499             *sfrpoolInfo = sfrPool;
21500             return (TRUE);
21501          }
21502          else
21503          {
21504             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21505             {
21506                if (bwAvlbl < sfrPool->bw - sfrPool->bwAlloced)
21507                {
21508                   if (isUeCellEdge)
21509                   {
21510                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
21511                   }
21512                   bwAvlbl = sfrPool->bw - sfrPool->bwAlloced;
21513                   poolWithMaxAvlblBw = sfrPool;
21514                }
21515                n = cmLListNext(l);
21516
21517                if ((isUeCellEdge == FALSE) && (n == NULLP))
21518                {
21519                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
21520                   {
21521                      l = &dlSf->sfrTotalPoolInfo.cePool;
21522                      n = cmLListFirst(l);                          
21523                   }
21524                }
21525
21526                if (n == NULLP)
21527                {
21528                   if (bwAvlbl == 0)
21529                   {                                                             
21530                      if (isUeCellEdge)
21531                      {
21532                         dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
21533                      }
21534                      else
21535                      {
21536                         dlSf->sfrTotalPoolInfo.ccBwFull = TRUE;  
21537                      }
21538                      return (FALSE);
21539                   }
21540                   else
21541                   {
21542                      /* set the remaining RBs for the requested UE */
21543                      allocInfo->rbsReq = poolWithMaxAvlblBw->bw - 
21544                         poolWithMaxAvlblBw->bwAlloced;
21545                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21546                      noLyrs = allocInfo->tbInfo[0].noLyr;
21547                      allocInfo->tbInfo[0].bytesReq = 
21548                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21549                      *sfrpoolInfo = poolWithMaxAvlblBw;            
21550                      return (TRUE);
21551                   }
21552                }                          
21553             }
21554             else
21555             {                   
21556                n = cmLListNext(l);
21557
21558                if ((isUeCellEdge == FALSE) && (n == NULLP))
21559                {
21560                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
21561                   {
21562                      l = &dlSf->sfrTotalPoolInfo.cePool;
21563                      n = cmLListFirst(l);                          
21564                   }
21565                }
21566
21567                if (n == NULLP)
21568                {
21569                   return (FALSE);
21570                }
21571             }
21572
21573          }
21574       }   
21575    } 
21576    return (FALSE);
21577 }
21578 #endif
21579 #endif /* end of ifndef LTE_TDD*/
21580 /* LTE_ADV_FLAG_REMOVED_END */
21581
21582 /**
21583  * @brief To check if DL BW available for non-DLFS allocation.
21584  *
21585  * @details
21586  *
21587  *     Function : rgSCHCmnNonDlfsUeRbAlloc
21588  *
21589  *     Processing Steps:
21590  *      - Determine availability based on RA Type.
21591  *
21592  *  @param[in]  RgSchCellCb     *cell
21593  *  @param[in]  RgSchDlSf       *dlSf
21594  *  @param[in]  RgSchDlRbAlloc  *allocInfo
21595  *
21596  *  @return Bool
21597  *      -# TRUE
21598  *      -# FALSE
21599  **/
21600 #ifdef UNUSED_FUNC
21601 static Bool rgSCHCmnNonDlfsBwAvlbl
21602 (
21603 RgSchCellCb     *cell,
21604 RgSchDlSf       *dlSf,
21605 RgSchDlRbAlloc  *allocInfo
21606 )
21607 {
21608    uint8_t tbs;
21609    uint8_t noLyrs;
21610    uint8_t ignoredDfctRbg = FALSE;
21611
21612    if (dlSf->bw <= dlSf->bwAlloced)
21613    {
21614       DU_LOG("\nERROR  -->  SCH : (%d:%d)FAILED CRNTI:%d",
21615          dlSf->bw, dlSf->bwAlloced,allocInfo->rnti);
21616       return (FALSE);
21617    }
21618    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
21619    {
21620        /* Fix for ccpu00123919 : Number of RBs in case of RETX should be same as 
21621         * that of initial transmission. */
21622        if(allocInfo->tbInfo[0].tbCb->txCntr)
21623        {
21624           /* If RB assignment is being done for RETX. Then if reqRbs are 
21625            * a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
21626            * not a multiple of rbgSize then check if lsgRbgDfct exists */
21627           if (allocInfo->rbsReq % cell->rbgSize == 0)
21628           {
21629              if (dlSf->lstRbgDfct)
21630              {
21631                 /* In this scenario we are wasting the last RBG for this dlSf */
21632                 
21633                 dlSf->type0End--;
21634                 dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21635                 /* Fix: MUE_PERTTI_DL */
21636                 dlSf->lstRbgDfct = 0;
21637                 ignoredDfctRbg = TRUE;
21638                 
21639              }
21640           }
21641           else
21642           {
21643              if (dlSf->lstRbgDfct)
21644              {
21645                 /* Check if type0 allocation can cater to this RETX requirement */
21646                 if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
21647                 {
21648                    return (FALSE);
21649                 }
21650              }
21651              else
21652              {
21653                 /* cannot allocate same number of required RBs */
21654                 return (FALSE);              
21655              }
21656           }
21657        }
21658
21659        /* Condition is modified approprialtely to find
21660         * if rbsReq is less than available RBS*/
21661       if(allocInfo->rbsReq <= (((dlSf->type0End - dlSf->type2End + 1)*\
21662                cell->rbgSize) - dlSf->lstRbgDfct))
21663       {
21664          return (TRUE);
21665       }
21666       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
21667        * allocation in TDD when requested RBs are more than available RBs*/
21668       else
21669       {
21670           /* MS_WORKAROUND for ccpu00122022 */
21671          if (dlSf->bw < dlSf->bwAlloced + cell->rbgSize)
21672          {
21673             /* ccpu00132358- Re-assigning the values which were updated above 
21674              * if it is RETX and Last  RBG available*/
21675             if(ignoredDfctRbg == TRUE)
21676             {
21677                dlSf->type0End++;
21678                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
21679                dlSf->lstRbgDfct = 1;
21680             }
21681
21682
21683             return (FALSE);
21684          }
21685          /* Fix: Number of RBs in case of RETX should be same as 
21686           * that of initial transmission. */
21687          if(allocInfo->tbInfo[0].tbCb->txCntr == 0 
21688 #ifdef LTE_ADV
21689             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
21690 #endif
21691             )
21692          {
21693             /* Setting the remaining RBs for the requested UE*/
21694             allocInfo->rbsReq = (((dlSf->type0End - dlSf->type2End + 1)*\
21695                         cell->rbgSize) - dlSf->lstRbgDfct);
21696             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21697             noLyrs = allocInfo->tbInfo[0].noLyr;
21698             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21699             /* DwPts Scheduling Changes Start */
21700 #if LTE_TDD
21701             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
21702             {   
21703                allocInfo->tbInfo[0].bytesReq = 
21704                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
21705             }
21706 #endif            
21707             /* DwPts Scheduling Changes End */
21708          }
21709          else
21710          {
21711                     /* ccpu00132358- Re-assigning the values which were updated above 
21712              * if it is RETX and Last  RBG available*/
21713             if(ignoredDfctRbg == TRUE)
21714             {
21715                dlSf->type0End++;
21716                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
21717                dlSf->lstRbgDfct = 1;
21718             }
21719
21720             DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",
21721                   allocInfo->rnti);
21722             DU_LOG("\nERROR  -->  SCH : RB Alloc failed for LAA TB type 0\n");
21723             return (FALSE);
21724          }
21725          return (TRUE);
21726       }
21727    }
21728    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
21729    {
21730       if (allocInfo->rbsReq <= (dlSf->bw - dlSf->bwAlloced))
21731       {
21732          return (TRUE);
21733       }
21734       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
21735        * allocation in TDD when requested RBs are more than available RBs*/
21736       else
21737       {
21738          /* Fix: Number of RBs in case of RETX should be same as 
21739           * that of initial transmission. */
21740          if((allocInfo->tbInfo[0].tbCb->txCntr == 0) 
21741 #ifdef LTE_ADV
21742             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
21743 #endif
21744             )
21745          {
21746             /* set the remaining RBs for the requested UE */
21747             allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
21748             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21749             noLyrs = allocInfo->tbInfo[0].noLyr;
21750             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21751             /* DwPts Scheduling Changes Start */
21752 #ifdef LTE_TDD
21753             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
21754             {   
21755                allocInfo->tbInfo[0].bytesReq = 
21756                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
21757             }
21758 #endif            
21759             /* DwPts Scheduling Changes End */
21760          }
21761          else
21762          {
21763             DU_LOG("\nERROR  -->  SCH : RB Alloc failed for LAA TB type 2\n");
21764             DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",allocInfo->rnti);
21765             return (FALSE);
21766          }
21767          /* Fix: Number of RBs in case of RETX should be same as 
21768           * that of initial transmission. */
21769          return (TRUE);
21770       }
21771    }
21772    DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",allocInfo->rnti);
21773    return (FALSE);
21774 }
21775 #endif
21776 /* LTE_ADV_FLAG_REMOVED_START */
21777 #ifndef LTE_TDD
21778 /**
21779  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21780  *
21781  * @details
21782  *
21783  *     Function : rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
21784  *
21785  *     Processing Steps:
21786  *
21787  *  @param[in]  RgSchCellCb     *cell
21788  *  @param[in]  RgSchDlSf       *dlSf
21789  *  @param[in]  uint8_t              rbStrt
21790  *  @param[in]  uint8_t              numRb
21791  *
21792  *  @return Void
21793  **/
21794 Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
21795 (
21796 RgSchCellCb  *cell,
21797 RgSchDlSf    *dlSf,
21798 uint8_t      rbStrt,
21799 uint8_t      numRb
21800 )
21801
21802    CmLListCp   *l;
21803    CmLList     *n;
21804    RgSchSFRPoolInfo  *sfrPool;
21805    
21806    l = &dlSf->sfrTotalPoolInfo.ccPool;
21807      
21808    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21809    dlSf->bwAlloced += numRb;
21810    dlSf->type2Start += numRb;
21811    n = cmLListFirst(l);
21812         
21813    while(n->node)
21814    {
21815         sfrPool = (RgSchSFRPoolInfo*)(n->node);
21816         n = cmLListNext(l);
21817          
21818          /* 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   */
21819         if((sfrPool->poolendRB >= dlSf->type2Start) && (sfrPool->type2Start < dlSf->type2Start))
21820         {
21821                 sfrPool->type2End   =  dlSf->type2End;
21822                 sfrPool->bwAlloced  =  dlSf->type2Start - sfrPool->poolstartRB; 
21823                 sfrPool->type2Start =  dlSf->type2Start;
21824         }          
21825         else 
21826         { 
21827                 /* If the pool contains all RBs allocated in this allocation*/
21828                 if(dlSf->type2Start > sfrPool->poolendRB)
21829                 {                
21830                         sfrPool->type2End   =  sfrPool->type0End + 1;
21831                         sfrPool->bwAlloced  =  sfrPool->bw; 
21832                         sfrPool->type2Start =  sfrPool->poolendRB + 1;             
21833                 }  
21834         }
21835       if (!n)
21836       { 
21837          if (l != &dlSf->sfrTotalPoolInfo.cePool)
21838          {
21839             l = &dlSf->sfrTotalPoolInfo.cePool;   
21840             n = cmLListFirst(l);
21841          }
21842          else
21843             return;
21844       }
21845    }
21846    return;
21847 }
21848
21849 /**
21850  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21851  *
21852  * @details
21853  *
21854  *     Function : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
21855  *
21856  *     Processing Steps:
21857  *
21858  *  @param[in]  RgSchCellCb     *cell
21859  *  @param[in]  RgSchDlSf       *dlSf
21860  *  @param[in]  uint8_t              rbStrt
21861  *  @param[in]  uint8_t              numRb
21862  *
21863  *  @return Void
21864  **/
21865 #ifdef UNUSED_FUNC
21866 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
21867 (
21868 RgSchCellCb  *cell,
21869 RgSchUeCb    *ue,
21870 RgSchDlSf    *dlSf,
21871 uint8_t      rbStrt,
21872 uint8_t      numRb
21873 )
21874 {
21875    CmLListCp   *l;
21876    CmLList     *n;
21877    RgSchSFRPoolInfo  *sfrCCPool1 = NULL;
21878    RgSchSFRPoolInfo  *sfrCCPool2 = NULL;
21879    S16 ret = RFAILED;
21880
21881    /* Move the type2End pivot forward */
21882    
21883    
21884    l = &dlSf->sfrTotalPoolInfo.ccPool;
21885    n = cmLListFirst(l);
21886    while(n)
21887    {
21888       sfrCCPool1 = (RgSchSFRPoolInfo*)(n->node);
21889       /* KWork fix */
21890       if (sfrCCPool1 ==  NULLP)
21891             {
21892                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
21893                         "sfrCCPool1 is NULL for CRNTI:%d",ue->ueId);
21894                return RFAILED;
21895             }
21896       n = cmLListNext(l);
21897       if(n)
21898       {
21899           sfrCCPool2 = (RgSchSFRPoolInfo*)(n->node);
21900           n = cmLListNext(l);
21901       }
21902       if((sfrCCPool1) && (sfrCCPool2))
21903       { 
21904           /* Based on RNTP info, the CC user is assigned high power per subframe basis */
21905           if(((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
21906               (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) || 
21907              ((dlSf->type2Start >= sfrCCPool2->pwrHiCCRange.startRb) &&
21908               (dlSf->type2Start + numRb < sfrCCPool2->pwrHiCCRange.endRb)))
21909           {
21910                ue->lteAdvUeCb.isCCUePHigh = TRUE;
21911
21912                /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
21913                ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
21914                if (ret != ROK)
21915                {
21916                     DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
21917                       "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
21918                     return RFAILED;
21919                }
21920            }
21921       }
21922       else
21923       {
21924          if((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
21925                (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb))
21926          {
21927             ue->lteAdvUeCb.isCCUePHigh = TRUE;
21928
21929             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
21930             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
21931             if (ret != ROK)
21932             {
21933                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" 
21934                         "rgSCHCmnBuildRntpInfo() function returned RFAILED CRNTI:%d",ue->ueId);
21935                return RFAILED;
21936             }
21937          }
21938       }
21939    }
21940    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21941 #ifndef LTEMAC_SPS
21942    dlSf->bwAlloced += numRb;
21943    /*MS_FIX for ccpu00123918*/
21944    dlSf->type2Start += numRb;
21945 #endif
21946    return ROK;
21947
21948 }
21949 #endif
21950 #endif /* end of ifndef LTE_TDD*/
21951 /* LTE_ADV_FLAG_REMOVED_END */
21952 /**
21953  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21954  *
21955  * @details
21956  *
21957  *     Function : rgSCHCmnNonDlfsUpdTyp2Alloc
21958  *
21959  *     Processing Steps:
21960  *
21961  *  @param[in]  RgSchCellCb     *cell
21962  *  @param[in]  RgSchDlSf       *dlSf
21963  *  @param[in]  uint8_t              rbStrt
21964  *  @param[in]  uint8_t              numRb
21965  *
21966  *  @return Void
21967  **/
21968 static Void rgSCHCmnNonDlfsUpdTyp2Alloc
21969 (
21970 RgSchCellCb *cell,
21971 RgSchDlSf   *dlSf,
21972 uint8_t     rbStrt,
21973 uint8_t     numRb
21974 )
21975 {
21976    /* Move the type2End pivot forward */
21977    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21978 //#ifndef LTEMAC_SPS
21979    dlSf->bwAlloced += numRb;
21980    /*Fix for ccpu00123918*/
21981    dlSf->type2Start += numRb;
21982 //#endif
21983    return;
21984 }
21985
21986 /**
21987  * @brief To do DL allocation using TYPE0 RA.
21988  *
21989  * @details
21990  *
21991  *     Function : rgSCHCmnNonDlfsType0Alloc
21992  *
21993  *     Processing Steps:
21994  *      - Perform TYPE0 allocation using the RBGs between
21995  *        type0End and type2End.
21996  *      - Build the allocation mask as per RBG positioning.
21997  *      - Update the allocation parameters.
21998  *
21999  *  @param[in]  RgSchCellCb     *cell
22000  *  @param[in]  RgSchDlSf       *dlSf
22001  *  @param[in]  RgSchDlRbAlloc  *allocInfo
22002  *
22003  *  @return Void
22004  **/
22005 #ifdef UNUSED_FUNC
22006 static Void rgSCHCmnNonDlfsType0Alloc
22007 (
22008 RgSchCellCb     *cell,
22009 RgSchDlSf       *dlSf,
22010 RgSchDlRbAlloc  *allocInfo,
22011 RgSchUeCb       *ue
22012 )
22013 {
22014    uint32_t dlAllocMsk = 0;
22015    uint8_t  rbgFiller = dlSf->lstRbgDfct;
22016    uint8_t  noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
22017    //uint8_t  noRbgs = (allocInfo->rbsReq + rbgFiller)/ cell->rbgSize;
22018    uint8_t  noRbs;
22019    uint8_t  noLyr;
22020    uint8_t  iTbs;
22021    uint32_t          tb1BytesAlloc = 0;
22022    uint32_t          tb2BytesAlloc = 0;
22023    RgSchCmnDlUe *dlUe         = RG_SCH_CMN_GET_DL_UE(ue,cell);
22024
22025    //if(noRbgs == 0) noRbgs = 1; /* Not required as ceilling is used above*/
22026
22027    /* Fix for ccpu00123919*/
22028    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22029    if (dlSf->bwAlloced + noRbs > dlSf->bw)
22030    {
22031       if (--noRbgs == 0)
22032       {
22033          return;
22034       }
22035       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22036    }
22037
22038    /* Fix for ccpu00138701: Ceilling is using to derive num of RBGs, Therefore, 
22039    *  after this operation,checking Max TB size and Max RBs are not crossed
22040    * if it is crossed then decrement num of RBGs. */
22041    //if((noRbs + rbgFiller) % cell->rbgSize)
22042    if((noRbs > allocInfo->rbsReq) &&
22043          (allocInfo->rbsReq + rbgFiller) % cell->rbgSize)
22044    {/* considering ue category limitation
22045      * due to ceiling */
22046
22047 #ifdef LTE_ADV
22048       if (rgSCHLaaIsLaaTB(allocInfo)== FALSE)
22049 #endif
22050       {
22051          if ((allocInfo->tbInfo[0].schdlngForTb) && (!allocInfo->tbInfo[0].tbCb->txCntr))
22052          {
22053             iTbs = allocInfo->tbInfo[0].iTbs;
22054             noLyr = allocInfo->tbInfo[0].noLyr;
22055             tb1BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22056          }
22057
22058          if ((allocInfo->tbInfo[1].schdlngForTb) && (!allocInfo->tbInfo[1].tbCb->txCntr))
22059          {
22060             iTbs = allocInfo->tbInfo[1].iTbs;
22061             noLyr = allocInfo->tbInfo[1].noLyr;
22062             tb2BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22063          }
22064       }
22065       
22066       /* Only Check for New Tx No need for Retx */
22067       if (tb1BytesAlloc || tb2BytesAlloc)
22068       {
22069          if (( ue->dl.aggTbBits >= dlUe->maxTbBits) ||
22070                (tb1BytesAlloc >= dlUe->maxTbSz/8) ||
22071                (tb2BytesAlloc >= dlUe->maxTbSz/8) ||
22072                (noRbs >= dlUe->maxRb))
22073          {
22074             if (--noRbgs == 0)
22075             {
22076                return;
22077             }
22078             noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22079          }
22080       }
22081    }
22082    /* type0End would have been initially (during subfrm Init) at the bit position
22083     * (cell->noOfRbgs - 1), 0 being the most significant.
22084     * Getting DlAllocMsk for noRbgs and at the appropriate position */
22085    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - dlSf->type0End));
22086    /* Move backwards the type0End pivot */
22087    dlSf->type0End -= noRbgs;
22088    /*Fix for ccpu00123919*/
22089    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
22090    /* Update the bwAlloced field accordingly */
22091 //#ifndef LTEMAC_SPS    /* ccpu00129474*/
22092    dlSf->bwAlloced += noRbs;
22093 //#endif
22094    /* Update Type0 Alloc Info */
22095    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
22096    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
22097    allocInfo->rbsAlloc = noRbs;
22098
22099    /* Update Tb info for each scheduled TB */
22100    iTbs = allocInfo->tbInfo[0].iTbs;
22101    noLyr = allocInfo->tbInfo[0].noLyr;
22102    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
22103     * RETX TB Size is same as Init TX TB Size */
22104    if (allocInfo->tbInfo[0].tbCb->txCntr)
22105    {
22106       allocInfo->tbInfo[0].bytesAlloc =
22107          allocInfo->tbInfo[0].bytesReq;
22108    }
22109    else
22110    {
22111       allocInfo->tbInfo[0].bytesAlloc =
22112          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22113       /* DwPts Scheduling Changes Start */
22114 #ifdef LTE_TDD
22115       if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
22116       {
22117          allocInfo->tbInfo[0].bytesAlloc =
22118             rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
22119       }
22120 #endif      
22121       /* DwPts Scheduling Changes End */
22122    }
22123
22124    if (allocInfo->tbInfo[1].schdlngForTb)
22125    {
22126       iTbs = allocInfo->tbInfo[1].iTbs;
22127       noLyr = allocInfo->tbInfo[1].noLyr;
22128       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
22129        * RETX TB Size is same as Init TX TB Size */
22130       if (allocInfo->tbInfo[1].tbCb->txCntr)
22131       {
22132          allocInfo->tbInfo[1].bytesAlloc =
22133             allocInfo->tbInfo[1].bytesReq;
22134       }
22135       else
22136       {
22137          allocInfo->tbInfo[1].bytesAlloc =
22138             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22139          /* DwPts Scheduling Changes Start */
22140 #ifdef LTE_TDD
22141          if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
22142          {
22143             allocInfo->tbInfo[1].bytesAlloc =
22144                rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
22145          }
22146 #endif      
22147          /* DwPts Scheduling Changes End */
22148       }
22149    }
22150
22151    /* The last RBG which can be smaller than the RBG size is consedered
22152     * only for the first time allocation of TYPE0 UE */
22153    dlSf->lstRbgDfct = 0;
22154    return;
22155 }
22156 #endif
22157 #ifndef LTE_TDD
22158
22159 /**
22160  * @brief To prepare RNTP value from the PRB allocation (P-High -> 1 and P-Low -> 0)
22161  *
22162  * @details
22163  *
22164  *     Function : rgSCHCmnBuildRntpInfo
22165  *
22166  *     Processing Steps:
22167  *
22168  *  @param[in]  uint8_t                 *rntpPtr
22169  *  @param[in]  uint8_t                 startRb
22170  *  @param[in]  uint8_t                 numRb
22171  *
22172  *  @return Void
22173  **/
22174 #ifdef UNUSED_FUNC
22175 static S16 rgSCHCmnBuildRntpInfo
22176 (
22177 RgSchCellCb  *cell,
22178 uint8_t      *rntpPtr,
22179 uint8_t      startRb,
22180 uint8_t      nmbRb,
22181 uint16_t     bw
22182 )
22183 {
22184    uint16_t rbPtrStartIdx;              /* Start Index of Octete Buffer to be filled */
22185    uint16_t rbPtrEndIdx;                /* End Index of Octete Buffer to be filled */
22186    uint16_t rbBitLoc;                   /* Bit Location to be set as 1 in the current Byte */
22187    uint16_t nmbRbPerByte;               /* PRB's to be set in the current Byte (in case of multiple Bytes) */
22188
22189
22190    rbPtrStartIdx = (startRb)/8;
22191    rbPtrEndIdx   = (startRb + nmbRb)/8;
22192
22193    if (rntpPtr == NULLP)
22194    {
22195       DU_LOG("\nERROR  -->  SCH : rgSCHCmnBuildRntpInfo():"
22196                "rntpPtr can't be NULLP (Memory Allocation Failed)");
22197       return RFAILED;
22198    }
22199
22200    while(rbPtrStartIdx <= rbPtrEndIdx)
22201    {
22202       rbBitLoc = (startRb)%8;
22203
22204       /* case 1: startRb and endRb lies in same Byte */
22205       if (rbPtrStartIdx == rbPtrEndIdx)
22206       {
22207          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
22208                                      | (((1<<nmbRb)-1)<<rbBitLoc);
22209       }
22210
22211       /* case 2: startRb and endRb lies in different Byte */
22212       if (rbPtrStartIdx != rbPtrEndIdx)
22213       {
22214          nmbRbPerByte = 8 - rbBitLoc;
22215          nmbRb        = nmbRb - nmbRbPerByte;
22216          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
22217                                      | (((1<<nmbRbPerByte)-1)<<rbBitLoc);
22218          startRb = startRb + nmbRbPerByte;
22219       }
22220
22221       rbPtrStartIdx++;
22222    }
22223
22224    /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** Adding Debug logs */
22225
22226    /* dsfr_pal_fixes ** 25-March-2013 ** SKS ** Adding Debug logs to print RNTP */
22227
22228    return ROK;
22229 }
22230
22231 /**
22232  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
22233  *
22234  * @details
22235  *
22236  *     Function : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
22237  *
22238  *     Processing Steps:
22239  *
22240  *  @param[in]  RgSchCellCb     *cell
22241  *  @param[in]  RgSchDlSf       *dlSf
22242  *  @param[in]  uint8_t              rbStrt
22243  *  @param[in]  uint8_t              numRb
22244  *
22245  *  @return Void
22246  **/
22247 static S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
22248 (
22249 RgSchCellCb        *cell,
22250 RgSchUeCb          *ue,
22251 RgSchDlSf          *dlSf,
22252 RgSchSFRPoolInfo   *sfrPool,
22253 uint8_t            rbStrt,
22254 uint8_t            numRb
22255 )
22256 {
22257 #ifndef LTEMAC_SPS
22258    S16 ret;
22259 #endif
22260
22261    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
22262    sfrPool->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
22263    
22264 #ifndef LTEMAC_SPS
22265    dlSf->type2Start += numRb;
22266    dlSf->bwAlloced += numRb;
22267    
22268    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
22269    {
22270       /* Based on RNTP info, the CC user is assigned high power per subframe basis */
22271       if(FALSE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge)
22272       {
22273          if((sfrPool->type2Start >= sfrPool->pwrHiCCRange.startRb) &&
22274                (sfrPool->type2Start + numRb < sfrPool->pwrHiCCRange.endRb))
22275          {
22276             ue->lteAdvUeCb.isCCUePHigh = TRUE;
22277
22278             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
22279             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
22280             if (ret != ROK)
22281             {
22282                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
22283                         "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
22284                return RFAILED;
22285             }
22286          }
22287       }
22288       else
22289       {
22290          /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
22291          ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
22292          if (ret != ROK)
22293          {
22294             DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
22295                      "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
22296             return RFAILED;
22297          }
22298       }
22299    }
22300    sfrPool->type2Start += numRb;
22301    sfrPool->bwAlloced += numRb;
22302 #endif 
22303
22304    return ROK;
22305 }
22306
22307 /**
22308  * @brief To do DL allocation using TYPE0 RA.
22309  *
22310  * @details
22311  *
22312  *     Function : rgSCHCmnNonDlfsSFRPoolType0Alloc
22313  *
22314  *     Processing Steps:
22315  *      - Perform TYPE0 allocation using the RBGs between type0End and type2End.
22316  *      - Build the allocation mask as per RBG positioning.
22317  *      - Update the allocation parameters.
22318  *
22319  *  @param[in]  RgSchCellCb     *cell
22320  *  @param[in]  RgSchDlSf       *dlSf
22321  *  @param[in]  RgSchDlRbAlloc  *allocInfo
22322  *
22323  *  @return Void
22324  **/
22325 static Void rgSCHCmnNonDlfsSFRPoolType0Alloc
22326 (
22327 RgSchCellCb        *cell,
22328 RgSchDlSf          *dlSf,
22329 RgSchSFRPoolInfo   *poolInfo,
22330 RgSchDlRbAlloc     *allocInfo
22331 )
22332 {
22333    uint32_t dlAllocMsk = 0;
22334    uint8_t  rbgFiller = 0;
22335    uint8_t  noRbgs = 0;
22336    uint8_t  noRbs;
22337    uint8_t  noLyr;
22338    uint8_t  iTbs;
22339
22340
22341    if (poolInfo->poolstartRB + poolInfo->bw == dlSf->bw)
22342    {
22343                 if (poolInfo->type0End == dlSf->bw/4)
22344                 {
22345                         rbgFiller = dlSf->lstRbgDfct;
22346                         /* The last RBG which can be smaller than the RBG size is consedered
22347                         * only for the first time allocation of TYPE0 UE */
22348                         dlSf->lstRbgDfct = 0;
22349                 }
22350    }
22351
22352    noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
22353
22354    /* Abhinav to-do start */
22355    /* MS_FIX for ccpu00123919*/
22356    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22357    if (dlSf->bwAlloced + noRbs > dlSf->bw)
22358    {
22359       if (--noRbgs == 0)
22360       {
22361          return;
22362       }
22363       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22364    }
22365    /* Abhinav to-do end */
22366
22367
22368    
22369    /* type0End would have been initially (during subfrm Init) at the bit position
22370     * (cell->noOfRbgs - 1), 0 being the most significant.
22371     * Getting DlAllocMsk for noRbgs and at the appropriate position */
22372    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - poolInfo->type0End));
22373    /* Move backwards the type0End pivot */
22374    poolInfo->type0End -= noRbgs;
22375    /*MS_FIX for ccpu00123919*/
22376    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
22377    /* Update the bwAlloced field accordingly */
22378    poolInfo->bwAlloced += noRbs + dlSf->lstRbgDfct;
22379    dlSf->bwAlloced += noRbs + dlSf->lstRbgDfct;
22380    
22381    /* Update Type0 Alloc Info */
22382    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
22383    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
22384    allocInfo->rbsAlloc = noRbs;
22385
22386    /* Update Tb info for each scheduled TB */
22387    iTbs = allocInfo->tbInfo[0].iTbs;
22388    noLyr = allocInfo->tbInfo[0].noLyr;
22389    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
22390     * RETX TB Size is same as Init TX TB Size */
22391    if (allocInfo->tbInfo[0].tbCb->txCntr)
22392    {
22393       allocInfo->tbInfo[0].bytesAlloc =
22394          allocInfo->tbInfo[0].bytesReq;
22395    }
22396    else
22397    {
22398       allocInfo->tbInfo[0].bytesAlloc =
22399          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22400    }
22401
22402    if (allocInfo->tbInfo[1].schdlngForTb)
22403    {
22404       iTbs = allocInfo->tbInfo[1].iTbs;
22405       noLyr = allocInfo->tbInfo[1].noLyr;
22406       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
22407        * RETX TB Size is same as Init TX TB Size */
22408       if (allocInfo->tbInfo[1].tbCb->txCntr)
22409       {
22410          allocInfo->tbInfo[1].bytesAlloc =
22411             allocInfo->tbInfo[1].bytesReq;
22412       }
22413       else
22414       {
22415          allocInfo->tbInfo[1].bytesAlloc =
22416             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22417       }
22418    }
22419
22420    /* The last RBG which can be smaller than the RBG size is consedered
22421     * only for the first time allocation of TYPE0 UE */
22422    dlSf->lstRbgDfct = 0;
22423    return;
22424 }
22425 #endif
22426 /**
22427  * @brief Computes RNTP Info for a subframe.
22428  *
22429  * @details
22430  *
22431  *     Function :  rgSCHCmnNonDlfsDsfrRntpComp 
22432  *
22433  *     Processing Steps:
22434  *      - Computes RNTP info from individual pools.
22435  *
22436  *  @param[in]  RgSchDlSf       *dlSf
22437  *
22438  *  @return  void
22439  
22440  **/
22441 static void rgSCHCmnNonDlfsDsfrRntpComp(RgSchCellCb *cell,RgSchDlSf *dlSf)
22442 {
22443    static uint16_t samples = 0;
22444    uint16_t i;
22445    uint16_t bwBytes = (dlSf->bw-1)/8;
22446    RgrLoadInfIndInfo *rgrLoadInf;
22447    uint16_t len;
22448    uint16_t ret     = ROK;
22449
22450
22451    len = (dlSf->bw % 8 == 0) ? dlSf->bw/8 : dlSf->bw/8 + 1;
22452
22453    /* RNTP info is ORed every TTI and the sample is stored in cell control block */ 
22454    for(i = 0; i <= bwBytes; i++)
22455    {
22456      cell->rntpAggrInfo.val[i] |= dlSf->rntpInfo.val[i];
22457    }
22458    samples = samples + 1;
22459    /* After every 1000 ms, the RNTP info will be sent to application to be further sent to all neighbouring eNB
22460          informing them about the load indication for cell edge users */
22461    if(RG_SCH_MAX_RNTP_SAMPLES == samples)
22462    {
22463       /* ccpu00134492 */
22464       ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf,
22465                sizeof(RgrLoadInfIndInfo));
22466       if (ret != ROK)
22467       {
22468          DU_LOG("\nERROR  -->  SCH : Could not "
22469             "allocate memory for sending LoadInfo");
22470          return;  
22471       }
22472      
22473       rgrLoadInf->u.rntpInfo.pres = cell->rntpAggrInfo.pres;
22474       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
22475       rgrLoadInf->u.rntpInfo.len  = len;
22476
22477       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
22478       rgrLoadInf->u.rntpInfo.val = cell->rntpAggrInfo.val; 
22479       rgrLoadInf->cellId = cell->cellId;
22480
22481       /* dsfr_pal_fixes ** 22-March-2013 ** SKS */
22482       rgrLoadInf->bw = dlSf->bw;
22483       rgrLoadInf->type = RGR_SFR;
22484
22485       ret = rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf);
22486       if(ret == RFAILED)
22487       {
22488          DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsDsfrRntpComp():"
22489                   "rgSCHUtlRgrLoadInfInd() returned RFAILED");
22490       }
22491
22492       memset(cell->rntpAggrInfo.val,0,len);
22493       samples = 0;
22494    }
22495  } 
22496 /* LTE_ADV_FLAG_REMOVED_END */
22497
22498 /* LTE_ADV_FLAG_REMOVED_START */
22499 /**
22500  * @brief Performs RB allocation per UE from a pool.
22501  *
22502  * @details
22503  *
22504  *     Function : rgSCHCmnSFRNonDlfsUeRbAlloc
22505  *
22506  *     Processing Steps:
22507  *      - Allocate consecutively available RBs.
22508  *
22509  *  @param[in]  RgSchCellCb     *cell
22510  *  @param[in]  RgSchUeCb       *ue
22511  *  @param[in]  RgSchDlSf       *dlSf
22512  *  @param[out] uint8_t              *isDlBwAvail
22513  *
22514  *  @return  S16
22515  *      -# ROK
22516  *      -# RFAILED
22517  **/
22518 #ifdef UNUSED_FUNC
22519 static S16 rgSCHCmnSFRNonDlfsUeRbAlloc
22520 (
22521 RgSchCellCb        *cell,
22522 RgSchUeCb          *ue,
22523 RgSchDlSf          *dlSf,
22524 uint8_t           *isDlBwAvail
22525 )
22526 {
22527    RgSchDlRbAlloc  *allocInfo;
22528    RgSchCmnDlUe    *dlUe;
22529    Bool isUECellEdge;
22530    RgSchSFRPoolInfo *sfrpoolInfo = NULLP;
22531
22532
22533    isUECellEdge = RG_SCH_CMN_IS_UE_CELL_EDGE(ue);
22534
22535    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
22536    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
22537    *isDlBwAvail = TRUE;
22538
22539    /*Find which pool is available for this UE*/
22540    if (rgSCHCmnNonDlfsSFRBwAvlbl(cell,  &sfrpoolInfo, dlSf, allocInfo, isUECellEdge) != TRUE)
22541    {
22542       /* SFR_FIX - If this is CE UE there may be BW available in CC Pool
22543          So CC UEs will be scheduled */
22544       if (isUECellEdge)
22545       {
22546          *isDlBwAvail = TRUE;
22547       }
22548       else
22549       {
22550          *isDlBwAvail = FALSE;
22551       }
22552       return RFAILED;
22553    }
22554
22555    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX || dlUe->proc->tbInfo[1].isAckNackDtx)
22556    {
22557       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
22558    }
22559    else
22560    {
22561       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
22562    }
22563    
22564    if (!(allocInfo->pdcch))
22565    {
22566       /* Returning ROK since PDCCH might be available for another UE and further allocations could be done */
22567       return RFAILED;
22568    }
22569    
22570 #ifdef LTEMAC_SPS
22571    allocInfo->rnti = ue->ueId;
22572 #endif
22573
22574    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
22575    {
22576       allocInfo->allocInfo.raType2.isLocal = TRUE;
22577       /* rg004.201 patch - ccpu00109921 fix end */
22578       /* MS_FIX for ccpu00123918*/
22579       allocInfo->allocInfo.raType2.rbStart = (uint8_t)sfrpoolInfo->type2Start;
22580       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22581       /* rg007.201 - Changes for MIMO feature addition */
22582       /* rg008.201 - Removed dependency on MIMO compile-time flag */
22583       rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrpoolInfo, \
22584             allocInfo->allocInfo.raType2.rbStart, \
22585             allocInfo->allocInfo.raType2.numRb);
22586       allocInfo->rbsAlloc = allocInfo->rbsReq;
22587       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22588    }
22589    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
22590    {
22591       rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, sfrpoolInfo, allocInfo);
22592    }
22593 #ifndef LTE_TDD
22594 #ifdef DEBUGP
22595    rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,0);
22596    if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
22597    {
22598       rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,1);
22599    }
22600 #endif
22601 #endif
22602
22603 #if defined(LTEMAC_SPS)
22604    /* Update the sub-frame with new allocation */
22605    dlSf->bwAlloced += allocInfo->rbsReq;
22606 #endif
22607
22608    return ROK;
22609 }
22610 #endif
22611 /* LTE_ADV_FLAG_REMOVED_END */
22612 #endif /* LTE_TDD */
22613
22614 /**
22615  * @brief Performs RB allocation per UE for frequency non-selective cell.
22616  *
22617  * @details
22618  *
22619  *     Function : rgSCHCmnNonDlfsUeRbAlloc
22620  *
22621  *     Processing Steps:
22622  *      - Allocate consecutively available RBs.
22623  *
22624  *  @param[in]  RgSchCellCb     *cell
22625  *  @param[in]  RgSchUeCb       *ue
22626  *  @param[in]  RgSchDlSf       *dlSf
22627  *  @param[out] uint8_t              *isDlBwAvail
22628  *
22629  *  @return  S16
22630  *      -# ROK
22631  *      -# RFAILED
22632  **/
22633 static S16 rgSCHCmnNonDlfsUeRbAlloc
22634 (
22635 RgSchCellCb  *cell,
22636 RgSchUeCb    *ue,
22637 RgSchDlSf    *dlSf,
22638 uint8_t      *isDlBwAvail
22639 )
22640 {
22641    RgSchDlRbAlloc  *allocInfo;
22642    RgSchCmnDlUe    *dlUe;
22643 #ifdef LAA_DBG
22644    uint32_t            dbgRbsReq = 0;
22645 #endif
22646
22647 #ifdef RG_5GTF
22648    RgSch5gtfUeCb  *ue5gtfCb = &(ue->ue5gtfCb);
22649         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[ue5gtfCb->BeamId]);
22650 #endif
22651    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
22652    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
22653    *isDlBwAvail = TRUE;
22654
22655         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
22656         {
22657            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
22658          ue->ueId);
22659            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
22660                 return RFAILED;
22661         }
22662
22663    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX 
22664        || dlUe->proc->tbInfo[1].isAckNackDtx)
22665    {
22666       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
22667    }
22668    else
22669    {
22670       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
22671    }
22672    if (!(allocInfo->pdcch))
22673    {
22674       /* Returning ROK since PDCCH might be available for another UE and
22675        * further allocations could be done */
22676         DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : PDCCH allocation failed :ue (%u)",
22677          ue->ueId);
22678         DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR PDCCH allocation failed\n");
22679       return RFAILED;
22680    }
22681 #ifdef RG_5GTF
22682         //maxPrb = RGSCH_MIN((allocInfo->vrbgReq * MAX_5GTF_VRBG_SIZE), ue5gtfCb->maxPrb);
22683    //maxPrb = RGSCH_MIN(maxPrb, 
22684                 //((beamInfo->totVrbgAvail - beamInfo->vrbgStart)* MAX_5GTF_VRBG_SIZE)));
22685         //TODO_SID Need to check for vrbg available after scheduling for same beam.
22686         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
22687         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
22688         //TODO_SID: Setting for max TP
22689         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
22690         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
22691          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
22692         allocInfo->tbInfo[0].tbCb->dlGrnt.SCID = 0;
22693         allocInfo->tbInfo[0].tbCb->dlGrnt.dciFormat = allocInfo->dciFormat;
22694    //Filling temporarily
22695    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
22696    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
22697
22698         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
22699         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
22700         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22701 #endif
22702
22703    return ROK;
22704 }
22705
22706 #ifdef RGR_V1
22707 /**
22708  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
22709  *
22710  * @details
22711  *
22712  *     Function : rgSCHCmnNonDlfsCcchSduAlloc
22713  *
22714  *     Processing Steps:
22715  *     - For each element in the list, Call rgSCHCmnNonDlfsCcchSduRbAlloc().
22716  *        - If allocation is successful, add the ueCb to scheduled list of CCCH
22717  *        SDU.
22718  *        - else, add UeCb to non-scheduled list.
22719  *
22720  *  @param[in]      RgSchCellCb         *cell
22721  *  @param[in, out] RgSchCmnCcchSduRbAlloc *allocInfo
22722  *  @param[in]      uint8_t                  isRetx
22723  *
22724  *  @return  Void
22725  **/
22726 static Void rgSCHCmnNonDlfsCcchSduAlloc
22727 (
22728 RgSchCellCb         *cell,
22729 RgSchCmnCcchSduRbAlloc *allocInfo,
22730 uint8_t                  isRetx
22731 )
22732 {
22733    S16             ret;
22734    CmLListCp       *ccchSduLst        = NULLP;
22735    CmLListCp       *schdCcchSduLst    = NULLP;
22736    CmLListCp       *nonSchdCcchSduLst = NULLP;
22737    CmLList         *schdLnkNode    = NULLP;
22738    CmLList         *toBeSchdLnk    = NULLP;
22739    RgSchDlSf       *dlSf           = allocInfo->ccchSduDlSf;
22740    RgSchUeCb       *ueCb           = NULLP;
22741    RgSchDlHqProcCb *hqP            = NULLP;
22742
22743    if (isRetx)
22744    {
22745       /* Initialize re-transmitting lists */
22746       ccchSduLst = &(allocInfo->ccchSduRetxLst);
22747       schdCcchSduLst = &(allocInfo->schdCcchSduRetxLst);
22748       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduRetxLst);
22749    }
22750    else
22751    {
22752       /* Initialize transmitting lists */
22753       ccchSduLst = &(allocInfo->ccchSduTxLst);
22754       schdCcchSduLst = &(allocInfo->schdCcchSduTxLst);
22755       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduTxLst);
22756    }
22757
22758    /* Perform allocaations  for the list */
22759    toBeSchdLnk = cmLListFirst(ccchSduLst);
22760    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
22761    {
22762       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
22763       ueCb = hqP->hqE->ue;
22764       schdLnkNode = &hqP->schdLstLnk;
22765       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
22766       ret = rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf);
22767       if (ret != ROK)
22768       {
22769          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
22770           * list and return */
22771          do
22772          {
22773             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
22774             ueCb = hqP->hqE->ue;
22775             schdLnkNode = &hqP->schdLstLnk;
22776             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
22777             cmLListAdd2Tail(nonSchdCcchSduLst, schdLnkNode);
22778             toBeSchdLnk = toBeSchdLnk->next;
22779          } while(toBeSchdLnk);
22780          return;
22781       }
22782
22783       /* Allocation successful: Add UE to the scheduled list */
22784       cmLListAdd2Tail(schdCcchSduLst, schdLnkNode);
22785    }
22786
22787
22788    return;
22789 }
22790
22791 /**
22792  * @brief Performs RB allocation for CcchSdu for frequency non-selective cell.
22793  *
22794  * @details
22795  *
22796  *     Function : rgSCHCmnNonDlfsCcchSduRbAlloc
22797  *
22798  *     Processing Steps:
22799  *     - Fetch PDCCH
22800  *     - Allocate consecutively available RBs
22801  *
22802  *  @param[in] RgSchCellCb     *cell
22803  *  @param[in] RgSchUeCb       *ueCb
22804  *  @param[in] RgSchDlSf       *dlSf
22805  *  @return  S16
22806  *      -# ROK
22807  *      -# RFAILED
22808  **/
22809 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc
22810 (
22811 RgSchCellCb        *cell,
22812 RgSchUeCb          *ueCb,
22813 RgSchDlSf          *dlSf
22814 )
22815 {
22816    RgSchDlRbAlloc  *allocInfo;
22817    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
22818
22819
22820
22821    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb,cell);
22822
22823    /* [ccpu00138802]-MOD-If Bw is less than required, return fail
22824       It will be allocated in next TTI */
22825 #ifdef LTEMAC_SPS
22826    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
22827          (dlSf->bwAlloced == dlSf->bw))
22828 #else
22829    if((dlSf->bwAlloced == dlSf->bw) ||
22830       (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
22831 #endif
22832    {
22833       return RFAILED;
22834    }
22835    /* Retrieve PDCCH */
22836    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
22837    if (ueDl->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
22838    {
22839       /*      allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, dlSf, y, ueDl->cqi,
22840        *      TFU_DCI_FORMAT_1A, TRUE);*/
22841       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, TRUE);
22842    }
22843    else
22844    {
22845       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE);
22846    }
22847    if (!(allocInfo->pdcch))
22848    {
22849       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
22850       return RFAILED;
22851    }
22852
22853    /* Update allocation information */
22854    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
22855    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
22856    allocInfo->allocInfo.raType2.isLocal = TRUE;
22857
22858       /*Fix for ccpu00123918*/
22859       /* Push this harq process back to the free queue */
22860       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
22861       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22862       allocInfo->rbsAlloc = allocInfo->rbsReq;
22863       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22864       /* Update the sub-frame with new allocation */
22865       /* ccpu00129469 */
22866       /* LTE_ADV_FLAG_REMOVED_START */
22867 #ifndef LTE_TDD
22868       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
22869       {
22870          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf,
22871                allocInfo->allocInfo.raType2.rbStart,
22872                allocInfo->allocInfo.raType2.numRb);
22873       }
22874       else
22875 #endif /* end of ifndef LTE_TDD*/
22876       {
22877          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, 
22878                allocInfo->allocInfo.raType2.rbStart, 
22879                allocInfo->allocInfo.raType2.numRb);
22880       }
22881
22882    /* LTE_ADV_FLAG_REMOVED_END */
22883    /* ccpu00131941 - bwAlloced is updated from SPS bandwidth */  
22884
22885
22886    return ROK;
22887 }
22888 #endif
22889
22890 /**
22891  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
22892  *
22893  * @details
22894  *
22895  *     Function : rgSCHCmnNonDlfsMsg4RbAlloc
22896  *
22897  *     Processing Steps:
22898  *     - Fetch PDCCH
22899  *     - Allocate consecutively available RBs
22900  *
22901  *  @param[in] RgSchCellCb     *cell
22902  *  @param[in] RgSchRaCb       *raCb
22903  *  @param[in] RgSchDlSf       *dlSf
22904  *  @return  S16
22905  *      -# ROK
22906  *      -# RFAILED
22907  **/
22908 static S16 rgSCHCmnNonDlfsMsg4RbAlloc
22909 (
22910 RgSchCellCb        *cell,
22911 RgSchRaCb          *raCb,
22912 RgSchDlSf          *dlSf
22913 )
22914 {
22915    RgSchDlRbAlloc  *allocInfo;
22916
22917
22918    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(raCb);
22919
22920 #ifdef RG_5GTF
22921         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
22922         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
22923         {
22924            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
22925          raCb->ue->ueId);
22926            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
22927                 return RFAILED;
22928         }
22929 #endif
22930 #ifdef LTEMAC_SPS
22931    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
22932          (dlSf->bwAlloced == dlSf->bw))
22933 #else
22934    if((dlSf->bwAlloced == dlSf->bw) ||
22935             (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
22936 #endif
22937    {
22938
22939       return RFAILED;
22940    }
22941
22942    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
22943    if (raCb->dlHqE->msg4Proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
22944    {
22945       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, TRUE);
22946    }
22947    else
22948    {
22949       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, FALSE);
22950    }
22951    if (!(allocInfo->pdcch))
22952    {
22953       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
22954       return RFAILED;
22955    }
22956    
22957 #ifndef RG_5GTF
22958  /* SR_RACH_STATS : MSG4 TX Failed */
22959    allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
22960
22961    /* Update allocation information */
22962    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
22963    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
22964    allocInfo->allocInfo.raType2.isLocal = TRUE;
22965
22966
22967         /*Fix for ccpu00123918*/
22968         allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
22969         allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22970         /* LTE_ADV_FLAG_REMOVED_START */
22971 #ifndef LTE_TDD
22972         if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
22973         {
22974           rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
22975                 allocInfo->allocInfo.raType2.rbStart, \
22976                 allocInfo->allocInfo.raType2.numRb);
22977         }
22978         else
22979 #endif /* end of ifndef LTE_TDD */
22980         {
22981           rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
22982                 allocInfo->allocInfo.raType2.rbStart, \
22983                 allocInfo->allocInfo.raType2.numRb);
22984         }
22985         /* LTE_ADV_FLAG_REMOVED_END */
22986
22987    allocInfo->rbsAlloc = allocInfo->rbsReq;
22988    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22989
22990 #else
22991
22992   allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
22993
22994         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
22995         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
22996
22997    /* Update allocation information */
22998    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
22999
23000         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
23001         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
23002          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
23003
23004    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
23005    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
23006
23007
23008         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
23009         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
23010         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
23011
23012 #endif
23013
23014    return ROK;
23015 }
23016
23017 /**
23018  * @brief Performs RB allocation for Msg4 lists of frequency non-selective cell.
23019  *
23020  * @details
23021  *
23022  *     Function : rgSCHCmnNonDlfsMsg4Alloc
23023  *
23024  *     Processing Steps:
23025  *     - For each element in the list, Call rgSCHCmnNonDlfsMsg4RbAlloc().
23026  *        - If allocation is successful, add the raCb to scheduled list of MSG4.
23027  *        - else, add RaCb to non-scheduled list.
23028  *
23029  *  @param[in]      RgSchCellCb         *cell
23030  *  @param[in, out] RgSchCmnMsg4RbAlloc *allocInfo
23031  *  @param[in]      uint8_t                  isRetx
23032  *
23033  *  @return  Void
23034  **/
23035 static Void rgSCHCmnNonDlfsMsg4Alloc
23036 (
23037 RgSchCellCb         *cell,
23038 RgSchCmnMsg4RbAlloc *allocInfo,
23039 uint8_t             isRetx
23040 )
23041 {
23042    S16             ret;
23043    CmLListCp       *msg4Lst        = NULLP;
23044    CmLListCp       *schdMsg4Lst    = NULLP;
23045    CmLListCp       *nonSchdMsg4Lst = NULLP;
23046    CmLList         *schdLnkNode    = NULLP;
23047    CmLList         *toBeSchdLnk    = NULLP;
23048    RgSchDlSf       *dlSf           = allocInfo->msg4DlSf;
23049    RgSchRaCb       *raCb           = NULLP;
23050    RgSchDlHqProcCb *hqP            = NULLP;
23051
23052    if (isRetx)
23053    {
23054       /* Initialize re-transmitting lists */
23055       msg4Lst = &(allocInfo->msg4RetxLst);
23056       schdMsg4Lst = &(allocInfo->schdMsg4RetxLst);
23057       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4RetxLst);
23058    }
23059    else
23060    {
23061       /* Initialize transmitting lists */
23062       msg4Lst = &(allocInfo->msg4TxLst);
23063       schdMsg4Lst = &(allocInfo->schdMsg4TxLst);
23064       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4TxLst);
23065    }
23066
23067    /* Perform allocaations  for the list */
23068    toBeSchdLnk = cmLListFirst(msg4Lst);
23069    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
23070    {
23071       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23072       raCb = hqP->hqE->raCb;
23073       schdLnkNode = &hqP->schdLstLnk;
23074       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23075       ret = rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf);
23076       if (ret != ROK)
23077       {
23078          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
23079           * list and return */
23080          do
23081          {
23082             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23083             raCb = hqP->hqE->raCb;
23084             schdLnkNode = &hqP->schdLstLnk;
23085             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23086             cmLListAdd2Tail(nonSchdMsg4Lst, schdLnkNode);
23087             toBeSchdLnk = toBeSchdLnk->next;
23088          } while(toBeSchdLnk);
23089          return;
23090       }
23091
23092       /* Allocation successful: Add UE to the scheduled list */
23093       cmLListAdd2Tail(schdMsg4Lst, schdLnkNode);
23094       if (isRetx)
23095       {
23096       }
23097    }
23098
23099
23100    return;
23101 }
23102
23103 /**
23104  * @brief Performs RB allocation for the list of UEs of a frequency
23105  * non-selective cell.
23106  *
23107  * @details
23108  *
23109  *     Function : rgSCHCmnNonDlfsDedRbAlloc
23110  *
23111  *     Processing Steps:
23112  *     - For each element in the list, Call rgSCHCmnNonDlfsUeRbAlloc().
23113  *        - If allocation is successful, add the ueCb to scheduled list of UEs.
23114  *        - else, add ueCb to non-scheduled list of UEs.
23115  *
23116  *  @param[in]      RgSchCellCb        *cell
23117  *  @param[in, out] RgSchCmnUeRbAlloc  *allocInfo
23118  *  @param[in]      CmLListCp          *ueLst,
23119  *  @param[in, out] CmLListCp          *schdHqPLst,
23120  *  @param[in, out] CmLListCp          *nonSchdHqPLst
23121  *
23122  *  @return  Void
23123  **/
23124 Void rgSCHCmnNonDlfsDedRbAlloc
23125 (
23126 RgSchCellCb        *cell,
23127 RgSchCmnUeRbAlloc  *allocInfo,
23128 CmLListCp          *ueLst,
23129 CmLListCp          *schdHqPLst,
23130 CmLListCp          *nonSchdHqPLst
23131 )
23132 {
23133    S16             ret;
23134    CmLList         *schdLnkNode  = NULLP;
23135    CmLList         *toBeSchdLnk  = NULLP;
23136    RgSchDlSf       *dlSf         = allocInfo->dedDlSf;
23137    RgSchUeCb       *ue           = NULLP;
23138    RgSchDlHqProcCb *hqP          = NULLP;
23139    uint8_t         isDlBwAvail;
23140
23141
23142    /* Perform allocaations  for the list */
23143    toBeSchdLnk = cmLListFirst(ueLst);
23144    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
23145    {
23146       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23147       ue = hqP->hqE->ue;
23148       schdLnkNode = &hqP->schdLstLnk;
23149       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23150
23151       ret = rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, &isDlBwAvail);
23152       if (!isDlBwAvail)
23153       {
23154          /* Allocation failed: Add remaining UEs to non-scheduled
23155           * list and return */
23156          do
23157          {
23158             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23159             ue = hqP->hqE->ue;
23160             schdLnkNode = &hqP->schdLstLnk;
23161             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23162             cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
23163             toBeSchdLnk = toBeSchdLnk->next;
23164          } while(toBeSchdLnk);
23165          break; 
23166       }
23167
23168       if (ret == ROK)
23169       {
23170 #if defined (TENB_STATS) && defined (RG_5GTF)
23171          cell->tenbStats->sch.dl5gtfRbAllocPass++;
23172 #endif
23173          /* Allocation successful: Add UE to the scheduled list */
23174          cmLListAdd2Tail(schdHqPLst, schdLnkNode);
23175       }
23176       else
23177       {
23178 #if defined (TENB_STATS) && defined (RG_5GTF)
23179          cell->tenbStats->sch.dl5gtfRbAllocFail++;
23180 #endif
23181          /* Allocation failed : Add UE to the non-scheduled list */
23182          DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR Dl rb alloc failed adding nonSchdHqPLst\n");
23183          cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
23184       }
23185    }
23186
23187    return;
23188 }
23189
23190 /**
23191  * @brief Handles RB allocation for frequency non-selective cell.
23192  *
23193  * @details
23194  *
23195  *     Function : rgSCHCmnNonDlfsRbAlloc
23196  *
23197  *     Invoking Module Processing:
23198  *      - SCH shall invoke this if downlink frequency selective is disabled for
23199  *        the cell for RB allocation.
23200  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
23201  *        estimate and subframe for each allocation to be made to SCH.
23202  *
23203  *     Processing Steps:
23204  *     - Allocate sequentially for common channels.
23205  *     - For transmitting and re-transmitting UE list.
23206  *      - For each UE:
23207  *       - Perform wide-band allocations for UE in increasing order of
23208  *         frequency.
23209  *       - Determine Imcs for the allocation.
23210  *       - Determine RA type.
23211  *       - Determine DCI format.
23212  *
23213  *  @param[in]  RgSchCellCb        *cell
23214  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
23215  *  @return  Void
23216  **/
23217
23218 Void rgSCHCmnNonDlfsRbAlloc
23219 (
23220 RgSchCellCb           *cell,
23221 RgSchCmnDlRbAllocInfo *allocInfo
23222 )
23223 {
23224    uint8_t        raRspCnt = 0;
23225    RgSchDlRbAlloc *reqAllocInfo;
23226
23227    /* Allocate for MSG4 retransmissions */
23228    if (allocInfo->msg4Alloc.msg4RetxLst.count)
23229    {
23230       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc RetxLst\n");
23231       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), TRUE);
23232    }
23233
23234    /* Allocate for MSG4 transmissions */
23235    /* Assuming all the nodes in the list need allocations: rbsReq is valid */
23236    if (allocInfo->msg4Alloc.msg4TxLst.count)
23237    {
23238       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc txLst\n");
23239       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), FALSE);
23240    }
23241 #ifdef RGR_V1
23242    /* Allocate for CCCH SDU (received after guard timer expiry)
23243     * retransmissions */
23244    if (allocInfo->ccchSduAlloc.ccchSduRetxLst.count)
23245    {
23246       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
23247       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), TRUE);
23248    }
23249
23250    /* Allocate for CCCD SDU transmissions */
23251    /* Allocate for CCCH SDU (received after guard timer expiry) transmissions */
23252    if (allocInfo->ccchSduAlloc.ccchSduTxLst.count)
23253    {
23254       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
23255       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), FALSE);
23256    }
23257 #endif
23258
23259    /* Allocate for Random access response */
23260    for (raRspCnt = 0; raRspCnt < RG_SCH_CMN_MAX_CMN_PDCCH; ++raRspCnt)
23261    {
23262       /* Assuming that the requests will be filled in sequentially */
23263       reqAllocInfo = &(allocInfo->raRspAlloc[raRspCnt]);
23264       if (!reqAllocInfo->rbsReq)
23265       {
23266          break;
23267       }
23268       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR calling RAR rgSCHCmnNonDlfsCmnRbAlloc\n");
23269    //   if ((rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo)) != ROK)
23270       if ((rgSCHCmnNonDlfsCmnRbAllocRar(cell, reqAllocInfo)) != ROK)
23271       {
23272          break;
23273       }
23274    }
23275
23276    /* Allocate for RETX+TX UEs */
23277    if(allocInfo->dedAlloc.txRetxHqPLst.count)
23278    {
23279       DU_LOG("\nDEBUG  -->  SCH : 5GTF_ERROR TX RETX rgSCHCmnNonDlfsDedRbAlloc\n");
23280       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23281             &(allocInfo->dedAlloc.txRetxHqPLst),
23282             &(allocInfo->dedAlloc.schdTxRetxHqPLst),
23283             &(allocInfo->dedAlloc.nonSchdTxRetxHqPLst));
23284    }
23285
23286    if((allocInfo->dedAlloc.retxHqPLst.count))
23287    {
23288       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23289             &(allocInfo->dedAlloc.retxHqPLst),
23290             &(allocInfo->dedAlloc.schdRetxHqPLst),
23291             &(allocInfo->dedAlloc.nonSchdRetxHqPLst));
23292    }
23293
23294    /* Allocate for transmitting UEs */
23295    if((allocInfo->dedAlloc.txHqPLst.count))
23296    {
23297       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23298             &(allocInfo->dedAlloc.txHqPLst),
23299             &(allocInfo->dedAlloc.schdTxHqPLst),
23300             &(allocInfo->dedAlloc.nonSchdTxHqPLst));
23301    }
23302    {
23303       RgSchCmnCell  *cmnCell = RG_SCH_CMN_GET_CELL(cell);
23304       if ((allocInfo->dedAlloc.txRetxHqPLst.count + 
23305                allocInfo->dedAlloc.retxHqPLst.count + 
23306                allocInfo->dedAlloc.txHqPLst.count) > 
23307             cmnCell->dl.maxUePerDlSf)
23308       {
23309 #ifndef ALIGN_64BIT
23310          DU_LOG("\nERROR  -->  SCH : UEs selected by"
23311                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %ld retx %ld tx %ld\n",
23312                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
23313                   allocInfo->dedAlloc.retxHqPLst.count,
23314                   allocInfo->dedAlloc.txHqPLst.count);
23315 #else
23316          DU_LOG("\nERROR  -->  SCH : UEs selected by"
23317                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %d retx %d tx %d\n",
23318                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
23319                   allocInfo->dedAlloc.retxHqPLst.count,
23320                   allocInfo->dedAlloc.txHqPLst.count);
23321 #endif
23322       }
23323    }
23324 #ifndef LTE_TDD
23325    /* LTE_ADV_FLAG_REMOVED_START */
23326    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
23327    {    
23328       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR RETX rgSCHCmnNonDlfsDsfrRntpComp\n");
23329       rgSCHCmnNonDlfsDsfrRntpComp(cell, allocInfo->dedAlloc.dedDlSf); 
23330    }  
23331    /* LTE_ADV_FLAG_REMOVED_END */
23332 #endif /* LTE_TDD */
23333    return;
23334 }
23335
23336 /***********************************************************
23337  *
23338  *     Func : rgSCHCmnCalcRiv
23339  *
23340  *     Desc : This function calculates RIV.
23341  *
23342  *     Ret  : None.
23343  *
23344  *     Notes: None.
23345  *
23346  *     File : rg_sch_utl.c
23347  *
23348  **********************************************************/
23349 #ifdef LTEMAC_SPS
23350 uint32_t rgSCHCmnCalcRiv
23351 (
23352 uint8_t    bw,
23353 uint8_t    rbStart,
23354 uint8_t    numRb
23355 )
23356 #else
23357 uint32_t rgSCHCmnCalcRiv
23358 (
23359 uint8_t    bw,
23360 uint8_t    rbStart,
23361 uint8_t    numRb
23362 )
23363 #endif
23364 {
23365    uint8_t  numRbMinus1 = numRb - 1;
23366    uint32_t riv;
23367
23368
23369    if (numRbMinus1 <= bw/2)
23370    {
23371       riv = bw * numRbMinus1 + rbStart;
23372    }
23373    else
23374    {
23375       riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
23376    }
23377    return (riv);
23378 } /* rgSCHCmnCalcRiv */
23379
23380 #ifdef LTE_TDD
23381 /**
23382  * @brief This function allocates and copies the RACH response scheduling
23383  *        related information into cell control block.
23384  *
23385  * @details
23386  *
23387  *     Function: rgSCHCmnDlCpyRachInfo
23388  *     Purpose:  This function allocates and copies the RACH response
23389  *               scheduling related information into cell control block
23390  *               for each DL subframe.
23391  *
23392  *
23393  *     Invoked by: Scheduler
23394  *
23395  *  @param[in]  RgSchCellCb*           cell
23396  *  @param[in]  RgSchTddRachRspLst     rachRspLst[][RGSCH_NUM_SUB_FRAMES]
23397  *  @param[in]  uint8_t                     raArrSz
23398  *  @return     S16
23399  *
23400  **/
23401 static S16 rgSCHCmnDlCpyRachInfo
23402 (
23403 RgSchCellCb         *cell,
23404 RgSchTddRachRspLst  rachRspLst[][RGSCH_NUM_SUB_FRAMES],
23405 uint8_t             raArrSz
23406 )
23407 {
23408    uint8_t   ulDlCfgIdx = cell->ulDlCfgIdx;
23409    uint8_t   sfNum;
23410    S16       sfnIdx;
23411    uint16_t  subfrmIdx;
23412    uint8_t   numRfs;
23413    uint8_t   numSubfrms;
23414    uint8_t   sfcount;
23415    S16       ret;
23416
23417
23418    /* Allocate RACH response information for each DL
23419     * subframe in a radio frame */
23420    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cell->rachRspLst,
23421          rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1] *
23422          sizeof(RgSchTddRachRspLst));
23423    if (ret != ROK)
23424    {
23425       return (ret);
23426    }
23427
23428    for(sfnIdx=raArrSz-1; sfnIdx>=0; sfnIdx--)
23429    {
23430       for(subfrmIdx=0; subfrmIdx < RGSCH_NUM_SUB_FRAMES; subfrmIdx++)
23431       {
23432          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
23433          if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
23434          {
23435             break;
23436          }
23437
23438          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx],subfrmIdx);
23439          numSubfrms =
23440             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
23441
23442          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddNumDlSubfrmTbl[ulDlCfgIdx],subfrmIdx);
23443          sfNum = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][subfrmIdx]-1;
23444          numRfs = cell->rachRspLst[sfNum].numRadiofrms;
23445          /* For each DL subframe in which RACH response can
23446           * be sent is updated */
23447          if(numSubfrms > 0)
23448          {
23449             cell->rachRspLst[sfNum].rachRsp[numRfs].sfnOffset =
23450                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset;
23451             for(sfcount=0; sfcount < numSubfrms; sfcount++)
23452             {
23453                cell->rachRspLst[sfNum].rachRsp[numRfs].\
23454                   subframe[sfcount] =
23455                   rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].\
23456                   subframe[sfcount];
23457             }
23458             cell->rachRspLst[sfNum].rachRsp[numRfs].numSubfrms =
23459                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
23460             cell->rachRspLst[sfNum].numRadiofrms++;
23461          }
23462
23463          /* Copy the subframes to be deleted at ths subframe */
23464          numSubfrms =
23465             rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
23466          if(numSubfrms > 0)
23467          {
23468             cell->rachRspLst[sfNum].delInfo.sfnOffset =
23469                rachRspLst[sfnIdx][subfrmIdx].delInfo.sfnOffset;
23470             for(sfcount=0; sfcount < numSubfrms; sfcount++)
23471             {
23472                cell->rachRspLst[sfNum].delInfo.subframe[sfcount] =
23473                   rachRspLst[sfnIdx][subfrmIdx].delInfo.subframe[sfcount];
23474             }
23475             cell->rachRspLst[sfNum].delInfo.numSubfrms =
23476                rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
23477          }
23478       }
23479    }
23480    return ROK;
23481 }
23482 #endif
23483 /**
23484  * @brief This function determines the iTbs based on the new CFI, 
23485  *        CQI and BLER based delta iTbs 
23486  *
23487  * @details
23488  *
23489  *     Function: rgSchCmnFetchItbs
23490  *     Purpose:  Fetch the new iTbs when CFI changes.
23491  *
23492  *  @param[in]  RgSchCellCb           *cell
23493  *  @param[in]  RgSchCmnDlUe          *ueDl
23494  *  @param[in]  uint8_t                    cqi
23495  *
23496  *  @return S32 iTbs
23497  *
23498  **/
23499 #ifdef LTE_TDD
23500 static S32 rgSchCmnFetchItbs 
23501 (
23502 RgSchCellCb   *cell,
23503 RgSchCmnDlUe  *ueDl,
23504 RgSchDlSf     *subFrm,
23505 uint8_t       cqi,
23506 uint8_t       cfi,
23507 uint8_t       cwIdx,
23508 uint8_t       noLyr
23509 )
23510 #else
23511 static S32 rgSchCmnFetchItbs 
23512 (
23513 RgSchCellCb   *cell,
23514 RgSchCmnDlUe  *ueDl,
23515 uint8_t       cqi,
23516 uint8_t       cfi,
23517 uint8_t       cwIdx,
23518 uint8_t       noLyr
23519 )
23520 #endif
23521 {
23522
23523    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
23524    S32 iTbs = 0;
23525
23526
23527 #ifdef LTE_TDD      
23528    /* Special Handling for Spl Sf when CFI is 3 as 
23529     * CFI in Spl Sf will be max 2 */
23530    if(subFrm->sfType == RG_SCH_SPL_SF_DATA) 
23531    {
23532       if((cellDl->currCfi == 3) || 
23533             ((cell->bwCfg.dlTotalBw <= 10) && (cellDl->currCfi == 1)))
23534       {    
23535          /* Use CFI 2 in this case */
23536          iTbs = (ueDl->laCb[cwIdx].deltaiTbs + 
23537                ((*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][2]))[cqi])* 100)/100;
23538
23539          RG_SCH_CHK_ITBS_RANGE(iTbs, RGSCH_NUM_ITBS - 1);
23540       }
23541       else
23542       {
23543          iTbs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1];
23544       }
23545       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
23546    }   
23547    else /* CFI Changed. Update with new iTbs Reset the BLER*/
23548 #endif         
23549    {
23550       S32 tmpiTbs  = (*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][cfi]))[cqi];
23551       
23552       iTbs = (ueDl->laCb[cwIdx].deltaiTbs + tmpiTbs*100)/100;
23553
23554       RG_SCH_CHK_ITBS_RANGE(iTbs, tmpiTbs);     
23555
23556       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
23557
23558       ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1] = iTbs;
23559
23560       ueDl->lastCfi = cfi;
23561       ueDl->laCb[cwIdx].deltaiTbs = 0;
23562    }
23563
23564    return (iTbs);
23565
23566 \f
23567 /**
23568  * @brief This function determines the RBs and Bytes required for BO
23569  *        transmission for UEs configured with TM 1/2/6/7.
23570  *
23571  * @details
23572  *
23573  *     Function: rgSCHCmnDlAllocTxRb1Tb1Cw
23574  *     Purpose:  Allocate TB1 on CW1.
23575  *
23576  *               Reference Parameter effBo is filled with alloced bytes.
23577  *               Returns RFAILED if BO not satisfied at all.
23578  *
23579  *     Invoked by: rgSCHCmnDlAllocTxRbTM1/2/6/7
23580  *
23581  *  @param[in]  RgSchCellCb           *cell
23582  *  @param[in]  RgSchDlSf             *subFrm
23583  *  @param[in]  RgSchUeCb             *ue
23584  *  @param[in]  uint32_t                   bo
23585  *  @param[out] uint32_t                   *effBo
23586  *  @param[in]  RgSchDlHqProcCb       *proc
23587  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23588  *  @return  Void
23589  *
23590  **/
23591 static Void rgSCHCmnDlAllocTxRb1Tb1Cw
23592 (
23593 RgSchCellCb           *cell,
23594 RgSchDlSf             *subFrm,
23595 RgSchUeCb             *ue,
23596 uint32_t              bo,
23597 uint32_t              *effBo,
23598 RgSchDlHqProcCb       *proc,
23599 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23600 )
23601 {
23602    RgSchDlRbAlloc   *allocInfo;
23603    S16              ret;
23604    uint8_t          numRb;
23605
23606    ret = ROK;
23607    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
23608 #ifdef RG_5GTF
23609    if (ue->ue5gtfCb.rank == 2)
23610    {
23611       allocInfo->dciFormat = TFU_DCI_FORMAT_B2;
23612    }
23613    else
23614    {
23615       allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
23616    }
23617 #else
23618    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
23619          allocInfo->raType);
23620 #endif
23621    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
23622          bo, &numRb, effBo);
23623    if (ret == RFAILED)
23624    {
23625       /* If allocation couldn't be made then return */
23626       return;
23627    }
23628    /* Adding UE to RbAllocInfo TX Lst */
23629    rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
23630    /* Fill UE alloc Info */
23631    allocInfo->rbsReq = numRb;
23632    allocInfo->dlSf   = subFrm;
23633 #ifdef RG_5GTF
23634    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
23635 #endif
23636
23637    return;
23638 }
23639
23640 \f
23641 /**
23642  * @brief This function determines the RBs and Bytes required for BO
23643  *        retransmission for UEs configured with TM 1/2/6/7.
23644  *
23645  * @details
23646  *
23647  *     Function: rgSCHCmnDlAllocRetxRb1Tb1Cw
23648  *     Purpose:  Allocate TB1 on CW1.
23649  *
23650  *               Reference Parameter effBo is filled with alloced bytes.
23651  *               Returns RFAILED if BO not satisfied at all.
23652  *
23653  *     Invoked by: rgSCHCmnDlAllocRetxRbTM1/2/6/7
23654  *
23655  *  @param[in]  RgSchCellCb           *cell
23656  *  @param[in]  RgSchDlSf             *subFrm
23657  *  @param[in]  RgSchUeCb             *ue
23658  *  @param[in]  uint32_t                   bo
23659  *  @param[out] uint32_t                   *effBo
23660  *  @param[in]  RgSchDlHqProcCb       *proc
23661  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23662  *  @return  Void
23663  *
23664  **/
23665 static Void rgSCHCmnDlAllocRetxRb1Tb1Cw
23666 (
23667 RgSchCellCb                *cell,
23668 RgSchDlSf                  *subFrm,
23669 RgSchUeCb                  *ue,
23670 uint32_t                   bo,
23671 uint32_t                   *effBo,
23672 RgSchDlHqProcCb            *proc,
23673 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23674 )
23675 {
23676    RgSchDlRbAlloc   *allocInfo;
23677    S16              ret;
23678    uint8_t          numRb;
23679
23680    ret = ROK;
23681    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
23682
23683 #ifndef RG_5GTF
23684    /* 5GTF: RETX DCI format same as TX */
23685    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
23686       &allocInfo->raType);
23687 #endif
23688
23689    /* Get the Allocation in terms of RBs that are required for
23690     * this retx of TB1 */
23691    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
23692          1, &numRb, effBo);
23693    if (ret == RFAILED)
23694    {
23695       /* Allocation couldn't be made for Retx */
23696       /* Fix : syed If TxRetx allocation failed then add the UE along with the proc
23697        * to the nonSchdTxRetxUeLst and let spfc scheduler take care of it during
23698        * finalization. */        
23699       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
23700       return;
23701    }
23702    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
23703    /* Fill UE alloc Info */
23704    allocInfo->rbsReq = numRb;
23705    allocInfo->dlSf   = subFrm;
23706 #ifdef RG_5GTF
23707    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
23708 #endif
23709
23710    return;
23711 }
23712
23713 \f
23714 /**
23715  * @brief This function determines the RBs and Bytes required for BO
23716  *        transmission for UEs configured with TM 2.
23717  *
23718  * @details
23719  *
23720  *     Function: rgSCHCmnDlAllocTxRbTM1
23721  *     Purpose:
23722  *
23723  *               Reference Parameter effBo is filled with alloced bytes.
23724  *               Returns RFAILED if BO not satisfied at all.
23725  *
23726  *     Invoked by: rgSCHCmnDlAllocTxRb
23727  *
23728  *  @param[in]  RgSchCellCb           *cell
23729  *  @param[in]  RgSchDlSf             *subFrm
23730  *  @param[in]  RgSchUeCb             *ue
23731  *  @param[in]  uint32_t                   bo
23732  *  @param[out] uint32_t                   *effBo
23733  *  @param[in]  RgSchDlHqProcCb       *proc
23734  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23735  *  @return Void
23736  *
23737  **/
23738 static Void rgSCHCmnDlAllocTxRbTM1
23739 (
23740 RgSchCellCb            *cell,
23741 RgSchDlSf              *subFrm,
23742 RgSchUeCb              *ue,
23743 uint32_t               bo,
23744 uint32_t               *effBo,
23745 RgSchDlHqProcCb        *proc,
23746 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
23747 )
23748 {
23749    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23750    return;
23751 }
23752
23753 \f
23754 /**
23755  * @brief This function determines the RBs and Bytes required for BO
23756  *        retransmission for UEs configured with TM 2.
23757  *
23758  * @details
23759  *
23760  *     Function: rgSCHCmnDlAllocRetxRbTM1
23761  *     Purpose:
23762  *
23763  *               Reference Parameter effBo is filled with alloced bytes.
23764  *               Returns RFAILED if BO not satisfied at all.
23765  *
23766  *     Invoked by: rgSCHCmnDlAllocRetxRb
23767  *
23768  *  @param[in]  RgSchCellCb           *cell
23769  *  @param[in]  RgSchDlSf             *subFrm
23770  *  @param[in]  RgSchUeCb             *ue
23771  *  @param[in]  uint32_t                   bo
23772  *  @param[out] uint32_t                   *effBo
23773  *  @param[in]  RgSchDlHqProcCb       *proc
23774  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23775  *  @return Void
23776  *
23777  **/
23778 static Void rgSCHCmnDlAllocRetxRbTM1
23779 (
23780 RgSchCellCb                *cell,
23781 RgSchDlSf                  *subFrm,
23782 RgSchUeCb                  *ue,
23783 uint32_t                   bo,
23784 uint32_t                   *effBo,
23785 RgSchDlHqProcCb            *proc,
23786 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23787 )
23788 {
23789    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23790    return;
23791 }
23792
23793 \f
23794 /**
23795  * @brief This function determines the RBs and Bytes required for BO
23796  *        transmission for UEs configured with TM 2.
23797  *
23798  * @details
23799  *
23800  *     Function: rgSCHCmnDlAllocTxRbTM2
23801  *     Purpose:
23802  *
23803  *               Reference Parameter effBo is filled with alloced bytes.
23804  *               Returns RFAILED if BO not satisfied at all.
23805  *
23806  *     Invoked by: rgSCHCmnDlAllocTxRb
23807  *
23808  *  @param[in]  RgSchCellCb           *cell
23809  *  @param[in]  RgSchDlSf             *subFrm
23810  *  @param[in]  RgSchUeCb             *ue
23811  *  @param[in]  uint32_t                   bo
23812  *  @param[out] uint32_t                   *effBo
23813  *  @param[in]  RgSchDlHqProcCb       *proc
23814  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23815  *  @return Void
23816  *
23817  **/
23818 static Void rgSCHCmnDlAllocTxRbTM2
23819 (
23820 RgSchCellCb                *cell,
23821 RgSchDlSf                  *subFrm,
23822 RgSchUeCb                  *ue,
23823 uint32_t                   bo,
23824 uint32_t                   *effBo,
23825 RgSchDlHqProcCb            *proc,
23826 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23827 )
23828 {
23829    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23830    return;
23831 }
23832
23833 \f
23834 /**
23835  * @brief This function determines the RBs and Bytes required for BO
23836  *        retransmission for UEs configured with TM 2.
23837  *
23838  * @details
23839  *
23840  *     Function: rgSCHCmnDlAllocRetxRbTM2
23841  *     Purpose:
23842  *
23843  *               Reference Parameter effBo is filled with alloced bytes.
23844  *               Returns RFAILED if BO not satisfied at all.
23845  *
23846  *     Invoked by: rgSCHCmnDlAllocRetxRb
23847  *
23848  *  @param[in]  RgSchCellCb           *cell
23849  *  @param[in]  RgSchDlSf             *subFrm
23850  *  @param[in]  RgSchUeCb             *ue
23851  *  @param[in]  uint32_t                   bo
23852  *  @param[out] uint32_t                   *effBo
23853  *  @param[in]  RgSchDlHqProcCb       *proc
23854  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23855  *  @return Void
23856  *
23857  **/
23858 static Void rgSCHCmnDlAllocRetxRbTM2
23859 (
23860 RgSchCellCb                *cell,
23861 RgSchDlSf                  *subFrm,
23862 RgSchUeCb                  *ue,
23863 uint32_t                   bo,
23864 uint32_t                   *effBo,
23865 RgSchDlHqProcCb            *proc,
23866 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23867 )
23868 {
23869    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23870    return;
23871 }
23872
23873 \f
23874 /**
23875  * @brief This function determines the RBs and Bytes required for BO
23876  *        transmission for UEs configured with TM 3.
23877  *
23878  * @details
23879  *
23880  *     Function: rgSCHCmnDlAllocTxRbTM3
23881  *     Purpose:
23882  *
23883  *               Reference Parameter effBo is filled with alloced bytes.
23884  *               Returns RFAILED if BO not satisfied at all.
23885  *
23886  *     Invoked by: rgSCHCmnDlAllocTxRb
23887  *
23888  *  @param[in]  RgSchCellCb           *cell
23889  *  @param[in]  RgSchDlSf             *subFrm
23890  *  @param[in]  RgSchUeCb             *ue
23891  *  @param[in]  uint32_t                   bo
23892  *  @param[out] uint32_t                   *effBo
23893  *  @param[in]  RgSchDlHqProcCb       *proc
23894  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23895  *  @return Void
23896  *
23897  **/
23898 static Void rgSCHCmnDlAllocTxRbTM3
23899 (
23900 RgSchCellCb                *cell,
23901 RgSchDlSf                  *subFrm,
23902 RgSchUeCb                  *ue,
23903 uint32_t                   bo,
23904 uint32_t                   *effBo,
23905 RgSchDlHqProcCb            *proc,
23906 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23907 )
23908 {
23909
23910
23911    /* Both TBs free for TX allocation */
23912    rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo,\
23913          proc, cellWdAllocInfo);
23914
23915    return;
23916 }
23917
23918 \f
23919 /**
23920  * @brief This function determines the RBs and Bytes required for BO
23921  *        retransmission for UEs configured with TM 3.
23922  *
23923  * @details
23924  *
23925  *     Function: rgSCHCmnDlAllocRetxRbTM3
23926  *     Purpose:
23927  *
23928  *               Reference Parameter effBo is filled with alloced bytes.
23929  *               Returns RFAILED if BO not satisfied at all.
23930  *
23931  *     Invoked by: rgSCHCmnDlAllocRetxRb
23932  *
23933  *  @param[in]  RgSchCellCb           *cell
23934  *  @param[in]  RgSchDlSf             *subFrm
23935  *  @param[in]  RgSchUeCb             *ue
23936  *  @param[in]  uint32_t                   bo
23937  *  @param[out] uint32_t                   *effBo
23938  *  @param[in]  RgSchDlHqProcCb       *proc
23939  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23940  *  @return Void
23941  *
23942  **/
23943 static Void rgSCHCmnDlAllocRetxRbTM3
23944 (
23945 RgSchCellCb                *cell,
23946 RgSchDlSf                  *subFrm,
23947 RgSchUeCb                  *ue,
23948 uint32_t                   bo,
23949 uint32_t                   *effBo,
23950 RgSchDlHqProcCb            *proc,
23951 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23952 )
23953 {
23954
23955
23956    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
23957          (proc->tbInfo[1].state == HQ_TB_NACKED))
23958    {
23959 #ifdef LAA_DBG_LOG
23960       DU_LOG("\nDEBUG  -->  SCH : RETX RB TM3 nack for both hqp %d cell %d \n", proc->procId, proc->hqE->cell->cellId);
23961 #endif
23962       /* Both TBs require RETX allocation */
23963       rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo,\
23964             proc, cellWdAllocInfo);
23965    }
23966    else
23967    {
23968       /* One of the TBs need RETX allocation. Other TB may/maynot
23969        * be available for new TX allocation. */
23970       rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo,\
23971             proc, cellWdAllocInfo);
23972    }
23973
23974    return;
23975 }
23976
23977 \f
23978 /**
23979  * @brief This function performs the DCI format selection in case of
23980  *        Transmit Diversity scheme where there can be more
23981  *        than 1 option for DCI format selection.
23982  *
23983  * @details
23984  *
23985  *     Function: rgSCHCmnSlctPdcchFrmt
23986  *     Purpose:  1. If DLFS is enabled, then choose TM specific
23987  *                  DCI format for Transmit diversity. All the
23988  *                  TM Specific DCI Formats support Type0 and/or
23989  *                  Type1 resource allocation scheme. DLFS
23990  *                  supports only Type-0&1 Resource allocation.
23991  *               2. If DLFS is not enabled, select a DCI format
23992  *                  which is of smaller size. Since Non-DLFS
23993  *                  scheduler supports all Resource allocation
23994  *                  schemes, selection is based on efficiency.
23995  *
23996  *     Invoked by: DL UE Allocation by Common Scheduler.
23997  *
23998  *  @param[in]  RgSchCellCb      *cell
23999  *  @param[in]  RgSchUeCb        *ue
24000  *  @param[out] uint8_t               *raType
24001  *  @return  TfuDciFormat
24002  *
24003  **/
24004 TfuDciFormat rgSCHCmnSlctPdcchFrmt
24005 (
24006 RgSchCellCb   *cell,
24007 RgSchUeCb     *ue,
24008 uint8_t       *raType
24009 )
24010 {
24011    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
24012
24013
24014    /* ccpu00140894- Selective DCI Format and RA type should be selected only 
24015     * after TX Mode transition is completed*/
24016    if ((cellSch->dl.isDlFreqSel) && (ue->txModeTransCmplt))
24017    {
24018       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciRAType;
24019       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciFrmt);
24020    }
24021    else
24022    {
24023       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciRAType;
24024       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciFrmt);
24025    }
24026 }
24027
24028 \f
24029 /**
24030  * @brief This function handles Retx allocation in case of TM3 UEs
24031  *        where both the TBs were NACKED previously.
24032  *
24033  * @details
24034  *
24035  *     Function: rgSCHCmnDlTM3RetxRetx
24036  *     Purpose:  If forceTD flag enabled
24037  *                  TD for TB1 on CW1.
24038  *               Else
24039  *                  DCI Frmt 2A and RA Type 0
24040  *                  RI layered SM of both TBs on 2 CWs
24041  *               Add UE to cell Alloc Info.
24042  *               Fill UE alloc Info.
24043  *
24044  *
24045  *               Successful allocation is indicated by non-zero effBo value.
24046  *
24047  *     Invoked by: rgSCHCmnDlAllocRbTM3
24048  *
24049  *  @param[in]  RgSchCellCb           *cell
24050  *  @param[in]  RgSchDlSf             *subFrm
24051  *  @param[in]  RgSchUeCb             *ue
24052  *  @param[in]  uint32_t                   bo
24053  *  @param[out] uint32_t                   *effBo
24054  *  @param[in]  RgSchDlHqProcCb       *proc
24055  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24056  *  @return  Void
24057  *
24058  **/
24059 static Void rgSCHCmnDlTM3RetxRetx
24060 (
24061 RgSchCellCb                *cell,
24062 RgSchDlSf                  *subFrm,
24063 RgSchUeCb                  *ue,
24064 uint32_t                   bo,
24065 uint32_t                   *effBo,
24066 RgSchDlHqProcCb            *proc,
24067 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
24068 )
24069 {
24070    S16           ret;
24071    RgSchDlRbAlloc *allocInfo;
24072    uint8_t       numRb;
24073    Bool          swpFlg;
24074    uint8_t       precInfo;
24075    uint8_t       noTxLyrs;
24076    uint8_t       precInfoAntIdx;
24077
24078
24079    ret = ROK;
24080    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24081    swpFlg = FALSE;
24082 /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
24083    {
24084       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
24085       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
24086
24087       ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
24088             effBo);
24089       if (ret == RFAILED)
24090       {
24091          /* Allocation couldn't be made for Retx */
24092          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24093          return;
24094       }
24095       /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
24096       noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
24097 #ifdef FOUR_TX_ANTENNA
24098       /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 should
24099        * have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
24100       if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
24101       {
24102          swpFlg = TRUE;
24103          proc->cwSwpEnabled = TRUE;
24104       }
24105 #endif
24106       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24107       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
24108    }
24109
24110 #ifdef LTEMAC_SPS
24111    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24112 #endif
24113    {
24114       /* Adding UE to allocInfo RETX Lst */
24115       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24116    }
24117    /* Fill UE alloc Info scratch pad */
24118    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24119          precInfo, noTxLyrs, subFrm);
24120
24121    return;
24122 }
24123
24124 \f
24125 /**
24126  * @brief This function handles Retx allocation in case of TM4 UEs
24127  *        where both the TBs were NACKED previously.
24128  *
24129  * @details
24130  *
24131  *     Function: rgSCHCmnDlTM4RetxRetx
24132  *     Purpose:  If forceTD flag enabled
24133  *                  TD for TB1 on CW1.
24134  *               Else
24135  *                  DCI Frmt 2 and RA Type 0
24136  *                  If RI == 1
24137  *                     1 layer SM of TB1 on CW1.
24138  *                  Else
24139  *                     RI layered SM of both TBs on 2 CWs
24140  *               Add UE to cell Alloc Info.
24141  *               Fill UE alloc Info.
24142  *
24143  *
24144  *               Successful allocation is indicated by non-zero effBo value.
24145  *
24146  *     Invoked by: rgSCHCmnDlAllocRbTM4
24147  *
24148  *  @param[in]  RgSchCellCb           *cell
24149  *  @param[in]  RgSchDlSf             *subFrm
24150  *  @param[in]  RgSchUeCb             *ue
24151  *  @param[in]  uint32_t                   bo
24152  *  @param[out] uint32_t                   *effBo
24153  *  @param[in]  RgSchDlHqProcCb       *proc
24154  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24155  *  @return  Void
24156  *
24157  **/
24158 static Void rgSCHCmnDlTM4RetxRetx
24159 (
24160 RgSchCellCb           *cell,
24161 RgSchDlSf             *subFrm,
24162 RgSchUeCb             *ue,
24163 uint32_t              bo,
24164 uint32_t              *effBo,
24165 RgSchDlHqProcCb       *proc,
24166 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24167 )
24168 {
24169    S16            ret;
24170    RgSchDlRbAlloc *allocInfo;
24171    uint8_t        numRb;
24172    Bool           swpFlg = FALSE;
24173    uint8_t        precInfo;
24174 #ifdef FOUR_TX_ANTENNA
24175    uint8_t        precInfoAntIdx;
24176 #endif
24177    uint8_t        noTxLyrs;
24178
24179
24180    ret = ROK;
24181    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24182                        
24183    /* Irrespective of RI Schedule both CWs */
24184    allocInfo->dciFormat = TFU_DCI_FORMAT_2;
24185    allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
24186
24187    ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
24188          effBo);
24189    if (ret == RFAILED)
24190    {
24191       /* Allocation couldn't be made for Retx */
24192       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24193       return;
24194    }
24195    noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
24196    precInfo = 0; 
24197 #ifdef FOUR_TX_ANTENNA
24198    /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1
24199     * should have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
24200    if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
24201    {
24202       swpFlg = TRUE;
24203       proc->cwSwpEnabled = TRUE;
24204 }
24205 precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24206 precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
24207 #endif
24208
24209 #ifdef LTEMAC_SPS
24210    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24211 #endif
24212    {
24213       /* Adding UE to allocInfo RETX Lst */
24214       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24215    }
24216    /* Fill UE alloc Info scratch pad */
24217    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24218          precInfo, noTxLyrs, subFrm);
24219
24220    return;
24221 }
24222
24223
24224 \f
24225 /**
24226  * @brief This function determines Transmission attributes
24227  *        incase of Spatial multiplexing for TX and RETX TBs.
24228  *
24229  * @details
24230  *
24231  *     Function: rgSCHCmnDlSMGetAttrForTxRetx
24232  *     Purpose:  1. Reached here for a TM3/4 UE's HqP whose one of the TBs is
24233  *                  NACKED and the other TB is either NACKED or WAITING.
24234  *               2. Select the NACKED TB for RETX allocation.
24235  *               3. Allocation preference for RETX TB by mapping it to a better
24236  *                  CW (better in terms of efficiency).
24237  *               4. Determine the state of the other TB.
24238  *                  Determine if swapFlag were to be set.
24239  *                  Swap flag would be set if Retx TB is cross
24240  *                  mapped to a CW.
24241  *               5. If UE has new data available for TX and if the other TB's state
24242  *                  is ACKED then set furtherScope as TRUE.
24243  *
24244  *     Invoked by: rgSCHCmnDlTM3[4]TxRetx
24245  *
24246  *  @param[in]  RgSchUeCb        *ue
24247  *  @param[in]  RgSchDlHqProcCb  *proc
24248  *  @param[out] RgSchDlHqTbCb    **retxTb
24249  *  @param[out] RgSchDlHqTbCb    **txTb
24250  *  @param[out] Bool             *frthrScp
24251  *  @param[out] Bool             *swpFlg
24252  *  @return  Void
24253  *
24254  **/
24255 static Void rgSCHCmnDlSMGetAttrForTxRetx
24256 (
24257 RgSchUeCb                  *ue,
24258 RgSchDlHqProcCb            *proc,
24259 RgSchDlHqTbCb              **retxTb,
24260 RgSchDlHqTbCb              **txTb,
24261 Bool                       *frthrScp,
24262 Bool                       *swpFlg
24263 )
24264 {
24265    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,proc->hqE->cell);
24266    RgSchDlRbAlloc  *allocInfo;
24267
24268
24269    if (proc->tbInfo[0].state == HQ_TB_NACKED)
24270    {
24271       *retxTb = &proc->tbInfo[0];
24272       *txTb = &proc->tbInfo[1];
24273       /* TENB_BRDCM_TM4- Currently disabling swapflag for TM3/TM4, since 
24274        * HqFeedback processing does not consider a swapped hq feedback */
24275       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 1))
24276       {
24277          *swpFlg = TRUE;
24278          proc->cwSwpEnabled = TRUE;
24279       }
24280       if (proc->tbInfo[1].state == HQ_TB_ACKED)
24281       {
24282          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
24283          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
24284       }
24285    }
24286    else
24287    {
24288       *retxTb = &proc->tbInfo[1];
24289       *txTb = &proc->tbInfo[0];
24290       /* TENB_BRDCM_TM4 - Currently disabling swapflag for TM3/TM4, since 
24291        * HqFeedback processing does not consider a swapped hq feedback */
24292       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 0))
24293       {
24294          *swpFlg = TRUE;
24295          proc->cwSwpEnabled = TRUE;
24296       }
24297       if (proc->tbInfo[0].state == HQ_TB_ACKED)
24298       {
24299          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
24300          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
24301       }
24302    }
24303    return;
24304 }
24305
24306 \f
24307 /**
24308  * @brief Determine Precoding information for TM3 2 TX Antenna.
24309  *
24310  * @details
24311  *
24312  *     Function: rgSCHCmnDlTM3PrecInf2
24313  *     Purpose:
24314  *
24315  *     Invoked by: rgSCHCmnDlGetAttrForTM3
24316  *
24317  *  @param[in]  RgSchUeCb        *ue
24318  *  @param[in]  uint8_t               numTxLyrs
24319  *  @param[in]  Bool             bothCwEnbld
24320  *  @return  uint8_t
24321  *
24322  **/
24323 static uint8_t rgSCHCmnDlTM3PrecInf2
24324 (
24325 RgSchCellCb *cell,
24326 RgSchUeCb   *ue,
24327 uint8_t     numTxLyrs,
24328 Bool        bothCwEnbld
24329 )
24330 {
24331
24332    return (0);
24333 }
24334
24335 \f
24336 /**
24337  * @brief Determine Precoding information for TM4 2 TX Antenna.
24338  *
24339  * @details
24340  *
24341  *     Function: rgSCHCmnDlTM4PrecInf2
24342  *     Purpose:  To determine a logic of deriving precoding index
24343  *               information from 36.212 table 5.3.3.1.5-4
24344  *
24345  *     Invoked by: rgSCHCmnDlGetAttrForTM4
24346  *
24347  *  @param[in]  RgSchUeCb        *ue
24348  *  @param[in]  uint8_t               numTxLyrs
24349  *  @param[in]  Bool             bothCwEnbld
24350  *  @return  uint8_t
24351  *
24352  **/
24353 static uint8_t rgSCHCmnDlTM4PrecInf2
24354 (
24355 RgSchCellCb  *cell,
24356 RgSchUeCb    *ue,
24357 uint8_t      numTxLyrs,
24358 Bool         bothCwEnbld
24359 )
24360 {
24361    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24362    uint8_t            precIdx;
24363
24364
24365    if (ueDl->mimoInfo.ri == numTxLyrs)
24366    {
24367       if (ueDl->mimoInfo.ri == 2)
24368       {
24369          /* PrecInfo corresponding to 2 CW
24370            Transmission */
24371          if (ue->mimoInfo.puschFdbkVld)
24372          {
24373             precIdx = 2;
24374          }
24375          else 
24376          {
24377             precIdx = ueDl->mimoInfo.pmi - 1;
24378          }
24379       }
24380       else
24381       {
24382          /* PrecInfo corresponding to 1 CW
24383           * Transmission */
24384          if (ue->mimoInfo.puschFdbkVld)
24385          {
24386             precIdx =  5;
24387          }
24388          else
24389          {
24390             precIdx =  ueDl->mimoInfo.pmi + 1;
24391          }
24392       }
24393    }
24394    else if (ueDl->mimoInfo.ri > numTxLyrs)
24395    {
24396       /* In case of choosing among the columns of a
24397        * precoding matrix, choose the column corresponding
24398        * to the MAX-CQI */
24399       if (ue->mimoInfo.puschFdbkVld)
24400       {
24401          precIdx = 5;
24402       }
24403       else
24404       {
24405          precIdx = (ueDl->mimoInfo.pmi- 1)* 2  + 1;
24406       }
24407    }
24408    else /* if RI < numTxLyrs */
24409    {
24410       precIdx = (ueDl->mimoInfo.pmi < 2)? 0:1;
24411    }
24412    return (precIdx);
24413 }
24414
24415 \f
24416 /**
24417  * @brief Determine Precoding information for TM3 4 TX Antenna.
24418  *
24419  * @details
24420  *
24421  *     Function: rgSCHCmnDlTM3PrecInf4
24422  *     Purpose:  To determine a logic of deriving precoding index
24423  *               information from 36.212 table 5.3.3.1.5A-2
24424  *
24425  *     Invoked by: rgSCHCmnDlGetAttrForTM3
24426  *
24427  *  @param[in]  RgSchUeCb        *ue
24428  *  @param[in]  uint8_t               numTxLyrs
24429  *  @param[in]  Bool             bothCwEnbld
24430  *  @return  uint8_t
24431  *
24432  **/
24433 static uint8_t rgSCHCmnDlTM3PrecInf4
24434 (
24435 RgSchCellCb *cell,
24436 RgSchUeCb   *ue,
24437 uint8_t     numTxLyrs,
24438 Bool        bothCwEnbld
24439 )
24440 {
24441    uint8_t  precIdx;
24442
24443
24444    if (bothCwEnbld)
24445    {
24446       precIdx = numTxLyrs - 2;
24447    }
24448    else /* one 1 CW transmission */
24449    {
24450       precIdx = 1;
24451    }
24452    return (precIdx);
24453 }
24454
24455 \f
24456 /**
24457  * @brief Determine Precoding information for TM4 4 TX Antenna.
24458  *
24459  * @details
24460  *
24461  *     Function: rgSCHCmnDlTM4PrecInf4
24462  *     Purpose:  To determine a logic of deriving precoding index
24463  *               information from 36.212 table 5.3.3.1.5-5
24464  *
24465  *     Invoked by: rgSCHCmnDlGetAttrForTM4
24466  *
24467  *  @param[in]  RgSchUeCb        *ue
24468  *  @param[in]  uint8_t               numTxLyrs
24469  *  @param[in]  Bool             bothCwEnbld
24470  *  @return  uint8_t
24471  *
24472  **/
24473 static uint8_t rgSCHCmnDlTM4PrecInf4
24474 (
24475 RgSchCellCb  *cell,
24476 RgSchUeCb    *ue,
24477 uint8_t      numTxLyrs,
24478 Bool         bothCwEnbld
24479 )
24480 {
24481    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24482    uint8_t       precInfoBaseIdx, precIdx;
24483
24484
24485    precInfoBaseIdx  = (ue->mimoInfo.puschFdbkVld)? (16):
24486       (ueDl->mimoInfo.pmi);
24487    if (bothCwEnbld)
24488    {
24489       precIdx = precInfoBaseIdx + (numTxLyrs-2)*17;
24490    }
24491    else /* one 1 CW transmission */
24492    {
24493       precInfoBaseIdx += 1;
24494       precIdx = precInfoBaseIdx + (numTxLyrs-1)*17;
24495    }
24496    return (precIdx);
24497 }
24498
24499 \f
24500 /**
24501  * @brief This function determines Transmission attributes
24502  *        incase of TM3 scheduling.
24503  *
24504  * @details
24505  *
24506  *     Function: rgSCHCmnDlGetAttrForTM3
24507  *     Purpose:  Determine retx TB and tx TB based on TB states.
24508  *               If forceTD enabled
24509  *                  perform only retx TB allocation.
24510  *                  If retxTB == TB2 then DCI Frmt = 2A, RA Type = 0.
24511  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
24512  *               If RI == 1
24513  *                  perform retxTB allocation on CW1.
24514  *               Else if RI > 1
24515  *                  Determine further Scope and Swap Flag attributes
24516  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
24517  *                  If no further scope for new TX allocation
24518  *                     Allocate only retx TB using 2 layers if
24519  *                     this TB was previously transmitted using 2 layers AND
24520  *                     number of Tx antenna ports == 4.
24521  *                     otherwise do single layer precoding.
24522  *
24523  *     Invoked by: rgSCHCmnDlTM3TxRetx
24524  *
24525  *  @param[in]  RgSchUeCb        *ue
24526  *  @param[in]  RgSchDlHqProcCb  *proc
24527  *  @param[out] uint8_t               *numTxLyrs
24528  *  @param[out] Bool             *isTraDiv
24529  *  @param[out] uint8_t               *prcdngInf
24530  *  @param[out] uint8_t               *raType
24531  *  @return  Void
24532  *
24533  **/
24534 static Void rgSCHCmnDlGetAttrForTM3
24535 (
24536 RgSchCellCb      *cell,
24537 RgSchUeCb        *ue,
24538 RgSchDlHqProcCb  *proc,
24539 uint8_t          *numTxLyrs,
24540 TfuDciFormat     *dciFrmt,
24541 uint8_t          *prcdngInf,
24542 RgSchDlHqTbCb    **retxTb,
24543 RgSchDlHqTbCb    **txTb,
24544 Bool             *frthrScp,
24545 Bool             *swpFlg,
24546 uint8_t          *raType
24547 )
24548 {
24549    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24550    uint8_t       precInfoAntIdx;
24551
24552
24553    /* Avoiding Tx-Retx for LAA cell as firstSchedTime is associated with 
24554       HQP */
24555    /* Integration_fix: SPS Proc shall always have only one Cw */
24556 #ifdef LTEMAC_SPS
24557    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
24558          (ueDl->mimoInfo.forceTD)) 
24559 #ifdef LTE_ADV
24560      ||(TRUE == rgSCHLaaSCellEnabled(cell))
24561 #endif
24562       )
24563 #else
24564    if ((ueDl->mimoInfo.forceTD) 
24565 #ifdef LTE_ADV
24566        || (TRUE == rgSCHLaaSCellEnabled(cell))
24567 #endif
24568       )
24569 #endif
24570    {
24571       /* Transmit Diversity. Format based on dlfsEnabled
24572        * No further scope */
24573       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24574       {
24575          *retxTb = &proc->tbInfo[0];
24576          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24577       }
24578       else
24579       {
24580          *retxTb = &proc->tbInfo[1];
24581          *dciFrmt = TFU_DCI_FORMAT_2A;
24582          *raType = RG_SCH_CMN_RA_TYPE0;
24583       }
24584       *numTxLyrs = 1;
24585       *frthrScp = FALSE;
24586       *prcdngInf = 0;
24587       return;
24588    }
24589
24590    /* Determine the 2 TB transmission attributes */
24591    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
24592          frthrScp, swpFlg);
24593    if (*frthrScp)
24594    {
24595       /* Prefer allocation of RETX TB over 2 layers rather than combining
24596        * it with a new TX. */
24597       if ((ueDl->mimoInfo.ri == 2)
24598             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
24599       {
24600          /* Allocate TB on CW1, using 2 Lyrs,
24601           * Format 2, precoding accordingly */
24602          *numTxLyrs = 2;
24603          *frthrScp = FALSE;
24604       }
24605       else
24606       {
24607          *numTxLyrs=  ((*retxTb)->numLyrs + ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)].noLyr);
24608
24609          if((*retxTb)->tbIdx == 0 && ((*retxTb)->numLyrs == 2 ) && *numTxLyrs ==3)
24610          {
24611             *swpFlg = TRUE;
24612             proc->cwSwpEnabled = TRUE;
24613          }
24614          else if((*retxTb)->tbIdx == 1 && ((*retxTb)->numLyrs == 1) && *numTxLyrs ==3)
24615          {
24616             *swpFlg = TRUE;
24617             proc->cwSwpEnabled = TRUE;
24618          }
24619       }
24620
24621       precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
24622       *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])\
24623                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
24624       *dciFrmt = TFU_DCI_FORMAT_2A;
24625       *raType = RG_SCH_CMN_RA_TYPE0;
24626    }
24627    else /* frthrScp == FALSE */
24628    {
24629       if (cell->numTxAntPorts == 2)
24630       {
24631          /*  Transmit Diversity  */
24632          *numTxLyrs = 1;
24633          if ((*retxTb)->tbIdx == 0)
24634          {
24635             *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24636          }
24637          else
24638          {
24639             /* If retxTB is TB2 then use format 2A */
24640             *dciFrmt = TFU_DCI_FORMAT_2A;
24641             *raType = RG_SCH_CMN_RA_TYPE0;
24642          }
24643          *prcdngInf = 0;
24644          return;
24645       }
24646       else /* NumAntPorts == 4 */
24647       {
24648          if ((*retxTb)->numLyrs == 2)
24649          {
24650             /* Allocate TB on CW1, using 2 Lyrs,
24651              * Format 2A, precoding accordingly */
24652             *numTxLyrs = 2;
24653             *dciFrmt = TFU_DCI_FORMAT_2A;
24654             *raType = RG_SCH_CMN_RA_TYPE0;
24655             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24656             *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, *numTxLyrs, *frthrScp);
24657             return;
24658          }
24659          else
24660          {
24661             /*  Transmit Diversity  */
24662             *numTxLyrs = 1;
24663             if ((*retxTb)->tbIdx == 0)
24664             {
24665                *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24666             }
24667             else
24668             {
24669                /* If retxTB is TB2 then use format 2A */
24670                *dciFrmt = TFU_DCI_FORMAT_2A;
24671                *raType = RG_SCH_CMN_RA_TYPE0;
24672             }
24673             *prcdngInf = 0;
24674             return;
24675          }
24676       }
24677    }
24678
24679    return;
24680 }
24681
24682
24683 \f
24684 /**
24685  * @brief This function determines Transmission attributes
24686  *        incase of TM4 scheduling.
24687  *
24688  * @details
24689  *
24690  *     Function: rgSCHCmnDlGetAttrForTM4
24691  *     Purpose:  Determine retx TB and tx TB based on TB states.
24692  *               If forceTD enabled
24693  *                  perform only retx TB allocation.
24694  *                  If retxTB == TB2 then DCI Frmt = 2, RA Type = 0.
24695  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
24696  *               If RI == 1
24697  *                  perform retxTB allocation on CW1.
24698  *               Else if RI > 1
24699  *                  Determine further Scope and Swap Flag attributes
24700  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
24701  *                  If no further scope for new TX allocation
24702  *                     Allocate only retx TB using 2 layers if
24703  *                     this TB was previously transmitted using 2 layers AND
24704  *                     number of Tx antenna ports == 4.
24705  *                     otherwise do single layer precoding.
24706  *
24707  *     Invoked by: rgSCHCmnDlTM4TxRetx
24708  *
24709  *  @param[in]  RgSchUeCb        *ue
24710  *  @param[in]  RgSchDlHqProcCb  *proc
24711  *  @param[out] uint8_t               *numTxLyrs
24712  *  @param[out] Bool             *isTraDiv
24713  *  @param[out] uint8_t               *prcdngInf
24714  *  @param[out] uint8_t               *raType
24715  *  @return  Void
24716  *
24717  **/
24718 static Void rgSCHCmnDlGetAttrForTM4
24719 (
24720 RgSchCellCb      *cell,
24721 RgSchUeCb        *ue,
24722 RgSchDlHqProcCb  *proc,
24723 uint8_t          *numTxLyrs,
24724 TfuDciFormat     *dciFrmt,
24725 uint8_t          *prcdngInf,
24726 RgSchDlHqTbCb    **retxTb,
24727 RgSchDlHqTbCb    **txTb,
24728 Bool             *frthrScp,
24729 Bool             *swpFlg,
24730 uint8_t          *raType
24731 )
24732 {
24733    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24734    uint8_t precInfoAntIdx;
24735
24736
24737    *frthrScp = FALSE;
24738    /* Integration_fix: SPS Proc shall always have only one Cw */
24739 #ifdef LTEMAC_SPS
24740    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
24741          (ueDl->mimoInfo.forceTD)) 
24742 #ifdef LTE_ADV
24743      ||(TRUE == rgSCHLaaSCellEnabled(cell))
24744 #endif
24745       )
24746 #else
24747    if ((ueDl->mimoInfo.forceTD) 
24748 #ifdef LTE_ADV
24749        || (TRUE == rgSCHLaaSCellEnabled(cell))
24750 #endif
24751       )
24752 #endif
24753    {
24754       /* Transmit Diversity. Format based on dlfsEnabled
24755        * No further scope */
24756       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24757       {
24758          *retxTb = &proc->tbInfo[0];
24759          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24760       }
24761       else
24762       {
24763          *retxTb = &proc->tbInfo[1];
24764          *dciFrmt = TFU_DCI_FORMAT_2;
24765          *raType = RG_SCH_CMN_RA_TYPE0;
24766       }
24767       *numTxLyrs = 1;
24768       *frthrScp = FALSE;
24769       *prcdngInf = 0;
24770       return;
24771    }
24772
24773    if (ueDl->mimoInfo.ri == 1)
24774    {
24775       /* single layer precoding. Format 2.
24776        * No further scope */
24777       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24778       {
24779          *retxTb = &proc->tbInfo[0];
24780       }
24781       else
24782       {
24783          *retxTb = &proc->tbInfo[1];
24784       }
24785       *numTxLyrs = 1;
24786       *dciFrmt = TFU_DCI_FORMAT_2;
24787       *raType = RG_SCH_CMN_RA_TYPE0;
24788       *frthrScp = FALSE;
24789       *prcdngInf = 0; /*When RI= 1*/
24790       return;
24791    }
24792
24793    /* Determine the 2 TB transmission attributes */
24794    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
24795          frthrScp, swpFlg);
24796    *dciFrmt = TFU_DCI_FORMAT_2;
24797    *raType = RG_SCH_CMN_RA_TYPE0;
24798    if (*frthrScp)
24799    {
24800       /* Prefer allocation of RETX TB over 2 layers rather than combining
24801        * it with a new TX. */
24802       if ((ueDl->mimoInfo.ri == 2)
24803             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
24804       {
24805          /* Allocate TB on CW1, using 2 Lyrs,
24806           * Format 2, precoding accordingly */
24807          *numTxLyrs = 2;
24808          *frthrScp = FALSE;
24809       }
24810       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24811       *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])
24812                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
24813    }
24814    else /* frthrScp == FALSE */
24815    {
24816       if (cell->numTxAntPorts == 2)
24817       {
24818          /* single layer precoding. Format 2. */
24819          *numTxLyrs = 1;
24820          *prcdngInf = (getPrecInfoFunc[1][cell->numTxAntPorts/2 - 1])\
24821                       (cell, ue, *numTxLyrs, *frthrScp);
24822          return;
24823       }
24824       else /* NumAntPorts == 4 */
24825       {
24826          if ((*retxTb)->numLyrs == 2)
24827          {
24828             /* Allocate TB on CW1, using 2 Lyrs,
24829              * Format 2, precoding accordingly */
24830             *numTxLyrs = 2;
24831             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24832             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
24833                          (cell, ue, *numTxLyrs, *frthrScp);
24834             return;
24835          }
24836          else
24837          {
24838             /* Allocate TB with 1 lyr precoding,
24839              * Format 2, precoding info accordingly */
24840             *numTxLyrs = 1;
24841             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24842             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
24843                          (cell, ue, *numTxLyrs, *frthrScp);
24844             return;
24845          }
24846       }
24847    }
24848
24849    return;
24850 }
24851
24852 \f
24853 /**
24854  * @brief This function handles Retx allocation in case of TM3 UEs
24855  *        where previously one of the TBs was NACKED and the other
24856  *        TB is either ACKED/WAITING.
24857  *
24858  * @details
24859  *
24860  *     Function: rgSCHCmnDlTM3TxRetx
24861  *     Purpose:  Determine the TX attributes for TM3 TxRetx Allocation.
24862  *               If futher Scope for New Tx Allocation on other TB
24863  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
24864  *                  Add UE to cell wide RetxTx List.
24865  *               Else
24866  *                  Perform only RETX alloc'n on CW1.
24867  *                  Add UE to cell wide Retx List.
24868  *
24869  *               effBo is set to a non-zero value if allocation is
24870  *               successful.
24871  *
24872  *     Invoked by: rgSCHCmnDlAllocRbTM3
24873  *
24874  *  @param[in]  RgSchCellCb           *cell
24875  *  @param[in]  RgSchDlSf             *subFrm
24876  *  @param[in]  RgSchUeCb             *ue
24877  *  @param[in]  uint32_t                   bo
24878  *  @param[out] uint32_t                   *effBo
24879  *  @param[in]  RgSchDlHqProcCb       *proc
24880  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24881  *  @return  Void
24882  *
24883  **/
24884 static Void rgSCHCmnDlTM3TxRetx
24885 (
24886 RgSchCellCb           *cell,
24887 RgSchDlSf             *subFrm,
24888 RgSchUeCb             *ue,
24889 uint32_t              bo,
24890 uint32_t              *effBo,
24891 RgSchDlHqProcCb       *proc,
24892 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24893 )
24894 {
24895    S16              ret;
24896    RgSchDlRbAlloc   *allocInfo;
24897    uint8_t          numRb;
24898    RgSchDlHqTbCb    *retxTb, *txTb;
24899    Bool             frthrScp;
24900    Bool             swpFlg;
24901    uint8_t          prcdngInf;
24902    uint8_t          numTxLyrs;
24903
24904    frthrScp = FALSE;
24905
24906    ret = ROK;
24907    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24908    swpFlg = FALSE;
24909
24910    /* Determine the transmission attributes */
24911    rgSCHCmnDlGetAttrForTM3(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
24912          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
24913          &allocInfo->raType);
24914
24915    if (frthrScp)
24916    {
24917 #ifdef LAA_DBG_LOG
24918       DU_LOG("\nDEBUG  -->  SCH : TX RETX called from proc %d cell %d \n",proc->procId, cell->cellId);
24919 #endif
24920       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
24921             &numRb, effBo);
24922       if (ret == RFAILED)
24923       {
24924          /* Allocation couldn't be made for Retx */
24925          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24926          return;
24927       }
24928       /* Adding UE to RbAllocInfo RETX-TX Lst */
24929       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
24930    }
24931    else
24932    {
24933       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
24934             numTxLyrs, &numRb, effBo);
24935       if (ret == RFAILED)
24936       {
24937          /* Allocation couldn't be made for Retx */
24938          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24939          return;
24940       }
24941 #ifdef LTEMAC_SPS
24942       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24943 #endif
24944       {
24945          /* Adding UE to allocInfo RETX Lst */
24946          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24947       }
24948    }
24949    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24950          prcdngInf, numTxLyrs, subFrm);
24951
24952    return;
24953 }
24954
24955 \f
24956 /**
24957  * @brief This function handles Retx allocation in case of TM4 UEs
24958  *        where previously one of the TBs was NACKED and the other
24959  *        TB is either ACKED/WAITING.
24960  *
24961  * @details
24962  *
24963  *     Function: rgSCHCmnDlTM4TxRetx
24964  *     Purpose:  Determine the TX attributes for TM4 TxRetx Allocation.
24965  *               If futher Scope for New Tx Allocation on other TB
24966  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
24967  *                  Add UE to cell wide RetxTx List.
24968  *               Else
24969  *                  Perform only RETX alloc'n on CW1.
24970  *                  Add UE to cell wide Retx List.
24971  *
24972  *               effBo is set to a non-zero value if allocation is
24973  *               successful.
24974  *
24975  *     Invoked by: rgSCHCmnDlAllocRbTM4
24976  *
24977  *  @param[in]  RgSchCellCb           *cell
24978  *  @param[in]  RgSchDlSf             *subFrm
24979  *  @param[in]  RgSchUeCb             *ue
24980  *  @param[in]  uint32_t                   bo
24981  *  @param[out] uint32_t                   *effBo
24982  *  @param[in]  RgSchDlHqProcCb       *proc
24983  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24984  *  @return  Void
24985  *
24986  **/
24987 static Void rgSCHCmnDlTM4TxRetx
24988 (
24989 RgSchCellCb                *cell,
24990 RgSchDlSf                  *subFrm,
24991 RgSchUeCb                  *ue,
24992 uint32_t                   bo,
24993 uint32_t                   *effBo,
24994 RgSchDlHqProcCb            *proc,
24995 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
24996 )
24997 {
24998    S16              ret;
24999    RgSchDlRbAlloc   *allocInfo;
25000    uint8_t          numRb;
25001    RgSchDlHqTbCb    *retxTb, *txTb;
25002    Bool             frthrScp;
25003    Bool             swpFlg;
25004    uint8_t          prcdngInf;
25005    uint8_t          numTxLyrs;
25006
25007
25008    ret = ROK;
25009    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25010    swpFlg = FALSE;
25011
25012    /* Determine the transmission attributes */
25013    rgSCHCmnDlGetAttrForTM4(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
25014          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
25015          &allocInfo->raType);
25016
25017    if (frthrScp)
25018    {
25019       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
25020             &numRb, effBo);
25021       if (ret == RFAILED)
25022       {
25023          /* Fix : syed If TxRetx allocation failed then add the UE along 
25024           * with the proc to the nonSchdTxRetxUeLst and let spfc scheduler
25025           *  take care of it during finalization. */       
25026          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25027          return;
25028       }
25029       /* Adding UE to RbAllocInfo RETX-TX Lst */
25030       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
25031    }
25032    else
25033    {
25034       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
25035             numTxLyrs, &numRb, effBo);
25036       if (ret == RFAILED)
25037       {
25038          /* Allocation couldn't be made for Retx */
25039          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25040          return;
25041       }
25042 #ifdef LTEMAC_SPS
25043       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25044 #endif
25045       {
25046          /* Adding UE to allocInfo RETX Lst */
25047          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
25048       }
25049    }
25050    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
25051          prcdngInf, numTxLyrs, subFrm)
25052
25053       return;
25054 }
25055
25056 \f
25057 /**
25058  * @brief This function handles Retx allocation in case of TM4 UEs
25059  *        where previously both the TBs were ACKED and ACKED
25060  *        respectively.
25061  *
25062  * @details
25063  *
25064  *     Function: rgSCHCmnDlTM3TxTx
25065  *     Purpose:  Reached here for a TM3 UE's HqP's fresh allocation
25066  *                  where both the TBs are free for TX scheduling.
25067  *               If forceTD flag is set
25068  *                  perform TD on CW1 with TB1.
25069  *                  precInfo = 0
25070  *               else
25071  *                  DCI Format = 2A.
25072  *                  RA Type = Type0.
25073  *                  RI layered precoding 2 TB on 2 CW.
25074  *                  Set precoding info.
25075  *               Add UE to cellAllocInfo.
25076  *               Fill ueAllocInfo.
25077  *
25078  *              effBo is set to a non-zero value if allocation is
25079  *              successful.
25080  *
25081  *     Invoked by: rgSCHCmnDlAllocRbTM3
25082  *
25083  *  @param[in]  RgSchCellCb           *cell
25084  *  @param[in]  RgSchDlSf             *subFrm
25085  *  @param[in]  RgSchUeCb             *ue
25086  *  @param[in]  uint32_t                   bo
25087  *  @param[out] uint32_t                   *effBo
25088  *  @param[in]  RgSchDlHqProcCb       *proc
25089  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25090  *  @return  Void
25091  *
25092  **/
25093 static Void rgSCHCmnDlTM3TxTx
25094 (
25095 RgSchCellCb           *cell,
25096 RgSchDlSf             *subFrm,
25097 RgSchUeCb             *ue,
25098 uint32_t              bo,
25099 uint32_t              *effBo,
25100 RgSchDlHqProcCb       *proc,
25101 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25102 )
25103 {
25104    RgSchCmnDlUe     *ueDl;
25105    RgSchDlRbAlloc   *allocInfo;
25106    uint8_t          numRb;
25107    uint8_t          noTxLyrs;
25108    uint8_t          precInfo;
25109    S16              ret;
25110    uint8_t          precInfoAntIdx;
25111
25112
25113    ret = ROK;
25114    ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
25115    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25116
25117    /* Integration_fix: SPS Proc shall always have only one Cw */
25118 #ifdef LTEMAC_SPS
25119 #ifdef FOUR_TX_ANTENNA
25120       if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25121                      (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
25122 #else
25123    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25124          (ueDl->mimoInfo.forceTD))
25125 #endif
25126 #else
25127    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
25128 #endif
25129    {
25130       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
25131             &allocInfo->raType);
25132       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25133             bo, &numRb, effBo);
25134       if (ret == RFAILED)
25135       {
25136          /* If allocation couldn't be made then return */
25137          return;
25138       }
25139       noTxLyrs = 1;
25140       precInfo = 0; /* TD */
25141    }
25142    else /* Precoding */
25143    {
25144       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
25145       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
25146
25147       /* Spatial Multiplexing using 2 CWs */
25148       ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
25149       if (ret == RFAILED)
25150       {
25151          /* If allocation couldn't be made then return */
25152          return;
25153       }
25154       noTxLyrs = ueDl->mimoInfo.ri;
25155       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
25156       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, getPrecInfoFunc[0], precInfoAntIdx);
25157       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
25158    }
25159
25160 #ifdef LTEMAC_SPS
25161    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25162 #endif
25163    {
25164       /* Adding UE to RbAllocInfo TX Lst */
25165       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25166    }
25167    /* Fill UE allocInfo scrath pad */
25168    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
25169          precInfo, noTxLyrs, subFrm);
25170
25171    return;
25172 }
25173
25174 \f
25175 /**
25176  * @brief This function handles Retx allocation in case of TM4 UEs
25177  *        where previously both the TBs were ACKED and ACKED
25178  *        respectively.
25179  *
25180  * @details
25181  *
25182  *     Function: rgSCHCmnDlTM4TxTx
25183  *     Purpose:  Reached here for a TM4 UE's HqP's fresh allocation
25184  *                  where both the TBs are free for TX scheduling.
25185  *               If forceTD flag is set
25186  *                  perform TD on CW1 with TB1.
25187  *                  precInfo = 0
25188  *               else
25189  *                  DCI Format = 2.
25190  *                  RA Type = Type0.
25191  *                  If Rank == 1
25192  *                     Single layer precoding of TB1 on CW1.
25193  *                     Set precoding info.
25194  *                  else
25195  *                     RI layered precoding 2 TB on 2 CW.
25196  *                     Set precoding info.
25197  *               Add UE to cellAllocInfo.
25198  *               Fill ueAllocInfo.
25199  *
25200  *              effBo is set to a non-zero value if allocation is
25201  *              successful.
25202  *
25203  *     Invoked by: rgSCHCmnDlAllocRbTM4
25204  *
25205  *  @param[in]  RgSchCellCb           *cell
25206  *  @param[in]  RgSchDlSf             *subFrm
25207  *  @param[in]  RgSchUeCb             *ue
25208  *  @param[in]  uint32_t                   bo
25209  *  @param[out] uint32_t                   *effBo
25210  *  @param[in]  RgSchDlHqProcCb       *proc
25211  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25212  *  @return  Void
25213  *
25214  **/
25215 static Void rgSCHCmnDlTM4TxTx
25216 (
25217 RgSchCellCb           *cell,
25218 RgSchDlSf             *subFrm,
25219 RgSchUeCb             *ue,
25220 uint32_t              bo,
25221 uint32_t              *effBo,
25222 RgSchDlHqProcCb       *proc,
25223 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25224 )
25225 {
25226    RgSchCmnDlUe     *ueDl;
25227    RgSchDlRbAlloc   *allocInfo;
25228    uint8_t          numRb;
25229    uint8_t          precInfo;
25230    uint8_t          noTxLyrs;
25231    uint8_t          precInfoAntIdx;
25232    S16              ret;
25233
25234
25235    ret       = ROK;
25236    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25237    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25238
25239    /* Integration_fix: SPS Proc shall always have only one Cw */
25240 #ifdef LTEMAC_SPS
25241 #ifdef FOUR_TX_ANTENNA
25242    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25243                   (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
25244 #else
25245    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25246          (ueDl->mimoInfo.forceTD))
25247 #endif
25248 #else
25249    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
25250 #endif
25251    {
25252       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
25253             &allocInfo->raType);
25254
25255       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25256             bo, &numRb, effBo);
25257       if (ret == RFAILED)
25258       {
25259          /* If allocation couldn't be made then return */
25260          return;
25261       }
25262       noTxLyrs = 1;
25263       precInfo = 0; /* TD */
25264    }
25265    else /* Precoding */
25266    {
25267       allocInfo->dciFormat = TFU_DCI_FORMAT_2;
25268       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
25269
25270       if (ueDl->mimoInfo.ri == 1)
25271       {
25272          /* Single Layer SM using FORMAT 2 */
25273          ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25274                bo, &numRb, effBo);
25275          if (ret == RFAILED)
25276          {
25277             /* If allocation couldn't be made then return */
25278             return;
25279          }
25280          noTxLyrs = 1;
25281          precInfo = 0; /* PrecInfo as 0 for RI=1*/
25282       }
25283       else
25284       {
25285          /* Spatial Multiplexing using 2 CWs */
25286          ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
25287          if (ret == RFAILED)
25288          {
25289             /* If allocation couldn't be made then return */
25290             return;
25291          }
25292          noTxLyrs = ueDl->mimoInfo.ri;
25293          precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
25294          precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
25295       }
25296    }
25297
25298    
25299 #ifdef LTEMAC_SPS
25300    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25301 #endif
25302    {
25303       /* Adding UE to RbAllocInfo TX Lst */
25304       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25305    }
25306
25307    /* Fill UE allocInfo scrath pad */
25308    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
25309          precInfo, noTxLyrs, subFrm);
25310
25311    return;
25312 }
25313
25314 \f
25315 /**
25316  * @brief This function determines the RBs and Bytes required for BO
25317  *        transmission for UEs configured with TM 4.
25318  *
25319  * @details
25320  *
25321  *     Function: rgSCHCmnDlAllocTxRbTM4
25322  *     Purpose:  Invokes the functionality particular to the
25323  *               current state of the TBs of the "proc".
25324  *
25325  *               Reference Parameter effBo is filled with alloced bytes.
25326  *               Returns RFAILED if BO not satisfied at all.
25327  *
25328  *     Invoked by: rgSCHCmnDlAllocTxRb
25329  *
25330  *  @param[in]  RgSchCellCb           *cell
25331  *  @param[in]  RgSchDlSf             *subFrm
25332  *  @param[in]  RgSchUeCb             *ue
25333  *  @param[in]  uint32_t                   bo
25334  *  @param[out] uint32_t                   *effBo
25335  *  @param[in]  RgSchDlHqProcCb       *proc
25336  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25337  *  @return  Void
25338  *
25339  **/
25340 static Void rgSCHCmnDlAllocTxRbTM4
25341 (
25342 RgSchCellCb            *cell,
25343 RgSchDlSf              *subFrm,
25344 RgSchUeCb              *ue,
25345 uint32_t               bo,
25346 uint32_t               *effBo,
25347 RgSchDlHqProcCb        *proc,
25348 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
25349 )
25350 {
25351
25352    /* Both TBs free for TX allocation */
25353    rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo,\
25354          proc, cellWdAllocInfo);
25355
25356    return;
25357 }
25358
25359 \f
25360 /**
25361  * @brief This function determines the RBs and Bytes required for BO
25362  *        retransmission for UEs configured with TM 4.
25363  *
25364  * @details
25365  *
25366  *     Function: rgSCHCmnDlAllocRetxRbTM4
25367  *     Purpose:  Invokes the functionality particular to the
25368  *               current state of the TBs of the "proc".
25369  *
25370  *               Reference Parameter effBo is filled with alloced bytes.
25371  *               Returns RFAILED if BO not satisfied at all.
25372  *
25373  *     Invoked by: rgSCHCmnDlAllocRetxRb
25374  *
25375  *  @param[in]  RgSchCellCb           *cell
25376  *  @param[in]  RgSchDlSf             *subFrm
25377  *  @param[in]  RgSchUeCb             *ue
25378  *  @param[in]  uint32_t                   bo
25379  *  @param[out] uint32_t                   *effBo
25380  *  @param[in]  RgSchDlHqProcCb       *proc
25381  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25382  *  @return  Void
25383  *
25384  **/
25385 static Void rgSCHCmnDlAllocRetxRbTM4
25386 (
25387 RgSchCellCb           *cell,
25388 RgSchDlSf             *subFrm,
25389 RgSchUeCb             *ue,
25390 uint32_t              bo,
25391 uint32_t              *effBo,
25392 RgSchDlHqProcCb       *proc,
25393 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25394 )
25395 {
25396
25397    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
25398          (proc->tbInfo[1].state == HQ_TB_NACKED))
25399    {
25400       /* Both TBs require RETX allocation */
25401       rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo,\
25402             proc, cellWdAllocInfo);
25403    }
25404    else
25405    {
25406       /* One of the TBs need RETX allocation. Other TB may/maynot
25407        * be available for new TX allocation. */
25408       rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo,\
25409             proc, cellWdAllocInfo);
25410    }
25411
25412    return;
25413 }
25414
25415 #ifdef RG_UNUSED
25416 \f
25417 /**
25418  * @brief This function determines the RBs and Bytes required for BO
25419  *        transmission for UEs configured with TM 5.
25420  *
25421  * @details
25422  *
25423  *     Function: rgSCHCmnDlAllocTxRbTM5
25424  *     Purpose:
25425  *
25426  *               Reference Parameter effBo is filled with alloced bytes.
25427  *               Returns RFAILED if BO not satisfied at all.
25428  *
25429  *     Invoked by: rgSCHCmnDlAllocTxRb
25430  *
25431  *  @param[in]  RgSchCellCb           *cell
25432  *  @param[in]  RgSchDlSf             *subFrm
25433  *  @param[in]  RgSchUeCb             *ue
25434  *  @param[in]  uint32_t                   bo
25435  *  @param[out] uint32_t                   *effBo
25436  *  @param[in]  RgSchDlHqProcCb       *proc
25437  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25438  *  @return Void
25439  *
25440  **/
25441 static Void rgSCHCmnDlAllocTxRbTM5
25442 (
25443 RgSchCellCb                *cell,
25444 RgSchDlSf                  *subFrm,
25445 RgSchUeCb                  *ue,
25446 uint32_t                   bo,
25447 uint32_t                   *effBo,
25448 RgSchDlHqProcCb            *proc,
25449 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25450 )
25451 {
25452 #if (ERRCLASS & ERRCLS_DEBUG)
25453    DU_LOG("\nERROR  -->  SCH : Invalid TM 5 for CRNTI:%d",ue->ueId);
25454 #endif
25455    return;
25456 }
25457
25458 \f
25459 /**
25460  * @brief This function determines the RBs and Bytes required for BO
25461  *        retransmission for UEs configured with TM 5.
25462  *
25463  * @details
25464  *
25465  *     Function: rgSCHCmnDlAllocRetxRbTM5
25466  *     Purpose:
25467  *
25468  *               Reference Parameter effBo is filled with alloced bytes.
25469  *               Returns RFAILED if BO not satisfied at all.
25470  *
25471  *     Invoked by: rgSCHCmnDlAllocRetxRb
25472  *
25473  *  @param[in]  RgSchCellCb           *cell
25474  *  @param[in]  RgSchDlSf             *subFrm
25475  *  @param[in]  RgSchUeCb             *ue
25476  *  @param[in]  uint32_t                   bo
25477  *  @param[out] uint32_t                   *effBo
25478  *  @param[in]  RgSchDlHqProcCb       *proc
25479  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25480  *  @return Void
25481  *
25482  **/
25483 static Void rgSCHCmnDlAllocRetxRbTM5
25484 (
25485 RgSchCellCb            *cell,
25486 RgSchDlSf              *subFrm,
25487 RgSchUeCb              *ue,
25488 uint32_t               bo,
25489 uint32_t               *effBo,
25490 RgSchDlHqProcCb        *proc,
25491 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
25492 )
25493 {
25494 #if (ERRCLASS & ERRCLS_DEBUG)
25495    DU_LOG("\nERROR  -->  SCH : Invalid TM 5 for CRNTI:%d",ue->ueId);
25496 #endif
25497    return;
25498 }
25499 #endif
25500
25501 \f
25502 /**
25503  * @brief This function determines the RBs and Bytes required for BO
25504  *        transmission for UEs configured with TM 6.
25505  *
25506  * @details
25507  *
25508  *     Function: rgSCHCmnDlAllocTxRbTM6
25509  *     Purpose:
25510  *
25511  *               Reference Parameter effBo is filled with alloced bytes.
25512  *               Returns RFAILED if BO not satisfied at all.
25513  *
25514  *     Invoked by: rgSCHCmnDlAllocTxRb
25515  *
25516  *  @param[in]  RgSchCellCb           *cell
25517  *  @param[in]  RgSchDlSf             *subFrm
25518  *  @param[in]  RgSchUeCb             *ue
25519  *  @param[in]  uint32_t                   bo
25520  *  @param[out] uint32_t                   *effBo
25521  *  @param[in]  RgSchDlHqProcCb       *proc
25522  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25523  *  @return Void
25524  *
25525  **/
25526 static Void rgSCHCmnDlAllocTxRbTM6
25527 (
25528 RgSchCellCb                *cell,
25529 RgSchDlSf                  *subFrm,
25530 RgSchUeCb                  *ue,
25531 uint32_t                   bo,
25532 uint32_t                   *effBo,
25533 RgSchDlHqProcCb            *proc,
25534 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25535 )
25536 {
25537    RgSchDlRbAlloc *allocInfo;
25538    RgSchCmnDlUe   *ueDl;
25539    S16            ret;
25540    uint8_t        numRb;
25541
25542
25543    ret       = ROK;
25544    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25545    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25546
25547    if (ueDl->mimoInfo.forceTD)
25548    {
25549       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25550       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25551    }
25552    else
25553    {
25554       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
25555       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25556       /* Fill precoding information for FORMAT 1B */
25557       /* First 4 least significant bits to indicate PMI.
25558        * 4th most significant corresponds to pmi Confirmation.
25559        */
25560       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
25561       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
25562    }
25563    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25564          bo, &numRb, effBo);
25565    if (ret == RFAILED)
25566    {
25567       /* If allocation couldn't be made then return */
25568       return;
25569    }
25570    
25571 #ifdef LTEMAC_SPS
25572    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25573 #endif
25574    {
25575       /* Adding UE to RbAllocInfo TX Lst */
25576       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25577    }
25578    /* Fill UE alloc Info */
25579    allocInfo->rbsReq = numRb;
25580    allocInfo->dlSf   = subFrm;
25581    return;
25582 }
25583
25584 \f
25585 /**
25586  * @brief This function determines the RBs and Bytes required for BO
25587  *        retransmission for UEs configured with TM 6.
25588  *
25589  * @details
25590  *
25591  *     Function: rgSCHCmnDlAllocRetxRbTM6
25592  *     Purpose:
25593  *
25594  *               Reference Parameter effBo is filled with alloced bytes.
25595  *               Returns RFAILED if BO not satisfied at all.
25596  *
25597  *     Invoked by: rgSCHCmnDlAllocRetxRb
25598  *
25599  *  @param[in]  RgSchCellCb           *cell
25600  *  @param[in]  RgSchDlSf             *subFrm
25601  *  @param[in]  RgSchUeCb             *ue
25602  *  @param[in]  uint32_t                   bo
25603  *  @param[out] uint32_t                   *effBo
25604  *  @param[in]  RgSchDlHqProcCb       *proc
25605  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25606  *  @return Void
25607  *
25608  **/
25609 static Void rgSCHCmnDlAllocRetxRbTM6
25610 (
25611 RgSchCellCb                *cell,
25612 RgSchDlSf                  *subFrm,
25613 RgSchUeCb                  *ue,
25614 uint32_t                   bo,
25615 uint32_t                   *effBo,
25616 RgSchDlHqProcCb            *proc,
25617 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25618 )
25619 {
25620    RgSchDlRbAlloc *allocInfo;
25621    RgSchCmnDlUe   *ueDl;
25622    S16            ret;
25623    uint8_t        numRb;
25624
25625
25626    ret       = ROK;
25627    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25628    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25629
25630    if (ueDl->mimoInfo.forceTD)
25631    {
25632       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25633       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25634    }
25635    else
25636    {
25637       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
25638       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25639       /* Fill precoding information for FORMAT 1B */
25640       /* First 4 least significant bits to indicate PMI.
25641        * 4th most significant corresponds to pmi Confirmation.
25642        */
25643       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
25644       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
25645    }
25646
25647    /* Get the Allocation in terms of RBs that are required for
25648     * this retx of TB1 */
25649    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
25650          1, &numRb, effBo);
25651    if (ret == RFAILED)
25652    {
25653       /* Allocation couldn't be made for Retx */
25654       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25655       return;
25656    }
25657    /* Adding UE to allocInfo RETX Lst */
25658    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
25659    /* Fill UE alloc Info */
25660    allocInfo->rbsReq = numRb;
25661    allocInfo->dlSf   = subFrm;
25662    return;
25663 }
25664
25665 \f
25666 /**
25667  * @brief This function determines the RBs and Bytes required for BO
25668  *        transmission for UEs configured with TM 7.
25669  *
25670  * @details
25671  *
25672  *     Function: rgSCHCmnDlAllocTxRbTM7
25673  *     Purpose:
25674  *
25675  *               Reference Parameter effBo is filled with alloced bytes.
25676  *               Returns RFAILED if BO not satisfied at all.
25677  *
25678  *     Invoked by: rgSCHCmnDlAllocTxRb
25679  *
25680  *  @param[in]  RgSchCellCb           *cell
25681  *  @param[in]  RgSchDlSf             *subFrm
25682  *  @param[in]  RgSchUeCb             *ue
25683  *  @param[in]  uint32_t                   bo
25684  *  @param[out] uint32_t                   *effBo
25685  *  @param[in]  RgSchDlHqProcCb       *proc
25686  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25687  *  @return Void
25688  *
25689  **/
25690 static Void rgSCHCmnDlAllocTxRbTM7
25691 (
25692 RgSchCellCb                *cell,
25693 RgSchDlSf                  *subFrm,
25694 RgSchUeCb                  *ue,
25695 uint32_t                   bo,
25696 uint32_t                   *effBo,
25697 RgSchDlHqProcCb            *proc,
25698 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25699 )
25700 {
25701    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
25702    return;
25703 }
25704
25705 \f
25706 /**
25707  * @brief This function determines the RBs and Bytes required for BO
25708  *        retransmission for UEs configured with TM 7.
25709  *
25710  * @details
25711  *
25712  *     Function: rgSCHCmnDlAllocRetxRbTM7
25713  *     Purpose:
25714  *
25715  *               Reference Parameter effBo is filled with alloced bytes.
25716  *               Returns RFAILED if BO not satisfied at all.
25717  *
25718  *     Invoked by: rgSCHCmnDlAllocRetxRb
25719  *
25720  *  @param[in]  RgSchCellCb           *cell
25721  *  @param[in]  RgSchDlSf             *subFrm
25722  *  @param[in]  RgSchUeCb             *ue
25723  *  @param[in]  uint32_t                   bo
25724  *  @param[out] uint32_t                   *effBo
25725  *  @param[in]  RgSchDlHqProcCb       *proc
25726  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25727  *  @return Void
25728  *
25729  **/
25730 static Void rgSCHCmnDlAllocRetxRbTM7
25731 (
25732 RgSchCellCb                *cell,
25733 RgSchDlSf                  *subFrm,
25734 RgSchUeCb                  *ue,
25735 uint32_t                   bo,
25736 uint32_t                   *effBo,
25737 RgSchDlHqProcCb            *proc,
25738 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25739 )
25740 {
25741    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
25742    return;
25743 }
25744
25745 \f
25746 /**
25747  * @brief This function invokes the TM specific DL TX RB Allocation routine.
25748  *
25749  * @details
25750  *
25751  *     Function: rgSCHCmnDlAllocTxRb
25752  *     Purpose:  This function invokes the TM specific
25753  *               DL TX RB Allocation routine.
25754  *
25755  *     Invoked by: Specific Schedulers
25756  *
25757  *  @param[in]  RgSchCellCb           *cell
25758  *  @param[in]  RgSchDlSf             *subFrm
25759  *  @param[in]  RgSchUeCb             *ue
25760  *  @param[in]  uint32_t                   bo
25761  *  @param[out] uint32_t                   *effBo
25762  *  @param[in]  RgSchDlHqProcCb       *proc
25763  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25764  *  @return  S16
25765  *
25766  **/
25767 S16 rgSCHCmnDlAllocTxRb
25768 (
25769 RgSchCellCb                *cell,
25770 RgSchDlSf                  *subFrm,
25771 RgSchUeCb                  *ue,
25772 uint32_t                   bo,
25773 uint32_t                   *effBo,
25774 RgSchDlHqProcCb            *proc,
25775 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25776 )
25777 {
25778    uint32_t                newSchBits = 0;
25779    uint32_t                prevSchBits = 0;
25780    RgSchDlRbAlloc          *allocInfo;
25781
25782
25783    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
25784    {
25785       ue->dl.aggTbBits = 0;
25786    }
25787    *effBo = 0;
25788
25789    /* Calculate totals bits previously allocated */
25790    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25791    if (allocInfo->tbInfo[0].schdlngForTb)
25792    {
25793       prevSchBits += allocInfo->tbInfo[0].bytesReq;
25794    }
25795    if (allocInfo->tbInfo[1].schdlngForTb)
25796    {
25797       prevSchBits += allocInfo->tbInfo[1].bytesReq;
25798    }
25799
25800    /* Call TM specific RB allocation routine */
25801    (dlAllocTxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
25802          proc, cellWdAllocInfo);
25803
25804    if (*effBo)
25805    {
25806       /* Calculate totals bits newly allocated */
25807       if (allocInfo->tbInfo[0].schdlngForTb)
25808       {
25809          newSchBits += allocInfo->tbInfo[0].bytesReq;
25810       }
25811       if (allocInfo->tbInfo[1].schdlngForTb)
25812       {
25813          newSchBits += allocInfo->tbInfo[1].bytesReq;
25814       }
25815       if (newSchBits > prevSchBits)
25816       {
25817          ue->dl.aggTbBits += ((newSchBits - prevSchBits) * 8);
25818          RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
25819       }
25820    }
25821
25822    return ROK;
25823 }
25824
25825 /* DwPTS Scheduling Changes Start */
25826 #ifdef LTE_TDD
25827 /**
25828  * @brief Retransmit decision for TDD. Retx is avoided in below cases
25829  *        1) DL Sf       -> Spl Sf
25830  *        2) DL SF       -> DL SF 0 
25831  *
25832  * @details
25833  *
25834  *     Function: rgSCHCmnRetxAvoidTdd 
25835  *     Purpose: Avoid allocating RETX for cases 1, 2 
25836  * 
25837  *     Invoked by: rgSCHCmnRetxAvoidTdd 
25838  *
25839  *  @param[in]  RgSchDlSf             *curSf
25840  *  @param[in]  RgSchCellCb           *cell
25841  *  @param[in]  RgSchDlHqProcCb       *proc
25842  *  @return  Bool 
25843  *
25844  **/
25845 Bool rgSCHCmnRetxAvoidTdd 
25846 (
25847 RgSchDlSf                  *curSf,
25848 RgSchCellCb                *cell,
25849 RgSchDlHqProcCb            *proc
25850 )
25851 {
25852    RgSchTddSfType   txSfType = 0;
25853
25854
25855    /* Get the RBs of TB that will be retransmitted */
25856    if (proc->tbInfo[0].state == HQ_TB_NACKED)
25857    {
25858       txSfType = proc->tbInfo[0].sfType;
25859
25860 #ifdef XEON_SPECIFIC_CHANGES
25861 #ifndef XEON_TDD_SPCL
25862       /* Avoid re-transmission on Normal SF when the corresponding TB wss transmitted on SPCL SF */
25863       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
25864       {
25865          return (TRUE);
25866       }
25867 #endif
25868 #endif
25869    }
25870    if (proc->tbInfo[1].state == HQ_TB_NACKED) 
25871    {
25872       /* Select the TxSf with the highest num of possible REs 
25873        * In ascending order -> 1) SPL SF 2) DL_SF_0 3) DL_SF */
25874       txSfType = RGSCH_MAX(txSfType, proc->tbInfo[1].sfType);
25875
25876 #ifdef XEON_SPECIFIC_CHANGES
25877 #ifndef XEON_TDD_SPCL
25878       /* Avoid re-transmission on Normal SF when the corresponding TB wss tranmitted on SPCL SF */
25879       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
25880       {
25881          return (TRUE);
25882       }
25883 #endif
25884 #endif
25885    }
25886
25887    if (txSfType > curSf->sfType)
25888    {
25889       /* Avoid retx */
25890       return (TRUE);
25891    }
25892    
25893    /* Allow Retx */
25894    return (FALSE);
25895 }
25896
25897 #else
25898 /* DwPTS Scheduling Changes End */
25899 \f
25900 /**
25901  * @brief Avoid allocating RETX incase of collision
25902  * with reserved resources for BCH/PSS/SSS occassions.
25903  *
25904  * @details
25905  *
25906  *     Function: rgSCHCmnRetxAllocAvoid 
25907  *     Purpose: Avoid allocating RETX incase of collision
25908  * with reserved resources for BCH/PSS/SSS occassions 
25909  *
25910  *     Invoked by: rgSCHCmnDlAllocRetxRb 
25911  *
25912  *  @param[in]  RgSchDlSf             *subFrm
25913  *  @param[in]  RgSchUeCb             *ue
25914  *  @param[in]  RgSchDlHqProcCb       *proc
25915  *  @return  Bool 
25916  *
25917  **/
25918 Bool rgSCHCmnRetxAllocAvoid 
25919 (
25920 RgSchDlSf                  *subFrm,
25921 RgSchCellCb                *cell,
25922 RgSchDlHqProcCb            *proc
25923 )
25924 {
25925    uint8_t          reqRbs;
25926
25927
25928    if (proc->tbInfo[0].state == HQ_TB_NACKED)
25929    {
25930       reqRbs = proc->tbInfo[0].dlGrnt.numRb;    
25931    }
25932    else
25933    {
25934       reqRbs = proc->tbInfo[1].dlGrnt.numRb;    
25935    }
25936    /* Consider the dlGrnt.numRb of the Retransmitting proc->tbInfo
25937     * and current available RBs to determine if this RETX TB
25938     * will collide with the BCH/PSS/SSS occassion */
25939    if (subFrm->sfNum % 5 == 0)
25940    {
25941       if ((subFrm->bwAssigned < cell->pbchRbEnd) &&
25942           (((subFrm->bwAssigned + reqRbs) - cell->pbchRbStart) > 0))
25943       {
25944          return (TRUE);
25945       }
25946    }
25947    return (FALSE);
25948 }
25949
25950 #endif
25951
25952 \f
25953 /**
25954  * @brief This function invokes the TM specific DL RETX RB Allocation routine.
25955  *
25956  * @details
25957  *
25958  *     Function: rgSCHCmnDlAllocRetxRb
25959  *     Purpose:  This function invokes the TM specific
25960  *               DL RETX RB Allocation routine.
25961  *
25962  *     Invoked by: Specific Schedulers
25963  *
25964  *  @param[in]  RgSchCellCb           *cell
25965  *  @param[in]  RgSchDlSf             *subFrm
25966  *  @param[in]  RgSchUeCb             *ue
25967  *  @param[in]  uint32_t                   bo
25968  *  @param[out] uint32_t                   *effBo
25969  *  @param[in]  RgSchDlHqProcCb       *proc
25970  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25971  *  @return  S16
25972  *
25973  **/
25974 S16 rgSCHCmnDlAllocRetxRb
25975 (
25976 RgSchCellCb                *cell,
25977 RgSchDlSf                  *subFrm,
25978 RgSchUeCb                  *ue,
25979 uint32_t                   bo,
25980 uint32_t                   *effBo,
25981 RgSchDlHqProcCb            *proc,
25982 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25983 )
25984 {
25985    uint32_t                     newSchBits = 0;
25986    RgSchDlRbAlloc          *allocInfo;
25987
25988
25989    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
25990    {
25991       ue->dl.aggTbBits = 0;
25992    }
25993  
25994    *effBo = 0;
25995    /* Check for DL BW exhaustion */
25996    if (subFrm->bw <= subFrm->bwAssigned)
25997    {
25998       return RFAILED;
25999    }
26000    /* Call TM specific RB allocation routine */
26001    (dlAllocRetxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
26002          proc, cellWdAllocInfo);
26003
26004    if (*effBo)
26005    {
26006       allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26007       /* Calculate totals bits newly allocated */
26008       if (allocInfo->tbInfo[0].schdlngForTb)
26009       {
26010          newSchBits += allocInfo->tbInfo[0].bytesReq;
26011       }
26012       if (allocInfo->tbInfo[1].schdlngForTb)
26013       {
26014          newSchBits += allocInfo->tbInfo[1].bytesReq;
26015       }
26016       ue->dl.aggTbBits += (newSchBits * 8);
26017       RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
26018    }
26019    
26020    return ROK;
26021 }
26022
26023 \f
26024 /**
26025  * @brief This function determines the RBs and Bytes required for
26026  *        Transmission on 1 CW.
26027  *
26028  * @details
26029  *
26030  *     Function: rgSCHCmnDlAlloc1CwTxRb
26031  *     Purpose:  This function determines the RBs and Bytes required
26032  *               for Transmission of DL SVC BO on 1 CW.
26033  *               Also, takes care of SVC by SVC allocation by tracking
26034  *               previous SVCs allocations.
26035  *               Returns RFAILED if BO not satisfied at all.
26036  *
26037  *     Invoked by: DL UE Allocation
26038  *
26039  *  @param[in]  RgSchCellCb      *cell
26040  *  @param[in]  RgSchDlSf        *subFrm
26041  *  @param[in]  RgSchUeCb        *ue
26042  *  @param[in]  RgSchDlHqTbCb    *tbInfo
26043  *  @param[in]  uint32_t              bo
26044  *  @param[out] uint8_t               *numRb
26045  *  @param[out] uint32_t              *effBo
26046  *  @return  S16
26047  *
26048  **/
26049 static S16 rgSCHCmnDlAlloc1CwTxRb
26050 (
26051 RgSchCellCb       *cell,
26052 RgSchDlSf         *subFrm,
26053 RgSchUeCb         *ue,
26054 RgSchDlHqTbCb     *tbInfo,
26055 uint32_t          bo,
26056 uint8_t           *numRb,
26057 uint32_t          *effBo
26058 )
26059 {
26060    uint32_t        tbSz;
26061    uint8_t         imcs;
26062    uint8_t         iTbs;
26063    RgSchCmnDlUe    *ueDl;
26064    RgSchDlRbAlloc  *allocInfo;
26065    uint32_t        oldReq;
26066    uint32_t        reqBytes;
26067    /* Correcting wrap around issue.
26068     * This change has been done at mutliple places in this function.*/
26069    uint32_t        tempNumRb;
26070
26071    reqBytes  = bo;
26072    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26073    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26074    oldReq    = ueDl->outStndAlloc;
26075
26076 #ifdef RG_5GTF
26077    //TODO_SID: Currently setting max Tb size wrt to 5GTF TM3
26078    iTbs = ue->ue5gtfCb.mcs;
26079    ueDl->maxTbSz = MAX_5GTF_TB_SIZE * ue->ue5gtfCb.rank;
26080    ueDl->maxRb = MAX_5GTF_PRBS;
26081 #endif
26082    ueDl->outStndAlloc += bo;
26083    /* consider Cumulative amount of this BO and bytes so far allocated */
26084    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbSz/8);
26085    /* Get the number of REs needed for this bo. */
26086    //noRes = ((bo * 8 * 1024) / eff);
26087
26088    /* Get the number of RBs needed for this transmission */
26089    /* Number of RBs = No of REs / No of REs per RB       */
26090    //tempNumRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
26091    tempNumRb = MAX_5GTF_PRBS;
26092    tbSz = RGSCH_MIN(bo, (rgSch5gtfTbSzTbl[iTbs]/8) * ue->ue5gtfCb.rank);
26093
26094    /* DwPts Scheduling Changes End */
26095    *effBo = RGSCH_MIN(tbSz - oldReq, reqBytes);
26096
26097 #ifdef RG_5GTF
26098    //RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs);
26099    imcs = iTbs;
26100 #endif
26101
26102
26103    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbSz, \
26104          iTbs, imcs, tbInfo, ue->ue5gtfCb.rank);
26105    *numRb = (uint8_t) tempNumRb;
26106    
26107    /* Update the subframe Allocated BW field */
26108    subFrm->bwAssigned = subFrm->bwAssigned + tempNumRb - allocInfo->rbsReq;
26109    
26110    return ROK;
26111 }
26112
26113 \f
26114 /**
26115  * @brief This function is invoked in the event of any TB's allocation
26116  *  being underutilized by the specific scheduler. Here we reduce iMcs
26117  *  to increase redundancy and hence increase reception quality at UE.
26118  *
26119  * @details
26120  *
26121  *     Function: rgSCHCmnRdcImcsTxTb
26122  *     Purpose:  This function shall reduce the iMcs in accordance with
26123  *               the total consumed bytes by the UE at allocation
26124  *               finalization.
26125  *
26126  *     Invoked by: UE DL Allocation finalization routine
26127  *                 of specific scheduler.
26128  *
26129  *  @param[in]  RgSchDlRbAlloc   *allocInfo
26130  *  @param[in]  uint8_t               tbInfoIdx
26131  *  @param[in]  uint32_t              cnsmdBytes
26132  *  @return  Void
26133  *
26134  **/
26135 Void rgSCHCmnRdcImcsTxTb
26136 (
26137 RgSchDlRbAlloc   *allocInfo,
26138 uint8_t          tbInfoIdx,
26139 uint32_t         cnsmdBytes
26140 )
26141 {
26142    return;
26143    /*The below functionality is not needed.*/
26144    uint8_t                 noLyr;
26145    uint8_t                 iTbs;
26146    uint16_t                numRb;
26147
26148
26149    iTbs = allocInfo->tbInfo[tbInfoIdx].iTbs;
26150    noLyr = allocInfo->tbInfo[tbInfoIdx].noLyr;
26151    numRb = allocInfo->rbsAlloc;
26152    if ( numRb > 0)
26153    {
26154       if ((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) == cnsmdBytes)
26155       {
26156          return;
26157       }
26158    }
26159    /* Get iTbs as suitable for the consumed bytes */
26160    while((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) > cnsmdBytes)
26161    {
26162       if (iTbs == 0)
26163       {
26164          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].\
26165                tbCb->dlGrnt.iMcs);
26166          return;
26167       }
26168       iTbs--;
26169    }
26170    iTbs++;
26171    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].tbCb->dlGrnt.iMcs);
26172
26173    return;
26174 }
26175
26176 \f
26177 /**
26178  * @brief This function determines the RBs and Bytes required for
26179  *        Transmission on 2 CWs.
26180  *
26181  * @details
26182  *
26183  *     Function: rgSCHCmnDlAlloc2CwTxRb
26184  *     Purpose:  This function determines the RBs and Bytes required
26185  *               for Transmission of DL SVC BO on 2 CWs.
26186  *               Also, takes care of SVC by SVC allocation by tracking
26187  *               previous SVCs allocations.
26188  *               Returns RFAILED if BO not satisfied at all.
26189  *
26190  *     Invoked by: TM3 and TM4 DL UE Allocation
26191  *
26192  *  @param[in]  RgSchCellCb      *cell
26193  *  @param[in]  RgSchDlSf        *subFrm
26194  *  @param[in]  RgSchUeCb        *ue
26195  *  @param[in]  RgSchDlHqProcCb  *proc
26196  *  @param[in]  RgSchDlHqProcCb  bo
26197  *  @param[out] uint8_t               *numRb
26198  *  @param[out] uint32_t              *effBo
26199  *  @return  Void
26200  *
26201  **/
26202 static S16 rgSCHCmnDlAlloc2CwTxRb
26203 (
26204 RgSchCellCb      *cell,
26205 RgSchDlSf        *subFrm,
26206 RgSchUeCb        *ue,
26207 RgSchDlHqProcCb  *proc,
26208 uint32_t         bo,
26209 uint8_t          *numRbRef,
26210 uint32_t         *effBo
26211 )
26212 {
26213    uint32_t       noRes;
26214    uint32_t       eff1, eff2;
26215    uint32_t       tb1Sz, tb2Sz;
26216    uint8_t        imcs1, imcs2;
26217    uint8_t        noLyr1, noLyr2;
26218    uint8_t        iTbs1, iTbs2;
26219    RgSchCmnDlCell *cellDl;
26220    RgSchCmnDlUe   *ueDl;
26221    RgSchDlRbAlloc *allocInfo;
26222    uint32_t       oldReq;
26223    uint32_t       reqBytes;
26224    /* Fix: MUE_PERTTI_DL */
26225    uint32_t       numRb;
26226    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
26227    uint8_t        cfi = cellSch->dl.currCfi;
26228    S16            availBw; 
26229    uint32_t       availBits = 0;
26230 #ifdef LTE_ADV
26231    uint32_t       boTmp = bo;
26232 #endif
26233
26234
26235    reqBytes  = bo;
26236    cellDl    = RG_SCH_CMN_GET_DL_CELL(cell);
26237    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26238    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26239    oldReq    = ueDl->outStndAlloc;
26240
26241    
26242    if (ueDl->maxTbBits > ue->dl.aggTbBits)
26243    {
26244       availBits = ueDl->maxTbBits - ue->dl.aggTbBits;
26245    }
26246    /* check if we can further allocate to this UE */
26247    if ((ue->dl.aggTbBits >= ueDl->maxTbBits) ||
26248          (allocInfo->tbInfo[0].bytesReq >= ueDl->maxTbSz/8) ||
26249          (allocInfo->tbInfo[1].bytesReq >= ueDl->maxTbSz/8) ||
26250          (allocInfo->rbsReq >= ueDl->maxRb))
26251    {
26252       DU_LOG("\nDEBUG  -->  SCH : rgSCHCmnDlAllocRb(): UEs max allocation exceed");
26253       return RFAILED;
26254    }
26255
26256    noLyr1 = ueDl->mimoInfo.cwInfo[0].noLyr;
26257    noLyr2 = ueDl->mimoInfo.cwInfo[1].noLyr;
26258
26259    /* If there is no CFI change, continue to use the BLER based
26260     * iTBS value */
26261    if (ueDl->lastCfi == cfi)
26262    {   
26263       iTbs1  = ueDl->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
26264       iTbs2  = ueDl->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
26265    }
26266    else
26267    {  
26268       uint8_t cqi = ueDl->mimoInfo.cwInfo[0].cqi;
26269 #ifdef LTE_TDD      
26270       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 0, noLyr1);
26271 #else      
26272       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 0, noLyr1);
26273 #endif         
26274
26275       cqi = ueDl->mimoInfo.cwInfo[1].cqi;
26276 #ifdef LTE_TDD      
26277       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 1, noLyr2);
26278 #else      
26279       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 1, noLyr2);
26280 #endif         
26281    } 
26282
26283    /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure
26284     * issue for VoLTE call */
26285    //if ((proc->hasDcch)  || (TRUE == rgSCHLaaSCellEnabled(cell)))
26286    if (proc->hasDcch)
26287    {
26288       if (iTbs1 > 5)
26289       {
26290          iTbs1  = iTbs1 - 5;
26291       }
26292       else
26293       {
26294          iTbs1  = 0; 
26295       }
26296       if (iTbs2 > 5)
26297       {
26298          iTbs2  = iTbs2 - 5;
26299       }
26300       else
26301       {
26302          iTbs2  = 0; 
26303       }
26304    }
26305    else if(!cellSch->dl.isDlFreqSel)
26306    {
26307 #ifdef LTE_TDD
26308       /* for Tdd reduce iTbs only for SF0. SF5 contains only 
26309        * SSS and can be ignored */
26310       if (subFrm->sfNum == 0)
26311       {
26312          (iTbs1 > 1)? (iTbs1 -= 1) : (iTbs1 = 0);
26313          (iTbs2 > 1)? (iTbs2 -= 1) : (iTbs2 = 0);
26314       }
26315       /* For SF 3 and 8 CRC is getting failed in DL.
26316          Need to do proper fix after the replay from 
26317          BRCM PHY team*/
26318 #ifdef CA_PHY_BRDCM_61765      
26319       if ((subFrm->sfNum == 3) || (subFrm->sfNum == 8))
26320       {
26321          (iTbs1 > 2)? (iTbs1 -= 2) : (iTbs1 = 0);
26322          (iTbs2 > 2)? (iTbs2 -= 2) : (iTbs2 = 0);
26323       }
26324 #endif
26325 #else
26326 #endif
26327    }
26328
26329 #ifdef LTE_TDD
26330    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
26331    {
26332       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
26333    }
26334 #endif 
26335
26336    eff1 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
26337    eff2 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
26338
26339
26340    bo = RGSCH_MIN(bo,availBits/8);
26341    ueDl->outStndAlloc += bo;
26342    /* consider Cumulative amount of this BO and bytes so far allocated */
26343    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbBits/8);
26344    bo = RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff1)/(eff1+eff2)), 
26345                   ueDl->maxTbSz/8) +
26346         RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff2)/(eff1+eff2)), 
26347                   (ueDl->maxTbSz)/8) +
26348         1; /* Add 1 to adjust the truncation at weighted averaging */
26349    /* Get the number of REs needed for this bo. */
26350    noRes = ((bo * 8 * 1024) / (eff1 + eff2));
26351
26352    /* Get the number of RBs needed for this transmission */
26353    /* Number of RBs = No of REs / No of REs per RB       */
26354    numRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
26355    /* Cannot exceed the maximum number of RBs per UE */
26356    if (numRb > ueDl->maxRb)
26357    {
26358       numRb = ueDl->maxRb;
26359    }
26360    else
26361    {
26362 #ifdef LTE_ADV
26363       if(RFAILED == rgSCHLaaCmn2CwAdjustPrb(allocInfo,  boTmp, &numRb, ueDl, noLyr1, noLyr2, iTbs1, iTbs2))
26364 #endif
26365       {
26366          while ((numRb <= ueDl->maxRb) &&
26367                (rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1] <= ueDl->maxTbSz) &&
26368                (rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1] <= ueDl->maxTbSz) &&
26369                ((rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8 +
26370                  rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8) <= bo))
26371          {
26372             (numRb)++;
26373          }
26374       }
26375    }
26376    availBw = subFrm->bw - subFrm->bwAssigned;
26377    /* Cannot exceed the total number of RBs in the cell */
26378    if ((S16)(numRb - allocInfo->rbsReq) > availBw)
26379    {
26380       numRb = availBw + allocInfo->rbsReq;
26381    }
26382    tb1Sz = rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8;
26383    tb2Sz = rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8;
26384    /* DwPts Scheduling Changes Start */
26385 #ifdef LTE_TDD
26386    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
26387    { 
26388       /* Max Rb for Special Sf is approximated as 4/3 of maxRb */
26389       rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, (uint8_t*)&numRb,  ueDl->maxRb*4/3, 
26390                                 &iTbs1, &iTbs2, noLyr1, 
26391                                 noLyr2, &tb1Sz, &tb2Sz, cfi);   
26392       /* Check for available Bw */
26393       if ((S16)numRb - allocInfo->rbsReq > availBw)
26394       {
26395          numRb = availBw + allocInfo->rbsReq;
26396          tb1Sz = rgTbSzTbl[noLyr1-1][iTbs1][RGSCH_MAX(numRb*3/4,1)-1]/8;
26397          tb2Sz = rgTbSzTbl[noLyr2-1][iTbs2][RGSCH_MAX(numRb*3/4,1)-1]/8;
26398       }
26399    }
26400 #endif
26401    /* DwPts Scheduling Changes End */
26402    /* Update the subframe Allocated BW field */
26403    subFrm->bwAssigned = subFrm->bwAssigned + numRb - \
26404                         allocInfo->rbsReq;
26405
26406    *effBo = RGSCH_MIN((tb1Sz + tb2Sz) - oldReq, reqBytes);
26407
26408 #ifdef LTE_ADV
26409    if (ROK != rgSCHLaaCmn2TBPrbCheck(allocInfo, tb1Sz, tb2Sz, boTmp, effBo, iTbs1, iTbs2, numRb, proc))
26410    {
26411       return RFAILED;
26412    }
26413 #endif
26414
26415    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs1, imcs1);
26416    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs2, imcs2);
26417    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tb1Sz, \
26418          iTbs1, imcs1, &proc->tbInfo[0], noLyr1);
26419    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
26420          iTbs2, imcs2, &proc->tbInfo[1], noLyr2);
26421    *numRbRef = (uint8_t)numRb;
26422
26423
26424    return ROK;
26425 }
26426
26427 \f
26428 /**
26429  * @brief This function determines the RBs and Bytes required for
26430  *        Transmission & Retransmission on 2 CWs.
26431  *
26432  * @details
26433  *
26434  *     Function: rgSCHCmnDlAlloc2CwTxRetxRb
26435  *     Purpose:  This function determines the RBs and Bytes required
26436  *               for Transmission & Retransmission on 2 CWs. Allocate
26437  *               RETX TB on a better CW and restrict new TX TB by
26438  *               RETX allocation.
26439  *               Returns RFAILED if BO not satisfied at all.
26440  *
26441  *     Invoked by: TM3 and TM4 DL UE Allocation
26442  *
26443  *  @param[in]  RgSchCellCb      *cell
26444  *  @param[in]  RgSchDlSf        *subFrm
26445  *  @param[in]  RgSchUeCb        *ue
26446  *  @param[in]  RgSchDlHqTbCb    *reTxTb
26447  *  @param[in]  RgSchDlHqTbCb    *txTb
26448  *  @param[out] uint8_t               *numRb
26449  *  @param[out] uint32_t              *effBo
26450  *  @return  Void
26451  *
26452  **/
26453 static S16 rgSCHCmnDlAlloc2CwTxRetxRb
26454 (
26455 RgSchCellCb     *cell,
26456 RgSchDlSf       *subFrm,
26457 RgSchUeCb       *ue,
26458 RgSchDlHqTbCb   *reTxTb,
26459 RgSchDlHqTbCb   *txTb,
26460 uint8_t         *numRb,
26461 uint32_t                        *effBo
26462 )
26463 {
26464    RgSchCmnDlUe       *ueDl;
26465    RgSchDlRbAlloc     *allocInfo;
26466    uint8_t            imcs1, imcs2;
26467    uint8_t            noLyr2;
26468    uint16_t           tb2Sz;
26469    RgSchCmnDlUeCwInfo *otherCw;
26470    S16                 availBw;
26471    RgSchCmnDlCell     *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
26472    uint8_t            cfi = cellDl->currCfi; 
26473    uint8_t            iTbs;
26474
26475
26476    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26477    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26478    otherCw   = &ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)];
26479
26480
26481    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26482     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26483     * MCS.  */
26484    availBw = subFrm->bw - subFrm->bwAssigned; 
26485    *numRb = reTxTb->dlGrnt.numRb;
26486
26487 #ifdef XEON_TDD_SPCL
26488    *numRb = (reTxTb->initTxNumRbs);
26489    if(reTxTb->sfType == RG_SCH_SPL_SF_DATA && subFrm->sfType != RG_SCH_SPL_SF_DATA)
26490    {
26491       *numRb = (reTxTb->initTxNumRbs*3/4);
26492
26493       if(*numRb <= 3)
26494       {
26495          DU_LOG("\nERROR  -->  SCH : Number of RBs [%d] are less than or equal to 3",*numRb);
26496          return RFAILED;
26497       }
26498    }
26499 #endif
26500
26501    if ((S16)*numRb > availBw)
26502    {
26503       return RFAILED;
26504    }
26505    /* Update the subframe Allocated BW field */
26506    subFrm->bwAssigned += *numRb;
26507    noLyr2 = otherCw->noLyr;
26508    RG_SCH_CMN_GET_MCS_FOR_RETX(reTxTb, imcs1);
26509
26510    /* If there is no CFI change, continue to use the BLER based
26511     * iTBS value */
26512    if (ueDl->lastCfi == cfi)
26513    {   
26514       iTbs = otherCw->iTbs[noLyr2-1];
26515    }
26516    else
26517    {  
26518 #ifdef LTE_TDD      
26519       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, otherCw->cqi, cfi, 
26520                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
26521 #else      
26522       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, otherCw->cqi, cfi, 
26523                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
26524 #endif 
26525    } 
26526    tb2Sz = rgTbSzTbl[noLyr2-1][iTbs][*numRb-1]/8;
26527    /* DwPts Scheduling Changes Start */
26528 #ifdef LTE_TDD
26529 #endif
26530    /* DwPts Scheduling Changes End */
26531    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs2);
26532    
26533    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], reTxTb->tbSz, \
26534                               0, imcs1, reTxTb, reTxTb->numLyrs);
26535    
26536    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
26537                               iTbs, imcs2, txTb, noLyr2);
26538    
26539    *effBo = reTxTb->tbSz + tb2Sz;
26540
26541    return ROK;
26542 }
26543
26544 \f
26545 /**
26546  * @brief This function determines the RBs and Bytes required for BO
26547  *        Retransmission on 2 CWs.
26548  *
26549  * @details
26550  *
26551  *     Function: rgSCHCmnDlAlloc2CwRetxRb
26552  *     Purpose:  This function determines the RBs and Bytes required
26553  *               for BO Retransmission on 2 CWs. Allocate larger TB
26554  *               on a better CW and check if the smaller TB can be
26555  *               accomodated on the other CW.
26556  *               Returns RFAILED if BO not satisfied at all.
26557  *
26558  *     Invoked by: Common Scheduler
26559  *
26560  *  @param[in]  RgSchCellCb      *cell
26561  *  @param[in]  RgSchDlSf        *subFrm
26562  *  @param[in]  RgSchUeCb        *ue
26563  *  @param[in]  RgSchDlHqProcCb  *proc
26564  *  @param[out] uint8_t               *numRb
26565  *  @param[out] Bool             *swpFlg
26566  *  @param[out] uint32_t              *effBo
26567  *  @return  Void
26568  *
26569  **/
26570 static S16 rgSCHCmnDlAlloc2CwRetxRb
26571 (
26572 RgSchCellCb      *cell,
26573 RgSchDlSf        *subFrm,
26574 RgSchUeCb        *ue,
26575 RgSchDlHqProcCb  *proc,
26576 uint8_t          *numRb,
26577 Bool             *swpFlg,
26578 uint32_t         *effBo
26579 )
26580 {
26581    RgSchDlRbAlloc  *allocInfo;
26582    uint8_t         imcs1;
26583    uint8_t         imcs2;
26584    RgSchDlHqTbCb   *lrgTbInfo, *othrTbInfo;
26585
26586
26587    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26588
26589
26590    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26591     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26592     * MCS.  */
26593    lrgTbInfo  = &proc->tbInfo[0];
26594    othrTbInfo = &proc->tbInfo[1];
26595    *numRb = lrgTbInfo->dlGrnt.numRb;
26596 #ifdef XEON_TDD_SPCL
26597    if((lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA || othrTbInfo->sfType == RG_SCH_SPL_SF_DATA))
26598    {
26599       if(lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA)
26600       {       
26601           *numRb = (lrgTbInfo->initTxNumRbs);
26602       }
26603       else
26604       {
26605           *numRb = (othrTbInfo->initTxNumRbs);
26606       }
26607
26608       if(subFrm->sfType != RG_SCH_SPL_SF_DATA)
26609       {
26610          *numRb = (*numRb)*3/4;
26611       }
26612        
26613       if(*numRb <= 3)
26614       {
26615          DU_LOG("\nERROR  -->  SCH :  Number of RBs [%d] are less than or equal to 3",*numRb);
26616          return RFAILED;
26617       }
26618    }
26619 #endif
26620    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
26621    {
26622       return RFAILED;
26623    }
26624    /* Update the subframe Allocated BW field */
26625    subFrm->bwAssigned += *numRb;
26626    RG_SCH_CMN_GET_MCS_FOR_RETX(lrgTbInfo, imcs1);
26627    RG_SCH_CMN_GET_MCS_FOR_RETX(othrTbInfo, imcs2);
26628    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], lrgTbInfo->tbSz, \
26629          0, imcs1, lrgTbInfo, lrgTbInfo->numLyrs);
26630    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], othrTbInfo->tbSz, \
26631          0, imcs2, othrTbInfo, othrTbInfo->numLyrs);
26632    *effBo = lrgTbInfo->tbSz + othrTbInfo->tbSz;
26633
26634
26635
26636    return ROK;
26637 }
26638
26639 \f
26640 /**
26641  * @brief This function determines the RBs and Bytes required for BO
26642  *        Retransmission on 1 CW.
26643  *
26644  * @details
26645  *
26646  *     Function: rgSCHCmnDlAlloc1CwRetxRb
26647  *     Purpose:  This function determines the RBs and Bytes required
26648  *               for BO Retransmission on 1 CW, the first CW.
26649  *               Returns RFAILED if BO not satisfied at all.
26650  *
26651  *     Invoked by: Common Scheduler
26652  *
26653  *  @param[in]  RgSchCellCb      *cell
26654  *  @param[in]  RgSchDlSf        *subFrm
26655  *  @param[in]  RgSchUeCb        *ue
26656  *  @param[in]  RgSchDlHqTbCb    *tbInfo
26657  *  @param[in]  uint8_t               noLyr
26658  *  @param[out] uint8_t               *numRb
26659  *  @param[out] uint32_t              *effBo
26660  *  @return  S16
26661  *
26662  **/
26663 static S16 rgSCHCmnDlAlloc1CwRetxRb
26664 (
26665 RgSchCellCb    *cell,
26666 RgSchDlSf      *subFrm,
26667 RgSchUeCb      *ue,
26668 RgSchDlHqTbCb  *tbInfo,
26669 uint8_t        noLyr,
26670 uint8_t        *numRb,
26671 uint32_t       *effBo
26672 )
26673 {
26674    RgSchDlRbAlloc  *allocInfo;
26675    uint8_t              imcs;
26676
26677
26678    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26679
26680
26681    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26682     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26683     * MCS.  */
26684    *numRb = tbInfo->dlGrnt.numRb;
26685    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
26686    {
26687       return RFAILED;
26688    }
26689    /* Update the subframe Allocated BW field */
26690    subFrm->bwAssigned += *numRb;
26691    imcs = tbInfo->dlGrnt.iMcs;
26692    allocInfo->dciFormat = tbInfo->dlGrnt.dciFormat; 
26693    /* Fix: For a RETX TB the iTbs is irrelevant, hence setting 0 */
26694    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbInfo->tbSz, \
26695          0, imcs, tbInfo, tbInfo->numLyrs);
26696    *effBo = tbInfo->tbSz;
26697
26698    return ROK;
26699 }
26700
26701 #ifdef LTEMAC_SPS
26702
26703 /**
26704  * @brief This function is called to handle Release PDCCH feedback for SPS UE
26705  *
26706  * @details
26707  *
26708  *     Function: rgSCHCmnDlRelPdcchFbk
26709  *     Purpose:  Invokes SPS module to handle release PDCCH feedback
26710  *
26711  *     Invoked by: DHM
26712  *
26713  *  @param[in]   RgSchCellCb     *cell
26714  *  @param[in]   RgSchUeCb       *ue
26715  *  @param[in]   Bool            isAck
26716  *  @return  Void
26717  *
26718  **/
26719 Void rgSCHCmnDlRelPdcchFbk
26720 (
26721 RgSchCellCb        *cell,
26722 RgSchUeCb          *ue,
26723 Bool               isAck
26724 )
26725 {
26726
26727    rgSCHCmnSpsDlRelPdcchFbk(cell, ue, isAck);
26728    return;
26729
26730 }
26731
26732
26733 /**
26734  * @brief This function is invoked to handle Ack processing for a HARQ proc.
26735  *
26736  * @details
26737  *
26738  *     Function: rgSCHCmnDlProcAck
26739  *     Purpose:  DTX processing for HARQ proc
26740  *
26741  *     Invoked by: DHM
26742  *
26743  *  @param[in]   RgSchCellCb     *cell
26744  *  @param[in]   RgSchDlHqProcCb *hqP
26745  *  @return  Void
26746  *
26747  **/
26748 Void rgSCHCmnDlProcAck
26749 (
26750 RgSchCellCb        *cell,
26751 RgSchDlHqProcCb    *hqP
26752 )
26753 {
26754
26755
26756    if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
26757    {
26758       /* Invoke SPS module if SPS service was scheduled for this HARQ proc */
26759       rgSCHCmnSpsDlProcAck(cell, hqP);
26760    }
26761    return;
26762 }
26763 #ifdef RGSCH_SPS_STATS
26764 uint32_t rgSchStatCrntiCeRcvCnt;
26765 #endif
26766 /**
26767  * @brief This function is invoked to handle CRNTI CE reception for an UE
26768  *
26769  * @details
26770  *
26771  *     Function: rgSCHCmnHdlCrntiCE
26772  *     Purpose:  Handle CRNTI CE reception
26773  *
26774  *     Invoked by: DHM
26775  *
26776  *  @param[in]   RgSchCellCb     *cell
26777  *  @param[in]   RgSchDlHqProcCb *hqP
26778  *  @return  Void
26779  *
26780  **/
26781 Void rgSCHCmnHdlCrntiCE
26782 (
26783 RgSchCellCb        *cell,
26784 RgSchUeCb          *ue
26785 )
26786 {
26787
26788 #ifdef RGSCH_SPS_STATS   
26789    rgSchStatCrntiCeRcvCnt++;
26790 #endif
26791
26792    /* When UL sync lost happened due to TA timer expiry UE is being moved to 
26793       PDCCH order inactivity list.But when CRNTI CE received in msg3 from UE
26794       we are not moving UE into active state due to that RRC Reconfiguration is
26795       not happening.
26796       So here we are moving UE to active list whenever we receive the CRNTI CE and
26797       UE is inactive */
26798    /* CR ccpu00144525 */      
26799    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
26800    {
26801        /* Activate this UE if it was inactive */
26802        RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
26803        RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
26804    }
26805
26806    /* Handling is same as reception of UE RESET for both DL and UL */
26807    if (ue->dl.dlSpsCfg.isDlSpsEnabled)
26808    {
26809       rgSCHCmnSpsDlUeReset(cell, ue);
26810    }
26811    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26812    {
26813       rgSCHCmnSpsUlUeReset(cell, ue);
26814    }
26815    
26816    return;
26817 }
26818
26819
26820 /**
26821  * @brief This function is called to handle relInd from MAC for a UE
26822  *
26823  * @details
26824  *
26825  *     Function: rgSCHCmnUlSpsRelInd
26826  *     Purpose:  Invokes SPS module to handle UL SPS release for a UE
26827  *
26828  *     Invoked by: SCH_UTL
26829  *
26830  *  @param[in]   RgSchCellCb        *cell
26831  *  @param[in]   RgSchUeCb          *ue
26832  *  @param[in]   Bool               isExplRel
26833  *  @return  Void
26834  *
26835  **/
26836 Void rgSCHCmnUlSpsRelInd
26837 (
26838 RgSchCellCb        *cell,
26839 RgSchUeCb          *ue,
26840 Bool               isExplRel
26841 )
26842 {
26843
26844    rgSCHCmnSpsUlProcRelInd(cell, ue, isExplRel);
26845    return;
26846
26847 } /* end of rgSCHCmnUlSpsRelInd */
26848
26849 /**
26850  * @brief This function is called to handle SPS Activate Ind from MAC for a UE
26851  *
26852  * @details
26853  *
26854  *     Function: rgSCHCmnUlSpsActInd
26855  *     Purpose:  Invokes SPS module to handle UL SPS activate for a UE
26856  *
26857  *     Invoked by: SCH_UTL
26858  *
26859  *  @param[in]   RgSchCellCb        *cell
26860  *  @param[in]   RgSchUeCb          *ue
26861  *  @return  Void
26862  *
26863  **/
26864 Void rgSCHCmnUlSpsActInd
26865 (
26866 RgSchCellCb     *cell,
26867 RgSchUeCb       *ue,
26868 uint16_t        spsSduSize
26869 )
26870 {
26871
26872
26873    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26874    {
26875       rgSCHCmnSpsUlProcActInd(cell, ue,spsSduSize);
26876    }
26877    return;
26878
26879 } /* end of rgSCHCmnUlSpsActInd */
26880
26881 /**
26882  * @brief This function is called to handle CRC in UL for UEs
26883  * undergoing SPS release
26884  *
26885  * @details
26886  *
26887  *     Function: rgSCHCmnUlCrcInd
26888  *     Purpose:  Invokes SPS module to handle CRC in UL for SPS UE
26889  *
26890  *     Invoked by: SCH_UTL
26891  *
26892  *  @param[in]   RgSchCellCb        *cell
26893  *  @param[in]   RgSchUeCb          *ue
26894  *  @param[in]   CmLteTimingInfo    crcTime
26895  *  @return  Void
26896  *
26897  **/
26898 Void rgSCHCmnUlCrcInd
26899 (
26900 RgSchCellCb        *cell,
26901 RgSchUeCb          *ue,
26902 CmLteTimingInfo    crcTime
26903 )
26904 {
26905
26906    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26907    {
26908       rgSCHCmnSpsUlProcCrcInd(cell, ue, crcTime);
26909    }
26910    return;
26911
26912 } /* end of rgSCHCmnUlCrcFailInd */
26913
26914 /**
26915  * @brief This function is called to handle CRC failure in UL
26916  *
26917  * @details
26918  *
26919  *     Function: rgSCHCmnUlCrcFailInd
26920  *     Purpose:  Invokes SPS module to handle CRC failure in UL for SPS UE
26921  *
26922  *     Invoked by: SCH_UTL
26923  *
26924  *  @param[in]   RgSchCellCb        *cell
26925  *  @param[in]   RgSchUeCb          *ue
26926  *  @param[in]   CmLteTimingInfo    crcTime
26927  *  @return  Void
26928  *
26929  **/
26930 Void rgSCHCmnUlCrcFailInd
26931 (
26932 RgSchCellCb        *cell,
26933 RgSchUeCb          *ue,
26934 CmLteTimingInfo    crcTime
26935 )
26936 {
26937
26938    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26939    {
26940       rgSCHCmnSpsUlProcDtxInd(cell, ue, crcTime);
26941    }
26942    return;
26943
26944 } /* end of rgSCHCmnUlCrcFailInd */
26945
26946 #endif /* LTEMAC_SPS */
26947
26948 /**
26949  * @brief BCH,BCCH,PCCH Dowlink Scheduling Handler.
26950  *
26951  * @details
26952  *
26953  *     Function: rgSCHCmnDlBcchPcchAlloc
26954  *     Purpose:  This function calls common scheduler APIs to
26955  *     schedule for BCCH/PCCH.
26956  *     It then invokes Allocator for actual RB
26957  *     allocations. It processes on the actual resources allocated
26958  *     against requested to the allocator module.
26959  *
26960  *     Invoked by: Common Scheduler
26961  *
26962  *  @param[in]  RgSchCellCb *cell
26963  *  @return  Void
26964  **/
26965 static Void rgSCHCmnDlBcchPcchAlloc(RgSchCellCb  *cell)
26966 {
26967 #ifdef LTE_TDD
26968    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
26969 #else
26970 #ifdef LTEMAC_HDFDD
26971    uint8_t           nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
26972 #else
26973    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
26974 #endif
26975 #endif
26976    RgInfSfAlloc *nextsfAlloc = &(cell->sfAllocArr[nextSfIdx]);
26977    RgSchCmnCell           *cellSch   = RG_SCH_CMN_GET_CELL(cell);
26978    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo;  
26979    
26980
26981
26982    /*Reset the bitmask for BCCH/PCCH*/
26983    rgSCHUtlResetSfAlloc(nextsfAlloc,TRUE,FALSE);
26984 #ifndef DISABLE_MIB_SIB /* Not sending MIB and SIB to CL */
26985 #ifdef RGR_SI_SCH
26986    rgSCHChkNUpdSiCfg(cell);
26987    rgSCHSelectSi(cell);
26988 #endif
26989
26990    /*Perform the scheduling for BCCH,PCCH*/
26991    rgSCHCmnDlBcchPcch(cell, allocInfo, nextsfAlloc);
26992
26993    /* Call common allocator for RB Allocation */
26994    rgSCHBcchPcchDlRbAlloc(cell, allocInfo);
26995
26996    /* Finalize the Allocations for reqested Against alloced */
26997    rgSCHCmnDlBcchPcchFnlz(cell, allocInfo);
26998 #endif /* DISABLE_MIB_SIB */
26999    return;
27000 }
27001
27002 /**
27003  * @brief Handles RB allocation for BCCH/PCCH for downlink.
27004  *
27005  * @details
27006  *
27007  *     Function : rgSCHBcchPcchDlRbAlloc
27008  *
27009  *     Invoking Module Processing:
27010  *     - This function is invoked for DL RB allocation of BCCH/PCCH
27011  *
27012  *     Processing Steps:
27013  *     - If cell is frequency selecive,
27014  *       - Call rgSCHDlfsBcchPcchAllocRb().
27015  *     - else,
27016  *       - Do the processing
27017  *
27018  *  @param[in]  RgSchCellCb        *cell
27019  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
27020  *  @return  Void
27021  **/
27022
27023 static Void rgSCHBcchPcchDlRbAlloc
27024 (
27025 RgSchCellCb           *cell,
27026 RgSchCmnDlRbAllocInfo *allocInfo
27027 )
27028 {
27029    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
27030
27031
27032
27033    if (cellSch->dl.isDlFreqSel)
27034    {
27035       cellSch->apisDlfs->rgSCHDlfsBcchPcchAllocRb(cell, allocInfo);
27036    }
27037    else
27038    {
27039       rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo);
27040    }
27041
27042    return;
27043 }
27044
27045 /**
27046  * @brief Handles RB allocation for BCCH,PCCH for frequency
27047  *  non-selective cell.
27048  *
27049  * @details
27050  *
27051  *     Function : rgSCHCmnNonDlfsBcchPcchRbAlloc
27052  *
27053  *     Invoking Module Processing:
27054  *      - SCH shall invoke this if downlink frequency selective is disabled for
27055  *        the cell for RB allocation.
27056  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
27057  *        estimate and subframe for each allocation to be made to SCH.
27058  *
27059  *     Processing Steps:
27060  *     - Allocate sequentially for BCCH,PCCH common channels.
27061  *
27062  *  @param[in]  RgSchCellCb        *cell
27063  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
27064  *  @return  Void
27065  **/
27066
27067 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc
27068 (
27069 RgSchCellCb           *cell,
27070 RgSchCmnDlRbAllocInfo *allocInfo
27071 )
27072 {
27073    RgSchDlRbAlloc     *reqAllocInfo;
27074
27075
27076    /* 143473 */
27077    /* Allocate for PCCH */
27078    reqAllocInfo = &(allocInfo->pcchAlloc);
27079    if (reqAllocInfo->rbsReq)
27080    {
27081       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
27082    }
27083    /* Allocate for BCCH on DLSCH */
27084    reqAllocInfo = &(allocInfo->bcchAlloc);
27085    if (reqAllocInfo->rbsReq)
27086    {
27087       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
27088    }
27089    return;
27090 }
27091
27092
27093 #ifdef RGR_SI_SCH
27094 /**
27095  * @brief This function implements the handling to check and
27096  *        update the SI cfg at the start of the modificiation period.
27097  *
27098  * @details
27099  *
27100  *     Function: rgSCHChkNUpdSiCfg
27101  *     Purpose:  This function implements handling for update of SI Cfg
27102  *               at the start of modification period.
27103  *
27104  *     Invoked by: Scheduler
27105  *
27106  *  @param[in]  RgSchCellCb*     cell
27107  *  @return  S16
27108  *      -# ROK
27109  *      -# RFAILED
27110  **/
27111 static Void rgSCHChkNUpdSiCfg
27112 (
27113 RgSchCellCb             *cell
27114 )
27115 {
27116    CmLteTimingInfo   pdSchTmInfo;
27117
27118
27119
27120    pdSchTmInfo   = cell->crntTime;
27121 #ifdef LTEMAC_HDFDD
27122    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27123       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27124    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27125 #else
27126    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA);
27127 #endif
27128
27129
27130    /* Updating the SIB1 for Warning SI message immediately after it is received 
27131     * from application. No need to wait for next modification period.
27132     */
27133    if((pdSchTmInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
27134          && (RGSCH_SIB1_TX_SF_NUM == (pdSchTmInfo.slot % RGSCH_NUM_SUB_FRAMES)))
27135    {   
27136       /*Check whether SIB1 with PWS has been updated*/
27137       if(cell->siCb.siBitMask & RGSCH_SI_SIB1_PWS_UPD)
27138       {
27139          RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
27140                cell->siCb.newSiInfo.sib1Info.sib1);
27141          cell->siCb.crntSiInfo.sib1Info.mcs = 
27142             cell->siCb.newSiInfo.sib1Info.mcs;
27143          cell->siCb.crntSiInfo.sib1Info.nPrb = 
27144              cell->siCb.newSiInfo.sib1Info.nPrb;
27145          cell->siCb.crntSiInfo.sib1Info.msgLen = 
27146             cell->siCb.newSiInfo.sib1Info.msgLen;
27147          cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_PWS_UPD;
27148       }
27149    }
27150
27151    /*Check if this SFN and SF No marks the start of next modification
27152      period. If current SFN,SF No doesn't marks the start of next
27153      modification period, then return. */
27154    if(!((pdSchTmInfo.sfn % cell->siCfg.modPrd == 0)
27155             && (0 == pdSchTmInfo.slot)))
27156    /*if(!((((pdSchTmInfo.hSfn * 1024) + pdSchTmInfo.sfn) % cell->siCfg.modPrd == 0)
27157             && (0 == pdSchTmInfo.slot)))*/
27158    {
27159       return;
27160    }
27161
27162    /*Check whether MIB has been updated*/
27163    if(cell->siCb.siBitMask & RGSCH_SI_MIB_UPD)
27164    {
27165       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.mib,
27166             cell->siCb.newSiInfo.mib);
27167       cell->siCb.siBitMask &= ~RGSCH_SI_MIB_UPD;
27168    }
27169
27170    /*Check whether SIB1 has been updated*/
27171    if(cell->siCb.siBitMask & RGSCH_SI_SIB1_UPD)
27172    {
27173       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
27174             cell->siCb.newSiInfo.sib1Info.sib1);
27175       cell->siCb.crntSiInfo.sib1Info.mcs = cell->siCb.newSiInfo.sib1Info.mcs;
27176       cell->siCb.crntSiInfo.sib1Info.nPrb = cell->siCb.newSiInfo.sib1Info.nPrb;
27177       cell->siCb.crntSiInfo.sib1Info.msgLen = 
27178          cell->siCb.newSiInfo.sib1Info.msgLen;
27179       cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_UPD;
27180    }
27181
27182    /*Check whether SIs have been updated*/
27183    if(cell->siCb.siBitMask & RGSCH_SI_SI_UPD)
27184    {
27185       uint8_t  idx;
27186
27187       /*Check if SI cfg have been modified And Check if numSi have
27188         been changed, if yes then we would need to update the
27189         pointers for all the SIs */
27190       if((cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) &&
27191             (cell->siCfg.numSi != cell->siCb.newSiCfg.numSi))
27192       {
27193          for(idx = 0;idx < cell->siCb.newSiCfg.numSi;idx++)
27194          {
27195             RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
27196                   cell->siCb.newSiInfo.siInfo[idx].si);
27197             cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
27198             cell->siCb.siArray[idx].isWarningSi = FALSE;
27199
27200             cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
27201             cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
27202             cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
27203          }
27204
27205          /*If numSi have been reduced then we need to free the
27206            pointers at the indexes in crntSiInfo which haven't
27207            been exercised. If numSi has increased then nothing
27208            additional is requires as above handling has taken
27209            care.*/
27210          if(cell->siCfg.numSi > cell->siCb.newSiCfg.numSi)
27211          {
27212             for(idx = cell->siCb.newSiCfg.numSi;
27213                   idx < cell->siCfg.numSi;idx++)
27214             {
27215                RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si);
27216                cell->siCb.siArray[idx].si = NULLP;
27217             }
27218          }
27219       }
27220       else
27221       {
27222          /*numSi has not been updated, we just need to update the
27223            pointers for the SIs which are set to NON NULLP */
27224          /*ccpu00118260 - Correct Update of SIB2 */
27225          for(idx = 0;idx < cell->siCfg.numSi;idx++)
27226          {
27227             if(NULLP != cell->siCb.newSiInfo.siInfo[idx].si)
27228             {
27229                RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
27230                      cell->siCb.newSiInfo.siInfo[idx].si);
27231
27232                cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
27233                cell->siCb.siArray[idx].isWarningSi = FALSE;
27234                cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
27235                cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
27236                cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
27237             }
27238          }
27239       }
27240       cell->siCb.siBitMask &= ~RGSCH_SI_SI_UPD;
27241    }
27242
27243    /*Check whether SI cfg have been updated*/
27244    if(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD)
27245    {
27246       cell->siCfg = cell->siCb.newSiCfg;
27247       cell->siCb.siBitMask &= ~RGSCH_SI_SICFG_UPD;
27248    }
27249
27250    return;
27251 }
27252
27253
27254 /**
27255  * @brief This function implements the selection of the SI
27256  *        that is to be scheduled.
27257  *
27258  * @details
27259  *
27260  *     Function: rgSCHSelectSi
27261  *     Purpose:  This function implements the selection of SI
27262  *               that is to be scheduled.
27263  *
27264  *     Invoked by: Scheduler
27265  *
27266  *  @param[in]  RgSchCellCb*     cell
27267  *  @return  S16
27268  *      -# ROK
27269  *      -# RFAILED
27270  **/
27271 static Void rgSCHSelectSi
27272 (
27273 RgSchCellCb             *cell
27274 )
27275 {
27276    CmLteTimingInfo crntTmInfo;
27277    uint8_t         siWinSize;
27278    uint16_t        x; 
27279    uint16_t        windowId; 
27280
27281
27282
27283    crntTmInfo  = cell->crntTime;
27284 #ifdef LTEMAC_HDFDD
27285    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27286       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27287    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27288 #else
27289    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA);
27290 #endif
27291
27292    siWinSize    = cell->siCfg.siWinSize;
27293
27294    /* Select SI only once at the starting of the new window */
27295    if(cell->siCb.inWindow)
27296    {
27297       if ((crntTmInfo.sfn % cell->siCfg.minPeriodicity) == 0 && 
27298           crntTmInfo.slot == 0)
27299       {
27300          /* Reinit inWindow at the beginning of every SI window */
27301          cell->siCb.inWindow = siWinSize - 1;
27302       }
27303       else
27304       {
27305          cell->siCb.inWindow--;
27306          return;
27307       }
27308    }
27309    else /* New window. Re-init the winSize counter with the window length */
27310    {
27311       if((cell->siCb.siArray[cell->siCb.siCtx.siId - 1].isWarningSi == TRUE)&&
27312             (cell->siCb.siCtx.retxCntRem != 0))   
27313       {
27314          rgSCHUtlFreeWarningSiPdu(cell);
27315          cell->siCb.siCtx.warningSiFlag  = FALSE;
27316       }
27317
27318       cell->siCb.inWindow = siWinSize - 1;
27319    }
27320
27321    x = rgSCHCmnGetSiSetId(crntTmInfo.sfn, crntTmInfo.slot, 
27322                                   cell->siCfg.minPeriodicity); 
27323
27324    /* Window Id within a SI set. This window Id directly maps to a
27325     * unique SI Id */
27326    windowId = (((crntTmInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + 
27327             crntTmInfo.slot) - (x * (cell->siCfg.minPeriodicity * 10))) 
27328                                                                / siWinSize;
27329
27330    if(windowId >= RGR_MAX_NUM_SI)
27331       return;
27332
27333    /* Update the siCtx if there is a valid SI and its periodicity
27334     * has occurred */
27335    if (NULLP != cell->siCb.siArray[windowId].si)
27336    {
27337       /* Warning SI Periodicity is same as SIB2 Periodicity */
27338       if(((cell->siCb.siArray[windowId].isWarningSi == FALSE) && 
27339                (x % (cell->siCfg.siPeriodicity[windowId]
27340                      /cell->siCfg.minPeriodicity) == 0)) || 
27341             ((cell->siCb.siArray[windowId].isWarningSi == TRUE) &&
27342              (x % (cell->siCfg.siPeriodicity[0]
27343                    /cell->siCfg.minPeriodicity) == 0)))
27344       {
27345          cell->siCb.siCtx.siId = windowId+1;
27346          cell->siCb.siCtx.retxCntRem = cell->siCfg.retxCnt;
27347          cell->siCb.siCtx.warningSiFlag = cell->siCb.siArray[windowId].
27348                                                            isWarningSi;
27349          cell->siCb.siCtx.timeToTx.sfn = crntTmInfo.sfn;
27350          cell->siCb.siCtx.timeToTx.slot = crntTmInfo.slot;
27351
27352          RG_SCH_ADD_TO_CRNT_TIME(cell->siCb.siCtx.timeToTx,
27353                cell->siCb.siCtx.maxTimeToTx, (siWinSize - 1))
27354       }
27355    }
27356    else
27357    {/* Update the siCtx with invalid si Id */
27358       cell->siCb.siCtx.siId = 0;
27359    }
27360
27361    return;
27362 }
27363
27364
27365 /**
27366  * @brief This function implements scheduler DL allocation for
27367  *        SI.
27368  *
27369  * @details
27370  *
27371  *     Function: rgSCHDlSiSched
27372  *     Purpose:  This function implements scheduler for DL allocation
27373  *               for SI.
27374  *
27375  *     Invoked by: Scheduler
27376  *
27377  *  @param[in]  RgSchCellCb*     cell
27378  *  @return  S16
27379  *      -# ROK
27380  *      -# RFAILED
27381  **/
27382 static Void rgSCHDlSiSched
27383 (
27384 RgSchCellCb             *cell,
27385 RgSchCmnDlRbAllocInfo   *allocInfo,
27386 RgInfSfAlloc            *subfrmAlloc
27387 )
27388 {
27389    CmLteTimingInfo   crntTimInfo;
27390    RgSchDlSf         *sf;
27391    uint8_t           nPrb = 0;
27392    uint8_t           mcs  = 0;
27393    MsgLen            msgLen = 0;
27394    uint32_t          rb=0;
27395    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
27396    /* DwPTS Scheduling Changes Start */
27397 #ifdef LTE_TDD   
27398    uint16_t          lostRe;  
27399    uint8_t           cfi = cellDl->currCfi;      
27400 #endif
27401    /* DwPTS Scheduling Changes End */
27402
27403
27404
27405    crntTimInfo   = cell->crntTime;
27406 #ifdef LTEMAC_HDFDD
27407    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27408       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27409    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27410 #else
27411    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA);
27412 #endif
27413
27414    /* Compute the subframe for which allocation is being made.
27415       Essentially, we need pointer to the dl frame for this subframe */
27416    sf = rgSCHUtlSubFrmGet(cell, crntTimInfo);
27417
27418    /*Check if scheduling of MIB is required */
27419 #ifdef EMTC_ENABLE
27420    /* since we are adding the MIB repetition logic for EMTC UEs, checking if
27421     * emtcEnabled or not,  If enabled MIB would be repeted at as part of EMTC
27422     * feature, otherwise scheduling at (n,0) */
27423    if(0 == cell->emtcEnable)
27424    {
27425 #endif
27426    if((crntTimInfo.sfn % RGSCH_MIB_PERIODICITY == 0)
27427          && (RGSCH_MIB_TX_SF_NUM == crntTimInfo.slot))
27428    {
27429       MsgLen  mibLen = 0;
27430       uint8_t      sfnOctet, mibOct2 = 0;
27431       uint8_t      mibOct1 = 0;
27432       /*If MIB has not been yet setup by Application, return*/
27433       if(NULLP == cell->siCb.crntSiInfo.mib)
27434          return;
27435
27436       SFndLenMsg(cell->siCb.crntSiInfo.mib, &mibLen);
27437       sf->bch.tbSize = mibLen;
27438       /*Fill the interface information */
27439       rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, NULLD, NULLD);
27440
27441       /*Set the bits of MIB to reflect SFN */
27442       /*First get the Most signficant 8 bits of SFN */
27443       sfnOctet = (uint8_t)(crntTimInfo.sfn >> 2);
27444       /*Get the first two octets of MIB, and then update them
27445         using the SFN octet value obtained above.*/
27446       if(ROK != SExamMsg((Data *)(&mibOct1),
27447                cell->siCb.crntSiInfo.mib, 0))
27448          return;
27449
27450       if(ROK != SExamMsg((Data *)(&mibOct2),
27451                cell->siCb.crntSiInfo.mib, 1))
27452          return;
27453
27454       /* ccpu00114572- Fix for improper way of MIB Octet setting for SFN */
27455       mibOct1 = (mibOct1 & 0xFC) | (sfnOctet >> 6);
27456       mibOct2 = (mibOct2 & 0x03) | (sfnOctet << 2);
27457       /* ccpu00114572- Fix ends*/
27458
27459       /*Now, replace the two octets in MIB */
27460       if(ROK != SRepMsg((Data)(mibOct1),
27461                cell->siCb.crntSiInfo.mib, 0))
27462          return;
27463
27464       if(ROK != SRepMsg((Data)(mibOct2),
27465                cell->siCb.crntSiInfo.mib, 1))
27466          return;
27467
27468       /*Copy the MIB msg buff into interface buffer */
27469       SCpyMsgMsg(cell->siCb.crntSiInfo.mib,
27470             rgSchCb[cell->instIdx].rgSchInit.region,
27471             rgSchCb[cell->instIdx].rgSchInit.pool,
27472             &subfrmAlloc->cmnLcInfo.bchInfo.pdu);
27473       /* Added Dl TB count for MIB message transmission
27474        * This counter is incremented 4 times to consider 
27475        * the retransmission at the PHY level on PBCH channel*/
27476 #ifdef LTE_L2_MEAS
27477       cell->dlUlTbCnt.tbTransDlTotalCnt += RG_SCH_MIB_CNT;
27478 #endif      
27479    }
27480 #ifdef EMTC_ENABLE
27481    }
27482 #endif
27483
27484    allocInfo->bcchAlloc.schdFirst = FALSE;
27485    /*Check if scheduling of SIB1 is required.
27486      Check of (crntTimInfo.sfn % RGSCH_SIB1_PERIODICITY == 0)
27487      is not required here since the below check takes care
27488      of SFNs applicable for this one too.*/
27489    if((crntTimInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
27490          && (RGSCH_SIB1_TX_SF_NUM == crntTimInfo.slot))
27491    {
27492       /*If SIB1 has not been yet setup by Application, return*/
27493       if(NULLP == (cell->siCb.crntSiInfo.sib1Info.sib1))
27494       {
27495          return;
27496       }
27497
27498       allocInfo->bcchAlloc.schdFirst = TRUE;
27499       mcs =  cell->siCb.crntSiInfo.sib1Info.mcs;
27500       nPrb =  cell->siCb.crntSiInfo.sib1Info.nPrb;
27501       msgLen =  cell->siCb.crntSiInfo.sib1Info.msgLen;
27502    }
27503    else
27504    {
27505       /*Check if scheduling of SI can be performed.*/
27506       Bool    invalid = FALSE;
27507
27508       if(cell->siCb.siCtx.siId == 0)
27509          return;
27510
27511       /*Check if the Si-Window for the current Si-Context is completed*/
27512       invalid = rgSCHCmnChkPastWin(crntTimInfo, cell->siCb.siCtx.maxTimeToTx);
27513       if(invalid)
27514       {
27515          /* LTE_ADV_FLAG_REMOVED_START */
27516          if(cell->siCb.siCtx.retxCntRem)
27517          { 
27518              DU_LOG("\nERROR  -->  SCH : rgSCHDlSiSched(): SI not scheduled and window expired");
27519          }
27520          /* LTE_ADV_FLAG_REMOVED_END */
27521          if(cell->siCb.siCtx.warningSiFlag == TRUE)
27522          {
27523             rgSCHUtlFreeWarningSiPdu(cell);
27524             cell->siCb.siCtx.warningSiFlag  = FALSE;
27525          }
27526          return;
27527       }
27528
27529       /*Check the timinginfo of the current SI-Context to see if its
27530         transmission can be scheduled. */
27531       if(FALSE == (rgSCHCmnChkInWin(crntTimInfo,
27532                   cell->siCb.siCtx.timeToTx,
27533                   cell->siCb.siCtx.maxTimeToTx)))
27534       {
27535          return;
27536
27537       }
27538       /*Check if retransmission count has become 0*/
27539       if(0 == cell->siCb.siCtx.retxCntRem)
27540       {
27541          return;
27542       }
27543
27544       /* LTE_ADV_FLAG_REMOVED_START */
27545       /* Check if ABS is enabled/configured  */
27546       if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
27547       {
27548          /* The pattern type is RGR_ABS_MUTE, then eNB need to blank the subframe */
27549          if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
27550          {
27551             /* Determine next scheduling subframe is ABS or not */
27552             if(RG_SCH_ABS_ENABLED_ABS_SF == (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern
27553                   [((crntTimInfo.sfn*RGSCH_NUM_SUB_FRAMES) + crntTimInfo.slot) % RGR_ABS_PATTERN_LEN]))
27554             {
27555                /* Skip the SI scheduling to next tti */
27556                return;
27557             }
27558          }
27559       }
27560       /* LTE_ADV_FLAG_REMOVED_END */
27561
27562       /*Schedule the transmission of the current SI-Context */
27563       /*Find out the messg length for the SI message */
27564       /* warningSiFlag is to differentiate between Warning SI
27565        * and Other SI */
27566         if((rgSCHUtlGetMcsAndNPrb(cell, &nPrb, &mcs, &msgLen)) != ROK)
27567         {
27568            return; 
27569         }
27570
27571       cell->siCb.siCtx.i = RGSCH_CALC_SF_DIFF(crntTimInfo,
27572             cell->siCb.siCtx.timeToTx);
27573    } 
27574
27575
27576    /*Get the number of rb required */
27577    /*rgSCHCmnClcRbAllocForFxdTb(cell, msgLen, cellDl->ccchCqi, &rb);*/
27578    if(cellDl->bitsPerRb==0)
27579    {
27580       while ((rgTbSzTbl[0][0][rb]) < (uint32_t) (msgLen*8))
27581       {
27582          rb++;
27583       }
27584       rb = rb+1;
27585    }
27586    else
27587    {
27588       rb = RGSCH_CEIL((msgLen*8), cellDl->bitsPerRb);
27589    }
27590    /* DwPTS Scheduling Changes Start */   
27591 #ifdef LTE_TDD
27592    if (sf->sfType == RG_SCH_SPL_SF_DATA) 
27593    {
27594       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
27595
27596       /* Calculate the less RE's because of DwPTS */
27597        lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
27598
27599        /* Increase number of RBs in Spl SF to compensate for lost REs */
27600        rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
27601    }
27602 #endif
27603    /* DwPTS Scheduling Changes End */   
27604    /*ccpu00115595- end*/
27605    /* Additional check to see if required RBs
27606     * exceeds the available */
27607    if (rb > sf->bw - sf->bwAssigned)
27608    {
27609       DU_LOG("\nERROR  -->  SCH : rgSCHDlSiSched(): "
27610          "BW allocation failed CRNTI:%d",RGSCH_SI_RNTI);
27611       return;
27612    }
27613
27614    /* Update the subframe Allocated BW field */
27615    sf->bwAssigned = sf->bwAssigned + rb;
27616
27617    /*Fill the parameters in allocInfo */
27618    allocInfo->bcchAlloc.rnti = RGSCH_SI_RNTI;
27619    allocInfo->bcchAlloc.dlSf = sf;
27620    allocInfo->bcchAlloc.rbsReq = rb;
27621    /*ccpu00116710- MCS is not getting assigned */
27622    allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
27623
27624    /* ccpu00117510 - ADD - Assignment of nPrb and other information */
27625    allocInfo->bcchAlloc.nPrb = nPrb;
27626    allocInfo->bcchAlloc.tbInfo[0].bytesReq = msgLen;
27627    allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
27628    return;
27629 }
27630 #endif /*RGR_SI_SCH*/
27631
27632 \f
27633 /* ccpu00117452 - MOD - Changed macro name from
27634    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
27635 #ifdef RGR_CQI_REPT
27636 /**
27637  * @brief This function Updates the DL CQI for the UE.
27638  *
27639  * @details
27640  *
27641  *     Function: rgSCHCmnUeDlPwrCtColltCqiRept
27642  *     Purpose:  Manages PUSH N CQI reporting
27643  *         Step 1: Store the CQI in collation array
27644  *         Step 2: Increament the tracking count
27645  *         Step 3: Check is it time to to send the report
27646  *         Step 4: if yes, Send StaInd to RRM
27647  *         Step 4.1: Fill StaInd for sending collated N CQI rpeorts
27648  *         Step 4.2: Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM
27649  *         Step 4.2.1: If sending was not sucessful, return RFAILED
27650  *         Step 4.2.2: If sending was sucessful, return ROK
27651  *         Step 5: If no, return
27652  *     Invoked by: rgSCHCmnDlCqiInd
27653  *
27654  *  @param[in]  RgSchCellCb        *cell
27655  *  @param[in]  RgSchUeCb          *ue
27656  *  @param[in]  RgrUeCqiRept        *ueCqiRpt
27657  *  @return  Void
27658  *
27659  **/
27660 static S16 rgSCHCmnUeDlPwrCtColltCqiRept
27661 (
27662 RgSchCellCb        *cell,
27663 RgSchUeCb          *ue,
27664 RgrUeCqiRept        *ueCqiRpt
27665 )
27666 {
27667    uint8_t    *cqiCount = NULLP;
27668    S16   retVal;
27669    RgrStaIndInfo *staInfo = NULLP;
27670
27671
27672    /* Step 1: Store the CQI in collation array */
27673    /* Step 2: Increament the tracking count */
27674    cqiCount = &(ue->schCqiInfo.cqiCount);
27675    ue->schCqiInfo.cqiRept[(*cqiCount)++] =
27676                   *ueCqiRpt;
27677
27678
27679    /* Step 3: Check is it time to to send the report */
27680    if(RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(ue))
27681    {
27682    /* Step 4: if yes, Send StaInd to RRM */
27683       retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo,
27684                sizeof(RgrStaIndInfo));
27685       if (retVal != ROK)
27686       {
27687          DU_LOG("\nERROR  -->  SCH : Could not "
27688             "allocate memory for sending StaInd CRNTI:%d",ue->ueId);
27689          return (retVal);
27690       }
27691
27692    /* Step 4.1: Fill StaInd for sending collated N CQI rpeorts */
27693 #ifdef CA_DBG
27694       {
27695          uint32_t gCqiReptToAppCount;
27696          gCqiReptToAppCount++;
27697       
27698       }
27699
27700 #endif
27701       retVal = rgSCHUtlFillSndStaInd(cell, ue, staInfo,
27702             ue->cqiReptCfgInfo.numColltdCqiRept);
27703       return (retVal);
27704
27705    }
27706
27707    return ROK;
27708 } /* End of rgSCHCmnUeDlPwrCtColltCqiRept */
27709
27710 #endif /* End of RGR_CQI_REPT */
27711
27712 /**
27713  * @brief This function checks for the retransmisson
27714  *        for a DTX scenario.
27715  * @details
27716  *
27717  *     Function:
27718  *     Purpose:
27719  *     Invoked by:
27720  *
27721  *  @param[in]  RgSchCellCb        *cell
27722  *  @param[in]  RgSchUeCb          *ue
27723  *  @param[in]
27724  *  @return  Void
27725  *
27726  **/
27727 Void rgSCHCmnChkRetxAllowDtx
27728 (
27729 RgSchCellCb        *cell,
27730 RgSchUeCb          *ueCb,
27731 RgSchDlHqProcCb    *proc,
27732 Bool               *reTxAllwd
27733 )
27734 {
27735
27736
27737    *reTxAllwd = TRUE;
27738    /* Fix */
27739    if ((proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX))
27740    {
27741        *reTxAllwd = FALSE;
27742    }
27743
27744    return;
27745 }
27746
27747 /**
27748  * @brief API for calculating the SI Set Id 
27749  *
27750  * @details
27751  *
27752  *     Function: rgSCHCmnGetSiSetId
27753  *
27754  *     This API is used for calculating the SI Set Id, as shown below
27755  *     
27756  *          siSetId = 0        siSetId = 1
27757  *     |******************|******************|---------------->
27758  *   (0,0)              (8,0)              (16,0)          (SFN, SF)
27759  *    
27760  *
27761  *  @param[in]  uint16_t     sfn                   
27762  *  @param[in]  uint8_t      sf
27763  *  @return     uint16_t     siSetId
27764  **/
27765 uint16_t rgSCHCmnGetSiSetId
27766 (
27767 uint16_t    sfn,
27768 uint8_t     sf,
27769 uint16_t    minPeriodicity
27770 )
27771 {
27772    /* 80 is the minimum SI periodicity in sf. Also
27773     * all other SI periodicities are multiples of 80 */
27774     return  (((sfn * RGSCH_NUM_SUB_FRAMES_5G) + sf) / (minPeriodicity * 10));
27775 }
27776 #ifdef LTE_TDD
27777 /**
27778  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
27779  *
27780  * @details
27781  *
27782  *     Function: rgSCHCmnCalcDwPtsTbSz
27783  *
27784  *  @param[in]     RgSchCellCb    *cell                   
27785  *  @param[in]     uint32_t             bo
27786  *  @param[in/out] uint8_t             *rb
27787  *  @param[in/out] uint8_t             *iTbs
27788  *  @param[in]     uint8_t              lyr
27789  *  @param[in]     uint8_t              cfi
27790  *  @return        uint32_t             tbSz
27791  **/
27792 static uint32_t rgSCHCmnCalcDwPtsTbSz
27793 (
27794 RgSchCellCb *cell,
27795 uint32_t    bo,
27796 uint8_t     *rb,
27797 uint8_t     *iTbs,
27798 uint8_t     lyr,
27799 uint8_t     cfi
27800 )
27801 {
27802     uint32_t       tbSz;
27803     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
27804     uint32_t       numRE      = *rb * cellDl->noResPerRb[cfi];
27805     uint32_t       numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
27806
27807
27808     /* DwPts Rb cannot exceed the cell Bw */
27809     numDwPtsRb = RGSCH_MIN(numDwPtsRb, cellDl->maxDlBwPerUe);
27810     
27811     /* Adjust the iTbs for optimum usage of the DwPts region. 
27812      * Using the same iTbs adjustment will not work for all 
27813      * special subframe configurations and iTbs levels. Hence use the 
27814      * static iTbs Delta table for adjusting the iTbs  */
27815     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs);
27816     
27817     if (bo)
27818     {
27819        while(rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1] < bo*8 &&
27820              numDwPtsRb < cellDl->maxDlBwPerUe) 
27821        {
27822           (numDwPtsRb)++;
27823        }
27824
27825        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
27826     }
27827     else
27828     {
27829        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
27830     }
27831     *rb = numDwPtsRb;
27832
27833     return (tbSz/8);
27834 }
27835
27836 /**
27837  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
27838  *
27839  * @details
27840  *
27841  *     Function: rgSCHCmnCalcDwPtsTbSz2Cw
27842  *
27843  *  @param[in]      RgSchCellCb    *cell                   
27844  *  @param[in]      uint32_t             bo
27845  *  @param[in/out]  uint8_t             *rb
27846  *  @param[in]      uint8_t              maxRb
27847  *  @param[in/out]  uint8_t             *iTbs1
27848  *  @param[in/out]  uint8_t             *iTbs2
27849  *  @param[in]      uint8_t              lyr1
27850  *  @param[in]      uint8_t              lyr2
27851  *  @return[in/out] uint32_t            *tb1Sz
27852  *  @return[in/out] uint32_t            *tb2Sz
27853  *  @param[in]      uint8_t              cfi 
27854  **/
27855 static Void rgSCHCmnCalcDwPtsTbSz2Cw
27856 (
27857 RgSchCellCb  *cell,
27858 uint32_t     bo,
27859 uint8_t      *rb,
27860 uint8_t      maxRb,
27861 uint8_t      *iTbs1,
27862 uint8_t      *iTbs2,
27863 uint8_t      lyr1,
27864 uint8_t      lyr2,
27865 uint32_t     *tb1Sz, 
27866 uint32_t     *tb2Sz,
27867 uint8_t      cfi
27868 )
27869 {
27870     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
27871     uint32_t       numRE      = *rb * cellDl->noResPerRb[cfi];
27872     uint32_t       numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
27873
27874
27875     /* DwPts Rb cannot exceed the cell Bw */
27876     numDwPtsRb = RGSCH_MIN(numDwPtsRb, maxRb);
27877     
27878     /* Adjust the iTbs for optimum usage of the DwPts region. 
27879      * Using the same iTbs adjustment will not work for all 
27880      * special subframe configurations and iTbs levels. Hence use the 
27881      * static iTbs Delta table for adjusting the iTbs  */
27882     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs1);
27883     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs2);
27884     
27885     while((rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1] +
27886            rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1])< bo*8 &&
27887           numDwPtsRb < maxRb) 
27888     {
27889        (numDwPtsRb)++;
27890     }
27891
27892     *tb1Sz = rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
27893     *tb2Sz = rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
27894
27895     *rb = numDwPtsRb;
27896
27897     return;    
27898 }
27899
27900 #endif
27901
27902 /**
27903  * @brief Updates the GBR LCGs when datInd is received from MAC
27904  * 
27905  * @details
27906  *
27907  *     Function: rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
27908  *     Purpose:  This function updates the GBR LCGs 
27909  *               when datInd is received from MAC.
27910  *
27911  *     Invoked by: TOM
27912  *
27913  *  @param[in]  RgSchCellCb      *cell
27914  *  @param[in]  RgSchUeCb        *ue
27915  *  @param[in]  RgInfUeDatInd    *datInd
27916  *  @return Void
27917  **/
27918 Void rgSCHCmnUpdUeDataIndLcg 
27919 (
27920 RgSchCellCb    *cell,
27921 RgSchUeCb      *ue,
27922 RgInfUeDatInd  *datInd
27923 )
27924 {
27925    uint32_t idx = 0;
27926    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
27927
27928
27929    for (idx = 0; (idx < RGINF_MAX_LCG_PER_UE - 1); idx++)
27930    {
27931       if (datInd->lcgInfo[idx].bytesRcvd != 0)
27932       {
27933          uint8_t  lcgId     = datInd->lcgInfo[idx].lcgId;
27934          uint32_t bytesRcvd = datInd->lcgInfo[idx].bytesRcvd;
27935
27936          if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
27937          {
27938             RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
27939             if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
27940             {
27941                if(bytesRcvd > cmnLcg->effGbr)
27942                {
27943                   bytesRcvd -= cmnLcg->effGbr;
27944                   cmnLcg->effDeltaMbr = (cmnLcg->effDeltaMbr > bytesRcvd) ? \
27945                                         (cmnLcg->effDeltaMbr - bytesRcvd) : (0);
27946                   cmnLcg->effGbr = 0;
27947                }
27948                else
27949                {
27950                   cmnLcg->effGbr -= bytesRcvd;
27951                }
27952                /* To keep BS updated with the amount of data received for the GBR */
27953                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27954                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27955                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr+cmnLcg->effDeltaMbr);
27956             }
27957             else if(lcgId != 0)
27958             {
27959                ue->ul.effAmbr = (ue->ul.effAmbr > datInd->lcgInfo[idx].bytesRcvd) ? \
27960                                (ue->ul.effAmbr - datInd->lcgInfo[idx].bytesRcvd) : (0);
27961                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27962                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27963                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
27964                ue->ul.nonGbrLcgBs = (ue->ul.nonGbrLcgBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27965                                    (ue->ul.nonGbrLcgBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27966             }
27967             ue->ul.nonLcg0Bs = (ue->ul.nonLcg0Bs > datInd->lcgInfo[idx].bytesRcvd) ? \
27968                               (ue->ul.nonLcg0Bs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27969          }
27970       }
27971       else
27972       {
27973          break;
27974       }
27975    }
27976 #ifdef EMTC_ENABLE
27977    if(TRUE == ue->isEmtcUe)
27978    {
27979       if (cellSch->apisEmtcUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
27980       {
27981          DU_LOG("\nERROR  -->  SCH :  rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure");
27982       }
27983
27984    }
27985    else
27986 #endif
27987    {
27988       if (cellSch->apisUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
27989       {
27990          DU_LOG("\nERROR  -->  SCH : rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure");
27991       }
27992    }
27993 }
27994
27995
27996 /** @brief This function initializes DL allocation lists and prepares
27997  *         for scheduling  
27998  *
27999  * @details
28000  *
28001  *     Function: rgSCHCmnInitRbAlloc
28002  *
28003  * @param  [in] RgSchCellCb    *cell
28004  *
28005  * Returns: Void
28006  *
28007  */
28008 static Void  rgSCHCmnInitRbAlloc 
28009 (
28010 RgSchCellCb        *cell
28011 )
28012 {
28013    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
28014    CmLteTimingInfo        frm;
28015    RgSchDlSf              *dlSf;
28016    uint8_t                idx;
28017    
28018
28019 /* Initializing RgSchCmnUlRbAllocInfo structure.*/
28020    rgSCHCmnInitDlRbAllocInfo(&cellSch->allocInfo);
28021
28022    frm = cellSch->dl.time;
28023
28024    dlSf = rgSCHUtlSubFrmGet(cell, frm);
28025 #ifdef RG_5GTF
28026    dlSf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
28027    dlSf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
28028         for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
28029    {
28030       dlSf->sfBeamInfo[idx].totVrbgAllocated = 0;
28031       dlSf->sfBeamInfo[idx].totVrbgRequired = 0;
28032       dlSf->sfBeamInfo[idx].vrbgStart = 0;
28033    }
28034 #endif
28035    dlSf->remUeCnt = cellSch->dl.maxUePerDlSf;
28036    /* Updating the Subframe information in RBAllocInfo */
28037    cellSch->allocInfo.dedAlloc.dedDlSf   = dlSf;
28038    cellSch->allocInfo.msg4Alloc.msg4DlSf = dlSf;
28039
28040    /* LTE_ADV_FLAG_REMOVED_START */
28041    /* Determine next scheduling subframe is ABS or not */
28042    if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
28043    {
28044       cell->lteAdvCb.absPatternDlIdx = 
28045          ((frm.sfn*RGSCH_NUM_SUB_FRAMES_5G) + frm.slot) % RGR_ABS_PATTERN_LEN;
28046       cell->lteAdvCb.absDlSfInfo = (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern[
28047             cell->lteAdvCb.absPatternDlIdx]);
28048
28049    }
28050    else
28051    {
28052       cell->lteAdvCb.absDlSfInfo = RG_SCH_ABS_DISABLED;
28053    }
28054    /* LTE_ADV_FLAG_REMOVED_END */
28055
28056 #ifdef RGR_V1
28057    cellSch->allocInfo.ccchSduAlloc.ccchSduDlSf = dlSf;
28058 #endif
28059 #ifdef LTEMAC_SPS
28060    /* Update subframe-wide allocation information with SPS allocation */
28061    rgSCHCmnSpsDlUpdDlSfAllocWithSps(cell, frm, dlSf);
28062 #endif
28063    return;
28064 }
28065
28066
28067
28068 #ifdef DL_LA
28069 /**
28070  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
28071  * actual iTbs
28072  * 
28073  * @details
28074  *
28075  *     Function: rgSCHCmnSendTxModeInd(cell, ueUl, newTxMode)
28076  *     Purpose:  This function sends the TX mode Change 
28077  *               indication to RRM
28078  *     change
28079  *
28080  *     Invoked by: CMN
28081  *
28082  *  @param[in]  RgSchCellCb      *cell
28083  *  @param[in]  RgSchUeCb        *ue
28084  *  @param[in]  uint8_t               newTxMode
28085  *  @return Void
28086  **/
28087 static Void rgSCHCmnSendTxModeInd 
28088 (
28089 RgSchCellCb    *cell,
28090 RgSchUeCb      *ue,
28091 uint8_t        newTxMode
28092 )
28093
28094    RgmTransModeInd   *txModeChgInd;
28095    RgSchCmnDlUe      *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
28096
28097
28098    if(!(ueDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG))
28099    {
28100       /* Mem Alloc */
28101       SCH_ALLOC(txModeChgInd, sizeof(RgmTransModeInd));
28102       if(txModeChgInd == NULLP)
28103       {
28104          DU_LOG("ERROR  --> SCH : rgSCHCmnSendTxModeInd(): Memory allocation failed");
28105          return;
28106       }
28107       RG_SCH_FILL_RGM_TRANSMODE_IND(ue->ueId, cell->cellId, newTxMode, txModeChgInd);
28108       RgUiRgmChangeTransModeInd(&(cell->rgmSap->sapCfg.sapPst),
28109             cell->rgmSap->sapCfg.suId, txModeChgInd);
28110    }
28111
28112    ue->mimoInfo.txModUpChgFactor = 0;
28113    ue->mimoInfo.txModDownChgFactor = 0;
28114    ueDl->laCb[0].deltaiTbs = 0;
28115
28116    return;
28117 }
28118
28119 /**
28120  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
28121  * actual iTbs
28122  * 
28123  * @details
28124  *
28125  *     Function: rgSchCheckAndTriggerModeChange(cell, ueUl, iTbsNew)
28126  *     Purpose:  This function update and check for threashold for TM mode
28127  *     change
28128  *
28129  *     Invoked by: CMN
28130  *
28131  *  @param[in]  RgSchCellCb      *cell
28132  *  @param[in]  RgSchUeCb        *ue
28133  *  @param[in]  uint8_t               iTbs
28134  *  @return Void
28135  **/
28136 Void rgSchCheckAndTriggerModeChange
28137 (
28138 RgSchCellCb    *cell,
28139 RgSchUeCb      *ue,
28140 uint8_t        reportediTbs,
28141 uint8_t        previTbs,
28142 uint8_t        maxiTbs
28143 )
28144 {
28145    RgrTxMode          txMode;       /*!< UE's Transmission Mode */
28146    RgrTxMode          modTxMode;       /*!< UE's Transmission Mode */
28147
28148
28149    txMode = ue->mimoInfo.txMode;
28150
28151    /* Check for Step down */
28152    /* Step down only when TM4 is configured. */
28153    if(RGR_UE_TM_4 == txMode)
28154    {
28155       if((previTbs <= reportediTbs) && ((reportediTbs - previTbs) >= RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR))
28156       {
28157          ue->mimoInfo.txModDownChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
28158       }
28159       else
28160       {
28161          ue->mimoInfo.txModDownChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
28162       }
28163
28164       ue->mimoInfo.txModDownChgFactor =  
28165          RGSCH_MAX(ue->mimoInfo.txModDownChgFactor, -(RG_SCH_MODE_CHNG_STEPDOWN_THRSHD));
28166
28167       if(ue->mimoInfo.txModDownChgFactor >= RG_SCH_MODE_CHNG_STEPDOWN_THRSHD)
28168       {
28169          /* Trigger Mode step down */
28170          modTxMode = RGR_UE_TM_3;
28171          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
28172       }
28173    }
28174
28175    /* Check for Setup up */
28176    /* Step Up only when TM3 is configured, Max possible Mode is TM4*/
28177    if(RGR_UE_TM_3 == txMode)
28178    {
28179       if((previTbs > reportediTbs) || (maxiTbs == previTbs))
28180       {
28181          ue->mimoInfo.txModUpChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
28182       }
28183       else
28184       {
28185          ue->mimoInfo.txModUpChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
28186       }
28187
28188       ue->mimoInfo.txModUpChgFactor = 
28189          RGSCH_MAX(ue->mimoInfo.txModUpChgFactor, -(RG_SCH_MODE_CHNG_STEPUP_THRSHD));
28190
28191       /* Check if TM step up need to be triggered */
28192       if(ue->mimoInfo.txModUpChgFactor >= RG_SCH_MODE_CHNG_STEPUP_THRSHD)
28193       {
28194          /* Trigger mode chnage */
28195          modTxMode =  RGR_UE_TM_4;
28196          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
28197       }
28198    }
28199
28200    return;
28201 }
28202 #endif
28203
28204 /**
28205 * @brief Updates the GBR LCGs when datInd is received from MAC
28206  * 
28207  * @details
28208  *
28209  *     Function: rgSCHCmnIsDlCsgPrio (cell)
28210  *     Purpose:  This function returns if csg UEs are
28211  *               having priority at current time
28212  *
28213  *     Invoked by: Scheduler
28214  *
28215  *  @param[in]  RgSchCellCb      *cell
28216  *  @param[in]  RgSchUeCb        *ue
28217  *  @param[in]  RgInfUeDatInd    *datInd
28218  *  @return Void
28219  **/
28220 Bool rgSCHCmnIsDlCsgPrio(RgSchCellCb    *cell)
28221 {
28222   
28223    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
28224  
28225    /* Calculating the percentage resource allocated */
28226    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
28227    {
28228       return (FALSE);
28229    }
28230    else
28231    {
28232       if(((cmnDlCell->ncsgPrbCnt * 100) / cmnDlCell->totPrbCnt) < cell->minDlResNonCsg)
28233       {
28234          return (FALSE);
28235       }
28236       else
28237       {
28238          return (TRUE);
28239       }
28240    }
28241 }
28242
28243 /**
28244 * @brief Updates the GBR LCGs when datInd is received from MAC
28245  * 
28246  * @details
28247  *
28248  *     Function: rgSCHCmnIsUlCsgPrio (cell)
28249  *     Purpose:  This function returns if csg UEs are
28250  *               having priority at current time
28251  *
28252  *     Invoked by: Scheduler
28253  *
28254  *  @param[in]  RgSchCellCb      *cell
28255  *  @param[in]  RgSchUeCb        *ue
28256  *  @param[in]  RgInfUeDatInd    *datInd
28257  *  @return Void
28258  **/
28259 Bool rgSCHCmnIsUlCsgPrio(RgSchCellCb    *cell)
28260 {
28261    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
28262  
28263
28264    /* Calculating the percentage resource allocated */
28265    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
28266    {
28267       return (FALSE);
28268    }
28269    else
28270    {
28271       if (((cmnUlCell->ncsgPrbCnt * 100) /cmnUlCell->totPrbCnt) < cell->minUlResNonCsg)
28272       {
28273          return (FALSE);
28274       }
28275       else
28276       {
28277          return (TRUE);
28278       }
28279    }
28280 }
28281
28282 /** @brief DL scheduler for SPS, and all other downlink data
28283  *
28284  * @details
28285  *
28286  *      Function: rgSchCmnPreDlSch
28287  *
28288  *  @param  [in] Inst               schInst;
28289  *   Returns: Void
28290  *
28291  */
28292 Void rgSchCmnPreDlSch
28293 (
28294 RgSchCellCb   **cell,
28295 uint8_t       nCell,
28296 RgSchCellCb   **cellLst
28297 )
28298 {
28299    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell[0]);
28300    RgSchDlSf     *sf;
28301    uint8_t       idx;
28302
28303
28304    if(nCell > CM_LTE_MAX_CELLS)
28305    {
28306       return;
28307    }
28308
28309    if (cell[0]->isDlDataAllwd && (cell[0]->stopDlSch == FALSE))
28310    {
28311       /* Specific DL scheduler to perform UE scheduling */
28312       cellSch->apisDl->rgSCHDlPreSched(cell[0]);
28313
28314       /* Rearranging the cell entries based on their remueCnt in SF.
28315        * cells will be processed in the order of number of ue scheduled
28316        * in that cell */
28317       for (idx = 0; idx < nCell; idx++)
28318       {
28319          uint8_t    j;
28320          cellSch = RG_SCH_CMN_GET_CELL(cell[idx]);
28321          sf = cellSch->allocInfo.dedAlloc.dedDlSf;
28322
28323          if(idx == 0)
28324          {
28325             cellLst[idx] = cell[idx];
28326             continue;
28327          }
28328
28329          for(j = 0; j < idx; j++)
28330          {
28331             RgSchCmnCell *cmnCell = RG_SCH_CMN_GET_CELL(cellLst[j]);
28332             RgSchDlSf    *subfrm = cmnCell->allocInfo.dedAlloc.dedDlSf;
28333
28334             if(sf->remUeCnt < subfrm->remUeCnt)
28335             {
28336                uint8_t  k;
28337                for(k = idx; k > j; k--)
28338                {
28339                   cellLst[k] = cellLst[k-1];
28340                }
28341                break;
28342             }
28343          }
28344          cellLst[j] = cell[idx];
28345       }
28346    }
28347    else
28348    {
28349       for (idx = 0; idx < nCell; idx++)
28350       {
28351          cellLst[idx] = cell[idx];
28352       }
28353    }
28354    return;
28355 }
28356
28357 /** @brief DL scheduler for SPS, and all other downlink data
28358  *  @details
28359  *
28360  *       Function: rgSchCmnPstDlSch
28361  *
28362  *        @param  [in] Inst               schInst;
28363  *        Returns: Void
28364  *
28365  */
28366 Void rgSchCmnPstDlSch(RgSchCellCb  *cell)
28367 {
28368    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
28369
28370
28371    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
28372    {
28373       cellSch->apisDl->rgSCHDlPstSched(cell->instIdx);
28374    }
28375 }
28376
28377 uint8_t rgSCHCmnCalcPcqiBitSz(RgSchUeCb *ueCb, uint8_t   numTxAnt)
28378 {
28379    uint8_t confRepMode;
28380    uint8_t pcqiSz;
28381    uint8_t ri;
28382    RgSchUePCqiCb *cqiCb = ueCb->nPCqiCb;
28383
28384
28385    confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
28386    if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && 
28387          (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
28388    {
28389       ri =1;
28390    }
28391    else
28392    {
28393       ri = cqiCb->perRiVal;
28394    }
28395    switch(confRepMode)
28396    {
28397       case RGR_PRD_CQI_MOD10:
28398          {
28399             pcqiSz = 4;
28400          }
28401          break;
28402
28403       case RGR_PRD_CQI_MOD11:
28404          {
28405             if(numTxAnt == 2)
28406             {
28407                if (ri ==1)
28408                {
28409                   pcqiSz = 6;
28410                }
28411                else
28412                {
28413                   pcqiSz = 8;
28414                }
28415             }
28416             else if(numTxAnt == 4)
28417             {
28418                if (ri ==1)
28419                {
28420                   pcqiSz = 8;
28421                }
28422                else
28423                {
28424                   pcqiSz = 11;
28425                }
28426             }
28427             else
28428             {
28429                /* This is number of antenna case 1.
28430                 * This is not applicable for Mode 1-1. 
28431                 * So setting it to invalid value */
28432                pcqiSz = 0;
28433             }
28434          }
28435          break;
28436
28437       case RGR_PRD_CQI_MOD20:
28438          {
28439             if(cqiCb->isWb)
28440             {
28441                pcqiSz = 4;
28442             }
28443             else
28444             {
28445                pcqiSz = 4 + cqiCb->label;
28446             }
28447          }
28448          break;
28449
28450       case RGR_PRD_CQI_MOD21:
28451          {
28452             if(cqiCb->isWb)
28453             {
28454                if(numTxAnt == 2)
28455                {
28456                   if (ri ==1)
28457                   {
28458                      pcqiSz = 6;
28459                   }
28460                   else
28461                   {
28462                      pcqiSz = 8;
28463                   }
28464                }
28465                else if(numTxAnt == 4)
28466                {
28467                   if (ri ==1)
28468                   {
28469                      pcqiSz = 8;
28470                   }
28471                   else
28472                   {
28473                      pcqiSz = 11;
28474                   }
28475                }
28476                else
28477                {
28478                   /* This might be number of antenna case 1.
28479                    * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
28480                    * So setting invalid value.*/
28481                   pcqiSz = 0;
28482                }
28483             }
28484             else
28485             {
28486                if (ri ==1)
28487                {
28488                   pcqiSz = 4 + cqiCb->label;
28489                }
28490                else
28491                {
28492                   pcqiSz = 7 + cqiCb->label;
28493                }
28494             }
28495          }
28496          break;
28497       default:
28498           pcqiSz = 0;
28499           break;
28500    }
28501    
28502    return (pcqiSz);
28503 }
28504
28505 /** @brief DL scheduler for SPS, and all other downlink data
28506  *
28507  * @details
28508  *
28509  *     Function: rgSCHCmnDlSch
28510  *
28511  * @param  [in] RgSchCellCb    *cell
28512  *
28513  * Returns: Void
28514  *
28515  */
28516 Void rgSCHCmnDlSch(RgSchCellCb *cell)
28517 {
28518    RgSchDlSf *dlSf;
28519    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
28520 #ifdef RG_5GTF
28521    RgSchDynTddCb  *rgSchDynTddInfo = &(rgSchCb[cell->instIdx].rgSchDynTdd);
28522    uint16_t dlCntrlSfIdx;
28523 #endif
28524
28525
28526    dlSf = rgSCHUtlSubFrmGet(cell, cellSch->dl.time);
28527 #ifdef RG_5GTF
28528         if (rgSchDynTddInfo->isDynTddEnbld)
28529    {
28530       RG_SCH_DYN_TDD_GET_SFIDX(dlCntrlSfIdx, rgSchDynTddInfo->crntDTddSfIdx, 
28531                                             RG_SCH_CMN_DL_DELTA);
28532                 if(RG_SCH_DYNTDD_DLC_ULD == rgSchDynTddInfo->sfInfo[dlCntrlSfIdx].sfType)
28533                 {
28534                    if(1 == cell->cellId)
28535          {
28536                       ul5gtfsidDlAlreadyMarkUl++;
28537             /*
28538                     DU_LOG("\nINFO   -->  SCH : ul5gtfsidDlAlreadyMarkUl: %d, [sfn:sf] [%04d:%02d]\n", 
28539                     ul5gtfsidDlAlreadyMarkUl, cellSch->dl.time.sfn, 
28540                     cellSch->dl.time.slot);
28541             */
28542          }
28543                    return;
28544                 }
28545    }
28546 #endif
28547
28548    /* Specific DL scheduler to perform UE scheduling */
28549    cellSch->apisDl->rgSCHDlNewSched(cell, &cellSch->allocInfo);      
28550    /* LTE_ADV_FLAG_REMOVED_END */
28551
28552    /* call common allocator for RB Allocation */
28553    rgSCHCmnDlRbAlloc(cell, &cellSch->allocInfo);
28554
28555    /* Finalize the Allocations for reqested Against alloced */
28556    rgSCHCmnDlAllocFnlz(cell);
28557
28558    /* Perform Pdcch allocations for PDCCH Order Q.
28559     * As of now, giving this the least preference.
28560     * This func call could be moved above other allocations
28561     * as per need */
28562    rgSCHCmnGenPdcchOrder(cell, dlSf);
28563
28564    /* Do group power control for PUCCH */
28565    rgSCHCmnGrpPwrCntrlPucch(cell, dlSf);
28566
28567    return;
28568 }
28569
28570 /**********************************************************************
28571
28572   End of file
28573 **********************************************************************/