Merge "[JIRA ID - ODUHIGH-275] Part -3 classifying of logs of sch folder"
[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 #include "rl_interface.h"
48 #include "rl_common.h"
49
50 /* header/extern include files (.x) */
51 #include "tfu.x"           /* TFU types */
52 #include "lrg.x"           /* layer management typedefs for MAC */
53 #include "rgr.x"           /* layer management typedefs for MAC */
54 #include "rgm.x"           /* layer management typedefs for MAC */
55 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
56 #include "rg_sch.x"        /* typedefs for Scheduler */
57 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
58 #ifdef MAC_SCH_STATS
59 #include "lrg.x"            /* Stats Structures */
60 #endif /* MAC_SCH_STATS */
61 #ifdef __cplusplus
62 extern "C" {
63 #endif /* __cplusplus */
64
65 #ifdef EMTC_ENABLE
66 uint32_t emtcStatsUlTomSrInd;
67 uint32_t emtcStatsUlBsrTmrTxp;
68 #endif
69
70 #define RG_ITBS_DIFF(_x, _y) ((_x) > (_y) ? (_x) - (_y) : (_y) - (_x))
71 Void rgSCHSc1UlInit ARGS((RgUlSchdApis *apis));
72 #ifdef RG_PHASE2_SCHED
73 Void rgSCHRrUlInit ARGS((RgUlSchdApis *apis));
74 #ifdef EMTC_ENABLE
75 Void rgSCHEmtcHqInfoFree ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP));
76 Void rgSCHEmtcRrUlInit ARGS((RgUlSchdApis *apis));
77 Void rgSCHEmtcCmnDlInit ARGS((Void));
78 Void rgSCHEmtcCmnUlInit ARGS((Void));
79 Void rgSCHEmtcCmnUeNbReset ARGS((RgSchUeCb *ueCb));
80 RgSchCmnCqiToTbs *rgSchEmtcCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
81 #endif
82 Void rgSCHMaxciUlInit ARGS((RgUlSchdApis *apis));
83 Void rgSCHPfsUlInit ARGS((RgUlSchdApis *apis));
84 #endif
85 Void rgSCHSc1DlInit ARGS((RgDlSchdApis *apis));
86 #ifdef RG_PHASE2_SCHED
87 Void rgSCHRrDlInit ARGS((RgDlSchdApis *apis));
88 #ifdef EMTC_ENABLE
89 Void rgSCHEmtcRrDlInit ARGS((RgDlEmtcSchdApis *apis));
90 #endif
91 Void rgSCHMaxciDlInit ARGS((RgDlSchdApis *apis));
92 Void rgSCHPfsDlInit ARGS((RgDlSchdApis *apis));
93 #ifdef TFU_UPGRADE
94 Void rgSCHDlfsInit ARGS((RgDlfsSchdApis *apis));
95 #endif
96 #endif
97 #ifdef EMTC_ENABLE
98 Void rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl ARGS((RgSchCellCb *cell));
99 Void rgSCHCmnGetEmtcDciFrmtSizes ARGS((RgSchCellCb *cell));
100 Void rgSCHEmtcRrUlProcRmvFrmRetx ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *proc));
101 S16 rgSCHCmnPrecompEmtcMsg3Vars
102 ARGS((
103 RgSchCmnUlCell *cellUl,
104 uint8_t           ccchCqi,
105 uint16_t          msgSzA,
106 uint8_t           sbSize,
107 Bool         isEcp
108 ));
109 Void rgSCHEmtcCmnUeCcchSduDel
110 (
111 RgSchCellCb  *cell,
112 RgSchUeCb    *ueCb
113 );
114 Void rgSCHEmtcRmvFrmTaLst
115 (
116 RgSchCmnDlCell  *cellDl,
117 RgSchUeCb       *ue
118 );
119 Void rgSCHEmtcInitTaLst
120 (
121 RgSchCmnDlCell  *cellDl
122 );
123 Void rgSCHEmtcAddToTaLst
124 (
125 RgSchCmnDlCell  *cellDl,
126 RgSchUeCb       *ue
127 );
128
129 #endif
130
131 #ifdef RGR_SI_SCH
132 static Void rgSCHDlSiSched ARGS((RgSchCellCb  *cell,
133                       RgSchCmnDlRbAllocInfo *allocInfo,
134                       RgInfSfAlloc  *subfrmAlloc));
135 static Void rgSCHChkNUpdSiCfg ARGS((RgSchCellCb  *cell));
136 static Void rgSCHSelectSi ARGS((RgSchCellCb *cell));
137 #endif /*RGR_SI_SCH*/
138 /* LTE_ADV_FLAG_REMOVED_START */
139 #ifdef UNUSED_FUNC
140 #ifndef LTE_TDD
141 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
142 (
143 RgSchCellCb        *cell,
144 RgSchUeCb          *ue,
145 RgSchDlSf          *dlSf,
146 uint8_t                 rbStrt,
147 uint8_t                 numRb
148 );
149 static S16 rgSCHCmnBuildRntpInfo (
150 RgSchCellCb        *cell,
151 uint8_t                 *rntpPtr,
152 uint8_t                  startRb,
153 uint8_t                  nmbRb,
154 uint16_t                 bw
155 );
156 #endif
157 static Void rgSCHCmnNonDlfsType0Alloc
158 (
159 RgSchCellCb        *cell,
160 RgSchDlSf          *dlSf,
161 RgSchDlRbAlloc     *allocInfo,
162 RgSchUeCb          *ue
163 );
164 static uint8_t rgSchCmnUlRvIdxToIMcsTbl[4] = {32, 30, 31, 29};
165 static Void rgSCHCmnUlNonadapRetx ARGS((
166 RgSchCmnUlCell  *cellUl,
167 RgSchUlAlloc    *alloc,
168 uint8_t               idx
169 ));
170 static Void rgSCHCmnUlSfRlsRetxProcs ARGS((
171 RgSchCellCb *cell,
172 RgSchUlSf   *sf
173 ));
174
175 #ifdef TFU_UPGRADE
176 static S16 rgSCHCmnUlMdfyGrntForCqi ARGS((
177 RgSchCellCb  *cell,
178 RgSchUeCb    *ue,
179 uint32_t          maxRb,
180 uint32_t          *numSb,
181 uint8_t           *iTbs,
182 uint32_t          hqSz,
183 uint32_t          stepDownItbs,
184 uint32_t          effTgt
185 ));
186 #endif
187 static Void rgSCHCmnFillHqPPdcchDciFrmt1 ARGS((
188 RgSchCellCb                *cell,
189 RgSchDlRbAlloc             *rbAllocInfo,
190 RgSchDlHqProcCb            *hqP,
191 RgSchPdcch                 *pdcch,
192 uint8_t                         tpc
193 ));
194 static Void rgSCHCmnFillHqPPdcchDciFrmt1A ARGS((
195 RgSchCellCb                *cell,
196 RgSchDlRbAlloc             *rbAllocInfo,
197 RgSchDlHqProcCb            *hqP,
198 RgSchPdcch                 *pdcch,
199 uint8_t                         tpc
200 ));
201 static Void rgSCHCmnFillHqPPdcchDciFrmt1B ARGS((
202 RgSchCellCb                *cell,
203 RgSchDlRbAlloc             *rbAllocInfo,
204 RgSchDlHqProcCb            *hqP,
205 RgSchPdcch                 *pdcch,
206 uint8_t                         tpc
207 ));
208 static Void rgSCHCmnFillHqPPdcchDciFrmt2 ARGS((
209 RgSchCellCb                *cell,
210 RgSchDlRbAlloc             *rbAllocInfo,
211 RgSchDlHqProcCb            *hqP,
212 RgSchPdcch                 *pdcch,
213 uint8_t                         tpc
214 ));
215 static Void rgSCHCmnFillHqPPdcchDciFrmt2A ARGS((
216 RgSchCellCb                *cell,
217 RgSchDlRbAlloc             *rbAllocInfo,
218 RgSchDlHqProcCb            *hqP,
219 RgSchPdcch                 *pdcch,
220 uint8_t                         tpc
221 ));
222
223 #endif
224
225 Void rgSCHCmnDlSpsSch
226 (
227  RgSchCellCb        *cell
228 );
229 /* LTE_ADV_FLAG_REMOVED_END */
230
231 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc ARGS((
232 RgSchCellCb           *cell,
233 RgSchCmnDlRbAllocInfo *allocInfo
234 ));
235 static Void rgSCHBcchPcchDlRbAlloc ARGS((
236 RgSchCellCb           *cell,
237 RgSchCmnDlRbAllocInfo *allocInfo
238 ));
239 static Void rgSCHCmnDlBcchPcchAlloc ARGS((
240 RgSchCellCb  *cell
241 ));
242 #ifdef RGR_CQI_REPT
243 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
244  RgSchCellCb        *cell,
245  RgSchUeCb          *ue,
246  TfuDlCqiPucch      *pucchCqi,
247  RgrUeCqiRept       *ueCqiRept,
248  Bool               *isCqiAvail,
249  Bool               *is2ndCwCqiAvail
250  ));
251 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
252  RgSchCellCb        *cell,
253  RgSchUeCb          *ue,
254  TfuDlCqiPusch      *puschCqi,
255  RgrUeCqiRept       *ueCqiRept,
256  Bool               *isCqiAvail,
257  Bool               *is2ndCwCqiAvail
258  ));
259 #else
260 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
261  RgSchCellCb        *cell,
262  RgSchUeCb          *ue,
263  TfuDlCqiPucch      *pucchCqi
264  ));
265 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
266  RgSchCellCb        *cell,
267  RgSchUeCb          *ue,
268  TfuDlCqiPusch      *puschCqi
269  ));
270 #endif
271 /* ccpu00117452 - MOD - Changed macro name from
272    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
273 #ifdef RGR_CQI_REPT
274 static S16 rgSCHCmnUeDlPwrCtColltCqiRept ARGS((
275    RgSchCellCb        *cell,
276    RgSchUeCb          *ue,
277    RgrUeCqiRept        *ueCqiRept));
278 #endif /* End of RGR_CQI_REPT */
279 /* Fix: syed align multiple UEs to refresh at same time */
280 static Void rgSCHCmnGetRefreshPer ARGS((
281    RgSchCellCb  *cell,
282    RgSchUeCb    *ue,
283    uint32_t          *waitPer));
284 static S16 rgSCHCmnApplyUeRefresh ARGS((
285 RgSchCellCb     *cell,
286 RgSchUeCb       *ue));
287 #ifdef DL_LA
288 Void rgSCHCmnDlSetUeAllocLmtLa ARGS
289 ((
290 RgSchCellCb   *cell,
291 RgSchUeCb     *ue
292 ));
293 static Void rgSCHCheckAndSetTxScheme ARGS
294 ((
295 RgSchCellCb   *cell,
296 RgSchUeCb     *ue
297 ));
298 #endif
299
300 #ifdef LTE_TDD
301 static uint32_t rgSCHCmnCalcDwPtsTbSz ARGS
302 ((
303 RgSchCellCb    *cell,
304 uint32_t             bo,
305 uint8_t             *rb,
306 uint8_t             *iTbs,
307 uint8_t              lyr,
308 uint8_t              cfi
309 ));
310
311 static Void rgSCHCmnCalcDwPtsTbSz2Cw ARGS
312 ((
313 RgSchCellCb    *cell,
314 uint32_t             bo,
315 uint8_t             *rb,
316 uint8_t              maxRb,
317 uint8_t             *iTbs1,
318 uint8_t             *iTbs2,
319 uint8_t              lyr1,
320 uint8_t              lyr2,
321 uint32_t            *tb1Sz, 
322 uint32_t            *tb2Sz, 
323 uint8_t              cfi
324 ));
325
326 #endif
327 static Void  rgSCHCmnInitRbAlloc ARGS 
328 ((
329 RgSchCellCb        *cell
330 ));
331 #ifdef __cplusplus
332 }
333 #endif /* __cplusplus */
334
335
336 /* local defines */
337  RgSchdApis          rgSchCmnApis;
338 static RgUlSchdApis        rgSchUlSchdTbl[RGSCH_NUM_SCHEDULERS];
339 static RgDlSchdApis        rgSchDlSchdTbl[RGSCH_NUM_SCHEDULERS];
340 #ifdef EMTC_ENABLE
341 static RgUlSchdApis        rgSchEmtcUlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
342 static RgDlEmtcSchdApis        rgSchEmtcDlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
343 #endif
344 #ifdef RG_PHASE2_SCHED
345 static RgDlfsSchdApis      rgSchDlfsSchdTbl[RGSCH_NUM_DLFS_SCHEDULERS];
346 #endif
347 RgUlSchdInits       rgSchUlSchdInits = RGSCH_ULSCHED_INITS;
348 RgDlSchdInits       rgSchDlSchdInits = RGSCH_DLSCHED_INITS;
349 #ifdef EMTC_ENABLE
350 static RgEmtcUlSchdInits       rgSchEmtcUlSchdInits = RGSCH_EMTC_ULSCHED_INITS;
351 static RgEmtcDlSchdInits       rgSchEmtcDlSchdInits = RGSCH_EMTC_DLSCHED_INITS;
352 #endif
353 #if (defined (RG_PHASE2_SCHED) && defined (TFU_UPGRADE))
354 static RgDlfsSchdInits     rgSchDlfsSchdInits = RGSCH_DLFSSCHED_INITS;
355 #endif
356
357 typedef Void (*RgSchCmnDlAllocRbFunc) ARGS((RgSchCellCb *cell, RgSchDlSf *subFrm,
358 RgSchUeCb *ue, uint32_t bo, uint32_t *effBo, RgSchDlHqProcCb *proc,
359 RgSchCmnDlRbAllocInfo *cellWdAllocInfo));
360 typedef uint8_t (*RgSchCmnDlGetPrecInfFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, 
361       uint8_t numLyrs, Bool bothCwEnbld));
362 static Void rgSCHCmnDlAllocTxRbTM1 ARGS((
363 RgSchCellCb                *cell,
364 RgSchDlSf                  *subFrm,
365 RgSchUeCb                  *ue,
366 uint32_t                        bo,
367 uint32_t                        *effBo,
368 RgSchDlHqProcCb            *proc,
369 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
370 ));
371 static Void rgSCHCmnDlAllocTxRbTM2 ARGS((
372 RgSchCellCb                *cell,
373 RgSchDlSf                  *subFrm,
374 RgSchUeCb                  *ue,
375 uint32_t                        bo,
376 uint32_t                        *effBo,
377 RgSchDlHqProcCb            *proc,
378 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
379 ));
380 static Void rgSCHCmnDlAllocTxRbTM3 ARGS((
381 RgSchCellCb                *cell,
382 RgSchDlSf                  *subFrm,
383 RgSchUeCb                  *ue,
384 uint32_t                        bo,
385 uint32_t                        *effBo,
386 RgSchDlHqProcCb            *proc,
387 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
388 ));
389 static Void rgSCHCmnDlAllocTxRbTM4 ARGS((
390 RgSchCellCb                *cell,
391 RgSchDlSf                  *subFrm,
392 RgSchUeCb                  *ue,
393 uint32_t                        bo,
394 uint32_t                        *effBo,
395 RgSchDlHqProcCb            *proc,
396 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
397 ));
398 #ifdef RG_UNUSED
399 static Void rgSCHCmnDlAllocTxRbTM5 ARGS((
400 RgSchCellCb                *cell,
401 RgSchDlSf                  *subFrm,
402 RgSchUeCb                  *ue,
403 uint32_t                        bo,
404 uint32_t                        *effBo,
405 RgSchDlHqProcCb            *proc,
406 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
407 ));
408 #endif
409 static Void rgSCHCmnDlAllocTxRbTM6 ARGS((
410 RgSchCellCb                *cell,
411 RgSchDlSf                  *subFrm,
412 RgSchUeCb                  *ue,
413 uint32_t                        bo,
414 uint32_t                        *effBo,
415 RgSchDlHqProcCb            *proc,
416 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
417 ));
418 static Void rgSCHCmnDlAllocTxRbTM7 ARGS((
419 RgSchCellCb                *cell,
420 RgSchDlSf                  *subFrm,
421 RgSchUeCb                  *ue,
422 uint32_t                        bo,
423 uint32_t                        *effBo,
424 RgSchDlHqProcCb            *proc,
425 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
426 ));
427 static Void rgSCHCmnDlAllocRetxRbTM1 ARGS((
428 RgSchCellCb                *cell,
429 RgSchDlSf                  *subFrm,
430 RgSchUeCb                  *ue,
431 uint32_t                        bo,
432 uint32_t                        *effBo,
433 RgSchDlHqProcCb            *proc,
434 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
435 ));
436 static Void rgSCHCmnDlAllocRetxRbTM2 ARGS((
437 RgSchCellCb                *cell,
438 RgSchDlSf                  *subFrm,
439 RgSchUeCb                  *ue,
440 uint32_t                        bo,
441 uint32_t                        *effBo,
442 RgSchDlHqProcCb            *proc,
443 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
444 ));
445 static Void rgSCHCmnDlAllocRetxRbTM3 ARGS((
446 RgSchCellCb                *cell,
447 RgSchDlSf                  *subFrm,
448 RgSchUeCb                  *ue,
449 uint32_t                        bo,
450 uint32_t                        *effBo,
451 RgSchDlHqProcCb            *proc,
452 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
453 ));
454 static Void rgSCHCmnDlAllocRetxRbTM4 ARGS((
455 RgSchCellCb                *cell,
456 RgSchDlSf                  *subFrm,
457 RgSchUeCb                  *ue,
458 uint32_t                        bo,
459 uint32_t                        *effBo,
460 RgSchDlHqProcCb            *proc,
461 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
462 ));
463 #ifdef RG_UNUSED
464 static Void rgSCHCmnDlAllocRetxRbTM5 ARGS((
465 RgSchCellCb                *cell,
466 RgSchDlSf                  *subFrm,
467 RgSchUeCb                  *ue,
468 uint32_t                        bo,
469 uint32_t                        *effBo,
470 RgSchDlHqProcCb            *proc,
471 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
472 ));
473 #endif
474 static Void rgSCHCmnDlAllocRetxRbTM6 ARGS((
475 RgSchCellCb                *cell,
476 RgSchDlSf                  *subFrm,
477 RgSchUeCb                  *ue,
478 uint32_t                        bo,
479 uint32_t                        *effBo,
480 RgSchDlHqProcCb            *proc,
481 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
482 ));
483 static Void rgSCHCmnDlAllocRetxRbTM7 ARGS((
484 RgSchCellCb                *cell,
485 RgSchDlSf                  *subFrm,
486 RgSchUeCb                  *ue,
487 uint32_t                        bo,
488 uint32_t                        *effBo,
489 RgSchDlHqProcCb            *proc,
490 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
491 ));
492
493 #ifdef LTE_ADV 
494 static uint8_t rgSchGetN1ResCount ARGS ((
495  RgSchUeCb *ue,
496  uint16_t       servCellId 
497 ));
498 Bool rgSchCmnChkDataOnlyOnPcell 
499 (
500  RgSchUeCb         *ue,
501  RgSchDlSf         *dlSf
502 );
503 #endif /*LTE_ADV */
504 uint8_t rgSCHCmnCalcPcqiBitSz
505 (
506  RgSchUeCb    *ueCb, 
507  uint8_t           numTxAnt
508 );
509
510 #ifndef LTE_ADV
511 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
512 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[7] = {rgSCHCmnDlAllocTxRbTM1,
513 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
514 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7};
515
516 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
517 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[7] = {rgSCHCmnDlAllocRetxRbTM1,
518 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
519 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7};
520 #else
521 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
522 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[9] = {rgSCHCmnDlAllocTxRbTM1,
523 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
524 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7, NULLP, NULLP};
525
526 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
527 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[9] = {rgSCHCmnDlAllocRetxRbTM1,
528 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
529 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7, NULLP, NULLP};
530
531 #endif
532
533
534 static uint8_t rgSCHCmnDlTM3PrecInf2 ARGS((
535 RgSchCellCb                *cell,
536 RgSchUeCb                  *ue,
537 uint8_t                         numTxLyrs,
538 Bool                       bothCwEnbld
539 ));
540 static uint8_t rgSCHCmnDlTM3PrecInf4 ARGS((
541 RgSchCellCb                *cell,
542 RgSchUeCb                  *ue,
543 uint8_t                         numTxLyrs,
544 Bool                       bothCwEnbld
545 ));
546 static uint8_t rgSCHCmnDlTM4PrecInf2 ARGS((
547 RgSchCellCb                *cell,
548 RgSchUeCb                  *ue,
549 uint8_t                         numTxLyrs,
550 Bool                       bothCwEnbld
551 ));
552 static uint8_t rgSCHCmnDlTM4PrecInf4 ARGS((
553 RgSchCellCb                *cell,
554 RgSchUeCb                  *ue,
555 uint8_t                         numTxLyrs,
556 Bool                       bothCwEnbld
557 ));
558 /* Functions specific to each transmission mode for DL RB Allocation*/
559 RgSchCmnDlGetPrecInfFunc getPrecInfoFunc[2][2] = {
560 {rgSCHCmnDlTM3PrecInf2, rgSCHCmnDlTM3PrecInf4},
561 {rgSCHCmnDlTM4PrecInf2, rgSCHCmnDlTM4PrecInf4}
562 };
563
564 static S16 rgSCHCmnDlAlloc1CwRetxRb ARGS((
565 RgSchCellCb                *cell,
566 RgSchDlSf                  *subFrm,
567 RgSchUeCb                  *ue,
568 RgSchDlHqTbCb              *tbInfo,
569 uint8_t                         noLyr,
570 uint8_t                         *numRb,
571 uint32_t                        *effBo
572 ));
573 static S16 rgSCHCmnDlAlloc2CwRetxRb ARGS((
574 RgSchCellCb                *cell,
575 RgSchDlSf                  *subFrm,
576 RgSchUeCb                  *ue,
577 RgSchDlHqProcCb            *proc,
578 uint8_t                         *numRb,
579 Bool                       *swpFlg,
580 uint32_t                        *effBo
581 ));
582 static Void rgSCHCmnDlTM3TxTx ARGS((
583 RgSchCellCb                *cell,
584 RgSchDlSf                  *subFrm,
585 RgSchUeCb                  *ue,
586 uint32_t                        bo,
587 uint32_t                        *effBo,
588 RgSchDlHqProcCb            *proc,
589 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
590 ));
591 static Void rgSCHCmnDlTM3TxRetx ARGS((
592 RgSchCellCb                *cell,
593 RgSchDlSf                  *subFrm,
594 RgSchUeCb                  *ue,
595 uint32_t                        bo,
596 uint32_t                        *effBo,
597 RgSchDlHqProcCb            *proc,
598 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
599 ));
600 static Void rgSCHCmnDlTM3RetxRetx ARGS((
601 RgSchCellCb                *cell,
602 RgSchDlSf                  *subFrm,
603 RgSchUeCb                  *ue,
604 uint32_t                        bo,
605 uint32_t                        *effBo,
606 RgSchDlHqProcCb            *proc,
607 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
608 ));
609
610 static Void rgSCHCmnNonDlfsUpdTyp2Alloc ARGS((
611 RgSchCellCb        *cell,
612 RgSchDlSf          *dlSf,
613 uint8_t                 rbStrt,
614 uint8_t                 numRb
615 ));
616 /* LTE_ADV_FLAG_REMOVED_START */
617 #ifndef LTE_TDD
618 static Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc ARGS((
619 RgSchCellCb        *cell,
620 RgSchDlSf          *dlSf,
621 uint8_t                 rbStrt,
622 uint8_t                 numRb
623 ));
624 #endif
625 /* LTE_ADV_FLAG_REMOVED_END */
626 static Void rgSCHCmnDlRbInfoAddUeTx ARGS((
627 RgSchCellCb        *cell,
628 RgSchCmnDlRbAllocInfo *allocInfo,
629 RgSchUeCb             *ue,
630 RgSchDlHqProcCb       *proc
631 ));
632 static Void rgSCHCmnDlRbInfoAddUeRetx ARGS((
633 RgSchCellCb        *cell,
634 RgSchCmnDlRbAllocInfo *allocInfo,
635 RgSchUeCb             *ue,
636 RgSchDlHqProcCb       *hqP
637 ));
638 static Void rgSCHCmnDlAdd2NonSchdRetxLst ARGS((
639 RgSchCmnDlRbAllocInfo *allocInfo,
640 RgSchUeCb             *ue,
641 RgSchDlHqProcCb       *proc
642 ));
643 static S16 rgSCHCmnDlAlloc2CwTxRetxRb ARGS((
644 RgSchCellCb                *cell,
645 RgSchDlSf                  *subFrm,
646 RgSchUeCb                  *ue,
647 RgSchDlHqTbCb              *reTxTb,
648 RgSchDlHqTbCb              *txTb,
649 uint8_t                         *numRb,
650 uint32_t                        *effBo
651 ));
652 static S16 rgSCHCmnDlAlloc2CwTxRb ARGS((
653 RgSchCellCb                *cell,
654 RgSchDlSf                  *subFrm,
655 RgSchUeCb                  *ue,
656 RgSchDlHqProcCb            *proc,
657 uint32_t                        bo,
658 uint8_t                         *numRb,
659 uint32_t                        *effBo
660 ));
661 static S16 rgSCHCmnDlAlloc1CwTxRb ARGS((
662 RgSchCellCb                *cell,
663 RgSchDlSf                  *subFrm,
664 RgSchUeCb                  *ue,
665 RgSchDlHqTbCb              *tbInfo,
666 uint32_t                        bo,
667 uint8_t                         *numRb,
668 uint32_t                        *effBo
669 ));
670 #ifndef LTEMAC_SPS
671 static Void rgSCHCmnFillHqPTb ARGS((
672 RgSchCellCb                *cell,
673 RgSchDlRbAlloc             *rbAllocInfo,
674 uint8_t                         tbAllocIdx,
675 RgSchPdcch                 *pdcch
676 ));
677 #endif
678 #ifdef LTEMAC_SPS
679 static Void rgSCHCmnDlGetBestFitHole ARGS((
680 uint32_t         *allocMask,
681 uint8_t          numMaskRbs,
682 uint32_t         *crntAllocMask,
683 uint8_t          rbsReq,
684 uint8_t          *allocStart,
685 uint8_t          *allocNumRbs,
686 Bool        isPartialAlloc
687 ));
688 #ifdef RGSCH_SPS_UNUSED
689 static uint32_t rgSCHCmnGetRaType1Mask ARGS((
690 uint8_t                rbIdx,
691 uint8_t                rbgSize,
692 uint8_t                *type1Subset
693 ));
694 #endif
695 static uint32_t rgSCHCmnGetRaType0Mask ARGS((
696 uint8_t                rbIdx,
697 uint8_t                rbgSize
698 ));
699 static uint32_t rgSCHCmnGetRaType2Mask ARGS((
700 uint8_t                rbIdx,
701 uint8_t                *maskIdx
702 ));
703 #endif
704
705 Bool rgSCHCmnRetxAllocAvoid ARGS(( 
706 RgSchDlSf                  *subFrm,
707 RgSchCellCb                *cell,
708 RgSchDlHqProcCb            *proc
709 ));
710
711 uint16_t rgSCHCmnGetSiSetId ARGS((
712 uint16_t    sfn,
713 uint8_t     sf,
714 uint16_t    minPeriodicity
715 ));
716
717
718 #ifdef RG_5GTF
719 //TODO_SID: Currenly table is only for 100 Prbs. Need to modify wrt VRBG table 8.1.5.2.1-1 V5G_213
720 uint32_t rgSch5gtfTbSzTbl[MAX_5GTF_MCS] = 
721     {1864, 5256, 8776, 13176, 17576, 21976, 26376, 31656, 35176, 39576, 43976, 47496, 52776, 59376, 66392};
722 uint32_t g5gtfTtiCnt = 0;
723 uint32_t gUl5gtfSrRecv = 0;
724 uint32_t gUl5gtfBsrRecv = 0;
725 uint32_t gUl5gtfUeSchPick = 0;
726 uint32_t gUl5gtfPdcchSchd = 0;
727 uint32_t gUl5gtfAllocAllocated = 0;
728 uint32_t gUl5gtfUeRbAllocDone = 0;
729 uint32_t gUl5gtfUeRmvFnlzZeroBo = 0;
730 uint32_t gUl5gtfUeFnlzReAdd = 0;
731 uint32_t gUl5gtfPdcchSend = 0;
732 uint32_t gUl5gtfRbAllocFail = 0;
733 uint32_t ul5gtfsidUlMarkUl = 0;
734 uint32_t ul5gtfsidDlSchdPass = 0;
735 uint32_t ul5gtfsidDlAlreadyMarkUl = 0;
736 uint32_t ul5gtfTotSchdCnt = 0;
737 #endif
738
739 /* CQI Offset Index to Beta CQI Offset value mapping,
740  * stored as parts per 1000. Reserved is set to 0.
741  * Refer 36.213 sec 8.6.3 Tbl 8.6.3-3 */
742 uint32_t rgSchCmnBetaCqiOffstTbl[16] = {0, 0, 1125,
743    1250, 1375, 1625, 1750, 2000, 2250, 2500, 2875,
744    3125, 3500, 4000, 5000, 6250};
745 uint32_t rgSchCmnBetaHqOffstTbl[16] =  {2000, 2500, 3125, 
746    4000, 5000, 6250, 8000,10000, 12625, 15875, 20000, 
747    31000, 50000,80000,126000,0};
748 uint32_t rgSchCmnBetaRiOffstTbl[16] = {1250, 1625, 2000, 
749    2500, 3125, 4000, 5000, 6250, 8000, 10000,12625,
750    15875,20000,0,0,0};
751 S8 rgSchCmnDlCqiDiffOfst[8] = {0, 1, 2, 3, -4, -3, -2, -1};
752
753 /* Include CRS REs while calculating Efficiency */
754 const static uint8_t rgSchCmnAntIdx[5] = {0,0,1,0,2};
755 const static uint8_t rgSchCmnNumResForCrs[5] = {0,6,12,0,16};
756 uint32_t cfiSwitchCnt ;
757 uint32_t cfiIncr ;
758 uint32_t cfiDecr ;
759
760
761 #ifdef TFU_UPGRADE
762 S8 rgSchCmnApUeSelDiffCqi[4] = {1, 2, 3, 4};
763 S8 rgSchCmnApEnbConfDiffCqi[4] = {0, 1, 2, -1};
764 #endif
765
766 typedef struct rgSchCmnDlUeDciFrmtOptns
767 {
768   TfuDciFormat spfcDciFrmt;   /* TM(Transmission Mode) specific DCI format.
769                                * Search space : UE Specific by C-RNTI only. */
770   uint8_t           spfcDciRAType; /* Resource Alloctn(RA) type for spfcDciFrmt */
771   TfuDciFormat prfrdDciFrmt;  /* Preferred DCI format among the available
772                                * options for TD (Transmit Diversity) */
773   uint8_t           prfrdDciRAType; /* Resource Alloctn(RA) type for prfrdDciFrmt */
774 }RgSchCmnDlUeDciFrmtOptns;
775 #ifndef LTE_ADV
776
777 /* DCI Format options for each Transmission Mode */
778 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[7] = {
779    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
780    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
781    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
782    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
783    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
784    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
785    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
786 };
787
788 #else
789 /* DCI Format options for each Transmission Mode */
790 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[9] = {
791    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
792    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
793    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
794    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
795    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
796    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
797    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
798 };
799 #endif
800
801
802 typedef struct rgSchCmnDlImcsTbl
803 {
804   uint8_t   modOdr; /* Modulation Order */
805   uint8_t   iTbs;   /* ITBS */
806 }RgSchCmnDlImcsTbl[29];
807
808 const struct rgSchCmnMult235Info
809 {
810    uint8_t   match;    /* Closest number satisfying 2^a.3^b.5^c, with a bias
811                   * towards the smaller number */
812    uint8_t   prvMatch; /* Closest number not greater than array index
813                   * satisfying 2^a.3^b.5^c */
814 } rgSchCmnMult235Tbl[110+1] = {
815    {0, 0},  /* dummy */
816    {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {6, 6}, {8, 8},
817    {9, 9}, {10, 10}, {10, 10}, {12, 12}, {12, 12}, {15, 12}, {15, 15},
818    {16, 16}, {16, 16}, {18, 18}, {18, 18}, {20, 20}, {20, 20}, {20, 20},
819    {24, 20}, {24, 24}, {25, 25}, {25, 25}, {27, 27}, {27, 27}, {30, 27},
820    {30, 30}, {30, 30}, {32, 32}, {32, 32}, {32, 32}, {36, 32}, {36, 36},
821    {36, 36}, {36, 36}, {40, 36}, {40, 40}, {40, 40}, {40, 40}, {45, 40},
822    {45, 40}, {45, 45}, {45, 45}, {48, 45}, {48, 48}, {48, 48}, {50, 50},
823    {50, 50}, {50, 50}, {54, 50}, {54, 54}, {54, 54}, {54, 54}, {54, 54},
824    {60, 54}, {60, 54}, {60, 60}, {60, 60}, {60, 60}, {64, 60}, {64, 64},
825    {64, 64}, {64, 64}, {64, 64}, {64, 64}, {72, 64}, {72, 64}, {72, 64},
826    {72, 72}, {72, 72}, {75, 72}, {75, 75}, {75, 75}, {75, 75}, {80, 75},
827    {80, 75}, {80, 80}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, {81, 81},
828    {90, 81}, {90, 81}, {90, 81}, {90, 81}, {90, 90}, {90, 90}, {90, 90},
829    {90, 90}, {96, 90}, {96, 90}, {96, 96}, {96, 96}, {96, 96}, {100, 96},
830    {100, 100}, {100, 100}, {100, 100}, {100, 100}, {100, 100}, {108, 100},
831    {108, 100}, {108, 100}, {108, 108}, {108, 108}, {108, 108}
832 };
833
834 /* R8 Upgrade */
835 /* BI table from 36.321 Table 7.2.1 */
836 const static S16 rgSchCmnBiTbl[RG_SCH_CMN_NUM_BI_VAL] = {
837       0, 10, 20, 30,40,60,80,120,160,240,320,480,960};
838 RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI] = {
839  {     0,                0              },
840  {RGSCH_CMN_QM_CQI_1,RGSCH_CMN_UL_EFF_CQI_1 },
841  {RGSCH_CMN_QM_CQI_2,RGSCH_CMN_UL_EFF_CQI_2 },
842  {RGSCH_CMN_QM_CQI_3,RGSCH_CMN_UL_EFF_CQI_3 },
843  {RGSCH_CMN_QM_CQI_4,RGSCH_CMN_UL_EFF_CQI_4 },
844  {RGSCH_CMN_QM_CQI_5,RGSCH_CMN_UL_EFF_CQI_5 },
845  {RGSCH_CMN_QM_CQI_6,RGSCH_CMN_UL_EFF_CQI_6 },
846  {RGSCH_CMN_QM_CQI_7,RGSCH_CMN_UL_EFF_CQI_7 },
847  {RGSCH_CMN_QM_CQI_8,RGSCH_CMN_UL_EFF_CQI_8 },
848  {RGSCH_CMN_QM_CQI_9,RGSCH_CMN_UL_EFF_CQI_9 },
849  {RGSCH_CMN_QM_CQI_10,RGSCH_CMN_UL_EFF_CQI_10 },
850  {RGSCH_CMN_QM_CQI_11,RGSCH_CMN_UL_EFF_CQI_11 },
851  {RGSCH_CMN_QM_CQI_12,RGSCH_CMN_UL_EFF_CQI_12 },
852  {RGSCH_CMN_QM_CQI_13,RGSCH_CMN_UL_EFF_CQI_13 },
853  {RGSCH_CMN_QM_CQI_14,RGSCH_CMN_UL_EFF_CQI_14 },
854  {RGSCH_CMN_QM_CQI_15,RGSCH_CMN_UL_EFF_CQI_15 },
855 };
856
857 #ifdef RG_UNUSED
858 /* This table maps a (delta_offset * 2 + 2) to a (beta * 8)
859  * where beta is 10^-(delta_offset/10) rounded off to nearest 1/8
860  */
861 static uint16_t rgSchCmnUlBeta8Tbl[29] = {
862    6, RG_SCH_CMN_UL_INVALID_BETA8, 8, 9, 10, 11, 13, 14, 16, 18, 20, 23,
863    25, 28, 32, RG_SCH_CMN_UL_INVALID_BETA8, 40, RG_SCH_CMN_UL_INVALID_BETA8,
864    50, RG_SCH_CMN_UL_INVALID_BETA8, 64, RG_SCH_CMN_UL_INVALID_BETA8, 80,
865    RG_SCH_CMN_UL_INVALID_BETA8, 101, RG_SCH_CMN_UL_INVALID_BETA8, 127,
866    RG_SCH_CMN_UL_INVALID_BETA8, 160
867 };
868 #endif
869
870 /* QCI to SVC priority mapping. Index specifies the Qci*/
871 static uint8_t rgSchCmnDlQciPrio[RG_SCH_CMN_MAX_QCI] = RG_SCH_CMN_QCI_TO_PRIO;
872
873 /* The configuration is efficiency measured per 1024 REs.  */
874 /* The first element stands for when CQI is not known      */
875 /* This table is used to translate CQI to its corrospoding */
876 /* allocation parameters. These are currently from 36.213  */
877 /* Just this talbe needs to be edited for modifying the    */
878 /* the resource allocation behaviour                       */
879
880 /* ADD CQI to MCS mapping correction
881  * single dimensional array is replaced by 2 dimensions for different CFI*/
882 static uint16_t rgSchCmnCqiPdschEff[4][16] = {RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1,
883     RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3};
884
885 static uint16_t rgSchCmn2LyrCqiPdschEff[4][16] = {RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1,
886     RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2, RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3};
887
888 /* This configuration determines the transalation of a UEs CQI to its    */
889 /* PDCCH coding efficiency. This may be edited based on the installation */
890 static uint8_t rgSchCmnDlRvTbl[4] = {0, 2, 3, 1}; /* RVIdx sequence is corrected*/
891
892 /* Indexed by [DciFrmt].
893  * Considering the following definition in determining the dciFrmt index.
894  * typedef enum
895 {
896    TFU_DCI_FORMAT_0,
897    TFU_DCI_FORMAT_1,
898    TFU_DCI_FORMAT_1A,
899    TFU_DCI_FORMAT_1B,
900    TFU_DCI_FORMAT_1C,
901    TFU_DCI_FORMAT_1D,
902    TFU_DCI_FORMAT_2,
903    TFU_DCI_FORMAT_2A,
904    TFU_DCI_FORMAT_3,
905    TFU_DCI_FORMAT_3A
906 } TfuDciFormat;
907 */
908 static uint16_t rgSchCmnDciFrmtSizes[10];
909
910 static uint16_t rgSchCmnCqiPdcchEff[16] = RG_SCH_CMN_CQI_TO_PDCCH_EFF;
911
912 #ifdef LTE_TDD
913
914 RgSchTddUlDlSubfrmTbl rgSchTddUlDlSubfrmTbl = {
915    {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},
916    {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},
917    {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},
918    {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},
919    {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},
920    {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},
921    {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}
922 };
923
924 /* SPS_INTG_FIX */
925 #ifdef LTEMAC_SPS
926 uint8_t rgSchTddSpsDlMaxRetxTbl[RGSCH_MAX_TDD_UL_DL_CFG] = {
927    /* 0 */ 6,
928    /* 1 */ 7,
929    /* 2 */ 8,
930    /* 3 */ 11,
931    /* 4 */ 12,
932    /* 5 */ 13,
933    /* 6 */ 7};
934
935 #endif
936
937
938 /* Special Subframes in OFDM symbols */
939 /* ccpu00134197-MOD-Correct the number of symbols */
940 RgSchTddSplSubfrmInfoTbl rgSchTddSplSubfrmInfoTbl = {
941         {3,  1, 1, 3,   1, 1},
942         {9,  1, 1, 8,   1, 1},
943         {10, 1, 1, 9,   1, 1},
944         {11, 1, 1, 10,  1, 1},
945         {12, 1, 1, 3,   2, 2},
946         {3,  2, 2, 8,   2, 2},
947         {9,  2, 2, 9,   2, 2},
948         {10, 2, 2, 0,   0, 0},
949         {11, 2, 2, 0,   0, 0}
950 };
951
952 /* PHICH 'm' value Table */
953 RgSchTddPhichMValTbl rgSchTddPhichMValTbl = {
954         {2, 1, 0, 0, 0, 2, 1, 0, 0, 0},
955         {0, 1, 0, 0, 1, 0, 1, 0, 0, 1},
956         {0, 0, 0, 1, 0, 0, 0, 0, 1, 0},
957         {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
958         {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
959         {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
960         {1, 1, 0, 0, 0, 1, 1, 0, 0, 1}
961 };
962
963 /* PHICH 'K' value Table */
964 RgSchTddKPhichTbl rgSchTddKPhichTbl = {
965         {0, 0, 4, 7, 6, 0, 0, 4, 7, 6},
966         {0, 0, 4, 6, 0, 0, 0, 4, 6, 0},
967         {0, 0, 6, 0, 0, 0, 0, 6, 0, 0},
968         {0, 0, 6, 6, 6, 0, 0, 0, 0, 0},
969         {0, 0, 6, 6, 0, 0, 0, 0, 0, 0},
970         {0, 0, 6, 0, 0, 0, 0, 0, 0, 0},
971         {0, 0, 4, 6, 6, 0, 0, 4, 7, 0}
972 };
973
974 /* Uplink association index 'K' value Table */
975 RgSchTddUlAscIdxKDashTbl rgSchTddUlAscIdxKDashTbl = {
976         {0, 0, 6, 4, 0, 0, 0, 6, 4, 0},
977         {0, 0, 4, 0, 0, 0, 0, 4, 0, 0},
978         {0, 0, 4, 4, 4, 0, 0, 0, 0, 0},
979         {0, 0, 4, 4, 0, 0, 0, 0, 0, 0},
980         {0, 0, 4, 0, 0, 0, 0, 0, 0, 0},
981         {0, 0, 7, 7, 5, 0, 0, 7, 7, 0}
982 };
983
984
985 /* PUSCH 'K' value Table */
986 RgSchTddPuschTxKTbl rgSchTddPuschTxKTbl = {
987         {4, 6, 0, 0, 0, 4, 6, 0, 0, 0},
988         {0, 6, 0, 0, 4, 0, 6, 0, 0, 4},
989         {0, 0, 0, 4, 0, 0, 0, 0, 4, 0},
990         {4, 0, 0, 0, 0, 0, 0, 0, 4, 4},
991         {0, 0, 0, 0, 0, 0, 0, 0, 4, 4},
992         {0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
993         {7, 7, 0, 0, 0, 7, 7, 0, 0, 5}
994 };
995
996 /* PDSCH to PUCCH Table for DL Harq Feed back. Based on the 
997    Downlink association set index 'K' table */
998 uint8_t rgSchTddPucchTxTbl[7][10] = {
999         {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1000         {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1001         {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1002         {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1003         {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1004         {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1005         {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1006 };
1007
1008 /* Table to fetch the next DL sf idx for applying the 
1009    new CFI. The next Dl sf Idx at which the new CFI 
1010    is applied is always the starting Sf of the next ACK/NACK
1011    Fdbk bundle. 
1012    
1013    Ex: In Cfg-2, sf4 and sf9 are the only subframes at which 
1014        a new ACK/NACK bundle of DL subframes can start
1015        
1016    D  S  U  D  D  D  S  U  D  D  D  S  U  D  D  D  S  U  D  D    
1017                4              9
1018    
1019    dlSf Array for Cfg-2:
1020    sfNum:  0  1  3  4  5  6  8  9  0  1   3  4  5  6  8  9 
1021    sfIdx:  0  1  2  3  4  5  6  7  8  9  10 11 12 12 14 15 
1022     
1023    If CFI changes at sf0,  nearest DL SF bundle >= 4 TTI is sf4
1024    So at sf4 the new CFI can be applied. To arrive at sf4 from
1025    sf0, the sfIdx has to be increased by 3 */  
1026                  
1027 uint8_t rgSchTddPdcchSfIncTbl[7][10] = {
1028  /* A/N Bundl: 0,1,5,6*/   {2,  1,  0, 0, 0, 2, 1,  0,  0,  0},
1029  /* A/N Bundl: 0,4,5,9*/   {2,  2,  0, 0, 3, 2, 2,  0,  0,  3},
1030  /* A/N Bundl: 4,9*/       {3,  6,  0, 5, 4, 3, 6,  0,  5,  4},
1031  /* A/N Bundl: 1,7,9*/     {4,  3,  0, 0, 0, 4, 5,  4,  6,  5},
1032  /* A/N Bundl: 0,6*/       {4,  3,  0, 0, 6, 5, 4,  7,  6,  5},
1033  /* A/N Bundl: 9*/         {8,  7,  0, 6, 5, 4, 12, 11, 10, 9},
1034  /* A/N Bundl: 0,1,5,6,9*/ {2,  1,  0, 0, 0, 2, 2,  0,  0,  3}
1035 };
1036    
1037
1038 /* combine compilation fixes */
1039 #ifdef LTEMAC_SPS
1040 /* subframe offset values to be used when twoIntervalsConfig is enabled in UL
1041  * SPS for a UE */
1042 RgSchTddSfOffTbl rgSchTddSfOffTbl = {
1043         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1044         {0, 0, 1, -1,  0, 0, 0,  1, -1, 0},
1045         {0, 0, 5,  0,  0, 0, 0, -5,  0, 0},
1046         {0, 0, 1,  1, -2, 0, 0,  0,  0, 0},
1047         {0, 0, 1, -1,  0, 0, 0,  0,  0, 0},
1048         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1049         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0}
1050 };
1051
1052
1053 /* Table to determine when uplink SPS configured grants should
1054  * explicitly be reserved in a subframe. When enries are same
1055  * as that of Msg3SubfrmTbl, indicates competition with msg3.
1056  * As of now, this is same as Msg3SubfrmTbl (leaving out uldlcfg 2),
1057  * except that all 255s are now zeros. */
1058 RgSchTddSpsUlRsrvTbl rgSchTddSpsUlRsrvTbl = {
1059         {0,    0,  0,  6,  8,  0, 0,  0,  6,  8},
1060         {0,    0,  6,  9,  0,  0, 0,  6,  9,  0},
1061         {0,    0,  10,  0,  0,  0, 0,  10,  0,  0},
1062         {0,   0,  0,  0,  8,  0, 7,  7,  14,  0},
1063         {0,   0,  0,  9,  0,  0, 7,  15,  0, 0},
1064         {0,   0,  10,  0,  0,  0, 16,  0, 0, 0},
1065         {0,    0,  0,  0,  8,  0, 0,  0,  9,  0}
1066 };
1067
1068 /* Inverse DL Assoc Set index Table */
1069 RgSchTddInvDlAscSetIdxTbl rgSchTddInvDlAscSetIdxTbl = {
1070        {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1071        {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1072        {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1073        {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1074        {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1075        {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1076        {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1077 };
1078
1079 #endif /* (LTEMAC_SPS ) */
1080
1081 /* Number of Uplink subframes Table */
1082 static uint8_t rgSchTddNumUlSf[] = {6, 4, 2, 3, 2, 1, 5};
1083
1084 /* Downlink HARQ processes Table */
1085 RgSchTddUlNumHarqProcTbl rgSchTddUlNumHarqProcTbl = { 7, 4, 2, 3, 2, 1, 6};
1086
1087 /* Uplink HARQ processes Table */
1088 RgSchTddDlNumHarqProcTbl rgSchTddDlNumHarqProcTbl = { 4, 7, 10, 9, 12, 15, 6};
1089
1090 /* Downlink association index set 'K' value Table */
1091 RgSchTddDlAscSetIdxKTbl rgSchTddDlAscSetIdxKTbl = {
1092         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1093
1094         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1095
1096         { {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}} },
1097
1098         { {0, {0}}, {0, {0}}, {3, {7, 6, 11}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1099
1100         { {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}} },
1101
1102         { {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}} },
1103
1104         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1105 };
1106
1107  /* ccpu132282-ADD-the table rgSchTddDlAscSetIdxKTbl is rearranged in 
1108   * decreasing order of Km, this is used to calculate the NCE used for 
1109   * calculating N1Pucch Resource for Harq*/
1110 RgSchTddDlAscSetIdxKTbl rgSchTddDlHqPucchResCalTbl = {
1111         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1112
1113         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1114
1115         { {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}} },
1116
1117         { {0, {0}}, {0, {0}}, {3, {11, 7, 6}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1118
1119         { {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}} },
1120
1121         { {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}} },
1122
1123         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1124 };
1125
1126 /* Minimum number of Ack/Nack feeback information to be
1127    stored for each UL-DL configuration */
1128 RgSchTddANFdbkMapTbl rgSchTddANFdbkMapTbl = {4, 4, 2, 3, 2, 1, 5};
1129
1130 /* Uplink switch points and number of UL subframes Table */
1131 RgSchTddMaxUlSubfrmTbl rgSchTddMaxUlSubfrmTbl = {
1132      {2,3,3}, {2,2,2}, {2,1,1}, {1,3,0}, {1,2,0}, {1,1,0}, {2,3,2}
1133 };
1134
1135 /* Uplink switch points and number of DL subframes Table */
1136 RgSchTddMaxDlSubfrmTbl rgSchTddMaxDlSubfrmTbl = {
1137      {2,2,2}, {2,3,3}, {2,4,4}, {1,7,0}, {1,8,0}, {1,9,0}, {2,2,3}
1138 };
1139
1140 /* Number of UL subframes present before a particular subframe */
1141 RgSchTddNumUlSubfrmTbl rgSchTddNumUlSubfrmTbl = {
1142         {0, 0, 1, 2, 3, 3, 3, 4, 5, 6},
1143         {0, 0, 1, 2, 2, 2, 2, 3, 4, 4},
1144         {0, 0, 1, 1, 1, 1, 1, 2, 2, 2},
1145         {0, 0, 1, 2, 3, 3, 3, 3, 3, 3},
1146         {0, 0, 1, 2, 2, 2, 2, 2, 2, 2},
1147         {0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
1148         {0, 0, 1, 2, 3, 3, 3, 4, 5, 5}
1149 };
1150
1151 /* Number of DL subframes present till a particular subframe */
1152 RgSchTddNumDlSubfrmTbl rgSchTddNumDlSubfrmTbl = {
1153         {1, 2, 2, 2, 2, 3, 4, 4, 4, 4},
1154         {1, 2, 2, 2, 3, 4, 5, 5, 5, 6},
1155         {1, 2, 2, 3, 4, 5, 6, 6, 7, 8},
1156         {1, 2, 2, 2, 2, 3, 4, 5, 6, 7},
1157         {1, 2, 2, 2, 3, 4, 5, 6, 7, 8},
1158         {1, 2, 2, 3, 4, 5, 6, 7, 8, 9},
1159         {1, 2, 2, 2, 2, 3, 4, 4, 4, 5}
1160 };
1161
1162
1163 /* Nearest possible UL subframe Index from UL subframe
1164  * DL Index < UL Index */
1165 RgSchTddLowDlSubfrmIdxTbl rgSchTddLowDlSubfrmIdxTbl = {
1166         {0, 1, 1, 1, 1, 5, 6, 6, 6, 6},
1167         {0, 1, 1, 1, 4, 5, 6, 6, 6, 9},
1168         {0, 1, 1, 3, 4, 5, 6, 6, 8, 9},
1169         {0, 1, 1, 1, 1, 5, 6, 7, 8, 9},
1170         {0, 1, 1, 1, 4, 5, 6, 7, 8, 9},
1171         {0, 1, 1, 3, 4, 5, 6, 7, 8, 9},
1172         {0, 1, 1, 1, 1, 5, 6, 6, 6, 9}
1173 };
1174
1175 /* Nearest possible DL subframe Index from UL subframe
1176  * DL Index > UL Index
1177  * 10 represents Next SFN low DL Idx */
1178 RgSchTddHighDlSubfrmIdxTbl rgSchTddHighDlSubfrmIdxTbl = {
1179         {0, 1, 5, 5, 5, 5, 6, 10, 10, 10},
1180         {0, 1, 4, 4, 4, 5, 6,  9,  9,  9},
1181         {0, 1, 3, 3, 4, 5, 6,  8,  8,  9},
1182         {0, 1, 5, 5, 5, 5, 6,  7,  8,  9},
1183         {0, 1, 4, 4, 4, 5, 6,  7,  8,  9},
1184         {0, 1, 3, 3, 4, 5, 6,  7,  8,  9},
1185         {0, 1, 5, 5, 5, 5, 6,  9,  9,  9}
1186 };
1187
1188 /* RACH Message3 related information */
1189 RgSchTddMsg3SubfrmTbl rgSchTddMsg3SubfrmTbl = {
1190         {7,      6,  255,  255,  255,  7,   6,  255,  255,  255},
1191         {7,      6,  255,  255,    8,  7,   6,  255,  255,    8},
1192         {7,      6,  255,  9,      8,  7,   6,  255,    9,    8},
1193         {12,    11,  255,  255,  255,  7,   6,    6,    6,   13},
1194         {12,    11,  255,  255,    8,  7,   6,    6,   14,   13},
1195         {12,    11,  255,    9,    8,  7,   6,   15,   14,   13},
1196         {7,      6,  255,  255,  255,  7,   6,  255,  255,    8}
1197 };
1198
1199 /* ccpu00132341-DEL Removed rgSchTddRlsDlSubfrmTbl and used Kset table for 
1200  * releasing DL HARQs */
1201
1202 /* DwPTS Scheduling Changes Start */
1203 /* Provides the number of Cell Reference Signals in DwPTS
1204  * region per RB */
1205 static uint8_t  rgSchCmnDwptsCrs[2][3] = {/* [Spl Sf cfg][Ant Port] */
1206            {4, 8,  16}, /* Spl Sf cfg 1,2,3,6,7,8 */
1207            {6, 12, 20}, /* Spl Sf cfg 4 */
1208 };
1209
1210 static S8  rgSchCmnSplSfDeltaItbs[9] = RG_SCH_DWPTS_ITBS_ADJ;
1211 /* DwPTS Scheduling Changes End */
1212 #endif
1213
1214
1215 static uint32_t rgSchCmnBsrTbl[64] = {
1216    0, 10, 12, 14, 17, 19, 22, 26,
1217    31, 36, 42, 49, 57, 67, 78, 91,
1218    107, 125, 146, 171, 200, 234, 274, 321,
1219    376, 440, 515, 603, 706, 826, 967, 1132,
1220    1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
1221    4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
1222    16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
1223    58255, 68201, 79846, 93479, 109439, 128125, 150000, 220000
1224 };
1225
1226 static uint32_t rgSchCmnExtBsrTbl[64] = {
1227    0, 10, 13, 16, 19, 23, 29, 35,
1228    43, 53, 65, 80, 98, 120, 147, 181,
1229    223, 274, 337, 414, 509, 625, 769, 945,
1230    1162, 1429, 1757, 2161, 2657, 3267, 4017, 4940,
1231    6074, 7469, 9185, 11294, 13888, 17077, 20999, 25822,
1232    31752, 39045, 48012, 59039, 72598, 89272, 109774, 134986,
1233    165989, 204111, 250990, 308634, 379519, 466683, 573866, 705666,
1234    867737, 1067031, 1312097, 1613447, 1984009, 2439678, 3000000, 3100000
1235 };
1236
1237 uint8_t rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI];
1238
1239 RgSchTbSzTbl rgTbSzTbl = {
1240  {
1241    {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},
1242    {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},
1243    {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},
1244    {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},
1245    {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},
1246    {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},
1247    {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},
1248    {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},
1249    {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},
1250    {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},
1251    {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},
1252    {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},
1253    {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},
1254    {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},
1255    {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},
1256    {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},
1257    {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},
1258    {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},
1259    {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},
1260    {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},
1261    {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},
1262    {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},
1263    {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},
1264    {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},
1265    {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},
1266    {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},
1267    {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}
1268  },
1269  {
1270    {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},
1271    {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},
1272    {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},
1273    {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},
1274    {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},
1275    {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},
1276    {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},
1277    {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},
1278    {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},
1279    {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},
1280    {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},
1281    {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},
1282    {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},
1283    {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},
1284    {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},
1285    {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},
1286    {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},
1287    {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},
1288    {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},
1289    {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},
1290    {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},
1291    {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},
1292    {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},
1293    {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},
1294    {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},
1295    {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},
1296    {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}
1297  }
1298 };
1299 RgSchUlIMcsTbl rgUlIMcsTbl = {
1300    {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
1301    {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10},
1302    {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14},
1303    {4, 15}, {4, 16}, {4, 17}, {4, 18}, {4, 19},
1304    {6, 19}, {6, 20}, {6, 21}, {6, 22}, {6, 23},
1305    {6, 24}, {6, 25}, {6, 26}
1306 };
1307 RgSchUeCatTbl rgUeCatTbl = {
1308    /*Column1:Maximum number of bits of an UL-SCH 
1309              transport block transmitted within a TTI
1310              - maxUlBits
1311      Column2:Maximum number of bits of a DLSCH
1312              transport block received within a TTI 
1313              - maxDlBits
1314      Column3:Total number of soft channel bits 
1315              - maxSftChBits
1316      Column4:Support for 64QAM in UL 
1317              - ul64qamSup
1318      Column5:Maximum number of DL-SCH transport
1319              block bits received within a TTI
1320              - maxDlTbBits
1321      Column6:Maximum number of supported layers for 
1322              spatial multiplexing in DL 
1323              - maxTxLyrs*/
1324    {5160,  {10296,0},      250368,  FALSE, 10296,  1},
1325    {25456, {51024,0},      1237248, FALSE, 51024,  2},
1326    {51024, {75376,0},      1237248, FALSE, 102048, 2},
1327    {51024, {75376,0},      1827072, FALSE, 150752, 2},
1328    {75376, {149776,0},     3667200, TRUE,  299552, 4},
1329    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1330    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1331    {149776,{299856,0},     35982720,TRUE,  2998560, 8}
1332 };
1333
1334 /* [ccpu00138532]-ADD-The below table stores the min HARQ RTT time
1335    in Downlink for TDD and FDD. Indices 0 to 6 map to tdd UL DL config 0-6. 
1336    Index 7 map to FDD */    
1337 uint8_t rgSchCmnHarqRtt[8] = {4,7,10,9,12,15,6,8};
1338 /* Number of CFI Switchover Index is equals to 7 TDD Indexes + 1 FDD index */
1339 uint8_t rgSchCfiSwitchOvrWinLen[] = {7, 4, 2, 3, 2, 1, 6, 8};
1340
1341 /* EffTbl is calculated for single layer and two layers.
1342   * CqiToTbs is calculated for single layer and two layers */
1343 RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1344 RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1345 /* New variable to store UL effiency values for normal and extended CP*/
1346 RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1];
1347 RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1348 RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1349 RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
1350 RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1351 RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1352 RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1353 RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1354 /* Include CRS REs while calculating Efficiency */
1355 RgSchCmnTbSzEff *rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI];
1356 RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP];
1357 #ifdef LTE_TDD
1358 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3, 1};
1359 #else
1360 /* Added matrix 'rgRaPrmblToRaFrmTbl'for computation of RA sub-frames from RA preamble */
1361 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3};
1362 #endif
1363
1364  RgUlSchdInits        rgSchUlSchdInits;
1365  RgDlSchdInits        rgSchDlSchdInits;
1366  RgDlfsSchdInits      rgSchDlfsSchdInits;
1367 #ifdef EMTC_ENABLE
1368  RgEmtcUlSchdInits        rgSchEmtcUlSchdInits;
1369  RgEmtcDlSchdInits        rgSchEmtcDlSchdInits;
1370 #endif
1371
1372 /* RACHO : start */
1373 static S16 rgSCHCmnUeIdleExdThrsld ARGS((
1374 RgSchCellCb     *cell,
1375 RgSchUeCb       *ue
1376 ));
1377 RgSchUeCb* rgSCHCmnGetHoUe ARGS((
1378 RgSchCellCb           *cell,
1379 uint16_t                   rapId
1380 ));
1381 static Void rgSCHCmnDelDedPreamble ARGS((
1382 RgSchCellCb           *cell,
1383 uint8_t                    preambleId
1384 ));
1385 RgSchUeCb* rgSCHCmnGetPoUe ARGS((
1386 RgSchCellCb           *cell,
1387 uint16_t                   rapId,
1388 CmLteTimingInfo       timingInfo
1389 ));
1390 static Void rgSCHCmnDelRachInfo ARGS((
1391 RgSchCellCb  *cell,
1392 RgSchUeCb    *ue
1393 ));
1394 static S16 rgSCHCmnUlRbAllocForPoHoUe ARGS((
1395 RgSchCellCb           *cell,
1396 RgSchUlSf             *sf,
1397 RgSchUeCb             *ue,
1398 uint8_t                    maxRb
1399 ));
1400 static Void rgSCHCmnHdlHoPo ARGS((
1401 RgSchCellCb           *cell,
1402 CmLListCp             *raRspLst,
1403 RgSchRaReqInfo        *raReq
1404 ));
1405 static Void rgSCHCmnAllocPoHoGrnt ARGS((
1406 RgSchCellCb           *cell,
1407 CmLListCp             *raRspLst,
1408 RgSchUeCb             *ue,
1409 RgSchRaReqInfo        *raReq
1410 ));
1411 static Void rgSCHCmnFillPdcchOdr2Sf ARGS((
1412 RgSchCellCb *cell,
1413 RgSchUeCb   *ue,
1414 RgSchPdcch  *pdcc,
1415 uint8_t          rapId,
1416 uint8_t          prachMskIdx
1417 ));
1418 static Void rgSCHCmnDlAdd2PdcchOdrQ ARGS((
1419 RgSchCellCb                *cell,
1420 RgSchUeCb                  *ue
1421 ));
1422 static Void rgSCHCmnDlRmvFrmPdcchOdrQ ARGS((
1423 RgSchCellCb                *cell,
1424 RgSchUeCb                  *ue
1425 ));
1426 static Void rgSCHCmnUpdNxtPrchMskIdx ARGS((
1427 RgSchCellCb  *cell
1428 ));
1429 static Void rgSCHCmnUpdRachParam ARGS((
1430 RgSchCellCb  *cell
1431 ));
1432 static S16 rgSCHCmnAllocPOParam ARGS((
1433 RgSchCellCb  *cell,
1434 RgSchDlSf    *dlSf,
1435 RgSchUeCb    *ue,
1436 RgSchPdcch   **pdcch,
1437 uint8_t           *rapId,
1438 uint8_t           *prachMskIdx
1439 ));
1440 static Void rgSCHCmnGenPdcchOrder ARGS((
1441 RgSchCellCb  *cell,
1442 RgSchDlSf    *dlSf
1443 ));
1444 static Void rgSCHCmnCfgRachDedPrm ARGS((
1445 RgSchCellCb   *cell
1446 ));
1447 /* RACHO : end */
1448
1449 static Void rgSCHCmnHdlUlInactUes ARGS((
1450 RgSchCellCb  *cell
1451 ));
1452 static Void rgSCHCmnHdlDlInactUes ARGS((
1453 RgSchCellCb  *cell
1454 ));
1455 static Void rgSCHCmnUlInit ARGS((Void
1456 ));
1457 static Void rgSCHCmnDlInit ARGS((Void
1458 ));
1459 static Void rgSCHCmnInitDlRbAllocInfo ARGS((
1460 RgSchCmnDlRbAllocInfo  *allocInfo
1461 ));
1462 static Void rgSCHCmnUpdUlCompEffBsr ARGS((
1463 RgSchUeCb *ue
1464 ));
1465 #if RG_UNUSED
1466 static Void rgSCHCmnUlSetAllUnSched  ARGS((
1467 RgSchCmnUlRbAllocInfo *allocInfo
1468 ));
1469 static Void rgSCHCmnUlUpdSf ARGS((
1470          RgSchCellCb           *cell,
1471          RgSchCmnUlRbAllocInfo *allocInfo,
1472          RgSchUlSf     *sf
1473          ));
1474 static Void rgSCHCmnUlHndlAllocRetx ARGS((
1475          RgSchCellCb           *cell,
1476          RgSchCmnUlRbAllocInfo *allocInfo,
1477          RgSchUlSf     *sf,
1478          RgSchUlAlloc  *alloc
1479          ));
1480 #endif
1481 static Void rgSCHCmnGrpPwrCntrlPucch ARGS((
1482 RgSchCellCb  *cell,
1483 RgSchDlSf    *dlSf
1484 ));
1485 static Void rgSCHCmnGrpPwrCntrlPusch ARGS((
1486 RgSchCellCb  *cell,
1487 RgSchUlSf    *ulSf
1488 ));
1489 static Void rgSCHCmnDelUeFrmRefreshQ ARGS((
1490 RgSchCellCb     *cell,
1491 RgSchUeCb       *ue
1492 ));
1493 static S16 rgSCHCmnTmrExpiry ARGS((
1494 PTR cb,               /* Pointer to timer control block */
1495 S16 tmrEvnt           /* Timer Event */
1496 ));
1497 static S16 rgSCHCmnTmrProc ARGS((
1498 RgSchCellCb *cell
1499 ));
1500 static Void rgSCHCmnAddUeToRefreshQ ARGS((
1501 RgSchCellCb     *cell,
1502 RgSchUeCb       *ue,
1503 uint32_t             wait
1504 ));
1505 static Void rgSCHCmnDlCcchRetx ARGS((
1506 RgSchCellCb             *cell,
1507 RgSchCmnDlRbAllocInfo   *allocInfo
1508 ));
1509 static Void rgSCHCmnUpdUeMimoInfo ARGS((
1510 RgrUeCfg     *ueCfg,
1511 RgSchCmnDlUe *ueDl,
1512 RgSchCellCb  *cell,
1513 RgSchCmnCell *cellSchd
1514 ));
1515 static Void rgSCHCmnUpdUeUlCqiInfo ARGS((
1516 RgSchCellCb   *cell,
1517 RgSchUeCb     *ue,
1518 RgSchCmnUlUe  *ueUl,
1519 RgSchCmnUe    *ueSchCmn,
1520 RgSchCmnCell  *cellSchd,
1521 Bool          isEcp 
1522 ));
1523 #ifdef RGR_V1
1524 static Void rgSCHCmnDlCcchSduRetx ARGS((
1525 RgSchCellCb             *cell,
1526 RgSchCmnDlRbAllocInfo   *allocInfo
1527 ));
1528 static Void rgSCHCmnDlCcchSduTx ARGS((
1529 RgSchCellCb             *cell,
1530 RgSchCmnDlRbAllocInfo   *allocInfo
1531 ));
1532 static S16 rgSCHCmnCcchSduAlloc ARGS((
1533 RgSchCellCb                *cell,
1534 RgSchUeCb                  *ueCb,
1535 RgSchCmnDlRbAllocInfo      *allocInfo
1536 ));
1537 static S16 rgSCHCmnCcchSduDedAlloc ARGS((
1538 RgSchCellCb                *cell,
1539 RgSchUeCb                  *ueCb
1540 ));
1541 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc ARGS((
1542 RgSchCellCb           *cell,
1543 RgSchUeCb             *ueCb,
1544 RgSchDlSf             *dlSf
1545 ));
1546 #endif
1547 static Void rgSCHCmnInitVars ARGS((
1548          RgSchCellCb *cell
1549          ));
1550
1551 /*ccpu00117180 - DEL - Moved rgSCHCmnUpdVars to .x as its access is now */
1552 static Void rgSCHCmnUlRbAllocForLst ARGS((
1553          RgSchCellCb           *cell,
1554          RgSchUlSf             *sf,
1555          uint32_t                   count,
1556          CmLListCp             *reqLst,
1557          CmLListCp             *schdLst,
1558          CmLListCp             *nonSchdLst,
1559          Bool                  isNewTx
1560          ));
1561 static S16 rgSCHCmnUlRbAllocForUe ARGS((
1562          RgSchCellCb           *cell,
1563          RgSchUlSf             *sf,
1564          RgSchUeCb             *ue,
1565          uint8_t                    maxRb,
1566          RgSchUlHole           *hole
1567          ));
1568 static Void rgSCHCmnMsg3GrntReq ARGS((
1569          RgSchCellCb     *cell,
1570          CmLteRnti       rnti,
1571          Bool            preamGrpA,
1572          RgSchUlHqProcCb *hqProc,
1573          RgSchUlAlloc    **ulAllocRef,
1574          uint8_t              *hqProcIdRef
1575          ));
1576 static Void rgSCHCmnDlCcchRarAlloc ARGS((
1577 RgSchCellCb             *cell
1578 ));
1579 static Void rgSCHCmnDlCcchTx ARGS((
1580 RgSchCellCb             *cell,
1581 RgSchCmnDlRbAllocInfo   *allocInfo
1582 ));
1583 static Void rgSCHCmnDlBcchPcch ARGS((
1584 RgSchCellCb             *cell,
1585 RgSchCmnDlRbAllocInfo   *allocInfo,
1586 RgInfSfAlloc            *subfrmAlloc
1587 ));
1588 Bool rgSCHCmnChkInWin ARGS((
1589 CmLteTimingInfo   frm,
1590 CmLteTimingInfo   start,
1591 CmLteTimingInfo   end
1592 ));
1593 Bool rgSCHCmnChkPastWin ARGS((
1594 CmLteTimingInfo   frm,
1595 CmLteTimingInfo   end
1596 ));
1597 static Void rgSCHCmnClcAlloc ARGS((
1598 RgSchCellCb             *cell,
1599 RgSchDlSf               *sf,
1600 RgSchClcDlLcCb          *lch,
1601 uint16_t                     rnti,
1602 RgSchCmnDlRbAllocInfo   *allocInfo
1603 ));
1604 #ifndef LTEMAC_SPS
1605 static Void rgSCHCmnClcRbAlloc ARGS((
1606 RgSchCellCb             *cell,
1607 uint32_t                     bo,
1608 uint8_t                      cqi,
1609 uint8_t                      *rb,
1610 uint32_t                     *tbs,
1611 uint8_t                      *mcs,
1612 RgSchDlSf               *sf 
1613 ));
1614 #endif
1615
1616 static S16 rgSCHCmnMsg4Alloc ARGS((
1617 RgSchCellCb                *cell,
1618 RgSchRaCb                  *raCb,
1619 RgSchCmnDlRbAllocInfo      *allocInfo
1620 ));
1621 static S16 rgSCHCmnMsg4DedAlloc ARGS((
1622 RgSchCellCb                *cell,
1623 RgSchRaCb                  *raCb
1624 ));
1625 static Void rgSCHCmnDlRaRsp ARGS((
1626 RgSchCellCb                *cell,
1627 RgSchCmnDlRbAllocInfo      *allocInfo
1628 ));
1629 static S16 rgSCHCmnRaRspAlloc ARGS((
1630 RgSchCellCb             *cell,
1631 RgSchDlSf               *subFrm,
1632 uint16_t                     rntiIdx,
1633 uint16_t                     rarnti,
1634 uint8_t                      noRaRnti,
1635 RgSchCmnDlRbAllocInfo   *allocInfo
1636 ));
1637 static Void rgSCHCmnUlUeDelAllocs ARGS((
1638 RgSchCellCb  *cell,
1639 RgSchUeCb   *ue
1640 ));
1641 static Void rgSCHCmnDlSetUeAllocLmt ARGS((
1642 RgSchCellCb   *cell,
1643 RgSchCmnDlUe  *ueDl,
1644 Bool          isEmtcUe
1645 ));
1646 static S16 rgSCHCmnDlRgrCellCfg ARGS((
1647 RgSchCellCb    *cell,
1648 RgrCellCfg     *cfg,
1649 RgSchErrInfo   *err
1650 ));
1651 static Void rgSCHCmnUlAdapRetx ARGS((
1652 RgSchUlAlloc    *alloc,
1653 RgSchUlHqProcCb *proc
1654 ));
1655 static Void rgSCHCmnUlUpdAllocRetx ARGS((
1656 RgSchCellCb    *cell,
1657 RgSchUlAlloc   *alloc
1658 ));
1659 static Void rgSCHCmnUlSfReTxAllocs ARGS((
1660 RgSchCellCb *cell,
1661 RgSchUlSf   *sf
1662 ));
1663 /* Fix: syed Adaptive Msg3 Retx crash. */
1664 #ifdef TFU_UPGRADE
1665 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1666 ((
1667 RgSchCellCb *cell,
1668 RgSchUeCb    *ue,
1669 RgrUeRecfg   *ueRecfg,
1670 uint8_t numTxPorts
1671 ));
1672 #else
1673 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1674 ((
1675 RgSchCellCb *cell,
1676 RgSchUeCb    *ue,
1677 RgrUeRecfg   *ueRecfg
1678 ));
1679 #endif
1680
1681
1682 /*
1683  * DL RB allocation specific functions
1684  */
1685
1686 static Void rgSCHCmnDlRbAlloc ARGS((
1687 RgSchCellCb           *cell,
1688 RgSchCmnDlRbAllocInfo *allocInfo
1689 ));
1690 static Void rgSCHCmnNonDlfsRbAlloc ARGS((
1691 RgSchCellCb           *cell,
1692 RgSchCmnDlRbAllocInfo *allocInfo
1693 ));
1694 static S16 rgSCHCmnNonDlfsCmnRbAlloc ARGS((
1695 RgSchCellCb           *cell,
1696 RgSchDlRbAlloc        *cmnAllocInfo));
1697
1698 #ifndef LTE_TDD
1699 static Void rgSCHCmnNonDlfsPbchRbAllocAdj ARGS((
1700 RgSchCellCb           *cell,
1701 RgSchDlRbAlloc        *cmnAllocInfo,
1702 uint8_t                    pbchSsRsSym,
1703 Bool                  isBcchPcch
1704 ));
1705 /* Added function to adjust TBSize*/
1706 static Void rgSCHCmnNonDlfsPbchTbSizeAdj ARGS((
1707 RgSchDlRbAlloc        *allocInfo,
1708 uint8_t                    numOvrlapgPbchRb,
1709 uint8_t                    pbchSsRsSym,
1710 uint8_t                    idx,
1711 uint32_t                   bytesReq
1712 ));
1713
1714 /* Added function to find num of overlapping PBCH rb*/
1715 static Void rgSCHCmnFindNumPbchOvrlapRbs ARGS((
1716 RgSchCellCb           *cell,
1717 RgSchDlSf             *dlSf,
1718 RgSchDlRbAlloc        *allocInfo,
1719 uint8_t                    *numOvrlapgPbchRb
1720 ));
1721
1722 static uint8_t rgSCHCmnFindNumAddtlRbsAvl ARGS((
1723 RgSchCellCb           *cell,
1724 RgSchDlSf             *dlSf,
1725 RgSchDlRbAlloc        *allocInfo
1726 ));
1727 #ifdef DEBUGP
1728 #ifdef UNUSED_FUNC
1729 static Void rgSCHCmnFindCodeRate ARGS((
1730 RgSchCellCb           *cell,
1731 RgSchDlSf             *dlSf,
1732 RgSchDlRbAlloc        *allocInfo,
1733 uint8_t                    idx
1734 ));
1735 #endif
1736 #endif
1737 #endif
1738 static Void rgSCHCmnNonDlfsMsg4Alloc ARGS((
1739 RgSchCellCb           *cell,
1740 RgSchCmnMsg4RbAlloc   *msg4AllocInfo,
1741 uint8_t                    isRetx
1742 ));
1743 static S16 rgSCHCmnNonDlfsMsg4RbAlloc ARGS((
1744 RgSchCellCb           *cell,
1745 RgSchRaCb             *raCb,
1746 RgSchDlSf             *dlSf
1747 ));
1748
1749 static S16 rgSCHCmnNonDlfsUeRbAlloc ARGS((
1750 RgSchCellCb           *cell,
1751 RgSchUeCb             *ue,
1752 RgSchDlSf             *dlSf,
1753 uint8_t                    *isDlBwAvail
1754 ));
1755 #ifndef LTEMAC_SPS
1756 static uint32_t rgSCHCmnCalcRiv ARGS(( uint8_t bw,
1757          uint8_t           rbStart,
1758          uint8_t           numRb));
1759 #endif
1760
1761 #ifdef LTE_TDD
1762 static Void rgSCHCmnUpdHqAndDai ARGS((
1763 RgSchDlHqProcCb   *hqP,
1764 RgSchDlSf         *subFrm,
1765 RgSchDlHqTbCb     *tbCb,
1766 uint8_t                tbAllocIdx
1767 ));
1768 static S16 rgSCHCmnUlCalcAvailBw ARGS((
1769 RgSchCellCb *cell,
1770 RgrCellCfg  *cellCfg,
1771 uint8_t          cfi,
1772 uint8_t          *rbStartRef,
1773 uint8_t          *bwAvailRef
1774 ));
1775 static S16 rgSCHCmnDlKdashUlAscInit ARGS((
1776 RgSchCellCb *cell
1777 ));
1778 static S16 rgSCHCmnDlANFdbkInit ARGS((
1779 RgSchCellCb *cell
1780 ));
1781 static S16 rgSCHCmnDlNpValInit ARGS((
1782 RgSchCellCb *cell
1783 ));
1784 static S16 rgSCHCmnDlCreateRachPrmLst ARGS((
1785 RgSchCellCb *cell
1786 ));
1787 static S16 rgSCHCmnDlCpyRachInfo ARGS((
1788 RgSchCellCb        *cell,
1789 RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES],
1790 uint8_t                 raArrSz
1791 ));
1792 static S16 rgSCHCmnDlRachInfoInit ARGS((
1793 RgSchCellCb *cell
1794 ));
1795 static S16 rgSCHCmnDlPhichOffsetInit ARGS((
1796 RgSchCellCb *cell
1797 ));
1798 #endif
1799 #ifdef TFU_UPGRADE
1800 static Void rgSCHCmnFindUlCqiUlTxAnt ARGS
1801 ((
1802  RgSchCellCb          *cell,
1803  RgSchUeCb            *ue,
1804  uint8_t                          wideCqi
1805  ));
1806  static RgSchCmnRank rgSCHCmnComputeRank ARGS
1807 ((
1808  RgrTxMode    txMode,
1809  uint32_t          *pmiBitMap,
1810  uint8_t           numTxPorts
1811  ));
1812
1813  static RgSchCmnRank rgSCHCmnComp2TxMode3 ARGS
1814 ((
1815  uint32_t *pmiBitMap
1816  ));
1817
1818   static RgSchCmnRank rgSCHCmnComp4TxMode3 ARGS
1819 ((
1820  uint32_t *pmiBitMap
1821  ));
1822
1823   static RgSchCmnRank rgSCHCmnComp2TxMode4 ARGS
1824 ((
1825  uint32_t *pmiBitMap
1826  ));
1827
1828   static RgSchCmnRank rgSCHCmnComp4TxMode4 ARGS
1829 ((
1830  uint32_t *pmiBitMap
1831  ));
1832
1833  static uint8_t rgSCHCmnCalcWcqiFrmSnr ARGS
1834 ((
1835  RgSchCellCb        *cell,
1836  TfuSrsRpt        *srsRpt
1837  ));
1838 #endif
1839
1840 /* comcodsepa : start */
1841 \f
1842 /**
1843  * @brief This function computes efficiency and stores in a table.
1844  *
1845  * @details
1846  *
1847  *     Function: rgSCHCmnCompEff
1848  *     Purpose:  this function computes the efficiency as number of
1849  *               bytes per 1024 symbols. The CFI table is also filled
1850  *               with the same information such that comparison is valid
1851  *
1852  *     Invoked by: Scheduler
1853  *
1854  *  @param[in]  uint8_t            noPdcchSym
1855  *  @param[in]  uint8_t            cpType
1856  *  @param[in]  uint8_t            txAntIdx
1857  *  @param[in]  RgSchCmnTbSzEff* effTbl
1858  *  @return  Void
1859  *
1860  **/
1861 static Void rgSCHCmnCompEff(uint8_t noPdcchSym,uint8_t cpType,uint8_t txAntIdx,RgSchCmnTbSzEff *effTbl)
1862 {
1863    uint8_t   noResPerRb;
1864    uint8_t   noSymPerRb;
1865    uint8_t   resOfCrs; /* Effective REs occupied by CRS */
1866    uint8_t   i, j;
1867
1868
1869    switch (cpType)
1870    {
1871       case RG_SCH_CMN_NOR_CP:
1872          noSymPerRb = 14;
1873          break;
1874       case RG_SCH_CMN_EXT_CP:
1875          noSymPerRb = 12;
1876          break;
1877       default:
1878          /* Generate a log error. This case should never be executed */
1879          return;
1880    }
1881
1882    /* Depending on the Tx Antenna Index, deduct the
1883     * Resource elements for the CRS */
1884    switch (txAntIdx)
1885    {
1886       case 0:
1887          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
1888          break;
1889       case 1:
1890          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
1891          break;
1892       case 2:
1893          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
1894          break;
1895       default:
1896          /* Generate a log error. This case should never be executed */
1897          return;
1898    }
1899    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
1900    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1901    {
1902       (*effTbl)[i] = 0;
1903       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1904       {
1905          /* This line computes the coding efficiency per 1024 REs */
1906          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1907       }
1908       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1909    }
1910    return;
1911 }
1912 /**
1913  * @brief This function computes efficiency and stores in a table.
1914  *
1915  * @details
1916  *
1917  *     Function: rgSCHCmnCompUlEff
1918  *     Purpose:  this function computes the efficiency as number of
1919  *               bytes per 1024 symbols. The CFI table is also filled
1920  *               with the same information such that comparison is valid
1921  *
1922  *     Invoked by: Scheduler
1923  *
1924  *  @param[in]  uint8_t            noUlRsSym
1925  *  @param[in]  uint8_t            cpType
1926  *  @param[in]  uint8_t            txAntIdx
1927  *  @param[in]  RgSchCmnTbSzEff* effTbl
1928  *  @return  Void
1929  *
1930  **/
1931 static Void rgSCHCmnCompUlEff(uint8_t noUlRsSym,uint8_t cpType,RgSchCmnTbSzEff *effTbl)
1932 {
1933    uint8_t noResPerRb;
1934    uint8_t noSymPerRb;
1935    uint8_t i, j;
1936
1937
1938    switch (cpType)
1939    {
1940       case RG_SCH_CMN_NOR_CP:
1941          noSymPerRb = 14;
1942          break;
1943       case RG_SCH_CMN_EXT_CP:
1944          noSymPerRb = 12;
1945          break;
1946       default:
1947          /* Generate a log error. This case should never be executed */
1948          return;
1949    }
1950
1951    noResPerRb = ((noSymPerRb - noUlRsSym) * RB_SCH_CMN_NUM_SCS_PER_RB);
1952    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1953    {
1954       (*effTbl)[i] = 0;
1955       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1956       {
1957          /* This line computes the coding efficiency per 1024 REs */
1958          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1959       }
1960       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1961    }
1962    return;
1963 }
1964
1965 /**
1966  * @brief This function computes efficiency for 2 layers and stores in a table.
1967  *
1968  * @details
1969  *
1970  *     Function: rgSCHCmn2LyrCompEff
1971  *     Purpose:  this function computes the efficiency as number of
1972  *               bytes per 1024 symbols. The CFI table is also filled
1973  *               with the same information such that comparison is valid
1974  *
1975  *     Invoked by: Scheduler
1976  *
1977  *  @param[in]  uint8_t            noPdcchSym
1978  *  @param[in]  uint8_t            cpType
1979  *  @param[in]  uint8_t            txAntIdx
1980  *  @param[in]  RgSchCmnTbSzEff* effTbl2Lyr
1981  *  @return  Void
1982  *
1983  **/
1984 static Void rgSCHCmn2LyrCompEff(uint8_t noPdcchSym,uint8_t cpType,uint8_t txAntIdx,RgSchCmnTbSzEff *effTbl2Lyr)
1985 {
1986    uint8_t  noResPerRb;
1987    uint8_t  noSymPerRb;
1988    uint8_t  resOfCrs; /* Effective REs occupied by CRS */
1989    uint8_t  i, j;
1990
1991
1992    switch (cpType)
1993    {
1994       case RG_SCH_CMN_NOR_CP:
1995          noSymPerRb = 14;
1996          break;
1997       case RG_SCH_CMN_EXT_CP:
1998          noSymPerRb = 12;
1999          break;
2000       default:
2001          /* Generate a log error. This case should never be executed */
2002          return;
2003    }
2004
2005    /* Depending on the Tx Antenna Index, deduct the
2006     * Resource elements for the CRS */
2007    switch (txAntIdx)
2008    {
2009       case 0:
2010          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
2011          break;
2012       case 1:
2013          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
2014          break;
2015       case 2:
2016          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
2017          break;
2018       default:
2019          /* Generate a log error. This case should never be executed */
2020          return;
2021    }
2022
2023    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
2024    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
2025    {
2026       (*effTbl2Lyr)[i] = 0;
2027       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
2028       {
2029          /* This line computes the coding efficiency per 1024 REs */
2030          (*effTbl2Lyr)[i] += (rgTbSzTbl[1][i][j] * 1024) / (noResPerRb * (j+1));
2031       }
2032       (*effTbl2Lyr)[i] /= RG_SCH_CMN_NUM_RBS;
2033    }
2034    return;
2035 }
2036
2037 \f
2038 /**
2039  * @brief This function initializes the rgSchCmnDciFrmtSizes table.
2040  *
2041  * @details
2042  *
2043  *     Function: rgSCHCmnGetDciFrmtSizes
2044  *     Purpose:  This function determines the sizes of all
2045  *               the available DCI Formats. The order of
2046  *               bits addition for each format is inaccordance
2047  *               with the specs.
2048  *     Invoked by: rgSCHCmnRgrCellCfg
2049  *
2050  *  @return  Void
2051  *
2052  **/
2053 static Void rgSCHCmnGetDciFrmtSizes(RgSchCellCb *cell)
2054 {
2055
2056
2057    /* DCI Format 0 size determination */
2058    rgSchCmnDciFrmtSizes[0] = 1 +
2059                              1 +
2060                              rgSCHUtlLog32bitNbase2((cell->bwCfg.ulTotalBw * \
2061                              (cell->bwCfg.ulTotalBw + 1))/2) +
2062                              5 +
2063                              1 +
2064                              2 +
2065                              3 +
2066 #ifdef LTE_TDD
2067                              2 +
2068                              2 +
2069 #endif
2070                              1;
2071    /* DCI Format 1 size determination */
2072    rgSchCmnDciFrmtSizes[1] = 1 +
2073    RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2074                              5 +
2075 #ifndef LTE_TDD
2076                              3 +
2077 #else
2078                              4 + 2 + /* HqProc Id and DAI */
2079 #endif
2080                              1 +
2081                              2 +
2082                              2;
2083
2084    /* DCI Format 1A size determination */
2085    rgSchCmnDciFrmtSizes[2] = 1 + /* Flag for format0/format1a differentiation */
2086                1 + /* Localized/distributed VRB assignment flag */
2087                5 + /* For mcs */
2088 #ifndef LTE_TDD
2089                3 + /* Harq process Id */
2090 #else
2091                4 + /* Harq process Id */
2092                2 + /* UL Index or DAI */
2093 #endif
2094                1 + /* New Data Indicator */
2095                2 + /* For RV */
2096                2 + /* For tpc */
2097                1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2098                    (cell->bwCfg.dlTotalBw + 1))/2);
2099                /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
2100                   Since VRB is local */
2101
2102    /* DCI Format 1B size determination */
2103    rgSchCmnDciFrmtSizes[3] = 1 +
2104                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2105                              (cell->bwCfg.dlTotalBw + 1))/2) +
2106                              5 +
2107                              3 +
2108 #ifdef LTE_TDD
2109                              1 + /* HqP */
2110                              2 + /* Dai */
2111 #endif
2112                              1 +
2113                              2 +
2114                              2 +
2115                              ((cell->numTxAntPorts == 4)? 4:2) +
2116                              1;
2117
2118    /* DCI Format 1C size determination */
2119    /* Approximation: NDLVrbGap1 ~= Nprb for DL */
2120    rgSchCmnDciFrmtSizes[4] = (cell->bwCfg.dlTotalBw < 50)? 0:1 +
2121                              (cell->bwCfg.dlTotalBw < 50)?
2122                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/2 * \
2123                                 (cell->bwCfg.dlTotalBw/2 + 1))/2)) :
2124                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/4 * \
2125                                 (cell->bwCfg.dlTotalBw/4 + 1))/2)) +
2126                              5;
2127
2128    /* DCI Format 1D size determination */
2129    rgSchCmnDciFrmtSizes[5] = 1 +
2130                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2131                              (cell->bwCfg.dlTotalBw + 1))/2) +
2132                              5 +
2133                              3 +
2134 #ifdef LTE_TDD
2135                              1 + 2 +
2136 #endif
2137                              1 +
2138                              2 +
2139                              2 +
2140                              ((cell->numTxAntPorts == 4)? 4:2) +
2141                              1;
2142
2143    /* DCI Format 2 size determination */
2144    rgSchCmnDciFrmtSizes[6] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2145                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2146                              2 +
2147 #ifdef LTE_TDD
2148                              2 + 1 +
2149 #endif
2150                              3 +
2151                              1 +
2152                              (5 + 1 + 2)*2 +
2153                              ((cell->numTxAntPorts == 4)? 6:3);
2154
2155    /* DCI Format 2A size determination */
2156    rgSchCmnDciFrmtSizes[7] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2157                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2158                              2 +
2159 #ifdef LTE_TDD
2160                              2 + 1 +
2161 #endif
2162                              3 +
2163                              1 +
2164                              (5 + 1 + 2)*2 +
2165                              ((cell->numTxAntPorts == 4)? 2:0);
2166
2167    /* DCI Format 3 size determination */
2168    rgSchCmnDciFrmtSizes[8] = rgSchCmnDciFrmtSizes[0];
2169
2170    /* DCI Format 3A size determination */
2171    rgSchCmnDciFrmtSizes[9] = rgSchCmnDciFrmtSizes[0];
2172
2173    return;
2174 }
2175
2176
2177 /**
2178  * @brief This function initializes the cmnCell->dciAggrLvl table.
2179  *
2180  * @details
2181  *
2182  *     Function: rgSCHCmnGetCqiDciFrmt2AggrLvl
2183  *     Purpose:  This function determines the Aggregation level
2184  *               for each CQI level against each DCI format.
2185  *     Invoked by: rgSCHCmnRgrCellCfg
2186  *
2187  *  @return  Void
2188  *
2189  **/
2190 static Void rgSCHCmnGetCqiDciFrmt2AggrLvl(RgSchCellCb *cell)
2191 {
2192    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2193    uint8_t            i;
2194    uint8_t            j;
2195
2196
2197    for (i = 0; i < RG_SCH_CMN_MAX_CQI; i++)
2198    {
2199       for (j = 0; j < 10; j++)
2200       {
2201          uint32_t pdcchBits; /* Actual number of phy bits needed for a given DCI Format
2202                * for a given CQI Level */
2203          pdcchBits = (rgSchCmnDciFrmtSizes[j] * 1024)/rgSchCmnCqiPdcchEff[i];
2204                         /* V5G_211 : 6.6 */
2205          if (pdcchBits < 192)
2206          {
2207              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL2;
2208              continue;
2209          }
2210          if (pdcchBits < 384)
2211          {
2212              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL4;
2213              continue;
2214          }
2215          if (pdcchBits < 768)
2216          {
2217              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL8;
2218              continue;
2219          }
2220          cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL16;
2221       }
2222    }
2223    return;
2224 }
2225 \f
2226 /**
2227  * @brief This function initializes all the data for the scheduler.
2228  *
2229  * @details
2230  *
2231  *     Function: rgSCHCmnDlInit
2232  *     Purpose:  This function initializes the following information:
2233  *               1. Efficiency table
2234  *               2. CQI to table index - It is one row for upto 3 RBs
2235  *                  and another row for greater than 3 RBs
2236  *                  currently extended prefix is compiled out.
2237  *     Invoked by: MAC intialization code..may be ActvInit
2238  *
2239  *  @return  Void
2240  *
2241  **/
2242 static Void rgSCHCmnDlInit()
2243 {
2244    uint8_t  i;
2245    S16      j;
2246    S16      k;
2247    uint8_t  idx;
2248    RgSchCmnTbSzEff  *effTbl;
2249    RgSchCmnCqiToTbs *tbsTbl;
2250
2251
2252    /* 0 corresponds to Single layer case, 1 corresponds to 2 layers case*/
2253    /* Init Efficiency table for normal cyclic prefix */
2254    /*Initialize Efficiency table for Layer Index 0 */
2255    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2256    /*Initialize Efficiency table for each of the CFI indices. The
2257     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2258    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[0];
2259    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[0];
2260    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[0];
2261    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[0];
2262    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2263    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[0];
2264    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[0];
2265    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[0];
2266    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[0];
2267    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2268    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[0];
2269    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[0];
2270    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[0];
2271    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[0];
2272
2273    /*Initialize CQI to TBS table for Layer Index 0 for Normal CP */
2274    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[0];
2275    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[0];
2276    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[0];
2277    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[0];
2278
2279    /*Intialize Efficency table for Layer Index 1 */
2280    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2281    /*Initialize Efficiency table for each of the CFI indices. The
2282     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2283    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[1];
2284    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[1];
2285    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[1];
2286    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[1];
2287    /*Initialize Efficiency table for Tx Antenna Port Index 1 */
2288    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[1];
2289    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[1];
2290    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[1];
2291    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[1];
2292    /*Initialize Efficiency table for Tx Antenna Port Index 2 */
2293    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[1];
2294    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[1];
2295    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[1];
2296    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[1];
2297
2298    /*Initialize CQI to TBS table for Layer Index 1 for Normal CP */
2299    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[1];
2300    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[1];
2301    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[1];
2302    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[1];
2303
2304    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2305    {
2306       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2307       {
2308          /* EfficiencyTbl calculation incase of 2 layers for normal CP  */
2309          rgSCHCmnCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx,\
2310                rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]);
2311          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx, \
2312                rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]);
2313       }
2314    }
2315
2316    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2317    {
2318       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2319       {
2320          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i];
2321          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][i];
2322          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2323                (j >= 0) && (k > 0); --j)
2324          {
2325             /* ADD CQI to MCS mapping correction
2326             * single dimensional array is replaced by 2 dimensions for different CFI*/
2327             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2328             {
2329                (*tbsTbl)[k--] = (uint8_t)j;
2330             }
2331          }
2332          for (; k > 0; --k)
2333          {
2334             (*tbsTbl)[k] = 0;
2335          }
2336          /* effTbl,tbsTbl calculation incase of 2 layers for normal CP */
2337          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i];
2338          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][i];
2339          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2340                (j >= 0) && (k > 0); --j)
2341          {
2342             /* ADD CQI to MCS mapping correction
2343             * single dimensional array is replaced by 2 dimensions for different CFI*/
2344             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2345             {
2346                (*tbsTbl)[k--] = (uint8_t)j;
2347             }
2348          }
2349          for (; k > 0; --k)
2350          {
2351             (*tbsTbl)[k] = 0;
2352          }
2353       }
2354    }
2355
2356    /* Efficiency Table for Extended CP */
2357    /*Initialize Efficiency table for Layer Index 0 */
2358    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2359    /*Initialize Efficiency table for each of the CFI indices. The
2360     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2361    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[0];
2362    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[0];
2363    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[0];
2364    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[0];
2365    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2366    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[0];
2367    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[0];
2368    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[0];
2369    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[0];
2370    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2371    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[0];
2372    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[0];
2373    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[0];
2374    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[0];
2375
2376    /*Initialize CQI to TBS table for Layer Index 0 for Extended CP */
2377    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[0];
2378    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[0];
2379    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[0];
2380    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[0];
2381
2382    /*Initialize Efficiency table for Layer Index 1 */
2383    /*Initialize Efficiency table for each of the CFI indices. The
2384     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2385    /*Initialize Efficency table for Tx Antenna Port Index 0 */
2386    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[1];
2387    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[1];
2388    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[1];
2389    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[1];
2390    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2391    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[1];
2392    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[1];
2393    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[1];
2394    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[1];
2395    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2396    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[1];
2397    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[1];
2398    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[1];
2399    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[1];
2400
2401    /*Initialize CQI to TBS table for Layer Index 1 for Extended CP */
2402    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[1];
2403    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[1];
2404    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[1];
2405    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[1];
2406    /* Activate this code when extended cp is supported */
2407    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2408    {
2409       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2410       {
2411          /* EfficiencyTbl calculation incase of 2 layers for extendedl CP  */
2412          rgSCHCmnCompEff( (uint8_t)(i + 1 ), (uint8_t)RG_SCH_CMN_EXT_CP, idx,\
2413                rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]);
2414          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), (uint8_t) RG_SCH_CMN_EXT_CP,idx, \
2415                rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]);
2416       }
2417    }
2418
2419    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2420    {
2421       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2422       {
2423          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i];
2424          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][i];
2425          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2426                (j >= 0) && (k > 0); --j)
2427          {
2428             /* ADD CQI to MCS mapping correction
2429             * single dimensional array is replaced by 2 dimensions for different CFI*/
2430             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2431             {
2432                (*tbsTbl)[k--] = (uint8_t)j;
2433             }
2434          }
2435          for (; k > 0; --k)
2436          {
2437             (*tbsTbl)[k] = 0;
2438          }
2439          /* effTbl,tbsTbl calculation incase of 2 layers for extended CP */
2440          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i];
2441          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][i];
2442          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2443                (j >= 0) && (k > 0); --j)
2444          {
2445            /* ADD CQI to MCS mapping correction
2446             * single dimensional array is replaced by 2 dimensions for different CFI*/
2447             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2448             {
2449                (*tbsTbl)[k--] = (uint8_t)j;
2450             }
2451          }
2452          for (; k > 0; --k)
2453          {
2454             (*tbsTbl)[k] = 0;
2455          }
2456       }
2457    }
2458    return;
2459 }
2460 \f
2461 /**
2462  * @brief This function initializes all the data for the scheduler.
2463  *
2464  * @details
2465  *
2466  *     Function: rgSCHCmnUlInit
2467  *     Purpose:  This function initializes the following information:
2468  *               1. Efficiency table
2469  *               2. CQI to table index - It is one row for upto 3 RBs
2470  *                  and another row for greater than 3 RBs
2471  *                  currently extended prefix is compiled out.
2472  *     Invoked by: MAC intialization code..may be ActvInit
2473  *
2474  *  @return  Void
2475  *
2476  **/
2477 static Void rgSCHCmnUlInit()
2478 {
2479    uint8_t            *mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_NOR_CP][0];
2480    RgSchCmnTbSzEff    *effTbl    = &rgSchCmnNorUlEff[0];
2481    const RgSchCmnUlCqiInfo *cqiTbl = &rgSchCmnUlCqiTbl[0];
2482    S16              i;
2483    S16              j;
2484
2485    /* Initaializing new variable added for UL eff */
2486    rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP] = &rgSchCmnNorUlEff[0];
2487    /* Reason behind using 3 as the number of symbols to rule out for
2488     * efficiency table computation would be that we are using 2 symbols for
2489     * DMRS(1 in each slot) and 1 symbol for SRS*/
2490    rgSCHCmnCompUlEff(RGSCH_UL_SYM_DMRS_SRS,RG_SCH_CMN_NOR_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP]);
2491
2492    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2493          i >= 0 && j > 0; --i)
2494    {
2495       if ((*effTbl)[i] <= cqiTbl[j].eff)
2496       {
2497          mapTbl[j--] = (uint8_t)i;
2498       }
2499    }
2500    for (; j > 0; --j)
2501    {
2502       mapTbl[j] = 0;
2503    }
2504    effTbl    = &rgSchCmnExtUlEff[0];
2505    mapTbl    = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_EXT_CP][0];
2506
2507    /* Initaializing new variable added for UL eff */
2508    rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP] = &rgSchCmnExtUlEff[0];
2509    /* Reason behind using 3 as the number of symbols to rule out for
2510     * efficiency table computation would be that we are using 2 symbols for
2511     * DMRS(1 in each slot) and 1 symbol for SRS*/
2512    rgSCHCmnCompUlEff(3,RG_SCH_CMN_EXT_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP]);
2513
2514    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2515          i >= 0 && j > 0; --i)
2516    {
2517       if ((*effTbl)[i] <= cqiTbl[j].eff)
2518       {
2519          mapTbl[j--] = (uint8_t)i;
2520       }
2521    }
2522    for (; j > 0; --j)
2523    {
2524       mapTbl[j] = 0;
2525    }
2526    rgSCHPwrInit();
2527    return;
2528 }
2529
2530 /**
2531  * @brief This function initializes all the data for the scheduler.
2532  *
2533  * @details
2534  *
2535  *     Function: rgSCHCmnInit
2536  *     Purpose:  This function initializes the following information:
2537  *               1. Efficiency table
2538  *               2. CQI to table index - It is one row for upto 3 RBs
2539  *                  and another row for greater than 3 RBs
2540  *                  currently extended prefix is compiled out.
2541  *     Invoked by: MAC intialization code..may be ActvInit
2542  *
2543  *  @return  Void
2544  *
2545  **/
2546 Void rgSCHCmnInit()
2547 {
2548    uint8_t   idx;
2549
2550    rgSCHCmnDlInit();
2551    rgSCHCmnUlInit();
2552 #ifdef EMTC_ENABLE
2553    rgSCHEmtcCmnDlInit();
2554    rgSCHEmtcCmnUlInit();
2555 #endif      
2556 #ifdef LTEMAC_SPS
2557    rgSCHCmnSpsInit();
2558 #endif
2559
2560    /* Init the function pointers */
2561    rgSchCmnApis.rgSCHRgrUeCfg         = rgSCHCmnRgrUeCfg;
2562    rgSchCmnApis.rgSCHRgrUeRecfg       = rgSCHCmnRgrUeRecfg;
2563    rgSchCmnApis.rgSCHFreeUe           = rgSCHCmnUeDel;
2564    rgSchCmnApis.rgSCHRgrCellCfg       = rgSCHCmnRgrCellCfg;
2565    rgSchCmnApis.rgSCHRgrCellRecfg     = rgSCHCmnRgrCellRecfg;
2566    rgSchCmnApis.rgSCHFreeCell         = rgSCHCmnCellDel;
2567    rgSchCmnApis.rgSCHRgrLchCfg        = rgSCHCmnRgrLchCfg;
2568    rgSchCmnApis.rgSCHRgrLcgCfg        = rgSCHCmnRgrLcgCfg;
2569    rgSchCmnApis.rgSCHRgrLchRecfg      = rgSCHCmnRgrLchRecfg;
2570    rgSchCmnApis.rgSCHRgrLcgRecfg      = rgSCHCmnRgrLcgRecfg;
2571    rgSchCmnApis.rgSCHFreeDlLc         = rgSCHCmnFreeDlLc;
2572    rgSchCmnApis.rgSCHFreeLcg          = rgSCHCmnLcgDel;
2573    rgSchCmnApis.rgSCHRgrLchDel        = rgSCHCmnRgrLchDel;
2574    rgSchCmnApis.rgSCHActvtUlUe        = rgSCHCmnActvtUlUe;
2575    rgSchCmnApis.rgSCHActvtDlUe        = rgSCHCmnActvtDlUe;
2576    rgSchCmnApis.rgSCHHdlUlTransInd    = rgSCHCmnHdlUlTransInd;
2577    rgSchCmnApis.rgSCHDlDedBoUpd       = rgSCHCmnDlDedBoUpd;
2578    rgSchCmnApis.rgSCHUlRecMsg3Alloc   = rgSCHCmnUlRecMsg3Alloc;
2579    rgSchCmnApis.rgSCHUlCqiInd         = rgSCHCmnUlCqiInd;
2580    rgSchCmnApis.rgSCHPucchDeltaPwrInd = rgSCHPwrPucchDeltaInd;
2581    rgSchCmnApis.rgSCHUlHqProcForUe    = rgSCHCmnUlHqProcForUe;
2582 #ifdef RG_UNUSED
2583    rgSchCmnApis.rgSCHUpdUlHqProc      = rgSCHCmnUpdUlHqProc;
2584 #endif
2585    rgSchCmnApis.rgSCHUpdBsrShort      = rgSCHCmnUpdBsrShort;
2586    rgSchCmnApis.rgSCHUpdBsrTrunc      = rgSCHCmnUpdBsrTrunc;
2587    rgSchCmnApis.rgSCHUpdBsrLong       = rgSCHCmnUpdBsrLong;
2588    rgSchCmnApis.rgSCHUpdPhr           = rgSCHCmnUpdPhr;
2589    rgSchCmnApis.rgSCHUpdExtPhr        = rgSCHCmnUpdExtPhr;
2590    rgSchCmnApis.rgSCHContResUlGrant   = rgSCHCmnContResUlGrant;
2591    rgSchCmnApis.rgSCHSrRcvd           = rgSCHCmnSrRcvd;
2592    rgSchCmnApis.rgSCHFirstRcptnReq    = rgSCHCmnFirstRcptnReq;
2593    rgSchCmnApis.rgSCHNextRcptnReq     = rgSCHCmnNextRcptnReq;
2594    rgSchCmnApis.rgSCHFirstHqFdbkAlloc = rgSCHCmnFirstHqFdbkAlloc;
2595    rgSchCmnApis.rgSCHNextHqFdbkAlloc  = rgSCHCmnNextHqFdbkAlloc;
2596    rgSchCmnApis.rgSCHDlProcAddToRetx  = rgSCHCmnDlProcAddToRetx;
2597    rgSchCmnApis.rgSCHDlCqiInd         = rgSCHCmnDlCqiInd;
2598 #ifdef EMTC_ENABLE
2599    rgSchCmnApis.rgSCHUlProcAddToRetx  = rgSCHCmnEmtcUlProcAddToRetx;
2600 #endif
2601 #ifdef TFU_UPGRADE
2602    rgSchCmnApis.rgSCHSrsInd           = rgSCHCmnSrsInd;
2603 #endif
2604    rgSchCmnApis.rgSCHDlTARpt          = rgSCHCmnDlTARpt;
2605    rgSchCmnApis.rgSCHDlRlsSubFrm      = rgSCHCmnDlRlsSubFrm;
2606    rgSchCmnApis.rgSCHUeReset          = rgSCHCmnUeReset;
2607 #ifdef LTEMAC_SPS
2608    rgSchCmnApis.rgSCHHdlCrntiCE         = rgSCHCmnHdlCrntiCE;
2609    rgSchCmnApis.rgSCHDlProcAck        = rgSCHCmnDlProcAck;
2610    rgSchCmnApis.rgSCHDlRelPdcchFbk    = rgSCHCmnDlRelPdcchFbk;
2611    rgSchCmnApis.rgSCHUlSpsRelInd      = rgSCHCmnUlSpsRelInd;
2612    rgSchCmnApis.rgSCHUlSpsActInd      = rgSCHCmnUlSpsActInd;
2613    rgSchCmnApis.rgSCHUlCrcFailInd     = rgSCHCmnUlCrcFailInd;
2614    rgSchCmnApis.rgSCHUlCrcInd     = rgSCHCmnUlCrcInd;
2615 #endif
2616    rgSchCmnApis.rgSCHDrxStrtInActvTmrInUl = rgSCHCmnDrxStrtInActvTmrInUl;
2617    rgSchCmnApis.rgSCHUpdUeDataIndLcg      = rgSCHCmnUpdUeDataIndLcg;
2618
2619    for (idx = 0; idx < RGSCH_NUM_SCHEDULERS; ++idx)
2620    {
2621       rgSchUlSchdInits[idx](&rgSchUlSchdTbl[idx]);
2622       rgSchDlSchdInits[idx](&rgSchDlSchdTbl[idx]);
2623    }
2624 #ifdef EMTC_ENABLE 
2625    for (idx = 0; idx < RGSCH_NUM_EMTC_SCHEDULERS; ++idx)
2626    {
2627       rgSchEmtcUlSchdInits[idx](&rgSchEmtcUlSchdTbl[idx]);
2628       rgSchEmtcDlSchdInits[idx](&rgSchEmtcDlSchdTbl[idx]);
2629    }
2630 #endif
2631 #if (defined (RG_PHASE2_SCHED) && defined(TFU_UPGRADE))
2632    for (idx = 0; idx < RGSCH_NUM_DLFS_SCHEDULERS; ++idx)
2633    {
2634       rgSchDlfsSchdInits[idx](&rgSchDlfsSchdTbl[idx]);
2635    }
2636 #endif
2637 #ifdef LTE_ADV
2638    rgSchCmnApis.rgSCHRgrSCellUeCfg         = rgSCHCmnRgrSCellUeCfg;
2639    rgSchCmnApis.rgSCHRgrSCellUeDel         = rgSCHCmnRgrSCellUeDel;
2640 #endif
2641    return;
2642 }
2643
2644 \f
2645 /**
2646  * @brief This function is a wrapper to call scheduler specific API.
2647  *
2648  * @details
2649  *
2650  *     Function: rgSCHCmnDlRlsSubFrm
2651  *     Purpose:  Releases scheduler Information from DL SubFrm.
2652  *
2653  *     Invoked by: DHM
2654  *
2655  *  @param[in]   RgSchCellCb     *cell
2656  *  @param[out]  CmLteTimingInfo frm
2657  *  @return  Void
2658  *
2659  **/
2660 Void rgSCHCmnDlRlsSubFrm(RgSchCellCb *cell,CmLteTimingInfo frm)
2661 {
2662    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2663    RgSchDlSf     *sf;
2664
2665
2666    /* Get the pointer to the subframe */
2667    sf = rgSCHUtlSubFrmGet(cell, frm);
2668
2669    rgSCHUtlSubFrmPut(cell, sf);
2670    if (sf->dlfsSf)
2671    {
2672       /* Re-initialize DLFS specific information for the sub-frame */
2673       cellSch->apisDlfs->rgSCHDlfsReinitSf(cell, sf);
2674    }
2675    return;
2676 }
2677
2678
2679 \f
2680 /**
2681  * @brief This function is the starting function for DL allocation.
2682  *
2683  * @details
2684  *
2685  *     Function: rgSCHCmnDlCmnChAlloc
2686  *     Purpose:  Scheduling for downlink. It performs allocation in the order
2687  *               of priority wich BCCH/PCH first, CCCH, Random Access and TA.
2688  *
2689  *     Invoked by: Scheduler
2690  *
2691  *  @param[in]  RgSchCellCb*           cell
2692  *  @param[out] RgSchCmnDlRbAllocInfo* allocInfo
2693  *  @return  Void
2694  *
2695  **/
2696 static Void rgSCHCmnDlCcchRarAlloc(RgSchCellCb *cell)
2697 {
2698    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2699
2700
2701    rgSCHCmnDlCcchRetx(cell, &cellSch->allocInfo);
2702    /* LTE_ADV_FLAG_REMOVED_START */
2703    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2704    {
2705       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2706       {
2707          /*eNodeB need to blank the subframe */
2708       }
2709       else
2710       {
2711          rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2712       }
2713    }
2714    else
2715    {
2716       rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2717    }
2718    /* LTE_ADV_FLAG_REMOVED_END */
2719
2720 #ifdef RGR_V1
2721
2722    /*Added these function calls for processing CCCH SDU arriving
2723     * after guard timer expiry.Functions differ from above two functions
2724     * in using ueCb instead of raCb.*/
2725    rgSCHCmnDlCcchSduRetx(cell, &cellSch->allocInfo);
2726    /* LTE_ADV_FLAG_REMOVED_START */
2727    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2728    {
2729       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2730       {
2731          /*eNodeB need to blank the subframe */
2732       }
2733       else
2734       {
2735          rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2736       }
2737    }
2738    else
2739    {
2740       rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2741    }
2742    /* LTE_ADV_FLAG_REMOVED_END */
2743 #endif
2744
2745 #ifdef LTE_TDD
2746    if(cellSch->ul.msg3SchdIdx != RGSCH_INVALID_INFO)
2747    {
2748       /* Do not schedule msg3 if there is a CFI change ongoing */
2749       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2750       {
2751          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2752       }
2753    }
2754 #else
2755    /* LTE_ADV_FLAG_REMOVED_START */
2756    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2757    {
2758       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2759       {
2760          /*eNodeB need to blank the subframe */
2761       }
2762       else
2763       {
2764          /* Do not schedule msg3 if there is a CFI change ongoing */
2765          if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2766          {
2767             rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2768          }
2769       }
2770    }
2771    else
2772    {
2773       /* Do not schedule msg3 if there is a CFI change ongoing */
2774       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2775       {
2776          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2777       }
2778    }
2779    /* LTE_ADV_FLAG_REMOVED_END */
2780 #endif
2781
2782    return;
2783 }
2784
2785 #ifdef RGR_V1
2786 /**
2787  * @brief Scheduling for CCCH SDU.
2788  *
2789  * @details
2790  *
2791  *     Function: rgSCHCmnCcchSduAlloc
2792  *     Purpose:  Scheduling for CCCH SDU
2793  *
2794  *     Invoked by: Scheduler
2795  *
2796  *  @param[in]  RgSchCellCb*          cell
2797  *  @param[in]  RgSchUeCb*            ueCb
2798  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2799  *  @return  S16
2800  *
2801  **/
2802 static S16 rgSCHCmnCcchSduAlloc(RgSchCellCb *cell,RgSchUeCb *ueCb,RgSchCmnDlRbAllocInfo *allocInfo)
2803 {
2804    RgSchDlRbAlloc  *rbAllocInfo;
2805    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
2806    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2807
2808
2809    /* Return if subframe BW exhausted */
2810    if (allocInfo->ccchSduAlloc.ccchSduDlSf->bw <=
2811        allocInfo->ccchSduAlloc.ccchSduDlSf->bwAssigned)
2812    {
2813       DU_LOG("\nERROR  -->  SCH : bw<=bwAssigned for UEID:%d",ueCb->ueId);
2814       return RFAILED;
2815    }
2816
2817    if (rgSCHDhmGetCcchSduHqProc(ueCb, cellSch->dl.time, &(ueDl->proc)) != ROK)
2818    {
2819       DU_LOG("\nERROR  -->  SCH : rgSCHDhmGetCcchSduHqProc failed UEID:%d",ueCb->ueId);
2820       return RFAILED;
2821    }
2822
2823    rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
2824    rbAllocInfo->dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2825
2826    if (rgSCHCmnCcchSduDedAlloc(cell, ueCb) != ROK)
2827    {
2828       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
2829       rgSCHDhmRlsHqpTb(ueDl->proc, 0, FALSE);
2830       DU_LOG("\nERROR  -->  SCH : rgSCHCmnCcchSduDedAlloc failed UEID:%d",ueCb->ueId);
2831       return RFAILED;
2832    }
2833    cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduTxLst, &ueDl->proc->reqLnk);
2834    ueDl->proc->reqLnk.node = (PTR)ueDl->proc;
2835    allocInfo->ccchSduAlloc.ccchSduDlSf->schdCcchUe++;
2836
2837    return ROK;
2838 }
2839 /**
2840  * @brief This function scheduler for downlink CCCH messages.
2841  *
2842  * @details
2843  *
2844  *     Function: rgSCHCmnDlCcchSduTx
2845  *     Purpose:  Scheduling for downlink CCCH
2846  *
2847  *     Invoked by: Scheduler
2848  *
2849  *  @param[in]  RgSchCellCb           *cell
2850  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2851  *  @return  Void
2852  *
2853  **/
2854 static Void rgSCHCmnDlCcchSduTx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2855 {
2856    CmLList      *node;
2857    RgSchUeCb    *ueCb;
2858    RgSchCmnDlUe *ueCmnDl;
2859    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2860    RgSchDlSf    *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2861    
2862
2863    node = cell->ccchSduUeLst.first;
2864    while(node)
2865    {
2866       if(cellSch->dl.maxCcchPerDlSf &&
2867             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2868       {
2869          break;
2870       }
2871       else
2872       {
2873          ueCb = (RgSchUeCb *)(node->node);
2874          ueCmnDl  = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2875          node = node->next;
2876          /* Fix : syed postpone scheduling for this
2877           * until msg4 is done */
2878          /* Fix : syed RLC can erroneously send CCCH SDU BO 
2879           * twice. Hence an extra guard to avoid if already 
2880           * scheduled for RETX */
2881          if ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
2882                (!ueCmnDl->proc))
2883          {
2884             if ((rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)) != ROK)
2885             {
2886                break;
2887             }
2888          }
2889          else
2890          {
2891             DU_LOG("\nERROR  -->  SCH :  THIS SHOULD "
2892                      "NEVER HAPPEN for UEID:%d", ueCb->ueId);
2893             continue;
2894          }
2895       }
2896    }
2897    return;
2898 }
2899 #endif
2900 \f
2901 /**
2902  * @brief This function scheduler for downlink CCCH messages.
2903  *
2904  * @details
2905  *
2906  *     Function: rgSCHCmnDlCcchTx
2907  *     Purpose:  Scheduling for downlink CCCH
2908  *
2909  *     Invoked by: Scheduler
2910  *
2911  *  @param[in]  RgSchCellCb           *cell
2912  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2913  *  @return  Void
2914  *
2915  **/
2916 static Void rgSCHCmnDlCcchTx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2917 {
2918    CmLList       *node;
2919    RgSchRaCb     *raCb;
2920    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2921    RgSchDlSf     *dlSf = allocInfo->msg4Alloc.msg4DlSf;
2922
2923    node = cell->raInfo.toBeSchdLst.first;
2924    while(node)
2925    {
2926       if(cellSch->dl.maxCcchPerDlSf &&
2927             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2928       {
2929          break;
2930       }
2931       else
2932       {
2933
2934          raCb = (RgSchRaCb *)(node->node);
2935          node = node->next;
2936          /* Address allocation for this UE for MSG 4 */
2937          /* Allocation for Msg4 */
2938          if ((rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)) != ROK)
2939          {
2940             break;
2941          }
2942       }
2943    }
2944    return;
2945 }
2946
2947 #ifdef RGR_V1
2948 /**
2949  * @brief This function scheduler for downlink CCCH messages.
2950  *
2951  * @details
2952  *
2953  *     Function: rgSCHCmnDlCcchSduRetx
2954  *     Purpose:  Scheduling for downlink CCCH
2955  *
2956  *     Invoked by: Scheduler
2957  *
2958  *  @param[in]  RgSchCellCb           *cell
2959  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2960  *  @return  Void
2961  *
2962  **/
2963 static Void rgSCHCmnDlCcchSduRetx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2964 {
2965    RgSchDlRbAlloc  *rbAllocInfo;
2966    CmLList         *node;
2967    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
2968    RgSchUeCb       *ueCb;
2969    RgSchDlHqProcCb *hqP;
2970    uint8_t         retxBw = 0;
2971    RgSchCmnDlUe    *ueDl;
2972    RgSchDlSf       *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2973    
2974
2975    node = cellSch->dl.ccchSduRetxLst.first;
2976    while(node)
2977    {
2978       if(cellSch->dl.maxCcchPerDlSf &&
2979             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2980       {
2981          break;
2982       }
2983       else
2984       {
2985
2986          hqP = (RgSchDlHqProcCb *)(node->node);
2987          node = node->next;
2988
2989          /* DwPts Scheduling Changes Start */      
2990 #ifdef LTE_TDD
2991          if (rgSCHCmnRetxAvoidTdd(allocInfo->ccchSduAlloc.ccchSduDlSf, 
2992                   cell, hqP) == TRUE)
2993          {
2994             continue;  
2995          }
2996 #endif
2997          /* DwPts Scheduling Changes End */     
2998
2999          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3000          {
3001             break;
3002          }
3003          ueCb = (RgSchUeCb*)(hqP->hqE->ue);
3004          ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
3005
3006          rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3007          /* Fill RB Alloc Info */
3008          rbAllocInfo->dlSf = dlSf;
3009          rbAllocInfo->tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3010          rbAllocInfo->rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3011          /* Fix : syed iMcs setting did not correspond to RETX */
3012          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3013                rbAllocInfo->tbInfo[0].imcs);
3014          rbAllocInfo->rnti = ueCb->ueId;
3015          rbAllocInfo->tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3016          /* Fix : syed Copying info in entirety without depending on stale TX information */
3017          rbAllocInfo->tbInfo[0].tbCb = &hqP->tbInfo[0];
3018          rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
3019          /* Fix : syed Assigning proc to scratchpad */ 
3020          ueDl->proc = hqP;
3021
3022          retxBw += rbAllocInfo->rbsReq;
3023
3024          cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduRetxLst, \
3025                &hqP->reqLnk);
3026          hqP->reqLnk.node = (PTR)hqP;
3027          dlSf->schdCcchUe++;
3028       }
3029    }
3030    dlSf->bwAssigned += retxBw;
3031    return;
3032 }
3033 #endif
3034 \f
3035 /**
3036  * @brief This function scheduler for downlink CCCH messages.
3037  *
3038  * @details
3039  *
3040  *     Function: rgSCHCmnDlCcchRetx
3041  *     Purpose:  Scheduling for downlink CCCH
3042  *
3043  *     Invoked by: Scheduler
3044  *
3045  *  @param[in]  RgSchCellCb           *cell
3046  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3047  *  @return  Void
3048  *
3049  **/
3050 static Void rgSCHCmnDlCcchRetx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
3051 {
3052    CmLList           *node;
3053    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3054    RgSchRaCb         *raCb;
3055    RgSchDlHqProcCb   *hqP;
3056    uint8_t           retxBw = 0;
3057    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3058         
3059
3060    node = cellSch->dl.msg4RetxLst.first;
3061    while(node)
3062    {
3063       if(cellSch->dl.maxCcchPerDlSf &&
3064             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3065       {
3066          break;
3067       }
3068       else
3069       {
3070          hqP = (RgSchDlHqProcCb *)(node->node);
3071
3072          node = node->next;
3073
3074          /* DwPts Scheduling Changes Start */     
3075 #ifdef LTE_TDD      
3076          if (rgSCHCmnRetxAvoidTdd(allocInfo->msg4Alloc.msg4DlSf, 
3077                   cell, hqP) == TRUE)
3078          {
3079             continue;  
3080          }
3081 #endif      
3082          /* DwPts Scheduling Changes End */      
3083
3084          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3085          {
3086             break;
3087          }
3088          raCb = (RgSchRaCb*)(hqP->hqE->raCb);
3089          /* Fill RB Alloc Info */
3090          raCb->rbAllocInfo.dlSf = dlSf;
3091          raCb->rbAllocInfo.tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3092          raCb->rbAllocInfo.rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3093          /* Fix : syed iMcs setting did not correspond to RETX */
3094          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3095                raCb->rbAllocInfo.tbInfo[0].imcs);
3096          raCb->rbAllocInfo.rnti = raCb->tmpCrnti;
3097          raCb->rbAllocInfo.tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3098          /* Fix; syed Copying info in entirety without depending on stale TX information */
3099          raCb->rbAllocInfo.tbInfo[0].tbCb = &hqP->tbInfo[0];
3100          raCb->rbAllocInfo.tbInfo[0].schdlngForTb = TRUE;
3101
3102          retxBw += raCb->rbAllocInfo.rbsReq;
3103
3104          cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4RetxLst, \
3105                &hqP->reqLnk);
3106          hqP->reqLnk.node = (PTR)hqP;
3107          dlSf->schdCcchUe++;
3108       }
3109    }
3110    dlSf->bwAssigned += retxBw;
3111    return;
3112 }
3113
3114 \f
3115 /**
3116  * @brief This function implements scheduler DL allocation for
3117  *        for broadcast (on PDSCH) and paging.
3118  *
3119  * @details
3120  *
3121  *     Function: rgSCHCmnDlBcchPcch
3122  *     Purpose:  This function implements scheduler for DL allocation
3123  *               for broadcast (on PDSCH) and paging.
3124  *
3125  *     Invoked by: Scheduler
3126  *
3127  *  @param[in]  RgSchCellCb*     cell
3128  *  @return  S16
3129  *      -# ROK
3130  *      -# RFAILED
3131  **/
3132 static Void rgSCHCmnDlBcchPcch(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo,RgInfSfAlloc *subfrmAlloc)
3133 {
3134    CmLteTimingInfo   frm;
3135    RgSchDlSf         *sf;
3136    RgSchClcDlLcCb    *pcch;
3137    RgSchClcBoRpt     *bo;
3138 #ifndef RGR_SI_SCH
3139    Bool              valid;
3140    RgSchClcDlLcCb    *bcch, *bch;
3141 #endif/*RGR_SI_SCH*/
3142
3143
3144    frm   = cell->crntTime;
3145 #ifdef LTEMAC_HDFDD
3146    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
3147       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
3148    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
3149 #else
3150   // RGSCH_SUBFRAME_INDEX(frm);
3151    //RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
3152 #endif
3153
3154    /* Compute the subframe for which allocation is being made        */
3155    /* essentially, we need pointer to the dl frame for this subframe */
3156    sf = rgSCHUtlSubFrmGet(cell, frm);
3157
3158
3159 #ifndef RGR_SI_SCH
3160    bch = rgSCHDbmGetBcchOnBch(cell);
3161 #if (ERRCLASS & ERRCLS_DEBUG)
3162    if (bch == NULLP)
3163    {
3164       DU_LOG("\nERROR  -->  SCH : BCCH on BCH is not configured");
3165       return;
3166    }
3167 #endif
3168    if (bch->boLst.first != NULLP)
3169    {
3170       bo = (RgSchClcBoRpt *)(bch->boLst.first->node);
3171       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3172       {
3173          sf->bch.tbSize = bo->bo;
3174          cmLListDelFrm(&bch->boLst, bch->boLst.first);
3175          /* ccpu00117052 - MOD - Passing double pointer
3176             for proper NULLP assignment*/
3177          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(*bo));
3178          rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, bch->lcId,TRUE);
3179       }
3180    }
3181    else
3182    {
3183       if ((frm.sfn % 4 == 0) && (frm.subframe == 0))
3184       {
3185       }
3186    }
3187
3188    allocInfo->bcchAlloc.schdFirst = FALSE;
3189    bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
3190 #if (ERRCLASS & ERRCLS_DEBUG)
3191    if (bcch == NULLP)
3192    {
3193       DU_LOG("\nERROR  -->  SCH : BCCH on DLSCH is not configured");
3194       return;
3195    }
3196 #endif
3197    if (bcch->boLst.first != NULLP)
3198    {
3199       bo = (RgSchClcBoRpt *)(bcch->boLst.first->node);
3200
3201       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3202       {
3203          allocInfo->bcchAlloc.schdFirst = TRUE;
3204          /* Time to perform allocation for this BCCH transmission */
3205          rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3206       }
3207    }
3208
3209    if(!allocInfo->bcchAlloc.schdFirst)
3210    {
3211       CmLList   *lnk;
3212       bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
3213 #if (ERRCLASS & ERRCLS_DEBUG)
3214       if (bcch == NULLP)
3215       {
3216          DU_LOG("\nERROR  -->  SCH : BCCH on DLSCH is not configured");
3217          return;
3218       }
3219 #endif
3220       lnk = bcch->boLst.first;
3221       while (lnk != NULLP)
3222       {
3223          bo = (RgSchClcBoRpt *)(lnk->node);
3224          lnk = lnk->next;
3225          valid = rgSCHCmnChkInWin(frm, bo->timeToTx, bo->maxTimeToTx);
3226
3227          if(valid)
3228          {
3229             bo->i = RGSCH_CALC_SF_DIFF(frm, bo->timeToTx);
3230             /* Time to perform allocation for this BCCH transmission */
3231             rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3232             break;
3233          }
3234          else
3235          {
3236             valid = rgSCHCmnChkPastWin(frm, bo->maxTimeToTx);
3237             if(valid)
3238             {
3239                cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
3240                /* ccpu00117052 - MOD - Passing double pointer
3241                   for proper NULLP assignment*/
3242                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo,
3243                      sizeof(RgSchClcBoRpt));
3244             }
3245          }
3246       }
3247    }
3248 #else
3249    rgSCHDlSiSched(cell, allocInfo, subfrmAlloc);
3250 #endif/*RGR_SI_SCH*/
3251
3252    pcch = rgSCHDbmGetPcch(cell);
3253 #ifdef ERRCLS_KW
3254    if (pcch == NULLP)
3255    {
3256       DU_LOG("\nERROR  -->  SCH : PCCH on DLSCH is not configured");
3257       return;
3258    }
3259 #endif
3260    if (pcch->boLst.first != NULLP)
3261    {
3262       bo = (RgSchClcBoRpt *)(pcch->boLst.first->node);
3263
3264       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3265       {
3266          /* Time to perform allocation for this PCCH transmission */
3267          rgSCHCmnClcAlloc(cell, sf, pcch, RGSCH_P_RNTI, allocInfo);
3268       }
3269    }
3270    return;
3271 }
3272
3273 /*
3274 *
3275 *       Fun:   rgSCHCmnChkInWin
3276 *
3277 *       Desc:  This function checks if frm occurs in window
3278 *
3279 *       Ret:   TRUE      - if in window
3280 *              FALSE     - otherwise
3281 *
3282 *       Notes: None
3283 *
3284 *       File:  rg_sch_cmn.c
3285 *
3286 */
3287 Bool rgSCHCmnChkInWin(CmLteTimingInfo frm,CmLteTimingInfo start,CmLteTimingInfo end)
3288 {
3289    Bool    inWin = FALSE;
3290
3291
3292    if (end.sfn > start.sfn)
3293    {
3294       if (frm.sfn > start.sfn
3295             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3296       {
3297          if (frm.sfn < end.sfn
3298 #ifdef EMTC_ENABLE
3299                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3300 #else
3301                || (frm.sfn == end.sfn && frm.slot <= start.slot))
3302 #endif
3303          {
3304             inWin = TRUE;
3305          }
3306       }
3307    }
3308    /* Testing for wrap around, sfn wraparound check should be enough */
3309    else if (end.sfn < start.sfn)
3310    {
3311       if (frm.sfn > start.sfn
3312             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3313       {
3314          inWin = TRUE;
3315       }
3316       else
3317       {
3318          if (frm.sfn < end.sfn
3319                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3320          {
3321             inWin = TRUE;
3322          }
3323       }
3324    }
3325    else  /* start.sfn == end.sfn */
3326    {
3327       if (frm.sfn == start.sfn
3328             && (frm.slot >= start.slot
3329                && frm.slot <= end.slot))
3330       {
3331          inWin = TRUE;
3332       }
3333    }
3334
3335    return (inWin);
3336 } /* end of rgSCHCmnChkInWin*/
3337
3338 /*
3339 *
3340 *       Fun:   rgSCHCmnChkPastWin
3341 *
3342 *       Desc:  This function checks if frm has gone past window edge
3343 *
3344 *       Ret:   TRUE      - if past window edge
3345 *              FALSE     - otherwise
3346 *
3347 *       Notes: None
3348 *
3349 *       File:  rg_sch_cmn.c
3350 *
3351 */
3352 Bool rgSCHCmnChkPastWin(CmLteTimingInfo frm,CmLteTimingInfo end)
3353 {
3354    CmLteTimingInfo  refFrm = end;
3355    Bool             pastWin;
3356
3357
3358    RGSCH_INCR_FRAME(refFrm.sfn);
3359    RGSCH_INCR_SUB_FRAME(end, 1);
3360    pastWin = rgSCHCmnChkInWin(frm, end, refFrm);
3361
3362    return (pastWin);
3363 } /* end of rgSCHCmnChkPastWin*/
3364 \f
3365 /**
3366  * @brief This function implements allocation of the resources for common
3367  * channels BCCH, PCCH.
3368  *
3369  * @details
3370  *
3371  *     Function: rgSCHCmnClcAlloc
3372  *     Purpose:  This function implements selection of number of RBs based
3373  *               the allowed grant for the service. It is also responsible
3374  *               for selection of MCS for the transmission.
3375  *
3376  *     Invoked by: Scheduler
3377  *
3378  *  @param[in]  RgSchCellCb                *cell,
3379  *  @param[in]  RgSchDlSf                  *sf,
3380  *  @param[in]  RgSchClcDlLcCb             *lch,
3381  *  @param[in]  uint16_t                        rnti,
3382  *  @param[out] RgSchCmnDlRbAllocInfo      *allocInfo
3383  *  @return     Void
3384  *
3385  **/
3386 static Void rgSCHCmnClcAlloc(RgSchCellCb *cell,RgSchDlSf *sf,RgSchClcDlLcCb  *lch,uint16_t rnti,RgSchCmnDlRbAllocInfo *allocInfo)
3387 {
3388    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3389    RgSchClcBoRpt        *bo;
3390    uint32_t                  rb=0;
3391    uint8_t                   mcs;
3392    uint32_t                  tbs;
3393 #ifdef LTE_TDD   
3394    uint8_t                   lostRe;
3395    uint8_t                   cfi = cellDl->currCfi;  
3396 #endif
3397
3398
3399    bo = (RgSchClcBoRpt *)(lch->boLst.first->node);
3400
3401    mcs = bo->mcs;
3402    tbs = bo->bo;
3403    /* rgSCHCmnClcRbAllocForFxdTb(cell, bo->bo, cellDl->ccchCqi, &rb);*/
3404    if(cellDl->bitsPerRb==0)
3405    {
3406       while ((rgTbSzTbl[0][0][rb]) < (tbs*8))
3407       {
3408          rb++;
3409       }
3410       rb = rb+1;
3411    }
3412    else
3413    {
3414       rb = RGSCH_CEIL((tbs*8), cellDl->bitsPerRb);
3415    }
3416    /* DwPTS Scheduling Changes Start */   
3417 #ifdef LTE_TDD
3418    if(sf->sfType == RG_SCH_SPL_SF_DATA) 
3419    {
3420       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
3421
3422       /* Calculate the less RE's because of DwPTS */
3423       lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
3424
3425       /* Increase number of RBs in Spl SF to compensate for lost REs */
3426       rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
3427    }
3428 #endif
3429    /* DwPTS Scheduling Changes End */   
3430    /*ccpu00115595- end*/
3431    /* additional check to see if required RBs
3432     * exceeds the available */
3433    if (rb > sf->bw - sf->bwAssigned)
3434    {
3435       DU_LOG("\nERROR  -->  SCH : BW allocation "
3436                 "failed for CRNTI:%d",rnti);
3437       return;
3438    }
3439
3440    /* Update the subframe Allocated BW field */
3441    sf->bwAssigned = sf->bwAssigned + rb;
3442    /* Fill in the BCCH/PCCH transmission info to the RBAllocInfo struct */
3443    if (rnti == RGSCH_SI_RNTI)
3444    {
3445       allocInfo->bcchAlloc.rnti = rnti;
3446       allocInfo->bcchAlloc.dlSf = sf;
3447       allocInfo->bcchAlloc.tbInfo[0].bytesReq = tbs;
3448       allocInfo->bcchAlloc.rbsReq = rb;
3449       allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
3450       allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
3451       /* Nprb indication at PHY for common Ch */
3452       allocInfo->bcchAlloc.nPrb = bo->nPrb;
3453    }
3454    else
3455    {
3456       allocInfo->pcchAlloc.rnti = rnti;
3457       allocInfo->pcchAlloc.dlSf = sf;
3458       allocInfo->pcchAlloc.tbInfo[0].bytesReq = tbs;
3459       allocInfo->pcchAlloc.rbsReq = rb;
3460       allocInfo->pcchAlloc.tbInfo[0].imcs = mcs;
3461       allocInfo->pcchAlloc.tbInfo[0].noLyr = 1;
3462       allocInfo->pcchAlloc.nPrb = bo->nPrb;
3463    }
3464    return;
3465 }
3466
3467 \f
3468 /**
3469  * @brief This function implements PDCCH allocation for common channels.
3470  *
3471  * @details
3472  *
3473  *     Function: rgSCHCmnCmnPdcchAlloc
3474  *     Purpose:  This function implements allocation of PDCCH for a UE.
3475  *               1. This uses index 0 of PDCCH table for efficiency.
3476  *               2. Uses he candidate PDCCH count for the aggr level.
3477  *               3. Look for availability for each candidate and choose
3478  *                  the first one available.
3479  *
3480  *     Invoked by: Scheduler
3481  *
3482  *  @param[in]  RgSchCellCb           *cell
3483  *  @param[in]  RgSchDlSf             *sf
3484  *  @return     RgSchPdcch *
3485  *               -# NULLP when unsuccessful
3486  *
3487  **/
3488 RgSchPdcch *rgSCHCmnCmnPdcchAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm)
3489 {
3490    CmLteAggrLvl         aggrLvl;
3491    RgSchPdcchInfo       *pdcchInfo;
3492    RgSchPdcch           *pdcch;
3493    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
3494    uint8_t              numCce;  /*store num CCEs based on 
3495                                   aggregation level */
3496
3497    aggrLvl   = cellSch->dl.cmnChAggrLvl;
3498
3499    pdcchInfo = &(subFrm->pdcchInfo);
3500
3501     /* Updating the no. of nCce in pdcchInfo, in case if CFI
3502     * was changed  */
3503 #ifdef LTE_TDD
3504    if(subFrm->nCce != pdcchInfo->nCce)
3505    {   
3506       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3507    }
3508 #else   
3509    if(cell->nCce != pdcchInfo->nCce)
3510    {
3511       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3512    }
3513 #endif  
3514
3515    switch (aggrLvl)
3516    {
3517       case CM_LTE_AGGR_LVL4:
3518         numCce = 4;
3519         break;
3520       case CM_LTE_AGGR_LVL8:
3521         numCce = 8;
3522         break;
3523                 case CM_LTE_AGGR_LVL16:
3524         numCce = 16;
3525         break;
3526       default:
3527         return (NULLP);
3528    }
3529
3530    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3531    {
3532 #ifdef LTEMAC_SPS
3533       pdcch->isSpsRnti = FALSE;
3534 #endif
3535       /* Increment the CCE used counter in the current subframe */
3536       subFrm->cceCnt += numCce;
3537       pdcch->pdcchSearchSpace = RG_SCH_CMN_SEARCH_SPACE;
3538
3539       return (pdcch);
3540    }
3541
3542    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3543    subFrm->isCceFailure = TRUE;
3544    DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN COMMON SEARCH SPACE aggr:%u", 
3545             aggrLvl);
3546    return (NULLP);
3547 }
3548
3549 \f
3550 /**
3551  * @brief This function implements bandwidth allocation for common channels.
3552  *
3553  * @details
3554  *
3555  *     Function: rgSCHCmnClcRbAlloc
3556  *     Purpose:  This function implements bandwith allocation logic
3557  *               for common control channels.
3558  *
3559  *     Invoked by: Scheduler
3560  *
3561  *  @param[in]  RgSchCellCb*  cell
3562  *  @param[in]  uint32_t           bo
3563  *  @param[in]  uint8_t            cqi
3564  *  @param[in]  uint8_t            *rb
3565  *  @param[in]  uint32_t           *tbs
3566  *  @param[in]  uint8_t            *mcs
3567  *  @param[in]  RgSchDlSf     *sf
3568  *  @return  Void
3569  *
3570  **/
3571 #ifdef LTEMAC_SPS
3572 Void rgSCHCmnClcRbAlloc
3573 (
3574 RgSchCellCb  *cell,
3575 uint32_t     bo,
3576 uint8_t      cqi,
3577 uint8_t      *rb,
3578 uint32_t     *tbs,
3579 uint8_t      *mcs,
3580 uint8_t      *iTbs,
3581 Bool         isSpsBo,
3582 RgSchDlSf    *sf 
3583 )
3584 #else
3585 static Void rgSCHCmnClcRbAlloc
3586 (
3587 RgSchCellCb  *cell,
3588 uint32_t     bo,
3589 uint8_t      cqi,
3590 uint8_t      *rb,
3591 uint32_t     *tbs,
3592 uint8_t      *mcs,
3593 RgSchDlSf    *sf 
3594 )
3595 #endif /* LTEMAC_SPS */
3596 {
3597    uint8_t          iTbsVal;
3598    RgSchCmnTbSzEff  *effTbl;
3599    uint32_t         eff;
3600    uint32_t         noRes;
3601    RgSchCmnCell     *cellSch = RG_SCH_CMN_GET_CELL(cell);
3602    uint8_t          cfi = cellSch->dl.currCfi;
3603    uint32_t         tmpRb=0;
3604
3605    /* first get the CQI to MCS table and determine the number of RBs */
3606    effTbl = (RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]);
3607    iTbsVal = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[cqi];
3608    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3609
3610    /* Efficiency is number of bits per 1024 REs */
3611    eff  = (*effTbl)[iTbsVal];
3612
3613    /* Get the number of REs needed for this bo  */
3614    noRes = ((bo * 8 * 1024) / eff );
3615
3616    /* Get the number of RBs needed for this transmission */
3617    /* Number of RBs = No of REs / No of REs per RB       */
3618    tmpRb = RGSCH_CEIL(noRes, cellSch->dl.noResPerRb[cfi]);
3619    /* KWORK_FIX: added check to see if rb has crossed maxRb*/
3620    RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3621    if (tmpRb > cellSch->dl.maxDlBwPerUe)
3622    {
3623       tmpRb = cellSch->dl.maxDlBwPerUe;
3624    }
3625    while ((rgTbSzTbl[0][iTbsVal][tmpRb-1]/8) < bo && 
3626            (tmpRb < cellSch->dl.maxDlBwPerUe))
3627    {
3628       tmpRb++;
3629       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3630    }
3631    *tbs =  rgTbSzTbl[0][iTbsVal][tmpRb-1]/8;
3632    *rb = (uint8_t)tmpRb;
3633    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3634
3635    return;
3636 }
3637
3638 \f
3639
3640 /**
3641  * @brief Scheduling for MSG4.
3642  *
3643  * @details
3644  *
3645  *     Function: rgSCHCmnMsg4Alloc
3646  *     Purpose:  Scheduling for MSG4
3647  *
3648  *     Invoked by: Scheduler
3649  *
3650  *  @param[in]  RgSchCellCb*          cell
3651  *  @param[in]  RgSchRaCb*            raCb
3652  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3653  *  @return  S16
3654  *
3655  **/
3656 static S16 rgSCHCmnMsg4Alloc(RgSchCellCb *cell,RgSchRaCb *raCb,RgSchCmnDlRbAllocInfo *allocInfo)
3657 {
3658    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
3659
3660
3661    /* SR_RACH_STATS : MSG4 TO BE TXED */
3662    rgNumMsg4ToBeTx++;
3663    /* Return if subframe BW exhausted */
3664    if (allocInfo->msg4Alloc.msg4DlSf->bw <=
3665        allocInfo->msg4Alloc.msg4DlSf->bwAssigned)
3666    {
3667       DU_LOG("\nERROR  -->  SCH : bw<=bwAssigned");
3668       return RFAILED;
3669    }
3670
3671    if (rgSCHDhmGetMsg4HqProc(raCb, cellSch->dl.time) != ROK)
3672    {
3673       DU_LOG("\nERROR  -->  SCH : rgSCHDhmGetMsg4HqProc failed");
3674       return RFAILED;
3675    }
3676
3677    raCb->rbAllocInfo.dlSf = allocInfo->msg4Alloc.msg4DlSf;
3678
3679    if (rgSCHCmnMsg4DedAlloc(cell, raCb) != ROK)
3680    {
3681       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
3682       rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, FALSE);
3683       DU_LOG("\nERROR  -->  SCH : rgSCHCmnMsg4DedAlloc failed.");
3684       return RFAILED;
3685    }
3686    cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4TxLst, &raCb->dlHqE->msg4Proc->reqLnk);
3687    raCb->dlHqE->msg4Proc->reqLnk.node = (PTR)raCb->dlHqE->msg4Proc;
3688    allocInfo->msg4Alloc.msg4DlSf->schdCcchUe++;
3689
3690    return ROK;
3691 }
3692
3693 \f
3694 /**
3695  * @brief This function implements PDCCH allocation for an UE.
3696  *
3697  * @details
3698  *
3699  *     Function: PdcchAlloc
3700  *     Purpose:  This function implements allocation of PDCCH for an UE.
3701  *               1. Get the aggregation level for the CQI of the UE.
3702  *               2. Get the candidate PDCCH count for the aggr level.
3703  *               3. Look for availability for each candidate and choose
3704  *                  the first one available.
3705  *
3706  *     Invoked by: Scheduler
3707  *
3708  *  @param[in]  cell
3709  *  @param[in]  subFrm
3710  *  @param[in]  cqi
3711  *  @param[in]  dciFrmt
3712  *  @return  RgSchPdcch *
3713  *         -# NULLP when unsuccessful
3714  *
3715  **/
3716 RgSchPdcch *rgSCHCmnPdcchAlloc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlSf *subFrm,uint8_t cqi,TfuDciFormat dciFrmt,Bool isDtx)
3717 {
3718    CmLteAggrLvl     aggrLvl;
3719    RgSchPdcchInfo   *pdcchInfo;
3720    RgSchPdcch       *pdcch;
3721
3722
3723    /* 3.1 consider the selected DCI format size in determining the
3724     * aggregation level */
3725    //TODO_SID Need to update. Currently using 4 aggregation level
3726    aggrLvl   = CM_LTE_AGGR_LVL2;//cellSch->dciAggrLvl[cqi][dciFrmt];
3727
3728 #ifdef LTE_ADV
3729    if((dciFrmt == TFU_DCI_FORMAT_1A) &&
3730       ((ue) && (ue->allocCmnUlPdcch)) )
3731    {
3732       pdcch = rgSCHCmnCmnPdcchAlloc(cell, subFrm);
3733       /* Since CRNTI Scrambled */
3734       if(NULLP != pdcch)
3735       {
3736          pdcch->dciNumOfBits = ue->dciSize.cmnSize[dciFrmt];
3737         // prc_trace_format_string(PRC_TRACE_GROUP_PS, PRC_TRACE_INFO_LOW,"Forcing alloc in CMN search spc size %d fmt %d \n",
3738         // pdcch->dciNumOfBits, dciFrmt);
3739       }
3740       return (pdcch);
3741    }
3742 #endif
3743
3744    /* Incrementing aggrLvl by 1 if it not AGGR_LVL8(MAX SIZE)
3745     * inorder to increse the redudancy bits for better decoding of UE */
3746    if (isDtx)
3747    {
3748       if (aggrLvl != CM_LTE_AGGR_LVL16)
3749       {
3750          switch(aggrLvl)
3751          {
3752             case CM_LTE_AGGR_LVL2:
3753                aggrLvl = CM_LTE_AGGR_LVL4;
3754                 break;
3755             case CM_LTE_AGGR_LVL4:
3756                aggrLvl = CM_LTE_AGGR_LVL8;
3757                break;
3758             case CM_LTE_AGGR_LVL8:
3759                aggrLvl = CM_LTE_AGGR_LVL16;
3760                break;
3761             default:
3762                break;
3763          }
3764          /* aggrLvl   += 1; */
3765       }
3766    }
3767
3768    pdcchInfo = &subFrm->pdcchInfo;
3769
3770    /* Updating the no. of nCce in pdcchInfo, in case if CFI
3771     * was changed  */
3772 #ifdef LTE_TDD
3773    if(subFrm->nCce != pdcchInfo->nCce)
3774    {   
3775       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3776    }
3777 #else   
3778    if(cell->nCce != pdcchInfo->nCce)
3779    {
3780       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3781    }
3782 #endif       
3783
3784    if (pdcchInfo->nCce < (1 << (aggrLvl - 1)))
3785    {
3786       /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3787       subFrm->isCceFailure = TRUE;
3788       DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", 
3789             aggrLvl);
3790
3791       return (NULLP);
3792    }
3793
3794    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3795    {
3796       /* SR_RACH_STATS : Reset isTBMsg4 */
3797       pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4= FALSE;         
3798       pdcch->dci.u.format0Info.isSrGrant = FALSE;
3799 #ifdef LTEMAC_SPS
3800       pdcch->isSpsRnti = FALSE;
3801 #endif
3802       /* Increment the CCE used counter in the current subframe */
3803       subFrm->cceCnt += aggrLvl;
3804       pdcch->pdcchSearchSpace = RG_SCH_UE_SPECIFIC_SEARCH_SPACE;
3805       if (ue != NULLP)
3806                 {
3807 #ifdef LTE_ADV
3808                  if (ue->cell != cell)
3809                  {
3810                     /* Secondary Cell */
3811                     //pdcch->dciNumOfBits = ue->dciSize.noUlCcSize[dciFrmt];
3812                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
3813                  }
3814                  else
3815 #endif
3816                  {
3817                     //pdcch->dciNumOfBits = ue->dciSize.dedSize[dciFrmt];
3818                     //TODO_SID Need to update dci size.
3819                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
3820                  }
3821                 }
3822       else
3823       {
3824          /* MSG4 */
3825          pdcch->dciNumOfBits = cell->dciSize.size[dciFrmt];
3826       }
3827       return (pdcch);
3828    }
3829
3830    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3831    subFrm->isCceFailure = TRUE;
3832
3833    DU_LOG("\nDEBUG  -->  SCH : PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)",
3834          aggrLvl);
3835    return (NULLP);
3836 }
3837
3838 #ifdef RGR_V1
3839 /**
3840  * @brief This function implements BW allocation for CCCH SDU
3841  *
3842  * @details
3843  *
3844  *     Function: rgSCHCmnCcchSduDedAlloc
3845  *     Purpose:  Downlink bandwidth Allocation for CCCH SDU.
3846  *
3847  *     Invoked by: Scheduler
3848  *
3849  *  @param[in]  RgSchCellCb*     cell
3850  *  @param[out] RgSchUeCb        *ueCb
3851  *  @return S16
3852  *
3853  **/
3854 static S16 rgSCHCmnCcchSduDedAlloc(RgSchCellCb *cell,RgSchUeCb *ueCb)
3855 {
3856    RgSchDlHqEnt   *hqE = NULLP;
3857    uint32_t       effBo;
3858    RgSchDlRbAlloc *rbAllocinfo = NULLP;
3859    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3860    uint8_t        iTbs;
3861    uint8_t        numRb;
3862 #ifdef LTE_TDD
3863    uint8_t        cfi     = cellDl->currCfi;
3864 #endif
3865
3866
3867    rbAllocinfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3868
3869    effBo  =   ueCb->dlCcchInfo.bo + RGSCH_CCCH_SDU_HDRSIZE;
3870
3871 #ifndef LTEMAC_SPS
3872    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
3873                       &rbAllocinfo->tbInfo[0].bytesReq,
3874                       &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
3875 #else /* LTEMAC_SPS */
3876    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
3877                       &rbAllocinfo->tbInfo[0].bytesReq,\
3878                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, 
3879                       rbAllocinfo->dlSf);
3880 #endif /* LTEMAC_SPS */
3881
3882    iTbs = 0;
3883    /* Cannot exceed the total number of RBs in the cell */
3884    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
3885                                    rbAllocinfo->dlSf->bwAssigned)))
3886    {
3887       /* Check if atleast one allocation was possible.
3888          This may be the case where the Bw is very less and
3889          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
3890       if (rbAllocinfo->dlSf->bwAssigned == 0)
3891       {
3892          numRb   = rbAllocinfo->dlSf->bw;
3893          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
3894          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
3895          {
3896             iTbs++;
3897          }
3898          rbAllocinfo->rbsReq = numRb;
3899          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
3900          /* DwPTS Scheduling Changes Start */
3901 #ifdef LTE_TDD
3902          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
3903          {
3904             rbAllocinfo->tbInfo[0].bytesReq =
3905                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1,cfi);
3906          }
3907 #endif
3908          /* DwPTS Scheduling Changes End */
3909          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
3910       }
3911       else
3912       {
3913          return RFAILED;
3914       }
3915    }
3916
3917    /* Update the subframe Allocated BW field */
3918    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
3919                                    rbAllocinfo->rbsReq;
3920    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
3921    rbAllocinfo->tbInfo[0].tbCb = &hqE->ccchSduProc->tbInfo[0];
3922    rbAllocinfo->rnti = ueCb->ueId;
3923    rbAllocinfo->tbInfo[0].noLyr = 1;
3924
3925    return ROK;
3926 }
3927 #endif
3928 \f
3929 /**
3930  * @brief This function implements BW allocation for MSG4
3931  *
3932  * @details
3933  *
3934  *     Function: rgSCHCmnMsg4DedAlloc
3935  *     Purpose:  Downlink bandwidth Allocation for MSG4.
3936  *
3937  *     Invoked by: Scheduler
3938  *
3939  *  @param[in]  RgSchCellCb*     cell
3940  *  @param[out] RgSchRaCb        *raCb
3941  *  @return S16
3942  *
3943  **/
3944 static S16 rgSCHCmnMsg4DedAlloc(RgSchCellCb *cell,RgSchRaCb *raCb)
3945 {
3946    uint32_t          effBo;
3947    RgSchDlRbAlloc    *rbAllocinfo = &raCb->rbAllocInfo;
3948    uint8_t           iTbs;
3949    uint8_t           numRb;
3950 #ifdef LTE_TDD
3951    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3952    uint8_t           cfi     = cellDl->currCfi;
3953 #endif
3954
3955
3956    effBo  = raCb->dlCcchInfo.bo + RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE;
3957
3958 #ifndef LTEMAC_SPS
3959    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
3960          &rbAllocinfo->tbInfo[0].bytesReq,\
3961          &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
3962 #else /* LTEMAC_SPS */
3963    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
3964                       &rbAllocinfo->tbInfo[0].bytesReq,\
3965                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE,
3966                       rbAllocinfo->dlSf);
3967 #endif /* LTEMAC_SPS */
3968
3969    iTbs = 0;
3970    /* Cannot exceed the total number of RBs in the cell */
3971    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
3972                rbAllocinfo->dlSf->bwAssigned)))
3973    {
3974       /* Check if atleast one allocation was possible.
3975          This may be the case where the Bw is very less and
3976          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
3977       if (rbAllocinfo->dlSf->bwAssigned == 0)
3978       {
3979          numRb   = rbAllocinfo->dlSf->bw;
3980          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
3981          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
3982          {
3983             iTbs++;
3984          }
3985          rbAllocinfo->rbsReq = numRb;
3986          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
3987          /* DwPTS Scheduling Changes Start */
3988 #ifdef LTE_TDD
3989          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
3990          {
3991             rbAllocinfo->tbInfo[0].bytesReq =
3992                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1, cfi);
3993          }
3994 #endif
3995          /* DwPTS Scheduling Changes End */
3996          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
3997       }
3998       else
3999       {
4000          return RFAILED;
4001       }
4002    }
4003
4004    /* Update the subframe Allocated BW field */
4005    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4006                                    rbAllocinfo->rbsReq;
4007    rbAllocinfo->rnti = raCb->tmpCrnti;
4008    rbAllocinfo->tbInfo[0].tbCb = &raCb->dlHqE->msg4Proc->tbInfo[0];
4009    rbAllocinfo->tbInfo[0].schdlngForTb = TRUE;
4010    rbAllocinfo->tbInfo[0].noLyr = 1;
4011
4012    return ROK;
4013 }
4014
4015 #ifdef LTE_TDD
4016 /**
4017  * @brief This function implements scheduling for RA Response.
4018  *
4019  * @details
4020  *
4021  *     Function: rgSCHCmnDlRaRsp
4022  *     Purpose:  Downlink scheduling for RA responses.
4023  *
4024  *     Invoked by: Scheduler
4025  *
4026  *  @param[in]  RgSchCellCb*     cell
4027  *  @return  Void
4028  *
4029  **/
4030 static Void rgSCHCmnDlRaRsp(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
4031 {
4032    CmLteTimingInfo      frm;
4033    CmLteTimingInfo      schFrm;
4034    RgSchDlSf            *subFrm;
4035    uint16_t             rarnti;
4036    uint8_t              i;
4037    uint8_t              noRaRnti=0;
4038    uint8_t              raIdx;
4039    RgSchTddRachRspLst   *rachRsp;
4040    uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
4041    uint8_t              sfnIdx;
4042    uint8_t              subfrmIdx;
4043    uint16_t             rntiIdx=0;
4044
4045    frm   = cell->crntTime;
4046    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4047
4048    /* Compute the subframe for which allocation is being made        */
4049    /* essentially, we need pointer to the dl frame for this subframe */
4050    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4051
4052    /* Get the RACH Response scheduling related information
4053     * for the subframe with RA index */
4054    raIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][frm.subframe]-1;
4055
4056    rachRsp = &cell->rachRspLst[raIdx];
4057
4058    for(sfnIdx = 0; sfnIdx < rachRsp->numRadiofrms; sfnIdx++)
4059    {
4060       /* For all scheduled RACH Responses in SFNs */
4061       schFrm = frm;
4062       RG_SCH_CMN_DECR_FRAME(schFrm.sfn, rachRsp->rachRsp[sfnIdx].sfnOffset);
4063       /* For all scheduled RACH Responses in subframes */
4064       for(subfrmIdx = 0;
4065             subfrmIdx < rachRsp->rachRsp[sfnIdx].numSubfrms; subfrmIdx++)
4066       {
4067          schFrm.subframe = rachRsp->rachRsp[sfnIdx].subframe[subfrmIdx];
4068          /* compute the last RA RNTI used in the previous subframe */
4069          raIdx = (((schFrm.sfn % cell->raInfo.maxRaSize) * \
4070                   RGSCH_NUM_SUB_FRAMES * RGSCH_MAX_RA_RNTI_PER_SUBFRM) \
4071                                     + schFrm.subframe);
4072
4073          /* For all RA RNTIs within a subframe */
4074
4075          for(i=0; (i < RGSCH_MAX_RA_RNTI_PER_SUBFRM) && \
4076                (noRaRnti < RGSCH_MAX_TDD_RA_RSP_ALLOC); i++)
4077          {
4078             rarnti = (schFrm.subframe + RGSCH_NUM_SUB_FRAMES*i + 1);
4079             rntiIdx = (raIdx + RGSCH_NUM_SUB_FRAMES*i);
4080
4081             if (cell->raInfo.raReqLst[rntiIdx].first != NULLP)
4082             {
4083                /* compute the next RA RNTI */
4084                if (rgSCHCmnRaRspAlloc(cell, subFrm, rntiIdx,
4085                         rarnti, noRaRnti, allocInfo) != ROK)
4086                {
4087                   /* The resources are exhausted */
4088                   break;
4089                }
4090                noRaRnti++;
4091             }
4092          }
4093          noRaRnti=0;
4094       }
4095    }
4096
4097    return;
4098 }
4099 #else
4100 /**
4101  * @brief This function implements scheduling for RA Response.
4102  *
4103  * @details
4104  *
4105  *     Function: rgSCHCmnDlRaRsp
4106  *     Purpose:  Downlink scheduling for RA responses.
4107  *
4108  *     Invoked by: Scheduler
4109  *
4110  *  @param[in]  RgSchCellCb*          cell
4111  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
4112  *  @return  Void
4113  *
4114  **/
4115 static Void rgSCHCmnDlRaRsp(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
4116 {
4117    CmLteTimingInfo frm;
4118    CmLteTimingInfo winStartFrm;
4119    RgSchDlSf       *subFrm;
4120    uint8_t         winStartIdx;
4121    uint8_t         winGap;
4122    uint8_t         rarnti;
4123    uint8_t         raIdx;
4124    RgSchCmnCell    *sched;
4125    uint8_t         i,noRaRnti=0;
4126
4127    frm   = cell->crntTime;
4128    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4129
4130    /* Compute the subframe for which allocation is being made        */
4131    /* essentially, we need pointer to the dl frame for this subframe */
4132    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4133    sched   = RG_SCH_CMN_GET_CELL(cell);
4134
4135    /* ccpu00132523 - Window Start calculated by considering RAR window size, 
4136     * RAR Wait period, Subframes occuppied for respective preamble format*/
4137    winGap = (sched->dl.numRaSubFrms-1) + (cell->rachCfg.raWinSize-1) 
4138              +RGSCH_RARSP_WAIT_PERIOD;
4139
4140    /* Window starting occassion is retrieved using the gap and tried to 
4141     * fit to the size of raReqLst array*/ 
4142    RGSCHDECRFRMCRNTTIME(frm, winStartFrm, winGap);
4143
4144         //5G_TODO TIMING update. Need to check
4145    winStartIdx = (winStartFrm.sfn & 1) * RGSCH_MAX_RA_RNTI+ winStartFrm.slot;
4146
4147    for(i = 0; ((i < cell->rachCfg.raWinSize) && (noRaRnti < RG_SCH_CMN_MAX_CMN_PDCCH)); i++)
4148    {
4149       raIdx = (winStartIdx + i) % RGSCH_RAREQ_ARRAY_SIZE;
4150
4151       if (cell->raInfo.raReqLst[raIdx].first != NULLP)
4152       {
4153          allocInfo->raRspAlloc[noRaRnti].biEstmt = \
4154                          (!i * RGSCH_ONE_BIHDR_SIZE);
4155          rarnti = raIdx % RGSCH_MAX_RA_RNTI+ 1;
4156          if (rgSCHCmnRaRspAlloc(cell, subFrm, raIdx,
4157                                  rarnti, noRaRnti, allocInfo) != ROK)
4158          {
4159             /* The resources are exhausted */
4160             break;
4161          }
4162          /* ccpu00132523- If all the RAP ids are not scheduled then need not 
4163           * proceed for next RA RNTIs*/
4164          if(allocInfo->raRspAlloc[noRaRnti].numRapids < cell->raInfo.raReqLst[raIdx].count)
4165          {
4166             break;
4167          }
4168          noRaRnti++; /* Max of RG_SCH_CMN_MAX_CMN_PDCCH RARNTIs
4169                         for response allocation */
4170       }
4171    }
4172    return;
4173 }
4174 #endif
4175
4176 \f
4177 /**
4178  * @brief This function allocates the resources for an RARNTI.
4179  *
4180  * @details
4181  *
4182  *     Function: rgSCHCmnRaRspAlloc
4183  *     Purpose:  Allocate resources to a RARNTI.
4184  *               0. Allocate PDCCH for sending the response.
4185  *               1. Locate the number of RA requests pending for the RARNTI.
4186  *               2. Compute the size of data to be built.
4187  *               3. Using common channel CQI, compute the number of RBs.
4188  *
4189  *     Invoked by: Scheduler
4190  *
4191  *  @param[in]  RgSchCellCb             *cell,
4192  *  @param[in]  RgSchDlSf               *subFrm,
4193  *  @param[in]  uint16_t                     rarnti,
4194  *  @param[in]  uint8_t                      noRaRnti
4195  *  @param[out] RgSchCmnDlRbAllocInfo   *allocInfo
4196  *  @return  S16
4197  *
4198  **/
4199 static S16 rgSCHCmnRaRspAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm,uint16_t raIndex,uint16_t rarnti,uint8_t noRaRnti,RgSchCmnDlRbAllocInfo *allocInfo)
4200 {
4201    RgSchCmnDlCell   *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4202    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4203    uint16_t         noBytes;
4204    uint32_t         rb = 0;
4205    uint32_t         tbs;
4206    /*ccpu00116700,ccpu00116708- Corrected the wrong type for mcs*/
4207    uint8_t          mcs;
4208    CmLListCp        *reqLst;
4209    /* RACH handling related changes */
4210    Bool             isAlloc = FALSE;
4211    static uint8_t   schdNumRapid = 0;
4212    uint8_t          remNumRapid = 0;
4213    uint8_t          nPrb = 0;
4214    S32              allwdTbSz = 0;
4215 #ifdef LTE_TDD   
4216    uint16_t         lostRe;  
4217    uint8_t          cfi = cellDl->currCfi;  
4218 #endif   
4219
4220 #ifndef RGR_V1
4221    UNUSED(cellUl);
4222 #endif
4223
4224    /* ccpu00132523: Resetting the schdRap Id count in every scheduling subframe*/
4225    if(noRaRnti == 0)
4226    {
4227       schdNumRapid = 0;
4228    }
4229
4230
4231    if (subFrm->bw == subFrm->bwAssigned)
4232    {
4233       DU_LOG("\nERROR  -->  SCH : bw == bwAssigned RARNTI:%d",rarnti);
4234       return RFAILED;
4235    }
4236
4237    reqLst = &cell->raInfo.raReqLst[raIndex];
4238    if (reqLst->count == 0)
4239    {
4240       DU_LOG("\nERROR  -->  SCH : reqLst Count=0 RARNTI:%d",rarnti);
4241       return RFAILED;
4242    }
4243    remNumRapid = reqLst->count;
4244
4245 #ifdef RGR_V1
4246    /* Limit number of rach rsps to maxMsg3PerUlsf */
4247    if ( schdNumRapid+remNumRapid > cellUl->maxMsg3PerUlSf )
4248    {
4249       remNumRapid = cellUl->maxMsg3PerUlSf-schdNumRapid;
4250    }
4251 #endif
4252  
4253    while (remNumRapid)
4254    {
4255       /* Try allocating for as many RAPIDs as possible */
4256       /* BI sub-header size to the tbSize requirement */
4257       noBytes  = RGSCH_GET_RAR_BYTES(remNumRapid) +\
4258                  allocInfo->raRspAlloc[noRaRnti].biEstmt;
4259       if ((allwdTbSz = rgSCHUtlGetAllwdCchTbSz(noBytes*8, &nPrb, &mcs)) == -1)
4260       {
4261          remNumRapid--;
4262          continue;
4263       }
4264
4265       /* rgSCHCmnClcRbAllocForFxdTb(cell, allwdTbSz/8, cellDl->ccchCqi, &rb);*/
4266       if(cellDl->bitsPerRb==0)
4267       {
4268          while ((rgTbSzTbl[0][0][rb]) <(uint32_t) allwdTbSz)
4269          {
4270             rb++;
4271          }
4272          rb = rb+1;
4273       }
4274       else
4275       {
4276          rb = RGSCH_CEIL(allwdTbSz, cellDl->bitsPerRb);
4277       }
4278       /* DwPTS Scheduling Changes Start */      
4279 #ifdef LTE_TDD      
4280       if (subFrm->sfType == RG_SCH_SPL_SF_DATA)
4281       {
4282          RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
4283
4284          /* Calculate the less RE's because of DwPTS */
4285          lostRe = rb * (cellDl->noResPerRb[cfi] - 
4286                                   cellDl->numReDwPts[cfi]);
4287           
4288          /* Increase number of RBs in Spl SF to compensate for lost REs */
4289          rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]);
4290       }
4291 #endif      
4292       /* DwPTS Scheduling Changes End */
4293
4294       /*ccpu00115595- end*/
4295       if (rb > subFrm->bw - subFrm->bwAssigned)
4296       {
4297          remNumRapid--;
4298          continue;
4299       }
4300       /* Allocation succeeded for 'remNumRapid' */
4301       isAlloc = TRUE;
4302       tbs = allwdTbSz/8;
4303       DU_LOG("\nINFO  -->  SCH : RAR alloc noBytes:%u,allwdTbSz:%u,tbs:%u,rb:%u\n",
4304                                       noBytes,allwdTbSz,tbs,rb);
4305       break;
4306    }
4307    if (!isAlloc)
4308    {
4309       DU_LOG("\nERROR  -->  SCH : BW alloc Failed");
4310       return RFAILED;
4311    }
4312
4313    subFrm->bwAssigned = subFrm->bwAssigned + rb;
4314
4315    /* Fill AllocInfo structure */
4316    allocInfo->raRspAlloc[noRaRnti].rnti = rarnti;
4317    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].bytesReq = tbs;
4318    allocInfo->raRspAlloc[noRaRnti].rbsReq = rb;
4319    allocInfo->raRspAlloc[noRaRnti].dlSf = subFrm;
4320    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].imcs = mcs;
4321    allocInfo->raRspAlloc[noRaRnti].raIndex = raIndex;
4322    /* RACH changes for multiple RAPID handling */
4323    allocInfo->raRspAlloc[noRaRnti].numRapids = remNumRapid;
4324    allocInfo->raRspAlloc[noRaRnti].nPrb = nPrb;
4325    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].noLyr = 1;
4326    allocInfo->raRspAlloc[noRaRnti].vrbgReq = RGSCH_CEIL(nPrb,MAX_5GTF_VRBG_SIZE); 
4327    schdNumRapid += remNumRapid; 
4328    return ROK;
4329 }
4330
4331 /***********************************************************
4332  *
4333  *     Func : rgSCHCmnUlAllocFillRbInfo
4334  *
4335  *     Desc : Fills the start RB and the number of RBs for
4336  *            uplink allocation.
4337  *
4338  *     Ret  : void
4339  *
4340  *     Notes:
4341  *
4342  *     File :
4343  *
4344  **********************************************************/
4345 Void rgSCHCmnUlAllocFillRbInfo(RgSchCellCb *cell,RgSchUlSf *sf,RgSchUlAlloc  *alloc)
4346 {
4347     RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4348     RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4349     uint8_t             cfi = cellDl->currCfi;
4350
4351
4352    alloc->grnt.rbStart = (alloc->sbStart * cellUl->sbSize) + 
4353                                     cell->dynCfiCb.bwInfo[cfi].startRb;
4354
4355    /* Num RBs = numSbAllocated * sbSize - less RBs in the last SB */
4356    alloc->grnt.numRb = (alloc->numSb * cellUl->sbSize);
4357
4358    return;
4359 }
4360
4361 /**
4362  * @brief Grant request for Msg3.
4363  *
4364  * @details
4365  *
4366  *     Function : rgSCHCmnMsg3GrntReq
4367  *
4368  *     This is invoked by downlink scheduler to request allocation
4369  *     for msg3.
4370  *     Steps:
4371  *     - Attempt to allocate msg3 in the current msg3 subframe
4372  *       Allocation attempt based on whether preamble is from group A
4373  *       and the value of MESSAGE_SIZE_GROUP_A
4374  *     - Link allocation with passed RNTI and msg3 HARQ process
4375  *     - Set the HARQ process ID (*hqProcIdRef)
4376  *
4377  *  @param[in]  RgSchCellCb       *cell
4378  *  @param[in]  CmLteRnti         rnti
4379  *  @param[in]  Bool              preamGrpA
4380  *  @param[in]  RgSchUlHqProcCb   *hqProc
4381  *  @param[out] RgSchUlAlloc      **ulAllocRef
4382  *  @param[out] uint8_t                *hqProcIdRef
4383  *  @return  Void
4384  **/
4385 static Void rgSCHCmnMsg3GrntReq
4386 (
4387 RgSchCellCb     *cell,
4388 CmLteRnti       rnti,
4389 Bool            preamGrpA,
4390 RgSchUlHqProcCb *hqProc,
4391 RgSchUlAlloc    **ulAllocRef,
4392 uint8_t         *hqProcIdRef
4393 )
4394 {
4395    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4396    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
4397    RgSchUlHole     *hole;
4398    RgSchUlAlloc    *alloc;
4399    uint8_t         iMcs;
4400    uint8_t         numSb;
4401
4402
4403    *ulAllocRef = NULLP;
4404
4405    /* Fix: ccpu00120610 Use remAllocs from subframe during msg3 allocation */
4406    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
4407    {
4408       return;
4409    }
4410    if (preamGrpA == FALSE)
4411    {
4412       numSb = cellUl->ra.prmblBNumSb;
4413       iMcs  = cellUl->ra.prmblBIMcs;
4414    }
4415    else
4416    {
4417       numSb = cellUl->ra.prmblANumSb;
4418       iMcs  = cellUl->ra.prmblAIMcs;
4419    }
4420
4421    if ((hole = rgSCHUtlUlHoleFirst(sf)) != NULLP)
4422    {
4423       if(*sf->allocCountRef == 0)
4424       {
4425          RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4426          /* Reinitialize the hole */
4427          if (sf->holeDb->count == 1 && (hole->start == 0)) /* Sanity check of holeDb */
4428          {
4429             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;
4430             /* Re-Initialize available subbands because of CFI change*/
4431             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
4432          }
4433          else
4434          {
4435             DU_LOG("\nERROR  -->  SCH :  holeDb sanity check failed RNTI:%d",rnti);
4436          } 
4437       }
4438       if (numSb <= hole->num)
4439       {
4440          uint8_t iTbs;
4441          alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
4442          rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
4443          alloc->grnt.iMcs     = iMcs;
4444          alloc->grnt.iMcsCrnt = iMcs;
4445          iTbs                 = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
4446          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); 
4447          /* To include the length and ModOrder in DataRecp Req.*/
4448          alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
4449          RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
4450          /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
4451          alloc->grnt.nDmrs    = 0;
4452          alloc->grnt.hop      = 0;
4453          alloc->grnt.delayBit = 0;
4454          alloc->grnt.isRtx    = FALSE;
4455          *ulAllocRef          = alloc;
4456          *hqProcIdRef         = (cellUl->msg3SchdHqProcIdx);
4457          hqProc->procId       = *hqProcIdRef;
4458          hqProc->ulSfIdx      = (cellUl->msg3SchdIdx);
4459          alloc->rnti          = rnti;
4460          alloc->ue            = NULLP;
4461          alloc->pdcch         = FALSE;
4462          alloc->forMsg3       = TRUE;
4463          alloc->hqProc        = hqProc;
4464          rgSCHUhmNewTx(hqProc, (uint8_t)(cell->rachCfg.maxMsg3Tx - 1), alloc);
4465          DU_LOG("\nDEBUG  -->  SCH : RNTI:%d MSG3 ALLOC proc(%lu)procId(%d)schdIdx(%d)\n",
4466                alloc->rnti,
4467                ((PTR)alloc->hqProc),
4468                alloc->hqProc->procId,
4469                alloc->hqProc->ulSfIdx);
4470          DU_LOG("\nDEBUG  -->  SCH : alloc(%p)maxMsg3Tx(%d)",
4471                ((void *)alloc),
4472                cell->rachCfg.maxMsg3Tx);
4473       }
4474    }
4475
4476    return;
4477 }
4478
4479 \f
4480 /**
4481  * @brief This function determines the allocation limits and
4482  *        parameters that aid in DL scheduling.
4483  *
4484  * @details
4485  *
4486  *     Function: rgSCHCmnDlSetUeAllocLmt
4487  *     Purpose:  This function determines the Maximum RBs
4488  *               a UE is eligible to get based on softbuffer
4489  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4490  *               specific parameters like iTbs, eff and noLyrs
4491  *               are also set in this function. This function
4492  *               is called while UE configuration and UeDlCqiInd.
4493  *
4494  *     Invoked by: Scheduler
4495  *
4496  *  @param[in]  RgSchCellCb   *cellCb
4497  *  @param[in]  RgSchCmnDlUe  *ueDl
4498  *  @return  Void
4499  *
4500  **/
4501 static Void rgSCHCmnDlSetUeAllocLmt(RgSchCellCb *cell,RgSchCmnDlUe *ueDl,Bool isEmtcUe)
4502 {
4503    uint8_t       modOrder;
4504    uint32_t      maxRb;
4505    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4506    uint8_t       cfi = cellSch->dl.currCfi;
4507
4508
4509 #ifdef EMTC_ENABLE
4510    if(TRUE == isEmtcUe)
4511    {
4512       /* ITbs for CW0 for 1 Layer Tx */
4513       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4514                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4515       /* ITbs for CW0 for 2 Layer Tx */
4516       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4517                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4518       /* Eff for CW0 for 1 Layer Tx */
4519       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4520                                             [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4521       /* Eff for CW0 for 2 Layer Tx */
4522       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4523                                             [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4524
4525       /* ITbs for CW1 for 1 Layer Tx */
4526       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4527                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4528       /* ITbs for CW1 for 2 Layer Tx */
4529       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4530                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4531       /* Eff for CW1 for 1 Layer Tx */
4532       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4533                                             [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4534       /* Eff for CW1 for 2 Layer Tx */
4535       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4536                                             [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4537    }
4538    else
4539 #endif 
4540    {
4541       /* ITbs for CW0 for 1 Layer Tx */
4542       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4543                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4544       /* ITbs for CW0 for 2 Layer Tx */
4545       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4546                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4547       /* Eff for CW0 for 1 Layer Tx */
4548       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4549                                         [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4550       /* Eff for CW0 for 2 Layer Tx */
4551       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4552                                         [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4553       
4554       /* ITbs for CW1 for 1 Layer Tx */
4555       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4556                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4557       /* ITbs for CW1 for 2 Layer Tx */
4558       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4559                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4560       /* Eff for CW1 for 1 Layer Tx */
4561       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4562                                         [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4563       /* Eff for CW1 for 2 Layer Tx */
4564       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4565                                         [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4566    }
4567
4568 //#ifdef DL_LA 
4569   // ueDl->laCb.cqiBasediTbs =  ueDl->mimoInfo.cwInfo[0].iTbs[0] * 100;
4570 //#endif
4571    /* Assigning noLyrs to each CW assuming optimal Spatial multiplexing
4572     * capability */
4573    (ueDl->mimoInfo.ri/2 == 0)? (ueDl->mimoInfo.cwInfo[0].noLyr = 1) : \
4574               (ueDl->mimoInfo.cwInfo[0].noLyr = ueDl->mimoInfo.ri/2);
4575    ueDl->mimoInfo.cwInfo[1].noLyr = ueDl->mimoInfo.ri - ueDl->mimoInfo.cwInfo[0].noLyr;
4576    /* rg002.101:ccpu00102106: correcting DL harq softbuffer limitation logic.
4577     * The maxTbSz is the maximum number of PHY bits a harq process can
4578     * hold. Hence we limit our allocation per harq process based on this.
4579     * Earlier implementation we misinterpreted the maxTbSz to be per UE
4580     * per TTI, but in fact it is per Harq per TTI. */
4581    /* rg002.101:ccpu00102106: cannot exceed the harq Tb Size
4582     * and harq Soft Bits limit.*/
4583
4584    /* Considering iTbs corresponding to 2 layer transmission for
4585     * codeword0(approximation) and the maxLayers supported by
4586     * this UE at this point of time. */
4587    RG_SCH_CMN_TBS_TO_MODODR(ueDl->mimoInfo.cwInfo[0].iTbs[1], modOrder);
4588
4589    /* Bits/modOrder gives #REs, #REs/noResPerRb gives #RBs */
4590    /* rg001.301 -MOD- [ccpu00119213] : avoiding wraparound */
4591    maxRb = ((ueDl->maxSbSz)/(cellSch->dl.noResPerRb[cfi] * modOrder *\
4592                    ueDl->mimoInfo.ri));
4593    if (cellSch->dl.isDlFreqSel)
4594    {
4595       /* Rounding off to left nearest multiple of RBG size */
4596       maxRb -= maxRb % cell->rbgSize;
4597    }
4598    ueDl->maxRb = RGSCH_MIN(maxRb, cellSch->dl.maxDlBwPerUe);
4599    if (cellSch->dl.isDlFreqSel)
4600    {
4601       /* Rounding off to right nearest multiple of RBG size */
4602       if (ueDl->maxRb % cell->rbgSize)
4603       {
4604          ueDl->maxRb += (cell->rbgSize - 
4605                          (ueDl->maxRb % cell->rbgSize));
4606       }
4607    }
4608
4609    /* Set the index of the cwInfo, which is better in terms of
4610     * efficiency. If RI<2, only 1 CW, hence btrCwIdx shall be 0 */
4611    if (ueDl->mimoInfo.ri < 2)
4612    {
4613       ueDl->mimoInfo.btrCwIdx = 0;
4614    }
4615    else
4616    {
4617       if (ueDl->mimoInfo.cwInfo[0].eff[ueDl->mimoInfo.cwInfo[0].noLyr-1] <\
4618           ueDl->mimoInfo.cwInfo[1].eff[ueDl->mimoInfo.cwInfo[1].noLyr-1])
4619       {
4620          ueDl->mimoInfo.btrCwIdx = 1;
4621       }
4622       else
4623       {
4624          ueDl->mimoInfo.btrCwIdx = 0;
4625       }
4626    }
4627
4628    return;
4629    }
4630
4631 #ifdef DL_LA
4632
4633 /**
4634  * @brief This function updates TX Scheme.
4635  *
4636  * @details
4637  *
4638  *     Function: rgSCHCheckAndSetTxScheme 
4639  *     Purpose:  This function determines the Maximum RBs
4640  *               a UE is eligible to get based on softbuffer
4641  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4642  *               specific parameters like iTbs, eff and noLyrs
4643  *               are also set in this function. This function
4644  *               is called while UE configuration and UeDlCqiInd.
4645  *
4646  *     Invoked by: Scheduler
4647  *
4648  *  @param[in]  RgSchCellCb   *cell
4649  *  @param[in]  RgSchUeCb     *ue
4650  *  @return  Void
4651  *
4652  **/
4653 static Void rgSCHCheckAndSetTxScheme(RgSchCellCb *cell,RgSchUeCb *ue)
4654 {
4655    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4656    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue ,cell);
4657    uint8_t       cfi = cellSch->dl.currCfi;
4658    uint8_t       maxiTbs;
4659    uint8_t       cqiBasediTbs;
4660    uint8_t       actualiTbs;
4661
4662
4663    maxiTbs      = (*(RgSchCmnCqiToTbs*)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4664                 [RG_SCH_CMN_MAX_CQI - 1];
4665    cqiBasediTbs = (ueDl->laCb[0].cqiBasediTbs)/100;
4666    actualiTbs   = ueDl->mimoInfo.cwInfo[0].iTbs[0];
4667
4668    if((actualiTbs < RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR) && (cqiBasediTbs >
4669      actualiTbs) && ((cqiBasediTbs - actualiTbs) > RG_SCH_TXSCHEME_CHNG_THRSHD)) 
4670    {
4671       RG_SCH_CMN_SET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
4672    }
4673    
4674    if(actualiTbs >= maxiTbs)
4675    {
4676       RG_SCH_CMN_UNSET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
4677    }
4678
4679    return;
4680 }
4681
4682 /**
4683  * @brief This function determines the allocation limits and
4684  *        parameters that aid in DL scheduling.
4685  *
4686  * @details
4687  *
4688  *     Function: rgSCHCmnDlSetUeAllocLmtLa
4689  *     Purpose:  This function determines the Maximum RBs
4690  *               a UE is eligible to get based on softbuffer
4691  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4692  *               specific parameters like iTbs, eff and noLyrs
4693  *               are also set in this function. This function
4694  *               is called while UE configuration and UeDlCqiInd.
4695  *
4696  *     Invoked by: Scheduler
4697  *
4698  *  @param[in]  RgSchCellCb   *cell
4699  *  @param[in]  RgSchUeCb     *ue
4700  *  @return  Void
4701  *
4702  **/
4703 Void rgSCHCmnDlSetUeAllocLmtLa(RgSchCellCb *cell,RgSchUeCb *ue)
4704 {
4705    uint8_t       modOrder;
4706    uint32_t      maxRb;
4707    uint8_t       reportediTbs;
4708    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4709    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
4710    uint8_t       cfi = cellSch->dl.currCfi;
4711    uint8_t       maxiTbs;
4712    uint8_t       cwIdx = 0; 
4713
4714
4715    maxiTbs      = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1];
4716    if(ueDl->cqiFlag == TRUE)
4717    {
4718       for(cwIdx=0; cwIdx < RG_SCH_CMN_MAX_CW_PER_UE; cwIdx++)
4719       {
4720          S32 iTbsNew;
4721
4722          /* Calcluating the reported iTbs for code word 0 */
4723          reportediTbs = ue->ue5gtfCb.mcs; 
4724
4725          iTbsNew = (S32) reportediTbs;
4726
4727          if(!ueDl->laCb[cwIdx].notFirstCqi)
4728          {
4729             /* This is the first CQI report from UE */
4730             ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
4731             ueDl->laCb[cwIdx].notFirstCqi  =  TRUE;
4732          }
4733          else if ((RG_ITBS_DIFF(reportediTbs, ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0])) > 5)
4734          {
4735             /* Ignore this iTBS report and mark that last iTBS report was */
4736             /* ignored so that subsequently we reset the LA algorithm     */
4737             ueDl->laCb[cwIdx].lastiTbsIgnored = TRUE;
4738             ueDl->laCb[cwIdx].numLastiTbsIgnored++;
4739             if( ueDl->laCb[cwIdx].numLastiTbsIgnored > 10)
4740             {
4741                /* CQI reported by UE is not catching up. Reset the LA algorithm */
4742                ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
4743                ueDl->laCb[cwIdx].deltaiTbs = 0;
4744                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
4745                ueDl->laCb[cwIdx].numLastiTbsIgnored = 0;
4746             }
4747          }
4748          else
4749          {
4750             if (ueDl->laCb[cwIdx].lastiTbsIgnored != TRUE)
4751             {
4752                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
4753                      (80 * ueDl->laCb[cwIdx].cqiBasediTbs))/100;
4754             }
4755             else
4756             {
4757                /* Reset the LA as iTbs in use caught up with the value   */
4758                /* reported by UE.                                        */
4759                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
4760                      (80 * ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] * 100))/100;
4761                ueDl->laCb[cwIdx].deltaiTbs = 0;
4762                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
4763             }
4764          }
4765
4766          iTbsNew = (ueDl->laCb[cwIdx].cqiBasediTbs + ueDl->laCb[cwIdx].deltaiTbs)/100;
4767
4768          RG_SCH_CHK_ITBS_RANGE(iTbsNew, maxiTbs);       
4769
4770          ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] = RGSCH_MIN(iTbsNew, cell->thresholds.maxDlItbs);
4771          //ueDl->mimoInfo.cwInfo[cwIdx].iTbs[1] = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
4772 #ifdef RG_5GTF
4773          ue->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
4774          /*
4775          DU_LOG("\nINFO   -->  SCH : reportediTbs[%d] cqiBasediTbs[%d] deltaiTbs[%d] iTbsNew[%d] mcs[%d] cwIdx[%d]\n", 
4776                  reportediTbs, ueDl->laCb[cwIdx].cqiBasediTbs, ueDl->laCb[cwIdx].deltaiTbs,
4777                  iTbsNew, ue->ue5gtfCb.mcs, cwIdx);
4778          */
4779 #endif
4780
4781          if((ue->mimoInfo.txMode != RGR_UE_TM_3) && (ue->mimoInfo.txMode != RGR_UE_TM_4))
4782          {
4783             break; 
4784          }
4785       }
4786       ueDl->cqiFlag = FALSE;
4787    } 
4788
4789
4790    return;
4791 }
4792 #endif
4793 /***********************************************************
4794  *
4795  *     Func : rgSCHCmnDlUeResetTemp
4796  *
4797  *     Desc : Reset whatever variables where temporarily used
4798  *            during UE scheduling.
4799  *
4800  *     Ret  : Void
4801  *
4802  *     Notes:
4803  *
4804  *     File :
4805  *
4806  **********************************************************/
4807 Void rgSCHCmnDlHqPResetTemp(RgSchDlHqProcCb *hqP)
4808 {
4809
4810    /* Fix: syed having a hqP added to Lists for RB assignment rather than
4811     * a UE, as adding UE was limiting handling some scenarios */ 
4812     hqP->reqLnk.node = (PTR)NULLP;
4813     hqP->schdLstLnk.node = (PTR)NULLP;
4814
4815    return;
4816 }  /* rgSCHCmnDlHqPResetTemp */
4817
4818 /***********************************************************
4819  *
4820  *     Func : rgSCHCmnDlUeResetTemp
4821  *
4822  *     Desc : Reset whatever variables where temporarily used
4823  *            during UE scheduling.
4824  *
4825  *     Ret  : Void
4826  *
4827  *     Notes:
4828  *
4829  *     File :
4830  *
4831  **********************************************************/
4832 Void rgSCHCmnDlUeResetTemp(RgSchUeCb *ue,RgSchDlHqProcCb *hqP)
4833 {
4834    RgSchDlRbAlloc  *allocInfo;
4835    RgSchCmnDlUe    *cmnUe = RG_SCH_CMN_GET_DL_UE(ue,hqP->hqE->cell);
4836 #ifdef LTE_ADV
4837    Void           *tmpCb;
4838 #endif
4839
4840
4841    /* Fix : syed check for UE's existence was useless.
4842     * Instead we need to check that reset is done only for the 
4843     * information of a scheduled harq proc, which is cmnUe->proc.
4844     * Reset should not be done for non-scheduled hqP */
4845    if((cmnUe->proc == hqP) || (cmnUe->proc == NULLP))
4846    {
4847       cmnUe->proc = NULLP;
4848       allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, hqP->hqE->cell);
4849 #ifdef LTE_ADV
4850       tmpCb = allocInfo->laaCb;
4851 #endif
4852       memset(allocInfo, 0, sizeof(RgSchDlRbAlloc));
4853       allocInfo->rnti = ue->ueId;
4854 #ifdef LTE_ADV
4855       allocInfo->laaCb = tmpCb;
4856 #endif
4857       /* Fix: syed moving this to a common function for both scheduled
4858        * and non-scheduled UEs */
4859       cmnUe->outStndAlloc = 0;
4860    }
4861    rgSCHCmnDlHqPResetTemp(hqP);
4862
4863    return;
4864 }  /* rgSCHCmnDlUeResetTemp */
4865
4866 /***********************************************************
4867  *
4868  *     Func : rgSCHCmnUlUeResetTemp
4869  *
4870  *     Desc : Reset whatever variables where temporarily used
4871  *            during UE scheduling.
4872  *
4873  *     Ret  : Void
4874  *
4875  *     Notes:
4876  *
4877  *     File :
4878  *
4879  **********************************************************/
4880 Void rgSCHCmnUlUeResetTemp(RgSchCellCb *cell,RgSchUeCb *ue)
4881 {
4882    RgSchCmnUlUe *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue,cell);
4883
4884    memset(&cmnUlUe->alloc, 0, sizeof(cmnUlUe->alloc));
4885
4886    return;
4887 }  /* rgSCHCmnUlUeResetTemp */
4888
4889
4890 \f
4891 /**
4892  * @brief This function fills the PDCCH information from dlProc.
4893  *
4894  * @details
4895  *
4896  *     Function: rgSCHCmnFillPdcch
4897  *     Purpose:  This function fills in the PDCCH information
4898  *               obtained from the RgSchDlRbAlloc
4899  *               during common channel scheduling(P, SI, RA - RNTI's).
4900  *
4901  *     Invoked by: Downlink Scheduler
4902  *
4903  *  @param[out] RgSchPdcch*       pdcch
4904  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
4905  *  @return  Void
4906  *
4907  **/
4908 Void rgSCHCmnFillPdcch(RgSchCellCb *cell,RgSchPdcch *pdcch,RgSchDlRbAlloc *rbAllocInfo)
4909 {
4910
4911    /* common channel pdcch filling,
4912     * only 1A and Local is supported */
4913    pdcch->rnti                       = rbAllocInfo->rnti;
4914    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
4915    switch(rbAllocInfo->dciFormat)
4916    {
4917 #ifdef RG_5GTF  /* ANOOP: ToDo: DCI format B1/B2 filling */
4918       case TFU_DCI_FORMAT_B1:
4919          {
4920             /* ToDo: Anoop */
4921             pdcch->dci.u.formatB1Info.formatType = 0;
4922             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].cmnGrnt.xPDSCHRange;
4923             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].cmnGrnt.rbAssign;
4924             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = 0;
4925             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
4926             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = 0;
4927             //pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].ndi;
4928             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].cmnGrnt.rv;
4929             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
4930             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
4931             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
4932             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
4933             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
4934             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
4935             //TODO_SID: Need to update
4936             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
4937             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
4938             pdcch->dci.u.formatB1Info.SRS_Config = 0;
4939             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
4940             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
4941             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
4942             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].cmnGrnt.SCID;
4943             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
4944             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
4945             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
4946
4947             break; /* case TFU_DCI_FORMAT_B1: */
4948          }
4949
4950       case TFU_DCI_FORMAT_B2:
4951          {
4952             //DU_LOG("\nINFO   -->  SCH : RG_5GTF:: Pdcch filling with DCI format B2\n");
4953             /* ToDo: Anoop */
4954             break; /* case TFU_DCI_FORMAT_B2: */
4955          }
4956 #endif
4957       case TFU_DCI_FORMAT_1A:
4958          pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
4959
4960          /*Nprb indication at PHY for common Ch
4961           *setting least significant bit of tpc field to 1 if
4962           nPrb=3 and 0 otherwise. */
4963          if (rbAllocInfo->nPrb == 3)
4964          {
4965             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 1;
4966          }
4967          else
4968          {
4969             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 0;
4970          }
4971          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
4972          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
4973          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
4974                                                                    rbAllocInfo->tbInfo[0].imcs;
4975          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = 0;
4976          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = 0;
4977          /* Add RIV CALC */
4978          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
4979             TFU_ALLOC_TYPE_RIV;
4980          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
4981             rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
4982                   rbAllocInfo->allocInfo.raType2.rbStart,
4983                   rbAllocInfo->allocInfo.raType2.numRb);
4984
4985 #ifdef LTE_TDD
4986          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = \
4987                                                                            FALSE;
4988 #ifdef TFU_TDD
4989          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
4990          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
4991 #endif
4992 #endif
4993          break; /* case TFU_DCI_FORMAT_1A: */
4994       case TFU_DCI_FORMAT_1:
4995          pdcch->dci.u.format1Info.tpcCmd = 0;
4996          /* Avoiding this check,as we dont support Type1 RA */
4997 #ifdef RG_UNUSED
4998          if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
4999          {
5000 #endif
5001             pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5002             pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5003                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5004                 & 0xff);
5005             pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5006                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5007                 & 0x00ff);
5008             pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5009                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5010                 & 0x0000ff);
5011             pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5012                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5013 #ifdef RG_UNUSED
5014          }
5015 #endif
5016          pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5017          pdcch->dci.u.format1Info.allocInfo.ndi = 0;
5018          pdcch->dci.u.format1Info.allocInfo.mcs = rbAllocInfo->tbInfo[0].imcs;
5019          pdcch->dci.u.format1Info.allocInfo.rv = 0;
5020 #ifdef TFU_TDD
5021          pdcch->dci.u.format1Info.dai = 1;
5022 #endif
5023          break;
5024       default:
5025          DU_LOG("\nERROR  -->  SCH : Allocator's icorrect "
5026             "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5027          break;
5028    }
5029    return;
5030 }
5031
5032 #ifdef LTE_TDD
5033 /**
5034  * @brief This function finds whether the subframe is special subframe or not.
5035  *
5036  * @details
5037  *
5038  *     Function: rgSCHCmnIsSplSubfrm
5039  *     Purpose:  This function finds the subframe index of the special subframe
5040  *               and finds whether the current DL index matches it or not.
5041  *
5042  *     Invoked by: Scheduler
5043  *
5044  *  @param[in] uint8_t                   splfrmCnt
5045  *  @param[in] uint8_t                   curSubfrmIdx
5046  *  @param[in] uint8_t                   periodicity
5047  *  @param[in] RgSchTddSubfrmInfo   *subfrmInfo
5048  *  @return  Bool
5049  *
5050  **/
5051 static Bool rgSCHCmnIsSplSubfrm(uint8_t splfrmCnt,uint8_t curSubfrmIdx,uint8_t periodicity,RgSchTddSubfrmInfo *subfrmInfo)
5052 {
5053    uint8_t dlSfCnt = 0;
5054    uint8_t splfrmIdx  = 0;
5055
5056    if(splfrmCnt > 0)
5057    {
5058       if(periodicity == RG_SCH_CMN_5_MS_PRD)
5059       {
5060          if(splfrmCnt%2)
5061          {
5062             dlSfCnt = ((splfrmCnt-1)/2) *\
5063                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5064             dlSfCnt = dlSfCnt + subfrmInfo->numFrmHf1;
5065          }
5066          else
5067          {
5068             dlSfCnt = (splfrmCnt/2) * \
5069                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5070          }
5071       }
5072       else
5073       {
5074          dlSfCnt = splfrmCnt * subfrmInfo->numFrmHf1;
5075       }
5076       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1 +\
5077                   (periodicity*splfrmCnt - dlSfCnt);
5078    }
5079    else
5080    {
5081       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1;
5082    }
5083
5084    if(splfrmIdx == curSubfrmIdx)
5085    {
5086       return (TRUE);
5087    }
5088
5089    return (FALSE);
5090 }
5091
5092 /**
5093  * @brief This function updates DAI or UL index.
5094  *
5095  * @details
5096  *
5097  *     Function: rgSCHCmnUpdHqAndDai
5098  *     Purpose:  Updates the DAI based on UL-DL Configuration
5099  *               index and UE. It also updates the HARQ feedback
5100  *               time and 'm' index.
5101  *
5102  *     Invoked by: TOM
5103  *
5104  *  @param[in]  RgDlHqProcCb  *hqP
5105  *  @param[in]  RgSchDlSf     *subFrm
5106  *  @param[in]  RgSchDlHqTbCb *tbCb
5107  *  @param[in]  uint8_t            tbAllocIdx
5108  *  @return  Void
5109  *
5110  **/
5111 static Void rgSCHCmnUpdHqAndDai(RgSchDlHqProcCb *hqP,RgSchDlSf *subFrm,RgSchDlHqTbCb *tbCb,uint8_t tbAllocIdx)
5112 {
5113    RgSchUeCb      *ue = hqP->hqE->ue;
5114    
5115
5116    if(subFrm != NULLP)
5117    {
5118       /* set the time at which UE shall send the feedback
5119        * for this process */
5120       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5121             subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5122       tbCb->fdbkTime.subframe = subFrm->dlFdbkInfo.subframe;
5123       tbCb->m = subFrm->dlFdbkInfo.m;
5124    }
5125    else
5126    {
5127       /* set the time at which UE shall send the feedback
5128        * for this process */
5129       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5130             hqP->subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5131       tbCb->fdbkTime.subframe = hqP->subFrm->dlFdbkInfo.subframe;
5132       tbCb->m = hqP->subFrm->dlFdbkInfo.m;
5133    }
5134
5135    /* ccpu00132340-MOD- DAI need to be updated for first TB only*/
5136    if(ue && !tbAllocIdx)
5137    {
5138       Bool   havePdcch = (tbCb->hqP->pdcch ? TRUE : FALSE);
5139       uint8_t     dlDai;
5140       
5141       dlDai = rgSCHCmnUpdDai(ue, &tbCb->fdbkTime, tbCb->m, havePdcch,tbCb->hqP,
5142             &tbCb->dai);
5143       if(havePdcch)
5144       {/* Non SPS occasions */
5145          tbCb->hqP->pdcch->dlDai = dlDai;
5146          /* hqP->ulDai is used for N1 resource filling
5147           * when SPS occaions present in a bundle */
5148          tbCb->hqP->ulDai = tbCb->dai;
5149          tbCb->hqP->dlDai = dlDai;
5150       }
5151    }
5152
5153    /* Updatijng pucchFdbkIdx for both PUCCH or PUSCH
5154       fdbk reception */
5155    tbCb->pucchFdbkIdx = tbCb->hqP->ulDai;
5156
5157    return;
5158 }
5159
5160
5161 /**
5162  * @brief This function updates DAI or UL index.
5163  *
5164  * @details
5165  *
5166  *     Function: rgSCHCmnUpdDai
5167  *     Purpose:  Updates the DAI in the ack-nack info, a valid
5168  *               ue should be passed
5169  *
5170  *     Invoked by: TOM
5171  *
5172  *  @param[in]  RgDlHqProcCb  *hqP
5173  *  @param[in]  RgSchDlSf     *subFrm
5174  *  @param[in]  RgSchDlHqTbCb *tbCb
5175  *  @return  uint8_t dlDai 
5176  *
5177  **/
5178 uint8_t rgSCHCmnUpdDai
5179 (
5180 RgSchUeCb       *ue,
5181 CmLteTimingInfo *fdbkTime,
5182 uint8_t         m,
5183 Bool            havePdcch,
5184 RgSchDlHqProcCb *hqP,
5185 uint8_t         *ulDai
5186 )
5187 {
5188    RgSchTddANInfo *anInfo;
5189    uint8_t servCellIdx;
5190    uint8_t ackNackFdbkArrSize;
5191
5192    if(hqP != NULLP)
5193    {/* Non SPS */
5194 #ifdef LTE_ADV
5195       servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5196             hqP->hqE->cell->cellId,
5197             ue);
5198 #else
5199      servCellIdx = RGSCH_PCELL_INDEX;
5200 #endif
5201       ackNackFdbkArrSize = hqP->hqE->cell->ackNackFdbkArrSize;
5202    }else
5203    {/* SPS on primary cell */
5204       servCellIdx = RGSCH_PCELL_INDEX;
5205       ackNackFdbkArrSize = ue->cell->ackNackFdbkArrSize;
5206    }
5207
5208
5209    anInfo = rgSCHUtlGetUeANFdbkInfo(ue, fdbkTime,servCellIdx);
5210
5211    /* If no ACK/NACK feedback already present, create a new one */
5212    if(NULLP == anInfo)
5213    {
5214       anInfo = &ue->cellInfo[servCellIdx]->anInfo[ue->cellInfo[servCellIdx]->nextFreeANIdx];
5215       anInfo->sfn = fdbkTime->sfn;
5216       anInfo->subframe = fdbkTime->subframe;
5217       anInfo->latestMIdx = m;
5218       /* Fixing DAI value - ccpu00109162 */
5219       /* Handle TDD case as in MIMO definition of the function */
5220       anInfo->ulDai = 1;
5221       if (havePdcch)
5222       {
5223          anInfo->dlDai = 1;
5224       }
5225       anInfo->isSpsOccasion = FALSE;
5226       /* set the free Index to store  Ack/Nack Information*/
5227       ue->cellInfo[servCellIdx]->nextFreeANIdx = (ue->cellInfo[servCellIdx]->nextFreeANIdx + 1) %
5228          ackNackFdbkArrSize;
5229
5230    }
5231    else
5232    {
5233       anInfo->latestMIdx = m;
5234       /* Fixing DAI value - ccpu00109162 */
5235       /* Handle TDD case as in MIMO definition of the function */
5236       anInfo->ulDai = anInfo->ulDai + 1;
5237       if (havePdcch)
5238       {
5239          anInfo->dlDai = anInfo->dlDai + 1;
5240       }
5241    }
5242 #ifdef LTE_ADV
5243    /* ignoring the Scell check,
5244     * for primary cell this field is unused*/
5245    if(hqP != NULLP)
5246    {/* SPS*/
5247       anInfo->n1ResTpcIdx = hqP->tpc;
5248    }
5249
5250    if(ulDai)
5251    {/* As this not required for release pdcch */
5252       *ulDai = anInfo->ulDai;
5253    }
5254 #endif
5255    return (anInfo->dlDai);
5256
5257 }
5258 #endif /* ifdef LTE_TDD */
5259
5260 uint32_t rgHqRvRetxCnt[4][2];
5261 uint32_t rgUlrate_grant;
5262
5263 /**
5264  * @brief This function fills the HqP TB with rbAllocInfo.
5265  *
5266  * @details
5267  *
5268  *     Function: rgSCHCmnFillHqPTb
5269  *     Purpose:  This function fills in the HqP TB with rbAllocInfo.
5270  *
5271  *     Invoked by: rgSCHCmnFillHqPTb
5272  *
5273  *  @param[in]  RgSchCellCb*      cell
5274  *  @param[in]  RgSchDlRbAlloc    *rbAllocInfo,
5275  *  @param[in]  uint8_t                tbAllocIdx
5276  *  @param[in]  RgSchPdcch        *pdcch
5277  *  @return  Void
5278  *
5279  **/
5280 #ifdef LTEMAC_SPS
5281 Void rgSCHCmnFillHqPTb
5282 (
5283 RgSchCellCb    *cell,
5284 RgSchDlRbAlloc *rbAllocInfo,
5285 uint8_t        tbAllocIdx,
5286 RgSchPdcch     *pdcch
5287 )
5288 #else
5289 static Void rgSCHCmnFillHqPTb
5290 (
5291 RgSchCellCb    *cell,
5292 RgSchDlRbAlloc *rbAllocInfo,
5293 uint8_t        tbAllocIdx,
5294 RgSchPdcch     *pdcch
5295 )
5296 #endif /* LTEMAC_SPS */
5297 {
5298    RgSchCmnDlCell     *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5299    RgSchDlTbAllocInfo *tbAllocInfo = &rbAllocInfo->tbInfo[tbAllocIdx];
5300    RgSchDlHqTbCb      *tbInfo = tbAllocInfo->tbCb;
5301    RgSchDlHqProcCb    *hqP = tbInfo->hqP;
5302
5303
5304    /*ccpu00120365-ADD-if tb is disabled, set mcs=0,rv=1.
5305     * Relevant for DCI format 2 & 2A as per 36.213-7.1.7.2
5306     */
5307    if ( tbAllocInfo->isDisabled)
5308    {
5309
5310       tbInfo->dlGrnt.iMcs = 0;
5311       tbInfo->dlGrnt.rv   = 1;
5312    }
5313    /* Fill for TB retransmission */
5314    else if (tbInfo->txCntr > 0)
5315    {
5316
5317       tbInfo->timingInfo = cmnCellDl->time;
5318       /* Fix */
5319       if ((tbInfo->isAckNackDtx == TFU_HQFDB_DTX)) 
5320       {
5321          tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;         
5322          rgHqRvRetxCnt[tbInfo->dlGrnt.rv][tbInfo->tbIdx]++;
5323       }
5324       else
5325       {
5326          tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[++(tbInfo->ccchSchdInfo.rvIdx) & 0x03];
5327       }
5328
5329       /* fill the scheduler information of hqProc */
5330       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5331       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx,hqP->tbInfo,tbInfo->tbIdx );
5332       rgSCHDhmHqTbRetx(hqP->hqE, tbInfo->timingInfo, hqP, tbInfo->tbIdx);
5333    }
5334    /* Fill for TB transmission */
5335    else
5336    {
5337       /* Fill the HqProc */
5338       tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;
5339       tbInfo->tbSz = tbAllocInfo->bytesAlloc;
5340       tbInfo->timingInfo = cmnCellDl->time;
5341
5342       tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[0];
5343       /* fill the scheduler information of hqProc */
5344       tbInfo->ccchSchdInfo.rvIdx = 0;
5345       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5346       /* DwPts Scheduling Changes Start */
5347       /* DwPts Scheduling Changes End */ 
5348       cell->measurements.dlBytesCnt += tbAllocInfo->bytesAlloc;
5349    }
5350
5351    /*ccpu00120365:-ADD-only add to subFrm list if tb is not disabled */
5352    if ( tbAllocInfo->isDisabled == FALSE )
5353    {
5354       /* Set the number of transmitting SM layers for this TB */
5355       tbInfo->numLyrs = tbAllocInfo->noLyr;
5356       /* Set the TB state as WAITING to indicate TB has been
5357        * considered for transmission */
5358       tbInfo->state  = HQ_TB_WAITING;
5359       hqP->subFrm = rbAllocInfo->dlSf;
5360       tbInfo->hqP->pdcch  = pdcch;
5361       //tbInfo->dlGrnt.numRb = rbAllocInfo->rbsAlloc;
5362       rgSCHUtlDlHqPTbAddToTx(hqP->subFrm, hqP, tbInfo->tbIdx);
5363    }
5364    return;
5365 }
5366
5367 /**
5368  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5369  *
5370  * @details
5371  *
5372  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5373  *     Purpose:  This function fills in the PDCCH information
5374  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5375  *               for dedicated service scheduling. It also
5376  *               obtains TPC to be filled in from the power module.
5377  *               Assign the PDCCH to HQProc.
5378  *
5379  *     Invoked by: Downlink Scheduler
5380  *
5381  *  @param[in]  RgSchCellCb*      cell
5382  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5383  *  @param[in]  RgDlHqProc*       hqP
5384  *  @param[out]  RgSchPdcch        *pdcch
5385  *  @param[in]   uint8_t               tpc
5386  *  @return  Void
5387  *
5388  **/
5389 static Void rgSCHCmnFillHqPPdcchDciFrmtB1B2
5390 (
5391 RgSchCellCb     *cell,
5392 RgSchDlRbAlloc  *rbAllocInfo,
5393 RgSchDlHqProcCb *hqP,
5394 RgSchPdcch      *pdcch,
5395 uint8_t         tpc
5396 )
5397 {
5398
5399
5400    rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);   
5401    //Currently hardcoding values here.
5402    //DU_LOG("\nINFO   -->  SCH : Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
5403    switch(rbAllocInfo->dciFormat)
5404    {
5405       case TFU_DCI_FORMAT_B1:
5406          {
5407             pdcch->dci.u.formatB1Info.formatType = 0;
5408             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5409             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5410             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5411             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5412             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5413             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5414             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5415             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5416             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5417             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5418             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5419             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5420             //TODO_SID: Need to update
5421             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5422             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5423             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5424             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5425             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5426             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5427             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5428             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5429             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5430             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5431             break;
5432          }
5433       case TFU_DCI_FORMAT_B2:
5434          {
5435             pdcch->dci.u.formatB2Info.formatType = 1;
5436             pdcch->dci.u.formatB2Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5437             pdcch->dci.u.formatB2Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5438             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5439             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5440             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5441             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5442             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5443             pdcch->dci.u.formatB2Info.CSI_BSI_BRI_Req = 0;
5444             pdcch->dci.u.formatB2Info.CSIRS_BRRS_TxTiming = 0;
5445             pdcch->dci.u.formatB2Info.CSIRS_BRRS_SymbIdx = 0;
5446             pdcch->dci.u.formatB2Info.CSIRS_BRRS_ProcInd = 0;
5447             pdcch->dci.u.formatB2Info.xPUCCH_TxTiming = 0;
5448             //TODO_SID: Need to update
5449             pdcch->dci.u.formatB2Info.freqResIdx_xPUCCH = 0;
5450             pdcch->dci.u.formatB2Info.beamSwitch  = 0;
5451             pdcch->dci.u.formatB2Info.SRS_Config = 0;
5452             pdcch->dci.u.formatB2Info.SRS_Symbol = 0;
5453             //TODO_SID: Need to check.Currently setting 4(2 layer, ports(8,9) w/o OCC).
5454             pdcch->dci.u.formatB2Info.AntPorts_numLayers = 4;
5455             pdcch->dci.u.formatB2Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5456             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5457             pdcch->dci.u.formatB2Info.tpcCmd = 1; //tpc;
5458             pdcch->dci.u.formatB2Info.DL_PCRS = 0;
5459             break;
5460          }
5461          default:
5462             DU_LOG("\nERROR  -->  SCH :  5GTF_ERROR Allocator's incorrect "
5463                "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5464             break;
5465    }
5466    
5467    return;
5468 }
5469
5470 uint32_t totPcellSCell;
5471 uint32_t addedForScell;
5472 uint32_t addedForScell1;
5473 uint32_t addedForScell2;
5474 /**
5475  * @brief This function fills the PDCCH information from dlProc.
5476  *
5477  * @details
5478  *
5479  *     Function: rgSCHCmnFillHqPPdcch
5480  *     Purpose:  This function fills in the PDCCH information
5481  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5482  *               for dedicated service scheduling. It also
5483  *               obtains TPC to be filled in from the power module.
5484  *               Assign the PDCCH to HQProc.
5485  *
5486  *     Invoked by: Downlink Scheduler
5487  *
5488  *  @param[in]  RgSchCellCb*      cell
5489  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5490  *  @param[in]  RgDlHqProc*       hqP
5491  *  @return  Void
5492  *
5493  **/
5494 Void rgSCHCmnFillHqPPdcch(RgSchCellCb *cell,RgSchDlRbAlloc *rbAllocInfo,RgSchDlHqProcCb *hqP)
5495 {
5496    RgSchCmnDlCell *cmnCell = RG_SCH_CMN_GET_DL_CELL(cell);
5497    RgSchPdcch     *pdcch = rbAllocInfo->pdcch;
5498    uint8_t        tpc = 1;
5499
5500
5501    if (hqP->hqE->ue)
5502    {
5503 #ifdef LTE_ADV
5504       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5505       {
5506          tpc = hqP->tpc;
5507       }
5508       else
5509 #endif
5510       {
5511          tpc = rgSCHPwrPucchTpcForUe(cell, hqP->hqE->ue);
5512       }
5513       /* Fix: syed moving this to a common function for both scheduled
5514        * and non-scheduled UEs */
5515
5516       pdcch->ue = hqP->hqE->ue;
5517       if (hqP->hqE->ue->csgMmbrSta == FALSE)
5518       {
5519          cmnCell->ncsgPrbCnt += rbAllocInfo->rbsAlloc;
5520       }
5521       cmnCell->totPrbCnt += rbAllocInfo->rbsAlloc;
5522 #ifdef TENB_STATS
5523       {
5524          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlPrbUsg += 
5525             rbAllocInfo->rbsAlloc;
5526          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw0iTbs += 
5527             rbAllocInfo->tbInfo[0].iTbs;
5528          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw0iTbs ++; 
5529          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
5530             (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5531
5532 #ifdef LTE_ADV
5533       totPcellSCell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5534       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5535       {
5536          addedForScell +=  (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5537          addedForScell1 += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
5538 /*
5539          DU_LOG("\nINFO   -->  SCH :  Hqp %d cell %d addedForScell %lu addedForScell1 %lu sfn:sf %d:%d \n",
5540          hqP->procId,
5541          hqP->hqE->cell->cellId,
5542          addedForScell,
5543          addedForScell1,
5544          cell->crntTime.sfn,
5545          cell->crntTime.slot);
5546          */
5547       }
5548 #endif
5549          hqP->hqE->cell->tenbStats->sch.dlPrbUsage[0] += 
5550             rbAllocInfo->rbsAlloc;
5551          hqP->hqE->cell->tenbStats->sch.dlSumCw0iTbs += 
5552             rbAllocInfo->tbInfo[0].iTbs;
5553          hqP->hqE->cell->tenbStats->sch.dlNumCw0iTbs ++; 
5554          hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
5555             (rbAllocInfo->tbInfo[0].bytesAlloc << 3); 
5556          if (rbAllocInfo->tbInfo[1].schdlngForTb)
5557          {
5558             hqP->hqE->cell->tenbStats->sch.dlSumCw1iTbs += 
5559                rbAllocInfo->tbInfo[1].iTbs;
5560             hqP->hqE->cell->tenbStats->sch.dlNumCw1iTbs ++; 
5561             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw1iTbs += 
5562                rbAllocInfo->tbInfo[1].iTbs;
5563             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw1iTbs ++; 
5564             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
5565                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5566
5567
5568 #ifdef LTE_ADV
5569             if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
5570             {
5571                addedForScell +=  (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5572                addedForScell2 += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5573 /*
5574          DU_LOG("\nINFO   -->  SCH :  Hqp %d cell %d addedForScell %lu addedForScell2 %lu \n",
5575          hqP->procId,
5576          hqP->hqE->cell->cellId,
5577          addedForScell,
5578          addedForScell2);
5579          */
5580             }
5581             totPcellSCell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5582 #endif
5583
5584
5585             hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
5586                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
5587          }
5588          /*
5589          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 ,
5590          cell->crntTime.sfn,
5591          cell->crntTime.slot);
5592          */
5593       }
5594 #endif
5595    }
5596
5597    pdcch->rnti                       = rbAllocInfo->rnti;
5598    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
5599    /* Update subframe and pdcch info in HqTb control block */
5600    switch(rbAllocInfo->dciFormat)
5601    {
5602 #ifdef RG_5GTF  
5603       case TFU_DCI_FORMAT_B1:
5604       case TFU_DCI_FORMAT_B2:
5605            {
5606         // DU_LOG("\nINFO   -->  SCH : RG_5GTF:: Pdcch filling with DCI format B1/B2\n");
5607               rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, \
5608                     pdcch, tpc);
5609               break;
5610            }
5611 #endif
5612       default:
5613          DU_LOG("\nERROR  -->  SCH : Allocator's incorrect dciForamt Fill for RNTI:%d",rbAllocInfo->rnti);
5614          break;
5615    }
5616    return;
5617 }
5618 #ifdef UNUSED_FUNC
5619 /**
5620  * @brief This function fills the PDCCH DCI format 1 information from dlProc.
5621  *
5622  * @details
5623  *
5624  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1
5625  *     Purpose:  This function fills in the PDCCH information
5626  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5627  *               for dedicated service scheduling. It also
5628  *               obtains TPC to be filled in from the power module.
5629  *               Assign the PDCCH to HQProc.
5630  *
5631  *     Invoked by: Downlink Scheduler
5632  *
5633  *  @param[in]  RgSchCellCb*      cell
5634  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5635  *  @param[in]  RgDlHqProc*       hqP
5636  *  @param[out]  RgSchPdcch        *pdcch
5637  *  @param[in]   uint8_t               tpc
5638  *  @return  Void
5639  *
5640  **/
5641
5642 static Void rgSCHCmnFillHqPPdcchDciFrmt1
5643 (
5644 RgSchCellCb     *cell,
5645 RgSchDlRbAlloc  *rbAllocInfo,
5646 RgSchDlHqProcCb *hqP,
5647 RgSchPdcch      *pdcch,
5648 uint8_t         tpc
5649 )
5650 {
5651
5652 #ifdef LTE_TDD
5653    RgSchTddANInfo *anInfo;
5654 #endif
5655
5656 #ifdef LTEMAC_SPS
5657 /* For activation or reactivation,
5658  * Harq ProcId should be 0 */
5659    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5660 #endif
5661
5662
5663     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5664     pdcch->dci.u.format1Info.tpcCmd = tpc;
5665      /* Avoiding this check,as we dont support Type1 RA */
5666 #ifdef RG_UNUSED
5667     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
5668     {
5669 #endif
5670        pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5671        pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5672          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5673                & 0xff);
5674        pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5675          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5676                & 0x00ff);
5677        pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5678            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5679                & 0x0000ff);
5680        pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5681            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5682 #ifdef RG_UNUSED
5683     }
5684 #endif
5685 #ifdef LTEMAC_SPS
5686     if ((!(hqP->tbInfo[0].txCntr)) &&
5687        (cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5688          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5689          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)))
5690        )
5691     {
5692        pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5693     }
5694     else
5695     {
5696       pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
5697     }
5698 #else
5699     pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
5700 #endif
5701
5702     pdcch->dci.u.format1Info.allocInfo.ndi = 
5703                         rbAllocInfo->tbInfo[0].tbCb->ndi;
5704     pdcch->dci.u.format1Info.allocInfo.mcs = 
5705                         rbAllocInfo->tbInfo[0].imcs;
5706     pdcch->dci.u.format1Info.allocInfo.rv = 
5707                         rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5708 #ifdef LTE_TDD
5709        if(hqP->hqE->ue != NULLP)
5710        {
5711 #ifdef LTE_ADV
5712            uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5713                                         hqP->hqE->cell->cellId,
5714                                         hqP->hqE->ue);
5715
5716            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5717                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5718 #else
5719            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5720                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5721 #endif
5722 #ifdef TFU_TDD
5723           if(anInfo)
5724           {
5725              pdcch->dci.u.format1Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5726           }
5727           else
5728           {
5729                /* Fixing DAI value - ccpu00109162 */
5730              pdcch->dci.u.format1Info.dai = RG_SCH_MAX_DAI_IDX;
5731           }
5732 #endif
5733        }
5734        else
5735        {
5736             /* always 0 for RACH */
5737            pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5738 #ifdef TFU_TDD
5739             /* Fixing DAI value - ccpu00109162 */
5740            pdcch->dci.u.format1Info.dai = 1;
5741 #endif
5742        }
5743 #endif
5744  
5745
5746        return;
5747 }
5748 /**
5749  * @brief This function fills the PDCCH DCI format 1A information from dlProc.
5750  *
5751  * @details
5752  *
5753  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1A
5754  *     Purpose:  This function fills in the PDCCH information
5755  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5756  *               for dedicated service scheduling. It also
5757  *               obtains TPC to be filled in from the power module.
5758  *               Assign the PDCCH to HQProc.
5759  *
5760  *     Invoked by: Downlink Scheduler
5761  *
5762  *  @param[in]  RgSchCellCb*      cell
5763  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5764  *  @param[in]  RgDlHqProc*       hqP
5765  *  @param[out]  RgSchPdcch        *pdcch
5766  *  @param[in]   uint8_t               tpc
5767  *  @return  Void
5768  *
5769  **/
5770 static Void rgSCHCmnFillHqPPdcchDciFrmt1A
5771 (
5772 RgSchCellCb     *cell,
5773 RgSchDlRbAlloc  *rbAllocInfo,
5774 RgSchDlHqProcCb *hqP,
5775 RgSchPdcch      *pdcch,
5776 uint8_t         tpc
5777 )
5778 {
5779
5780 #ifdef LTE_TDD
5781    RgSchTddANInfo     *anInfo;
5782 #endif
5783
5784 #ifdef LTEMAC_SPS
5785    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5786 #endif
5787
5788
5789     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5790     pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
5791     pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = tpc;
5792     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
5793       rbAllocInfo->tbInfo[0].imcs;
5794     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = TRUE;
5795 #ifdef LTEMAC_SPS
5796     if ((!(hqP->tbInfo[0].txCntr)) &&
5797        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5798          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5799          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
5800        ))
5801     {
5802        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = 0;
5803     }
5804     else
5805     {
5806       pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val
5807                                                 = hqP->procId;
5808     }
5809 #else
5810     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val =
5811                                               hqP->procId;
5812 #endif
5813     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = \
5814        rbAllocInfo->tbInfo[0].tbCb->ndi;
5815     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = \
5816        rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5817          /* As of now, we do not support Distributed allocations */
5818     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
5819     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
5820     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
5821             TFU_ALLOC_TYPE_RIV;
5822     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
5823     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5824                   rbAllocInfo->allocInfo.raType2.rbStart,
5825                   rbAllocInfo->allocInfo.raType2.numRb);
5826 #ifdef LTE_TDD
5827     if(hqP->hqE->ue != NULLP)
5828     {
5829 #ifdef LTE_ADV
5830        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5831                                         hqP->hqE->cell->cellId,
5832                                         hqP->hqE->ue);
5833        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5834                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5835 #else
5836        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5837                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5838 #endif
5839 #ifdef TFU_TDD
5840        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5841        if(anInfo)
5842        {
5843           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 
5844                               RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5845        }
5846        else
5847        {
5848           /* Fixing DAI value - ccpu00109162 */
5849           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = RG_SCH_MAX_DAI_IDX;
5850           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
5851                     rbAllocInfo->rnti);
5852        }
5853 #endif
5854     }
5855     else
5856     {
5857             /* always 0 for RACH */
5858        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres
5859                                                                      = FALSE;
5860 #ifdef TFU_TDD
5861        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5862             /* Fixing DAI value - ccpu00109162 */
5863        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
5864 #endif
5865     }
5866 #endif
5867  
5868     return;
5869 }       
5870 /**
5871  * @brief This function fills the PDCCH DCI format 1B information from dlProc.
5872  *
5873  * @details
5874  *
5875  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1B
5876  *     Purpose:  This function fills in the PDCCH information
5877  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5878  *               for dedicated service scheduling. It also
5879  *               obtains TPC to be filled in from the power module.
5880  *               Assign the PDCCH to HQProc.
5881  *
5882  *     Invoked by: Downlink Scheduler
5883  *
5884  *  @param[in]  RgSchCellCb*      cell
5885  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5886  *  @param[in]  RgDlHqProc*       hqP
5887  *  @param[out]  RgSchPdcch        *pdcch
5888  *  @param[in]   uint8_t               tpc
5889  *  @return  Void
5890  *
5891  **/
5892 static Void rgSCHCmnFillHqPPdcchDciFrmt1B
5893 (
5894 RgSchCellCb     *cell,
5895 RgSchDlRbAlloc  *rbAllocInfo,
5896 RgSchDlHqProcCb *hqP,
5897 RgSchPdcch      *pdcch,
5898 uint8_t         tpc
5899 )
5900 {
5901
5902 #ifdef LTE_TDD
5903    RgSchTddANInfo     *anInfo;
5904 #endif
5905
5906 #ifdef LTEMAC_SPS
5907    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
5908 #endif
5909
5910
5911     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
5912     pdcch->dci.u.format1bInfo.tpcCmd  = tpc;
5913     pdcch->dci.u.format1bInfo.allocInfo.mcs     = \
5914            rbAllocInfo->tbInfo[0].imcs;
5915 #ifdef LTEMAC_SPS
5916     if ((!(hqP->tbInfo[0].txCntr)) &&
5917        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
5918          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
5919          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
5920        ))
5921     {
5922        pdcch->dci.u.format1bInfo.allocInfo.harqProcId = 0;
5923     }
5924     else
5925     {
5926       pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
5927     }
5928 #else
5929     pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
5930 #endif
5931     pdcch->dci.u.format1bInfo.allocInfo.ndi     = \
5932           rbAllocInfo->tbInfo[0].tbCb->ndi;
5933     pdcch->dci.u.format1bInfo.allocInfo.rv      = \
5934            rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5935          /* As of now, we do not support Distributed allocations */
5936     pdcch->dci.u.format1bInfo.allocInfo.isLocal = TRUE;
5937     pdcch->dci.u.format1bInfo.allocInfo.nGap2.pres = NOTPRSNT;
5938     pdcch->dci.u.format1bInfo.allocInfo.alloc.type =
5939             TFU_ALLOC_TYPE_RIV;
5940     pdcch->dci.u.format1bInfo.allocInfo.alloc.u.riv =
5941     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5942                   rbAllocInfo->allocInfo.raType2.rbStart,
5943                   rbAllocInfo->allocInfo.raType2.numRb);
5944          /* Fill precoding Info */
5945     pdcch->dci.u.format1bInfo.allocInfo.pmiCfm = \
5946                rbAllocInfo->mimoAllocInfo.precIdxInfo >> 4;
5947     pdcch->dci.u.format1bInfo.allocInfo.tPmi   = \
5948                rbAllocInfo->mimoAllocInfo.precIdxInfo & 0x0F;
5949 #ifdef LTE_TDD
5950     if(hqP->hqE->ue != NULLP)
5951     {
5952 #ifdef LTE_ADV
5953        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5954                                         hqP->hqE->cell->cellId,
5955                                         hqP->hqE->ue);
5956        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5957              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
5958 #else
5959        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
5960              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
5961 #endif
5962 #ifdef TFU_TDD
5963        if(anInfo)
5964        {
5965           pdcch->dci.u.format1bInfo.dai = 
5966                          RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
5967        }
5968        else
5969        {
5970           pdcch->dci.u.format1bInfo.dai = RG_SCH_MAX_DAI_IDX;
5971           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
5972                    rbAllocInfo->rnti);
5973        }
5974 #endif
5975     }
5976 #endif
5977        
5978     return;
5979
5980 }
5981 /**
5982  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5983  *
5984  * @details
5985  *
5986  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5987  *     Purpose:  This function fills in the PDCCH information
5988  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5989  *               for dedicated service scheduling. It also
5990  *               obtains TPC to be filled in from the power module.
5991  *               Assign the PDCCH to HQProc.
5992  *
5993  *     Invoked by: Downlink Scheduler
5994  *
5995  *  @param[in]  RgSchCellCb*      cell
5996  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5997  *  @param[in]  RgDlHqProc*       hqP
5998  *  @param[out]  RgSchPdcch        *pdcch
5999  *  @param[in]   uint8_t               tpc
6000  *  @return  Void
6001  *
6002  **/
6003 static Void rgSCHCmnFillHqPPdcchDciFrmt2
6004 (
6005 RgSchCellCb     *cell,
6006 RgSchDlRbAlloc  *rbAllocInfo,
6007 RgSchDlHqProcCb *hqP,
6008 RgSchPdcch      *pdcch,
6009 uint8_t         tpc
6010 )
6011 {
6012
6013 #ifdef LTE_TDD
6014    RgSchTddANInfo     *anInfo;
6015 #endif
6016
6017 #ifdef LTEMAC_SPS
6018 /* ccpu00119023-ADD-For activation or reactivation,
6019  * Harq ProcId should be 0 */
6020    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6021 #endif
6022
6023
6024     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6025     /*ccpu00120365:-ADD-call also if tb is disabled */
6026     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6027         rbAllocInfo->tbInfo[1].isDisabled)
6028     {
6029         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6030     }
6031     pdcch->dci.u.format2Info.tpcCmd = tpc;
6032          /* Avoiding this check,as we dont support Type1 RA */
6033 #ifdef RG_UNUSED
6034     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6035     {
6036 #endif
6037         pdcch->dci.u.format2Info.allocInfo.isAllocType0 = TRUE;
6038         pdcch->dci.u.format2Info.allocInfo.resAllocMap[0] =
6039           ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6040                & 0xff);
6041         pdcch->dci.u.format2Info.allocInfo.resAllocMap[1] =
6042            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6043                & 0x00ff);
6044         pdcch->dci.u.format2Info.allocInfo.resAllocMap[2] =
6045                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6046                 & 0x0000ff);
6047         pdcch->dci.u.format2Info.allocInfo.resAllocMap[3] =
6048                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6049 #ifdef RG_UNUSED
6050     }
6051 #endif
6052 #ifdef LTEMAC_SPS
6053     if ((!(hqP->tbInfo[0].txCntr)) &&
6054        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6055          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6056          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6057        ))
6058     {
6059        pdcch->dci.u.format2Info.allocInfo.harqProcId = 0;
6060     }
6061     else
6062     {
6063       pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6064     }
6065 #else
6066      pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6067 #endif
6068          /* Initialize the TB info for both the TBs */
6069      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].mcs = 0;
6070      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].rv  = 1;
6071      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].mcs = 0;
6072      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].rv  = 1;
6073          /* Fill tbInfo for scheduled TBs */
6074      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6075         tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6076      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6077         tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6078      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6079             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6080           /* If we reach this function. It is safely assumed that
6081            *  rbAllocInfo->tbInfo[0] always has non default valid values.
6082            *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6083      if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6084      {
6085             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6086                 tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6087             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6088                 tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6089             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6090                 tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6091      }
6092      pdcch->dci.u.format2Info.allocInfo.transSwap =
6093              rbAllocInfo->mimoAllocInfo.swpFlg;
6094      pdcch->dci.u.format2Info.allocInfo.precoding =
6095              rbAllocInfo->mimoAllocInfo.precIdxInfo;
6096 #ifdef LTE_TDD
6097      if(hqP->hqE->ue != NULLP)
6098      {
6099
6100 #ifdef LTE_ADV
6101         uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6102                                         hqP->hqE->cell->cellId,
6103                                         hqP->hqE->ue);
6104         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6105                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6106 #else
6107         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6108                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6109 #endif
6110 #ifdef TFU_TDD
6111         if(anInfo)
6112         {
6113            pdcch->dci.u.format2Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6114         }
6115         else
6116         {
6117            pdcch->dci.u.format2Info.dai = RG_SCH_MAX_DAI_IDX;
6118            DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
6119                     rbAllocInfo->rnti);
6120         }
6121 #endif
6122      }
6123 #endif
6124
6125      return;
6126 }
6127 /**
6128  * @brief This function fills the PDCCH DCI format 2A information from dlProc.
6129  *
6130  * @details
6131  *
6132  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2A
6133  *     Purpose:  This function fills in the PDCCH information
6134  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6135  *               for dedicated service scheduling. It also
6136  *               obtains TPC to be filled in from the power module.
6137  *               Assign the PDCCH to HQProc.
6138  *
6139  *     Invoked by: Downlink Scheduler
6140  *
6141  *  @param[in]  RgSchCellCb*      cell
6142  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6143  *  @param[in]  RgDlHqProc*       hqP
6144  *  @param[out]  RgSchPdcch        *pdcch
6145  *  @param[in]   uint8_t               tpc
6146  *  @return  Void
6147  *
6148  **/
6149 static Void rgSCHCmnFillHqPPdcchDciFrmt2A
6150 (
6151 RgSchCellCb     *cell,
6152 RgSchDlRbAlloc  *rbAllocInfo,
6153 RgSchDlHqProcCb *hqP,
6154 RgSchPdcch      *pdcch,
6155 uint8_t         tpc
6156 )
6157 {
6158 #ifdef LTE_TDD
6159    RgSchTddANInfo     *anInfo;
6160 #endif
6161
6162 #ifdef LTEMAC_SPS
6163    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6164 #endif
6165
6166
6167     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6168     /*ccpu00120365:-ADD-call also if tb is disabled */
6169     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6170           rbAllocInfo->tbInfo[1].isDisabled)
6171     {
6172
6173         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6174     }
6175
6176     pdcch->dci.u.format2AInfo.tpcCmd = tpc;
6177          /* Avoiding this check,as we dont support Type1 RA */
6178 #ifdef RG_UNUSED
6179     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6180     {
6181 #endif
6182         pdcch->dci.u.format2AInfo.allocInfo.isAllocType0 = TRUE;
6183         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[0] =
6184               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6185                & 0xff);
6186         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[1] =
6187               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6188                & 0x00ff);
6189         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[2] =
6190                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6191                 & 0x0000ff);
6192         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[3] =
6193                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6194 #ifdef RG_UNUSED
6195     }
6196 #endif
6197 #ifdef LTEMAC_SPS
6198     if ((!(hqP->tbInfo[0].txCntr)) &&
6199        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6200          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6201          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6202        ))
6203     {
6204        pdcch->dci.u.format2AInfo.allocInfo.harqProcId = 0;
6205     }
6206     else
6207     {
6208       pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6209     }
6210 #else
6211     pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6212 #endif
6213          /* Initialize the TB info for both the TBs */
6214     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].mcs = 0;
6215     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].rv  = 1;
6216     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].mcs = 0;
6217     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].rv  = 1;
6218          /* Fill tbInfo for scheduled TBs */
6219     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6220             tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6221     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6222             tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6223     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6224             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6225          /* If we reach this function. It is safely assumed that
6226           *  rbAllocInfo->tbInfo[0] always has non default valid values.
6227           *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6228
6229     if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6230     {
6231             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6232                tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6233             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6234                tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6235             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6236                tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6237
6238     }
6239     pdcch->dci.u.format2AInfo.allocInfo.transSwap =
6240             rbAllocInfo->mimoAllocInfo.swpFlg;
6241     pdcch->dci.u.format2AInfo.allocInfo.precoding =
6242             rbAllocInfo->mimoAllocInfo.precIdxInfo;
6243 #ifdef LTE_TDD
6244     if(hqP->hqE->ue != NULLP)
6245     {
6246 #ifdef LTE_ADV
6247        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6248                                         hqP->hqE->cell->cellId,
6249                                         hqP->hqE->ue);
6250        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6251                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6252 #else
6253        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6254                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6255 #endif
6256 #ifdef TFU_TDD
6257        if(anInfo)
6258        {
6259           pdcch->dci.u.format2AInfo.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6260        }
6261        else
6262        {
6263           pdcch->dci.u.format2AInfo.dai = RG_SCH_MAX_DAI_IDX;
6264           DU_LOG("\nERROR  -->  SCH : PDCCH is been scheduled without updating anInfo RNTI:%d",
6265                    rbAllocInfo->rnti);
6266        }
6267 #endif
6268      }
6269 #endif
6270
6271
6272     return;
6273 }
6274 #endif
6275 /**
6276  * @brief init of Sch vars.
6277  *
6278  * @details
6279  *
6280  *     Function: rgSCHCmnInitVars
6281        Purpose:  Initialization of various UL subframe indices
6282  *
6283  *  @param[in]  RgSchCellCb *cell
6284  *  @return  Void
6285  *
6286  **/
6287 static Void rgSCHCmnInitVars(RgSchCellCb *cell)
6288 {
6289    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6290
6291
6292    cellUl->idx         = RGSCH_INVALID_INFO;
6293    cellUl->schdIdx     = RGSCH_INVALID_INFO;
6294    cellUl->schdHqProcIdx = RGSCH_INVALID_INFO;
6295    cellUl->msg3SchdIdx = RGSCH_INVALID_INFO;
6296 #ifdef EMTC_ENBLE
6297    cellUl->emtcMsg3SchdIdx = RGSCH_INVALID_INFO;
6298 #endif
6299    cellUl->msg3SchdHqProcIdx = RGSCH_INVALID_INFO;
6300    cellUl->rcpReqIdx   = RGSCH_INVALID_INFO;
6301    cellUl->hqFdbkIdx[0] = RGSCH_INVALID_INFO;
6302    cellUl->hqFdbkIdx[1] = RGSCH_INVALID_INFO;
6303    cellUl->reTxIdx[0]   = RGSCH_INVALID_INFO;
6304    cellUl->reTxIdx[1]   = RGSCH_INVALID_INFO;
6305   /* Stack Crash problem for TRACE5 Changes. Added the return below */
6306   return;
6307
6308 }
6309
6310 #ifndef LTE_TDD
6311 /**
6312  * @brief Updation of Sch vars per TTI.
6313  *
6314  * @details
6315  *
6316  *     Function: rgSCHCmnUpdVars
6317  *     Purpose:  Updation of Sch vars per TTI.
6318  *
6319  *  @param[in]  RgSchCellCb *cell
6320  *  @return  Void
6321  *
6322  **/
6323 Void rgSCHCmnUpdVars(RgSchCellCb *cell)
6324 {
6325    CmLteTimingInfo   timeInfo;
6326    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6327    uint16_t idx;
6328
6329
6330    idx = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot);
6331    cellUl->idx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6332 #ifdef UL_ADPT_DBG     
6333    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);
6334 #endif    
6335    /* Need to scheduler for after SCHED_DELTA */
6336    /* UL allocation has been advanced by 1 subframe
6337     * so that we do not wrap around and send feedback
6338     * before the data is even received by the PHY */
6339    /* Introduced timing delta for UL control */
6340    idx = (cellUl->idx + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA);
6341    cellUl->schdIdx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6342
6343    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6344             TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)
6345    cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6346
6347    /* ccpu00127193 filling schdTime for logging and enhancement purpose*/
6348    cellUl->schdTime = timeInfo;
6349
6350    /* msg3 scheduling two subframes after general scheduling */
6351    idx = (cellUl->idx + RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA);
6352    cellUl->msg3SchdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6353
6354    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6355             RG_SCH_CMN_DL_DELTA+ RGSCH_RARSP_MSG3_DELTA)
6356    cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6357
6358    idx = (cellUl->idx + TFU_RECPREQ_DLDELTA);
6359
6360    cellUl->rcpReqIdx   = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6361
6362    /* Downlink harq feedback is sometime after data reception / harq failure */
6363    /* Since feedback happens prior to scheduling being called, we add 1 to   */
6364    /* take care of getting the correct subframe for feedback                 */
6365    idx = (cellUl->idx - TFU_CRCIND_ULDELTA + RG_SCH_CMN_UL_NUM_SF);
6366 #ifdef UL_ADPT_DBG     
6367    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);
6368 #endif
6369    cellUl->hqFdbkIdx[0]   = (idx % (RG_SCH_CMN_UL_NUM_SF));
6370
6371    idx = ((cellUl->schdIdx) % (RG_SCH_CMN_UL_NUM_SF));
6372
6373    cellUl->reTxIdx[0] = (uint8_t) idx;
6374 #ifdef UL_ADPT_DBG     
6375    DU_LOG("\nDEBUG  -->  SCH : cellUl->hqFdbkIdx[0] %d cellUl->reTxIdx[0] %d \n",cellUl->hqFdbkIdx[0], cellUl->reTxIdx[0] );
6376 #endif
6377    /* RACHO: update cmn sched specific RACH variables,
6378     * mainly the prachMaskIndex */
6379    rgSCHCmnUpdRachParam(cell);
6380
6381    return;
6382 }
6383 #endif
6384
6385 #ifdef LTE_TDD
6386
6387 /**
6388  * @brief To get uplink subframe index associated with current PHICH
6389  *        transmission.
6390  *
6391  * @details
6392  *
6393  *     Function: rgSCHCmnGetPhichUlSfIdx
6394  *     Purpose:  Gets uplink subframe index associated with current PHICH
6395  *               transmission based on SFN and subframe no
6396  *
6397  *  @param[in]  CmLteTimingInfo  *timeInfo
6398  *  @param[in]  RgSchCellCb              *cell
6399  *  @return uint8_t
6400  *
6401  **/
6402 uint8_t  rgSCHCmnGetPhichUlSfIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6403 {
6404    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6405    RgSchDlSf       *dlsf;
6406    uint8_t         ulDlCfgIdx = cell->ulDlCfgIdx;
6407    uint8_t         idx;
6408    uint16_t        numUlSf;
6409    uint16_t        sfn;
6410    uint8_t         subframe;
6411
6412
6413    dlsf = rgSCHUtlSubFrmGet(cell, *timeInfo);
6414
6415    if(dlsf->phichOffInfo.sfnOffset == RGSCH_INVALID_INFO)
6416    {
6417       return (RGSCH_INVALID_INFO);
6418    }
6419    subframe = dlsf->phichOffInfo.subframe;
6420
6421    sfn = (RGSCH_MAX_SFN + timeInfo->sfn -
6422                    dlsf->phichOffInfo.sfnOffset) % RGSCH_MAX_SFN;
6423
6424    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
6425     * wrap case such that idx will be proper*/
6426    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6427    numUlSf = ((numUlSf * sfn) + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subframe]) - 1;
6428    idx = numUlSf % (cellUl->numUlSubfrms);
6429
6430    return (idx);
6431 }
6432
6433 /**
6434  * @brief To get uplink subframe index.
6435  *
6436  * @details
6437  *
6438  *
6439  *     Function: rgSCHCmnGetUlSfIdx
6440  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
6441  *
6442  *  @param[in]  CmLteTimingInfo  *timeInfo
6443  *  @param[in]  uint8_t               ulDlCfgIdx
6444  *  @return uint8_t
6445  *
6446  **/
6447 uint8_t  rgSCHCmnGetUlSfIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6448 {
6449    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6450    uint8_t  ulDlCfgIdx = cell->ulDlCfgIdx;
6451    uint8_t  idx = 0;
6452    uint16_t numUlSf;
6453
6454
6455    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
6456     * wrap case such that idx will be proper*/
6457    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6458    numUlSf = ((numUlSf * timeInfo->sfn) + \
6459          rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe]) - 1;
6460    idx = numUlSf % (cellUl->numUlSubfrms);
6461
6462    return (idx);
6463 }
6464
6465 #endif
6466
6467 /**
6468  * @brief To get uplink hq index.
6469  *
6470  * @details
6471  *
6472  *
6473  *     Function: rgSCHCmnGetUlHqProcIdx
6474  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
6475  *
6476  *  @param[in]  CmLteTimingInfo  *timeInfo
6477  *  @param[in]  uint8_t               ulDlCfgIdx
6478  *  @return uint8_t
6479  *
6480  **/
6481 uint8_t  rgSCHCmnGetUlHqProcIdx(CmLteTimingInfo *timeInfo,RgSchCellCb *cell)
6482 {
6483    uint8_t  procId;
6484    uint32_t numUlSf;
6485   
6486 #ifndef LTE_TDD
6487    numUlSf  = (timeInfo->sfn * RGSCH_NUM_SUB_FRAMES_5G + timeInfo->slot);
6488    procId   = numUlSf % RGSCH_NUM_UL_HQ_PROC;
6489 #else
6490    uint8_t  ulDlCfgIdx = cell->ulDlCfgIdx;
6491    /*ccpu00130639 - MOD - To get correct UL HARQ Proc IDs for all UL/DL Configs*/
6492    uint8_t  numUlSfInSfn;
6493    S8       sfnCycle = cell->tddHqSfnCycle;
6494    uint8_t  numUlHarq = rgSchTddUlNumHarqProcTbl[ulDlCfgIdx]
6495
6496    /* TRACE 5 Changes */
6497
6498    /* Calculate the number of UL SF in one SFN */
6499    numUlSfInSfn = RGSCH_NUM_SUB_FRAMES -
6500                rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6501
6502    /* Check for the SFN wrap around case */
6503    if(cell->crntTime.sfn == 1023 && timeInfo->sfn == 0)
6504    {
6505       sfnCycle++;
6506    }
6507    else if(cell->crntTime.sfn == 0 && timeInfo->sfn == 1023)
6508    {
6509       /* sfnCycle decremented by 1 */
6510       sfnCycle = (sfnCycle + numUlHarq-1) % numUlHarq;
6511    }
6512    /* Calculate the total number of UL sf */
6513    /*  -1 is done since uplink sf are counted from 0 */
6514    numUlSf = numUlSfInSfn *  (timeInfo->sfn + (sfnCycle*1024)) +
6515                   rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->slot] - 1;
6516
6517    procId = numUlSf % numUlHarq;   
6518 #endif
6519    return (procId);
6520 }
6521
6522
6523 /* UL_ALLOC_CHANGES */
6524 /***********************************************************
6525  *
6526  *     Func : rgSCHCmnUlFreeAlloc
6527  *
6528  *     Desc : Free an allocation - invokes UHM and releases
6529  *            alloc for the scheduler
6530  *            Doest need subframe as argument
6531  *
6532  *     Ret  :
6533  *
6534  *     Notes:
6535  *
6536  *     File :
6537  *
6538  **********************************************************/
6539 Void rgSCHCmnUlFreeAlloc(RgSchCellCb *cell,RgSchUlAlloc *alloc)
6540 {
6541    RgSchUlHqProcCb *hqProc;
6542
6543    if (alloc->forMsg3)
6544    {
6545       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
6546       if ((alloc->hqProc->remTx == 0) &&
6547           (alloc->hqProc->rcvdCrcInd == FALSE) &&
6548           (alloc->raCb))
6549       {
6550          RgSchRaCb      *raCb = alloc->raCb;
6551          rgSCHUhmFreeProc(alloc->hqProc, cell);
6552          rgSCHUtlUlAllocRelease(alloc);
6553          rgSCHRamDelRaCb(cell, raCb, TRUE);
6554          return;
6555       }
6556    }
6557    
6558    hqProc = alloc->hqProc;
6559    rgSCHUtlUlAllocRelease(alloc);
6560    rgSCHUhmFreeProc(hqProc, cell);
6561    return;
6562 }
6563
6564
6565 /***********************************************************
6566  *
6567  *     Func : rgSCHCmnUlFreeAllocation
6568  *
6569  *     Desc : Free an allocation - invokes UHM and releases
6570  *            alloc for the scheduler
6571  *
6572  *     Ret  :
6573  *
6574  *     Notes:
6575  *
6576  *     File :
6577  *
6578  **********************************************************/
6579 Void rgSCHCmnUlFreeAllocation(RgSchCellCb *cell,RgSchUlSf *sf,RgSchUlAlloc *alloc)
6580 {
6581    RgSchUlHqProcCb *hqProc;
6582
6583
6584    if (alloc->forMsg3)
6585    {
6586       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
6587       if ((alloc->hqProc->remTx == 0) &&
6588           (alloc->hqProc->rcvdCrcInd == FALSE) &&
6589           (alloc->raCb))
6590       {
6591          RgSchRaCb      *raCb = alloc->raCb;
6592          rgSCHUhmFreeProc(alloc->hqProc, cell);
6593          rgSCHUtlUlAllocRls(sf, alloc);
6594          rgSCHRamDelRaCb(cell, raCb, TRUE);
6595          return;
6596       }
6597    }
6598    
6599    hqProc = alloc->hqProc;
6600    rgSCHUhmFreeProc(hqProc, cell);
6601 #ifdef LTE_L2_MEAS
6602    /* re-setting the PRB count while freeing the allocations */
6603    sf->totPrb = 0;
6604 #endif
6605    rgSCHUtlUlAllocRls(sf, alloc);
6606
6607    return;
6608 }
6609
6610 /**
6611  * @brief This function implements PDCCH allocation for an UE
6612  *        in the currently running subframe.
6613  *
6614  * @details
6615  *
6616  *     Function: rgSCHCmnPdcchAllocCrntSf
6617  *     Purpose:  This function determines current DL subframe
6618  *               and UE DL CQI to call the actual pdcch allocator
6619  *               function.
6620  *               Note that this function is called only
6621  *               when PDCCH request needs to be made during
6622  *               uplink scheduling.
6623  *
6624  *     Invoked by: Scheduler
6625  *
6626  *  @param[in]  RgSchCellCb  *cell
6627  *  @param[in]  RgSchUeCb    *ue
6628  *  @return  RgSchPdcch *
6629  *         -# NULLP when unsuccessful
6630  **/
6631 RgSchPdcch *rgSCHCmnPdcchAllocCrntSf(RgSchCellCb *cell,RgSchUeCb *ue)
6632 {
6633    CmLteTimingInfo frm = cell->crntTime;
6634    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
6635    RgSchDlSf       *sf;
6636    RgSchPdcch      *pdcch = NULLP;
6637
6638    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
6639    sf = rgSCHUtlSubFrmGet(cell, frm);
6640
6641 #ifdef LTE_ADV
6642    if (ue->allocCmnUlPdcch)
6643    {
6644       pdcch = rgSCHCmnCmnPdcchAlloc(cell, sf);
6645       /* Since CRNTI Scrambled */
6646       if(NULLP != pdcch)
6647       {
6648          pdcch->dciNumOfBits = ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
6649       }
6650    }
6651    else
6652 #endif
6653    {
6654       //pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, y, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_0, FALSE);
6655                 pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_A1, FALSE);
6656    }
6657    return (pdcch);
6658 }
6659
6660 /***********************************************************
6661  *
6662  *     Func : rgSCHCmnUlAllocFillNdmrs
6663  *
6664  *     Desc : Determines and fills N_dmrs for a UE uplink
6665  *            allocation.
6666  *
6667  *     Ret  :
6668  *
6669  *     Notes: N_dmrs determination is straightforward, so
6670  *            it is configured per subband
6671  *
6672  *     File :
6673  *
6674  **********************************************************/
6675 Void rgSCHCmnUlAllocFillNdmrs(RgSchCmnUlCell *cellUl,RgSchUlAlloc *alloc)
6676 {
6677    alloc->grnt.nDmrs = cellUl->dmrsArr[alloc->sbStart];
6678    return;
6679 }
6680
6681 /***********************************************************
6682  *
6683  *     Func : rgSCHCmnUlAllocLnkHqProc
6684  *
6685  *     Desc : Links a new allocation for an UE with the
6686  *            appropriate HARQ process of the UE.
6687  *
6688  *     Ret  :
6689  *
6690  *     Notes:
6691  *
6692  *     File :
6693  *
6694  **********************************************************/
6695 Void rgSCHCmnUlAllocLnkHqProc(RgSchUeCb *ue,RgSchUlAlloc *alloc,RgSchUlHqProcCb *proc,Bool isRetx)
6696 {
6697
6698    if(TRUE == isRetx)
6699    {
6700       rgSCHCmnUlAdapRetx(alloc, proc);
6701    }
6702    else
6703    {
6704 #ifdef LTE_L2_MEAS /* L2_COUNTERS */
6705       alloc->ue = ue;
6706 #endif
6707       rgSCHUhmNewTx(proc, (((RgUeUlHqCb*)proc->hqEnt)->maxHqRetx), alloc);
6708    }
6709    return;
6710 }
6711
6712 /**
6713  * @brief This function releases a PDCCH in the subframe that is
6714  *        currently being allocated for.
6715  *
6716  * @details
6717  *
6718  *     Function: rgSCHCmnPdcchRlsCrntSf
6719  *     Purpose:  This function determines current DL subframe
6720  *               which is considered for PDCCH allocation,
6721  *               and then calls the actual function that
6722  *               releases a PDCCH in a specific subframe.
6723  *               Note that this function is called only
6724  *               when PDCCH release needs to be made during
6725  *               uplink scheduling.
6726  *
6727  *     Invoked by: Scheduler
6728  *
6729  *  @param[in]  RgSchCellCb  *cell
6730  *  @param[in]  RgSchPdcch   *pdcch
6731  *  @return  Void
6732  **/
6733 Void rgSCHCmnPdcchRlsCrntSf(RgSchCellCb *cell,RgSchPdcch *pdcch)
6734 {
6735    CmLteTimingInfo frm = cell->crntTime;
6736    RgSchDlSf *sf;
6737
6738    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
6739    sf = rgSCHUtlSubFrmGet(cell, frm);
6740    rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, pdcch);
6741    return;
6742 }
6743 /***********************************************************
6744  *
6745  *     Func : rgSCHCmnUlFillPdcchWithAlloc
6746  *
6747  *     Desc : Fills a PDCCH with format 0 information.
6748  *
6749  *     Ret  :
6750  *
6751  *     Notes:
6752  *
6753  *     File :
6754  *
6755  **********************************************************/
6756 Void rgSCHCmnUlFillPdcchWithAlloc(RgSchPdcch *pdcch,RgSchUlAlloc *alloc,RgSchUeCb *ue)
6757 {
6758
6759    pdcch->ue = ue;
6760    pdcch->rnti = alloc->rnti;
6761    //pdcch->dci.dciFormat = TFU_DCI_FORMAT_A2;
6762    pdcch->dci.dciFormat = alloc->grnt.dciFrmt;
6763
6764    //Currently hardcoding values here.
6765    //DU_LOG("\nINFO   -->  SCH : Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
6766    switch(pdcch->dci.dciFormat)
6767    {
6768       case TFU_DCI_FORMAT_A1:
6769                 {
6770                         pdcch->dci.u.formatA1Info.formatType = 0;
6771          pdcch->dci.u.formatA1Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
6772          pdcch->dci.u.formatA1Info.xPUSCH_TxTiming = 0;
6773          pdcch->dci.u.formatA1Info.RBAssign = alloc->grnt.rbAssign;
6774          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
6775          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
6776          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
6777          pdcch->dci.u.formatA1Info.CSI_BSI_BRI_Req = 0;
6778          pdcch->dci.u.formatA1Info.CSIRS_BRRS_TxTiming = 0;
6779          pdcch->dci.u.formatA1Info.CSIRS_BRRS_SymbIdx = 0;
6780          pdcch->dci.u.formatA1Info.CSIRS_BRRS_ProcInd = 0;
6781          pdcch->dci.u.formatA1Info.numBSI_Reports = 0;
6782          pdcch->dci.u.formatA1Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
6783          pdcch->dci.u.formatA1Info.beamSwitch  = 0;
6784          pdcch->dci.u.formatA1Info.SRS_Config = 0;
6785          pdcch->dci.u.formatA1Info.SRS_Symbol = 0;
6786          pdcch->dci.u.formatA1Info.REMapIdx_DMRS_PCRS_numLayers = 0;
6787          pdcch->dci.u.formatA1Info.SCID = alloc->grnt.SCID;
6788          pdcch->dci.u.formatA1Info.PMI = alloc->grnt.PMI;
6789          pdcch->dci.u.formatA1Info.UL_PCRS = 0;
6790          pdcch->dci.u.formatA1Info.tpcCmd = alloc->grnt.tpc;
6791                         break;
6792       }
6793                 case TFU_DCI_FORMAT_A2:
6794                 {
6795                         pdcch->dci.u.formatA2Info.formatType = 1;
6796          pdcch->dci.u.formatA2Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
6797          pdcch->dci.u.formatA2Info.xPUSCH_TxTiming = 0;
6798          pdcch->dci.u.formatA2Info.RBAssign = alloc->grnt.rbAssign;
6799          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
6800          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
6801          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
6802          pdcch->dci.u.formatA2Info.CSI_BSI_BRI_Req = 0;
6803          pdcch->dci.u.formatA2Info.CSIRS_BRRS_TxTiming = 0;
6804          pdcch->dci.u.formatA2Info.CSIRS_BRRS_SymbIdx = 0;
6805          pdcch->dci.u.formatA2Info.CSIRS_BRRS_ProcInd = 0;
6806          pdcch->dci.u.formatA2Info.numBSI_Reports = 0;
6807          pdcch->dci.u.formatA2Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
6808          pdcch->dci.u.formatA2Info.beamSwitch  = 0;
6809          pdcch->dci.u.formatA2Info.SRS_Config = 0;
6810          pdcch->dci.u.formatA2Info.SRS_Symbol = 0;
6811          pdcch->dci.u.formatA2Info.REMapIdx_DMRS_PCRS_numLayers = 0;
6812          pdcch->dci.u.formatA2Info.SCID = alloc->grnt.SCID;
6813          pdcch->dci.u.formatA2Info.PMI = alloc->grnt.PMI;
6814          pdcch->dci.u.formatA2Info.UL_PCRS = 0;
6815          pdcch->dci.u.formatA2Info.tpcCmd = alloc->grnt.tpc;
6816                         break;
6817                 }
6818       default:
6819          DU_LOG("\nERROR  -->  SCH :  5GTF_ERROR UL Allocator's icorrect "
6820                "dciForamt Fill RNTI:%d",alloc->rnti);
6821          break;
6822    }    
6823    
6824
6825    return;
6826 }
6827
6828 /***********************************************************
6829  *
6830  *     Func : rgSCHCmnUlAllocFillTpc
6831  *
6832  *     Desc : Determines and fills TPC for an UE allocation.
6833  *
6834  *     Ret  :
6835  *
6836  *     Notes:
6837  *
6838  *     File :
6839  *
6840  **********************************************************/
6841 Void rgSCHCmnUlAllocFillTpc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchUlAlloc *alloc)
6842 {
6843    alloc->grnt.tpc = rgSCHPwrPuschTpcForUe(cell, ue);
6844    return;
6845 }
6846
6847
6848 /***********************************************************
6849  *
6850  *     Func : rgSCHCmnAddUeToRefreshQ
6851  *
6852  *     Desc : Adds a UE to refresh queue, so that the UE is
6853  *            periodically triggered to refresh it's GBR and
6854  *            AMBR values.
6855  *
6856  *     Ret  :
6857  *
6858  *     Notes:
6859  *
6860  *     File :
6861  *
6862  **********************************************************/
6863 static Void rgSCHCmnAddUeToRefreshQ(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t wait)
6864 {
6865    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
6866    CmTmrArg       arg;
6867    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
6868
6869    UNUSED(cell);
6870
6871    memset(&arg, 0, sizeof(arg));
6872    arg.tqCp   = &sched->tmrTqCp;
6873    arg.tq     = sched->tmrTq;
6874    arg.timers = &ueSchd->tmr;
6875    arg.cb     = (PTR)ue;
6876    arg.tNum   = 0;
6877    arg.max    = 1;
6878    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
6879    arg.wait   = wait;
6880    cmPlcCbTq(&arg);
6881    return;
6882 }
6883
6884 /**
6885  * @brief Perform UE reset procedure.
6886  *
6887  * @details
6888  *
6889  *     Function : rgSCHCmnUlUeReset
6890  *
6891  *     This functions performs BSR resetting and
6892  *     triggers UL specific scheduler
6893  *     to Perform UE reset procedure.
6894  *
6895  *  @param[in]  RgSchCellCb  *cell
6896  *  @param[in]  RgSchUeCb    *ue
6897  *  @return  Void
6898  **/
6899 static Void rgSCHCmnUlUeReset(RgSchCellCb  *cell,RgSchUeCb    *ue)
6900 {
6901    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
6902    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
6903    uint8_t              lcgCnt=0;
6904    RgSchCmnLcg          *lcgCmn;
6905    CmLList              *node;
6906    RgSchCmnAllocRecord  *allRcd;
6907
6908    ue->ul.minReqBytes = 0;
6909    ue->ul.totalBsr = 0;
6910    ue->ul.effBsr = 0;
6911    ue->ul.nonGbrLcgBs = 0;
6912    ue->ul.effAmbr = ue->ul.cfgdAmbr;
6913
6914    node = ueUl->ulAllocLst.first;
6915    while (node)
6916    {
6917       allRcd = (RgSchCmnAllocRecord *)node->node;
6918       allRcd->alloc = 0;
6919       node = node->next;
6920    }
6921    for(lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++)
6922    {
6923       lcgCmn = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[lcgCnt]);
6924       lcgCmn->bs = 0;
6925       lcgCmn->reportedBs = 0;
6926       lcgCmn->effGbr = lcgCmn->cfgdGbr;
6927       lcgCmn->effDeltaMbr = lcgCmn->deltaMbr;
6928    }
6929    rgSCHCmnUlUeDelAllocs(cell, ue);
6930
6931    ue->isSrGrant = FALSE;
6932
6933    cellSchd->apisUl->rgSCHUlUeReset(cell, ue);
6934
6935    /* Stack Crash problem for TRACE5 changes. Added the return below */
6936    return;
6937
6938 }
6939
6940 /**
6941  * @brief RESET UL CQI and DL CQI&RI to conservative values
6942     * for a reestablishing UE.
6943  *
6944  * @details
6945  *
6946  *     Function : rgSCHCmnResetRiCqi 
6947  *     
6948  *     RESET UL CQI and DL CQI&RI to conservative values
6949  *     for a reestablishing UE
6950  *
6951  *  @param[in]  RgSchCellCb  *cell
6952  *  @param[in]  RgSchUeCb    *ue
6953  *  @return  Void
6954  **/
6955 static Void rgSCHCmnResetRiCqi(RgSchCellCb *cell,RgSchUeCb *ue)
6956 {
6957    RgSchCmnCell  *cellSchd = RG_SCH_CMN_GET_CELL(cell);
6958    RgSchCmnUe    *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
6959    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
6960    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
6961
6962
6963    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, 
6964          cell->isCpUlExtend);
6965
6966    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
6967    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
6968    ueDl->mimoInfo.ri = 1;
6969    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
6970           (ue->mimoInfo.txMode == RGR_UE_TM_6))
6971    {
6972       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
6973    }
6974    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
6975    {
6976       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
6977    }
6978 #ifdef EMTC_ENABLE   
6979    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
6980 #else
6981    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
6982 #endif      
6983
6984 #ifdef TFU_UPGRADE
6985    /* Request for an early Aper CQI in case of reest */
6986    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
6987    if(acqiCb && acqiCb->aCqiCfg.pres)
6988    {
6989       acqiCb->aCqiTrigWt = 0;
6990    }
6991 #endif   
6992
6993    return;
6994 }
6995
6996 /**
6997  * @brief Perform UE reset procedure.
6998  *
6999  * @details
7000  *
7001  *     Function : rgSCHCmnDlUeReset
7002  *
7003  *     This functions performs BO resetting and
7004  *     triggers DL specific scheduler
7005  *     to Perform UE reset procedure.
7006  *
7007  *  @param[in]  RgSchCellCb  *cell
7008  *  @param[in]  RgSchUeCb    *ue
7009  *  @return  Void
7010  **/
7011 static Void rgSCHCmnDlUeReset(RgSchCellCb  *cell,RgSchUeCb *ue)
7012 {
7013    RgSchCmnCell   *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7014    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
7015    RgSchCmnDlUe   *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7016
7017
7018    if (ueDl->rachInfo.poLnk.node != NULLP)
7019    {
7020       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
7021    }
7022
7023    /* Fix: syed Remove from TA List if this UE is there.
7024     * If TA Timer is running. Stop it */
7025    if (ue->dlTaLnk.node)
7026    {
7027       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
7028       ue->dlTaLnk.node = (PTR)NULLP;
7029    }
7030    else if (ue->taTmr.tmrEvnt != TMR_NONE)
7031    {
7032       rgSCHTmrStopTmr(cell, ue->taTmr.tmrEvnt, ue);
7033    }
7034
7035    cellSchd->apisDl->rgSCHDlUeReset(cell, ue);
7036 #ifdef LTE_ADV
7037    if (ue->numSCells)
7038    {
7039       rgSCHSCellDlUeReset(cell,ue);
7040    }
7041 #endif
7042 }
7043
7044 /**
7045  * @brief Perform UE reset procedure.
7046  *
7047  * @details
7048  *
7049  *     Function : rgSCHCmnUeReset
7050  *
7051  *     This functions triggers specific scheduler
7052  *     to Perform UE reset procedure.
7053  *
7054  *  @param[in]  RgSchCellCb  *cell
7055  *  @param[in]  RgSchUeCb    *ue
7056  *  @return  S16
7057  *      -# ROK
7058  *      -# RFAILED
7059  **/
7060 Void rgSCHCmnUeReset(RgSchCellCb  *cell,RgSchUeCb *ue)
7061 {
7062    uint8_t idx;
7063    Pst     pst;
7064    RgInfResetHqEnt   hqEntRstInfo;
7065
7066    /* RACHO: remove UE from pdcch, handover and rapId assoc Qs */
7067    rgSCHCmnDelRachInfo(cell, ue);
7068
7069    rgSCHPwrUeReset(cell, ue);
7070
7071    rgSCHCmnUlUeReset(cell, ue);
7072    rgSCHCmnDlUeReset(cell, ue);
7073    
7074 #ifdef LTE_ADV
7075    /* Making allocCmnUlPdcch TRUE to allocate DCI0/1A from Common search space.
7076       As because multiple cells are added hence 2 bits CqiReq is there 
7077       This flag will be set to FALSE once we will get Scell READY */
7078    ue->allocCmnUlPdcch = TRUE;
7079 #endif
7080
7081    /* Fix : syed RESET UL CQI and DL CQI&RI to conservative values
7082     * for a reestablishing UE */
7083    /*Reset Cqi Config for all the configured cells*/
7084    for (idx = 0;idx < CM_LTE_MAX_CELLS; idx++)
7085    {
7086       if (ue->cellInfo[idx] != NULLP) 
7087       {   
7088          rgSCHCmnResetRiCqi(ue->cellInfo[idx]->cell, ue);
7089       }
7090    }
7091    /*After Reset Trigger APCQI for Pcell*/
7092    RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7093    if(pCellInfo->acqiCb.aCqiCfg.pres)
7094    {
7095       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
7096    }
7097
7098 /* sending HqEnt reset to MAC */
7099    hqEntRstInfo.cellId = cell->cellId;
7100    hqEntRstInfo.crnti  = ue->ueId;
7101
7102    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
7103    RgSchMacRstHqEnt(&pst,&hqEntRstInfo);
7104
7105    return;
7106 }
7107
7108 /**
7109  * @brief UE out of MeasGap or AckNackReptn.
7110  *
7111  * @details
7112  *
7113  *     Function : rgSCHCmnActvtUlUe
7114  *
7115  *     This functions triggers specific scheduler
7116  *     to start considering it for scheduling.
7117  *
7118  *  @param[in]  RgSchCellCb  *cell
7119  *  @param[in]  RgSchUeCb    *ue
7120  *  @return  S16
7121  *      -# ROK
7122  *      -# RFAILED
7123  **/
7124 Void rgSCHCmnActvtUlUe(RgSchCellCb *cell,RgSchUeCb *ue)
7125 {
7126    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7127
7128    /* : take care of this in UL retransmission */
7129    cellSchd->apisUl->rgSCHUlActvtUe(cell, ue);
7130    return;
7131 }
7132
7133 /**
7134  * @brief UE out of MeasGap or AckNackReptn.
7135  *
7136  * @details
7137  *
7138  *     Function : rgSCHCmnActvtDlUe
7139  *
7140  *     This functions triggers specific scheduler
7141  *     to start considering it for scheduling.
7142  *
7143  *  @param[in]  RgSchCellCb  *cell
7144  *  @param[in]  RgSchUeCb    *ue
7145  *  @return  S16
7146  *      -# ROK
7147  *      -# RFAILED
7148  **/
7149 Void rgSCHCmnActvtDlUe(RgSchCellCb *cell,RgSchUeCb *ue)
7150 {
7151    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7152
7153    cellSchd->apisDl->rgSCHDlActvtUe(cell, ue);
7154    return;
7155 }
7156
7157 /**
7158  * @brief This API is invoked to indicate scheduler of a CRC indication.
7159  *
7160  * @details
7161  *
7162  *     Function : rgSCHCmnHdlUlTransInd
7163  *      This API is invoked to indicate scheduler of a CRC indication.
7164  *
7165  *  @param[in]  RgSchCellCb     *cell
7166  *  @param[in]  RgSchUeCb       *ue
7167  *  @param[in]  CmLteTimingInfo timingInfo
7168  *
7169  *  @return Void
7170  **/
7171 Void rgSCHCmnHdlUlTransInd(RgSchCellCb *cell,RgSchUeCb *ue,CmLteTimingInfo timingInfo)
7172 {
7173
7174    /* Update the latest UL dat/sig transmission time */
7175    RGSCHCPYTIMEINFO(timingInfo, ue->ul.ulTransTime);
7176    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
7177    {
7178       /* Some UL Transmission from this UE.
7179        * Activate this UE if it was inactive */
7180       RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7181       RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7182    }
7183    return;
7184 }
7185
7186 #ifdef TFU_UPGRADE
7187
7188 /**
7189  * @brief Compute the minimum Rank based on Codebook subset
7190  *        restriction configuration for 4 Tx Ports and Tx Mode 4.
7191  *
7192  * @details
7193  *
7194  *     Function : rgSCHCmnComp4TxMode4
7195  *
7196  *     Depending on BitMap set at CBSR during Configuration
7197  *      - return the least possible Rank
7198  *
7199  *
7200  *  @param[in]  uint32_t *pmiBitMap
7201  *  @return  RgSchCmnRank
7202  **/
7203 static RgSchCmnRank rgSCHCmnComp4TxMode4(uint32_t *pmiBitMap)
7204 {
7205    uint32_t bitMap0, bitMap1;
7206    bitMap0 = pmiBitMap[0];
7207    bitMap1 = pmiBitMap[1];
7208    if((bitMap1) & 0xFFFF)
7209    {
7210       return  (RG_SCH_CMN_RANK_1);
7211    }
7212    else if((bitMap1>>16) & 0xFFFF)
7213    {
7214       return  (RG_SCH_CMN_RANK_2);
7215    }
7216    else if((bitMap0) & 0xFFFF)
7217    {
7218       return  (RG_SCH_CMN_RANK_3);
7219    }
7220    else if((bitMap0>>16) & 0xFFFF)
7221    {
7222       return  (RG_SCH_CMN_RANK_4);
7223    }
7224    else
7225    {
7226       return  (RG_SCH_CMN_RANK_1);
7227    }
7228 }
7229
7230
7231 /**
7232  * @brief Compute the minimum Rank based on Codebook subset
7233  *        restriction configuration for 2 Tx Ports and Tx Mode 4.
7234  *
7235  * @details
7236  *
7237  *     Function : rgSCHCmnComp2TxMode4
7238  *
7239  *     Depending on BitMap set at CBSR during Configuration
7240  *      - return the least possible Rank
7241  *
7242  *
7243  *  @param[in]  uint32_t *pmiBitMap
7244  *  @return  RgSchCmnRank
7245  **/
7246 static RgSchCmnRank rgSCHCmnComp2TxMode4(uint32_t *pmiBitMap)
7247 {
7248    uint32_t bitMap0;
7249    bitMap0 = pmiBitMap[0];
7250    if((bitMap0>>26)& 0x0F)
7251    {
7252       return  (RG_SCH_CMN_RANK_1);
7253    }
7254    else if((bitMap0>>30) & 3)
7255    {
7256       return  (RG_SCH_CMN_RANK_2);
7257    }
7258    else
7259    {
7260       return  (RG_SCH_CMN_RANK_1);
7261    }
7262 }
7263
7264 /**
7265  * @brief Compute the minimum Rank based on Codebook subset
7266  *        restriction configuration for 4 Tx Ports and Tx Mode 3.
7267  *
7268  * @details
7269  *
7270  *     Function : rgSCHCmnComp4TxMode3
7271  *
7272  *     Depending on BitMap set at CBSR during Configuration
7273  *      - return the least possible Rank
7274  *
7275  *
7276  *  @param[in]  uint32_t *pmiBitMap
7277  *  @return  RgSchCmnRank
7278  **/
7279 static RgSchCmnRank rgSCHCmnComp4TxMode3(uint32_t *pmiBitMap)
7280 {
7281    uint32_t bitMap0;
7282    bitMap0 = pmiBitMap[0];
7283    if((bitMap0>>28)& 1)
7284    {
7285       return  (RG_SCH_CMN_RANK_1);
7286    }
7287    else if((bitMap0>>29) &1)
7288    {
7289       return  (RG_SCH_CMN_RANK_2);
7290    }
7291    else if((bitMap0>>30) &1)
7292    {
7293       return  (RG_SCH_CMN_RANK_3);
7294    }
7295    else if((bitMap0>>31) &1)
7296    {
7297       return  (RG_SCH_CMN_RANK_4);
7298    }
7299    else
7300    {
7301       return  (RG_SCH_CMN_RANK_1);
7302    }
7303 }
7304
7305 /**
7306  * @brief Compute the minimum Rank based on Codebook subset
7307  *        restriction configuration for 2 Tx Ports and Tx Mode 3.
7308  *
7309  * @details
7310  *
7311  *     Function : rgSCHCmnComp2TxMode3
7312  *
7313  *     Depending on BitMap set at CBSR during Configuration
7314  *      - return the least possible Rank
7315  *
7316  *
7317  *  @param[in]  uint32_t *pmiBitMap
7318  *  @return  RgSchCmnRank
7319  **/
7320 static RgSchCmnRank rgSCHCmnComp2TxMode3(uint32_t *pmiBitMap)
7321 {
7322    uint32_t bitMap0;
7323    bitMap0 = pmiBitMap[0];
7324    if((bitMap0>>30)& 1)
7325    {
7326       return  (RG_SCH_CMN_RANK_1);
7327    }
7328    else if((bitMap0>>31) &1)
7329    {
7330       return  (RG_SCH_CMN_RANK_2);
7331    }
7332    else
7333    {
7334       return  (RG_SCH_CMN_RANK_1);
7335    }
7336 }
7337
7338 /**
7339  * @brief Compute the minimum Rank based on Codebook subset
7340  *        restriction configuration.
7341  *
7342  * @details
7343  *
7344  *     Function : rgSCHCmnComputeRank
7345  *
7346  *     Depending on Num Tx Ports and Transmission mode
7347  *      - return the least possible Rank
7348  *
7349  *
7350  *  @param[in]  RgrTxMode txMode
7351  *  @param[in]  uint32_t *pmiBitMap
7352  *  @param[in]  uint8_t numTxPorts
7353  *  @return  RgSchCmnRank
7354  **/
7355 static RgSchCmnRank rgSCHCmnComputeRank(RgrTxMode txMode,uint32_t *pmiBitMap,uint8_t numTxPorts)
7356 {
7357
7358    if (numTxPorts ==2 && txMode == RGR_UE_TM_3)
7359    {
7360       return  (rgSCHCmnComp2TxMode3(pmiBitMap));
7361    }
7362    else if (numTxPorts ==4 && txMode == RGR_UE_TM_3)
7363    {
7364       return  (rgSCHCmnComp4TxMode3(pmiBitMap));
7365    }
7366    else if (numTxPorts ==2 && txMode == RGR_UE_TM_4)
7367    {
7368       return  (rgSCHCmnComp2TxMode4(pmiBitMap));
7369    }
7370    else if (numTxPorts ==4 && txMode == RGR_UE_TM_4)
7371    {
7372       return  (rgSCHCmnComp4TxMode4(pmiBitMap));
7373    }
7374    else
7375    {
7376       return  (RG_SCH_CMN_RANK_1);
7377    }
7378 }
7379
7380 #endif
7381
7382 /**
7383  * @brief Harq Entity Deinitialization for CMN SCH.
7384  *
7385  * @details
7386  *
7387  *     Function : rgSCHCmnDlDeInitHqEnt 
7388  *
7389  *     Harq Entity Deinitialization for CMN SCH 
7390  *
7391  *  @param[in]  RgSchCellCb  *cell
7392  *  @param[in]  RgSchDlHqEnt *hqE 
7393  *  @return  VOID
7394  **/
7395 /*KWORK_FIX:Changed function return type to void */
7396 Void rgSCHCmnDlDeInitHqEnt(RgSchCellCb  *cell,RgSchDlHqEnt *hqE)
7397 {
7398    RgSchCmnCell    *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7399    RgSchDlHqProcCb *hqP;
7400    uint8_t         cnt;
7401    S16             ret;
7402
7403    ret = cellSchd->apisDl->rgSCHDlUeHqEntDeInit(cell, hqE);
7404    /* Free only If the Harq proc are created*/
7405    if(RFAILED == ret)
7406    {
7407    }
7408
7409    for(cnt = 0; cnt < hqE->numHqPrcs; cnt++)
7410    {
7411       hqP = &hqE->procs[cnt];
7412       if ((RG_SCH_CMN_GET_DL_HQP(hqP)))
7413       {
7414          rgSCHUtlFreeSBuf(cell->instIdx,
7415               (Data**)(&(hqP->sch)), (sizeof(RgSchCmnDlHqProc)));
7416       }
7417    }
7418 #ifdef LTE_ADV
7419    rgSCHLaaDeInitDlHqProcCb (cell, hqE);
7420 #endif
7421
7422    return;
7423 }
7424
7425 /**
7426  * @brief Harq Entity initialization for CMN SCH.
7427  *
7428  * @details
7429  *
7430  *     Function : rgSCHCmnDlInitHqEnt 
7431  *
7432  *     Harq Entity initialization for CMN SCH 
7433  *
7434  *  @param[in]  RgSchCellCb  *cell
7435  *  @param[in]  RgSchUeCb    *ue
7436  *  @return  S16
7437  *      -# ROK
7438  *      -# RFAILED
7439  **/
7440 S16 rgSCHCmnDlInitHqEnt(RgSchCellCb *cell,RgSchDlHqEnt *hqEnt)
7441 {
7442    RgSchDlHqProcCb *hqP;
7443    uint8_t         cnt;
7444    RgSchCmnCell    *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7445
7446    for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
7447    {
7448       hqP = &hqEnt->procs[cnt];
7449       if (rgSCHUtlAllocSBuf(cell->instIdx,
7450                (Data**)&(hqP->sch), (sizeof(RgSchCmnDlHqProc))) != ROK)
7451       {
7452          return RFAILED;
7453       }
7454    }
7455 #ifdef EMTC_ENABLE
7456    if((cell->emtcEnable) &&(hqEnt->ue->isEmtcUe))
7457    {
7458       if(ROK != cellSchd->apisEmtcDl->rgSCHDlUeHqEntInit(cell, hqEnt))
7459       {
7460          return RFAILED;
7461       }
7462
7463    }
7464    else
7465 #endif
7466    {
7467       if(ROK != cellSchd->apisDl->rgSCHDlUeHqEntInit(cell, hqEnt))
7468       {
7469          return RFAILED;
7470       }
7471    }
7472
7473    return ROK;
7474 }  /* rgSCHCmnDlInitHqEnt */
7475
7476 /**
7477  * @brief This function computes distribution of refresh period
7478  *
7479  * @details
7480  *
7481  *     Function: rgSCHCmnGetRefreshDist 
7482  *     Purpose: This function computes distribution of refresh period
7483  *              This is required to align set of UEs refresh
7484  *              around the different consecutive subframe.
7485  *               
7486  *     Invoked by: rgSCHCmnGetRefreshPerDist
7487  *
7488  *  @param[in]  RgSchCellCb        *cell
7489  *  @param[in]  RgSchUeCb          *ue
7490  *  @return  Void
7491  *
7492  **/
7493 static uint8_t rgSCHCmnGetRefreshDist(RgSchCellCb *cell,RgSchUeCb *ue)
7494 {
7495    uint8_t   refOffst;
7496
7497    for(refOffst = 0; refOffst < RGSCH_MAX_REFRESH_OFFSET; refOffst++)
7498    {
7499       if(cell->refreshUeCnt[refOffst] < RGSCH_MAX_REFRESH_GRPSZ)
7500       {
7501          cell->refreshUeCnt[refOffst]++;
7502          ue->refreshOffset = refOffst;
7503          /* DU_LOG("\nINFO   -->  SCH : UE[%d] refresh offset[%d]. Cell refresh ue count[%d].\n", ue->ueId, refOffst,  cell->refreshUeCnt[refOffst]); */
7504          return (refOffst);
7505       }
7506    }
7507   
7508    DU_LOG("\nERROR  -->  SCH : Allocation of refresh distribution failed\n");
7509    /* We should not enter here  normally, but incase of failure, allocating from  last offset*/
7510    cell->refreshUeCnt[refOffst-1]++;
7511    ue->refreshOffset = refOffst-1;
7512
7513    return (refOffst-1);
7514 }
7515 /**
7516  * @brief This function computes initial Refresh Wait Period.
7517  *
7518  * @details
7519  *
7520  *     Function: rgSCHCmnGetRefreshPer 
7521  *     Purpose: This function computes initial Refresh Wait Period.
7522  *              This is required to align multiple UEs refresh
7523  *              around the same time.
7524  *               
7525  *     Invoked by: rgSCHCmnGetRefreshPer 
7526  *
7527  *  @param[in]  RgSchCellCb        *cell
7528  *  @param[in]  RgSchUeCb          *ue
7529  *  @param[in]  uint32_t                *waitPer 
7530  *  @return  Void
7531  *
7532  **/
7533 static Void rgSCHCmnGetRefreshPer(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t *waitPer)
7534 {
7535    uint32_t  refreshPer;           
7536    uint32_t  crntSubFrm;
7537
7538
7539    refreshPer = RG_SCH_CMN_REFRESH_TIME * RG_SCH_CMN_REFRESH_TIMERES;
7540    crntSubFrm = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot;
7541    /* Fix: syed align multiple UEs to refresh at same time */
7542    *waitPer = refreshPer - (crntSubFrm % refreshPer);
7543    *waitPer = RGSCH_CEIL(*waitPer, RG_SCH_CMN_REFRESH_TIMERES);
7544    *waitPer = *waitPer + rgSCHCmnGetRefreshDist(cell, ue);
7545
7546    return;
7547 }
7548
7549
7550 #ifdef LTE_ADV
7551 /**
7552  * @brief UE initialisation for scheduler.
7553  *
7554  * @details
7555  *
7556  *     Function : rgSCHCmnRgrSCellUeCfg
7557  *
7558  *     This functions intialises UE specific scheduler 
7559  *     information for SCELL
7560  *     0. Perform basic validations
7561  *     1. Allocate common sched UE cntrl blk
7562  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
7563  *     3. Perform UL cfg
7564  *     4. Perform DLFS cfg
7565  *
7566  *  @param[in]  RgSchCellCb  *cell
7567  *  @param[in]  RgSchUeCb    *ue
7568  *  @param[out] RgSchErrInfo *err
7569  *  @return  S16
7570  *      -# ROK
7571  *      -# RFAILED
7572  **/
7573 S16 rgSCHCmnRgrSCellUeCfg(RgSchCellCb *sCell,RgSchUeCb *ue,RgrUeSecCellCfg *sCellInfoCfg,RgSchErrInfo *err)
7574 {
7575    uint8_t i;
7576    S16     ret;
7577    uint8_t cnt;
7578    RgSchCmnAllocRecord  *allRcd;
7579    RgSchDlRbAlloc       *allocInfo;
7580    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
7581    RgSchCmnUlUe         *ueUl;
7582    RgSchCmnUlUe         *ueUlPcell;
7583    RgSchCmnUe           *pCellUeSchCmn;
7584    RgSchCmnUe           *ueSchCmn;
7585    RgSchCmnDlUe         *ueDl;
7586    RgSchCmnDlUe         *pCellUeDl;
7587 #ifdef DEBUGP
7588    Inst                 inst = ue->cell->instIdx;
7589 #endif
7590    uint32_t idx = (uint8_t)((sCell->cellId - rgSchCb[sCell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
7591
7592    pCellUeSchCmn = RG_SCH_CMN_GET_UE(ue,ue->cell);
7593    pCellUeDl = &pCellUeSchCmn->dl;
7594
7595    /* 1. Allocate Common sched control block */
7596    if((rgSCHUtlAllocSBuf(sCell->instIdx,
7597                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
7598    {
7599       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED\n");
7600       err->errCause = RGSCHERR_SCH_CFG;
7601       return RFAILED;
7602    }
7603    ueSchCmn = RG_SCH_CMN_GET_UE(ue,sCell);
7604
7605    /*2.  Perform UEs downlink configuration */
7606    ueDl = &ueSchCmn->dl;
7607
7608    /*CA TODO*/
7609    ueDl->mimoInfo = pCellUeDl->mimoInfo;
7610
7611    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
7612          (ue->mimoInfo.txMode == RGR_UE_TM_6))
7613    {
7614       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_NO_PMI);
7615    }
7616    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
7617    {
7618       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_RI_1);
7619    }
7620    RGSCH_ARRAY_BOUND_CHECK(sCell->instIdx, rgUeCatTbl, pCellUeSchCmn->cmn.ueCat);
7621    ueDl->maxTbBits = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlTbBits;
7622    /*CA dev-Start*/
7623    uint8_t ri = 0;
7624    ri = RGSCH_MIN(ri, sCell->numTxAntPorts);
7625    if(((CM_LTE_UE_CAT_6 == pCellUeSchCmn->cmn.ueCat )
7626             ||(CM_LTE_UE_CAT_7 == pCellUeSchCmn->cmn.ueCat)) 
7627          && (4 == ri))
7628    {
7629       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[1];
7630    }
7631    else
7632    {
7633       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[0];
7634    }
7635    /*CA dev-End*/
7636    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
7637 #ifdef LTE_TDD
7638    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
7639          rgSchTddDlNumHarqProcTbl[sCell->ulDlCfgIdx]);
7640 #else
7641    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
7642          RGSCH_NUM_DL_HQ_PROC);
7643 #endif
7644 #ifdef EMTC_ENABLE   
7645    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, ue->isEmtcUe);
7646 #else
7647    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, FALSE);
7648 #endif      
7649
7650    /* DL ambr */
7651    /* ambrCfgd config moved to ueCb.dl, as it's not needed for per cell wise*/
7652
7653    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, sCell);
7654    allocInfo->rnti = ue->ueId;
7655
7656    /* Initializing the lastCfi value to current cfi value */
7657    ueDl->lastCfi = cellSchd->dl.currCfi;
7658
7659    if ((cellSchd->apisDl->rgSCHRgrSCellDlUeCfg(sCell, ue, err)) != ROK)
7660    {
7661       DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED\n");
7662       return RFAILED;
7663    }
7664
7665    /* TODO: enhance for DLFS RB Allocation for SCELLs in future dev */
7666
7667    /* DLFS UE Config */
7668    if (cellSchd->dl.isDlFreqSel)
7669    {
7670       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeCfg(sCell, ue, sCellInfoCfg, err)) != ROK)
7671       {
7672          DU_LOG("\nERROR  -->  SCH : DLFS UE config FAILED\n");
7673          return RFAILED;
7674       }
7675    }
7676
7677    /* TODO: Do UL SCELL CFG during UL CA dev */
7678    {
7679       ueUl = RG_SCH_CMN_GET_UL_UE(ue, sCell);
7680
7681       /* TODO_ULCA: SRS for SCELL needs to be handled in the below function call */
7682       rgSCHCmnUpdUeUlCqiInfo(sCell, ue, ueUl, ueSchCmn, cellSchd,
7683             sCell->isCpUlExtend);
7684
7685       ret = rgSCHUhmHqEntInit(sCell, ue);
7686       if (ret != ROK)
7687       {
7688          DU_LOG("\nERROR  -->  SCH : SCELL UHM HARQ Ent Init "
7689                "Failed for CRNTI:%d", ue->ueId);
7690          return RFAILED;
7691       }
7692
7693       ueUlPcell = RG_SCH_CMN_GET_UL_UE(ue, ue->cell);
7694       /* Initialize uplink HARQ related information for UE */
7695       ueUl->hqEnt.maxHqRetx = ueUlPcell->hqEnt.maxHqRetx;
7696       cmLListInit(&ueUl->hqEnt.free);
7697       cmLListInit(&ueUl->hqEnt.inUse);
7698       for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
7699       {
7700          ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
7701          ueUl->hqEnt.hqProcCb[i].procId = i;
7702          ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
7703          ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
7704 #ifdef LTEMAC_SPS
7705          /* ccpu00139513- Initializing SPS flags*/
7706          ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
7707          ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
7708 #endif
7709          cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
7710          ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
7711       }
7712
7713       /* Allocate UL BSR allocation tracking List */
7714       cmLListInit(&ueUl->ulAllocLst);
7715
7716       for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
7717       {
7718          if((rgSCHUtlAllocSBuf(sCell->instIdx,
7719                      (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
7720          {
7721             DU_LOG("\nERROR  -->  SCH : SCELL Memory allocation FAILED"
7722                   "for CRNTI:%d",ue->ueId);
7723             err->errCause = RGSCHERR_SCH_CFG;
7724             return RFAILED;
7725          }
7726          allRcd->allocTime = sCell->crntTime;
7727          cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
7728          allRcd->lnk.node = (PTR)allRcd;
7729       }
7730
7731       /* After initialising UL part, do power related init */
7732       ret = rgSCHPwrUeSCellCfg(sCell, ue, sCellInfoCfg);
7733       if (ret != ROK)
7734       {
7735          DU_LOG("\nERROR  -->  SCH : Could not do "
7736                "power config for UE CRNTI:%d",ue->ueId);
7737          return RFAILED;
7738       }
7739
7740 #ifdef EMTC_ENABLE   
7741       if(TRUE == ue->isEmtcUe)
7742       {
7743          if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
7744          {
7745             DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
7746                   "for CRNTI:%d",ue->ueId);
7747             return RFAILED;
7748          }
7749       }
7750       else
7751 #endif
7752       {
7753       if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
7754       {
7755          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
7756                "for CRNTI:%d",ue->ueId);
7757          return RFAILED;
7758       }
7759       }
7760    
7761       ue->ul.isUlCaEnabled = TRUE;
7762    }
7763
7764    return ROK;
7765 }  /* rgSCHCmnRgrSCellUeCfg */
7766
7767
7768 /**
7769  * @brief UE initialisation for scheduler.
7770  *
7771  * @details
7772  *
7773  *     Function : rgSCHCmnRgrSCellUeDel 
7774  *
7775  *     This functions Delete UE specific scheduler 
7776  *     information for SCELL
7777  *
7778  *  @param[in]  RgSchCellCb  *cell
7779  *  @param[in]  RgSchUeCb    *ue
7780  *  @return  S16
7781  *      -# ROK
7782  *      -# RFAILED
7783  **/
7784 S16 rgSCHCmnRgrSCellUeDel(RgSchUeCellInfo *sCellInfo,RgSchUeCb *ue)
7785 {
7786    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
7787    Inst         inst = ue->cell->instIdx;
7788
7789
7790    cellSchd->apisDl->rgSCHRgrSCellDlUeDel(sCellInfo, ue);
7791
7792    /* UL CA */
7793    rgSCHCmnUlUeDelAllocs(sCellInfo->cell, ue);
7794
7795 #ifdef EMTC_ENABLE   
7796    if(TRUE == ue->isEmtcUe)
7797    {
7798       cellSchd->apisEmtcUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
7799    }
7800    else
7801 #endif
7802    {
7803    cellSchd->apisUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
7804    }
7805
7806    /* DLFS UE Config */
7807    if (cellSchd->dl.isDlFreqSel)
7808    {
7809       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeDel(sCellInfo->cell, ue)) != ROK)
7810       {
7811          DU_LOG("\nERROR  -->  SCH : DLFS Scell del FAILED\n");
7812          return RFAILED;
7813       }
7814    }
7815
7816    rgSCHUtlFreeSBuf(sCellInfo->cell->instIdx,
7817          (Data**)(&(sCellInfo->sch)), (sizeof(RgSchCmnUe)));
7818
7819
7820    return ROK;
7821 }  /* rgSCHCmnRgrSCellUeDel */
7822  
7823 #endif
7824
7825 #ifdef RG_5GTF
7826 /**
7827  * @brief Handles 5gtf configuration for a UE
7828  *
7829  * @details
7830  *
7831  *     Function : rgSCHCmn5gtfUeCfg
7832  *
7833  *     Processing Steps:
7834  *
7835  *      - Return ROK
7836  *
7837  *  @param[in]  RgSchCellCb  *cell
7838  *  @param[in]  RgSchUeCb    *ue
7839  *  @param[in]  RgrUeCfg     *cfg
7840  *  @return  S16
7841  *      -# ROK
7842  *      -# RFAILED
7843  **/
7844 S16 rgSCHCmn5gtfUeCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeCfg *cfg)
7845 {
7846
7847    RgSchUeGrp *ue5gtfGrp;
7848    ue->ue5gtfCb.grpId = cfg->ue5gtfCfg.grpId;
7849    ue->ue5gtfCb.BeamId = cfg->ue5gtfCfg.BeamId;
7850    ue->ue5gtfCb.numCC = cfg->ue5gtfCfg.numCC;   
7851    ue->ue5gtfCb.mcs = cfg->ue5gtfCfg.mcs;
7852    ue->ue5gtfCb.maxPrb = cfg->ue5gtfCfg.maxPrb;
7853
7854    ue->ue5gtfCb.cqiRiPer = 100;
7855    /* 5gtf TODO: CQIs to start from (10,0)*/
7856    ue->ue5gtfCb.nxtCqiRiOccn.sfn = 10;
7857    ue->ue5gtfCb.nxtCqiRiOccn.slot = 0;
7858    ue->ue5gtfCb.rank = 1;
7859
7860    DU_LOG("\nINFO  -->  SCH : schd cfg at mac,%u,%u,%u,%u,%u\n",ue->ue5gtfCb.grpId,ue->ue5gtfCb.BeamId,ue->ue5gtfCb.numCC,
7861          ue->ue5gtfCb.mcs,ue->ue5gtfCb.maxPrb); 
7862
7863    ue5gtfGrp = &(cell->cell5gtfCb.ueGrp5gConf[ue->ue5gtfCb.BeamId]);
7864
7865    /* TODO_5GTF: Currently handling 1 group only. Need to update when multi group 
7866       scheduling comes into picture */
7867    if(ue5gtfGrp->beamBitMask & (1 << ue->ue5gtfCb.BeamId))
7868    {
7869       DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR Invalid beam id CRNTI:%d",cfg->crnti);
7870       return RFAILED;
7871    }
7872    ue5gtfGrp->beamBitMask |= (1 << ue->ue5gtfCb.BeamId);
7873
7874    return ROK;
7875 }
7876 #endif
7877
7878 /**
7879  * @brief UE initialisation for scheduler.
7880  *
7881  * @details
7882  *
7883  *     Function : rgSCHCmnRgrUeCfg
7884  *
7885  *     This functions intialises UE specific scheduler
7886  *     information
7887  *     0. Perform basic validations
7888  *     1. Allocate common sched UE cntrl blk
7889  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
7890  *     3. Perform UL cfg
7891  *     4. Perform DLFS cfg
7892  *
7893  *  @param[in]  RgSchCellCb  *cell
7894  *  @param[in]  RgSchUeCb    *ue
7895  *  @param[int] RgrUeCfg     *ueCfg
7896  *  @param[out] RgSchErrInfo *err
7897  *  @return  S16
7898  *      -# ROK
7899  *      -# RFAILED
7900  **/
7901 S16 rgSCHCmnRgrUeCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeCfg *ueCfg,RgSchErrInfo *err)
7902 {
7903    RgSchDlRbAlloc  *allocInfo;
7904    S16              ret;
7905    RgSchCmnCell     *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7906    RgSchCmnUe       *ueSchCmn;
7907    RgSchCmnUlUe     *ueUl;
7908    RgSchCmnDlUe     *ueDl;
7909    uint8_t          cnt;
7910    RgSchCmnAllocRecord  *allRcd;
7911    uint32_t         waitPer;
7912    uint32_t         idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
7913    RgSchUeCellInfo  *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7914
7915
7916    /* 1. Allocate Common sched control block */
7917    if((rgSCHUtlAllocSBuf(cell->instIdx,
7918                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
7919    {
7920       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for CRNTI:%d",ueCfg->crnti);
7921       err->errCause = RGSCHERR_SCH_CFG;
7922       return RFAILED;
7923    }
7924    ueSchCmn   = RG_SCH_CMN_GET_UE(ue,cell);
7925    ue->dl.ueDlCqiCfg = ueCfg->ueDlCqiCfg;
7926    pCellInfo->acqiCb.aCqiCfg = ueCfg->ueDlCqiCfg.aprdCqiCfg;
7927    if(ueCfg->ueCatEnum > 0 )
7928    {
7929      /*KWORK_FIX removed NULL chk for ueSchCmn*/
7930       ueSchCmn->cmn.ueCat = ueCfg->ueCatEnum - 1; 
7931    }
7932    else
7933    {
7934       ueSchCmn->cmn.ueCat = 0; /* Assuming enum values correctly set */
7935    }
7936    cmInitTimers(&ueSchCmn->cmn.tmr, 1);
7937
7938    /*2.  Perform UEs downlink configuration */
7939    ueDl = &ueSchCmn->dl;
7940    /* RACHO : store the rapId assigned for HandOver UE.
7941     * Append UE to handover list of cmnCell */
7942    if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
7943    {
7944       rgSCHCmnDelDedPreamble(cell, ueCfg->dedPreambleId.val);
7945       ueDl->rachInfo.hoRapId = ueCfg->dedPreambleId.val;
7946       cmLListAdd2Tail(&cellSchd->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
7947       ueDl->rachInfo.hoLnk.node = (PTR)ue;
7948    }
7949
7950    rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd);
7951
7952    if (ueCfg->txMode.pres == TRUE)
7953    {
7954       if ((ueCfg->txMode.txModeEnum == RGR_UE_TM_4) ||
7955             (ueCfg->txMode.txModeEnum == RGR_UE_TM_6))
7956       {
7957          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
7958       }
7959       if (ueCfg->txMode.txModeEnum == RGR_UE_TM_3)
7960       {
7961          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
7962       }
7963    }
7964    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
7965    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
7966    /*CA dev-Start*/
7967    uint8_t ri = 0;
7968    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
7969    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
7970             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
7971                   && (4 == ri))
7972    {
7973       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
7974    }
7975    else
7976    {
7977       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
7978    }
7979    /*CA dev-End*/
7980    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
7981 #ifdef LTE_TDD
7982    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
7983          rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]);
7984 #else
7985    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
7986          RGSCH_NUM_DL_HQ_PROC);
7987 #endif
7988 #ifdef EMTC_ENABLE   
7989    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
7990 #else
7991    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
7992 #endif 
7993      /* if none of the DL and UL AMBR are configured then fail the configuration
7994     */     
7995    if((ueCfg->ueQosCfg.dlAmbr == 0) && (ueCfg->ueQosCfg.ueBr == 0))
7996    {
7997       DU_LOG("\nERROR  -->  SCH : UL Ambr and DL Ambr are"
7998          "configured as 0 for CRNTI:%d",ueCfg->crnti);
7999       err->errCause = RGSCHERR_SCH_CFG;
8000       return RFAILED;
8001    }
8002    /* DL ambr */
8003    ue->dl.ambrCfgd = (ueCfg->ueQosCfg.dlAmbr * RG_SCH_CMN_REFRESH_TIME)/100;
8004
8005    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
8006    allocInfo->rnti = ue->ueId;
8007
8008    /* Initializing the lastCfi value to current cfi value */
8009    ueDl->lastCfi = cellSchd->dl.currCfi;
8010 #ifdef EMTC_ENABLE
8011    if(cell->emtcEnable && ue->isEmtcUe)
8012    {
8013       if ((cellSchd->apisEmtcDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8014       {
8015          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8016          return RFAILED;
8017       }
8018
8019    }
8020    else
8021 #endif
8022    {
8023       if ((cellSchd->apisDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8024       {
8025          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8026          return RFAILED;
8027       }
8028    }
8029
8030
8031
8032    /* 3. Initialize ul part */
8033    ueUl     = &ueSchCmn->ul;
8034
8035    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd,
8036             cell->isCpUlExtend);
8037
8038    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
8039                                RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
8040
8041    ue->ul.cfgdAmbr = (ueCfg->ueQosCfg.ueBr * RG_SCH_CMN_REFRESH_TIME)/100;
8042    ue->ul.effAmbr = ue->ul.cfgdAmbr;
8043    RGSCHCPYTIMEINFO(cell->crntTime, ue->ul.ulTransTime);
8044
8045    /* Allocate UL BSR allocation tracking List */
8046    cmLListInit(&ueUl->ulAllocLst);
8047
8048    for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
8049    {
8050       if((rgSCHUtlAllocSBuf(cell->instIdx,
8051                   (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
8052       {
8053          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED"
8054                    "for CRNTI:%d",ueCfg->crnti);
8055          err->errCause = RGSCHERR_SCH_CFG;
8056          return RFAILED;
8057       }
8058       allRcd->allocTime = cell->crntTime;
8059       cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
8060       allRcd->lnk.node = (PTR)allRcd;
8061    }
8062    /* Allocate common sch cntrl blocks for LCGs */
8063    for (cnt=0; cnt<RGSCH_MAX_LCG_PER_UE; cnt++)
8064    {
8065       ret = rgSCHUtlAllocSBuf(cell->instIdx,
8066             (Data**)&(ue->ul.lcgArr[cnt].sch), (sizeof(RgSchCmnLcg)));
8067       if (ret != ROK)
8068       {
8069          DU_LOG("\nERROR  -->  SCH : SCH struct alloc failed for CRNTI:%d",ueCfg->crnti);
8070          err->errCause = RGSCHERR_SCH_CFG;
8071          return (ret);
8072       }
8073    }
8074    /* After initialising UL part, do power related init */
8075    ret = rgSCHPwrUeCfg(cell, ue, ueCfg);
8076    if (ret != ROK)
8077    {
8078       DU_LOG("\nERROR  -->  SCH : Could not do "
8079          "power config for UE CRNTI:%d",ueCfg->crnti);
8080       return RFAILED;
8081    }
8082 #ifdef LTEMAC_SPS
8083    ret = rgSCHCmnSpsUeCfg(cell, ue, ueCfg, err);
8084    if (ret != ROK)
8085    {
8086       DU_LOG("\nERROR  -->  SCH : Could not do "
8087          "SPS config for CRNTI:%d",ueCfg->crnti);
8088       return RFAILED;
8089    }
8090 #endif /* LTEMAC_SPS */
8091
8092 #ifdef EMTC_ENABLE   
8093    if(TRUE == ue->isEmtcUe)
8094    {
8095       if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
8096       {
8097          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
8098                   "for CRNTI:%d",ueCfg->crnti);
8099          return RFAILED;
8100       }
8101    }
8102    else
8103 #endif
8104    {
8105    if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
8106    {
8107       DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE CFG FAILED"
8108                "for CRNTI:%d",ueCfg->crnti);
8109       return RFAILED;
8110    }
8111    }
8112
8113    /* DLFS UE Config */
8114    if (cellSchd->dl.isDlFreqSel)
8115    {
8116       if ((cellSchd->apisDlfs->rgSCHDlfsUeCfg(cell, ue, ueCfg, err)) != ROK)
8117       {
8118          DU_LOG("\nERROR  -->  SCH : DLFS UE config FAILED"
8119                    "for CRNTI:%d",ueCfg->crnti);
8120          return RFAILED;
8121       }
8122    }
8123
8124    /* Fix: syed align multiple UEs to refresh at same time */
8125    rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
8126    /* Start UE Qos Refresh Timer */
8127    rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
8128 #ifdef RG_5GTF
8129    rgSCHCmn5gtfUeCfg(cell, ue, ueCfg);
8130 #endif
8131
8132    return ROK;
8133 }  /* rgSCHCmnRgrUeCfg */
8134
8135 /**
8136  * @brief UE TX mode reconfiguration handler.
8137  *
8138  * @details
8139  *
8140  *     Function : rgSCHCmnDlHdlTxModeRecfg
8141  *
8142  *     This functions updates UE specific scheduler
8143  *     information upon UE reconfiguration.
8144  *
8145  *  @param[in]  RgSchUeCb    *ue
8146  *  @param[in] RgrUeRecfg   *ueRecfg
8147  *  @return  Void
8148  **/
8149 #ifdef TFU_UPGRADE
8150 static Void rgSCHCmnDlHdlTxModeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,uint8_t numTxPorts)
8151 #else
8152 static Void rgSCHCmnDlHdlTxModeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg)
8153 #endif
8154 {
8155    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
8156
8157    if (ueRecfg->txMode.pres != PRSNT_NODEF)
8158    {
8159       return;
8160    }
8161    /* ccpu00140894- Starting Timer for TxMode Transition Completion*/
8162    ue->txModeTransCmplt =FALSE;
8163    rgSCHTmrStartTmr (ue->cell, ue, RG_SCH_TMR_TXMODE_TRNSTN, RG_SCH_TXMODE_TRANS_TIMER);
8164    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_CMPLT)
8165    {
8166       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell,
8167                                 RG_SCH_CMN_TD_TXMODE_RECFG);
8168      /* MS_WORKAROUND for ccpu00123186 MIMO Fix Start: need to set FORCE TD bitmap based on TX mode */
8169      ueDl->mimoInfo.ri = 1;
8170      if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8171           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
8172       {
8173          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8174       }
8175       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
8176       {
8177          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8178       }
8179       /* MIMO Fix End: need to set FORCE TD bitmap based on TX mode */
8180       return;
8181    }
8182    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_START)
8183    {
8184       /* start afresh forceTD masking */
8185       RG_SCH_CMN_INIT_FORCE_TD(ue, cell, 0);
8186       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_TXMODE_RECFG);
8187       /* Intialize MIMO related parameters of UE */
8188
8189 #ifdef TFU_UPGRADE
8190       if(ueRecfg->txMode.pres)
8191       {
8192          if((ueRecfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
8193                (ueRecfg->txMode.txModeEnum ==RGR_UE_TM_4))
8194          {
8195             if(ueRecfg->ueCodeBookRstRecfg.pres)
8196             {
8197                ueDl->mimoInfo.ri =
8198                   rgSCHCmnComputeRank(ueRecfg->txMode.txModeEnum,
8199                     ueRecfg->ueCodeBookRstRecfg.pmiBitMap, numTxPorts);
8200             }
8201             else
8202             {
8203                ueDl->mimoInfo.ri = 1;
8204             }
8205          }
8206          else
8207          {
8208             ueDl->mimoInfo.ri = 1;
8209          }
8210       }
8211       else
8212       {
8213          ueDl->mimoInfo.ri = 1;
8214       }
8215 #else
8216       ueDl->mimoInfo.ri = 1;
8217 #endif /* TFU_UPGRADE */
8218       if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8219           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
8220       {
8221          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8222       }
8223       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
8224       {
8225          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8226       }
8227       return;
8228    }
8229 }
8230 /***********************************************************
8231  *
8232  *     Func : rgSCHCmnUpdUeMimoInfo
8233  *
8234  *     Desc : Updates UL and DL Ue Information
8235  *
8236  *     Ret  :
8237  *
8238  *     Notes:
8239  *
8240  *     File :
8241  *
8242  **********************************************************/
8243 static Void rgSCHCmnUpdUeMimoInfo(RgrUeCfg *ueCfg,RgSchCmnDlUe *ueDl,RgSchCellCb  *cell,RgSchCmnCell *cellSchd)
8244 {
8245 #ifdef TFU_UPGRADE
8246    if(ueCfg->txMode.pres)
8247    {
8248       if((ueCfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
8249             (ueCfg->txMode.txModeEnum ==RGR_UE_TM_4))
8250       {
8251          if(ueCfg->ueCodeBookRstCfg.pres)
8252          {
8253             ueDl->mimoInfo.ri =
8254                rgSCHCmnComputeRank(ueCfg->txMode.txModeEnum,
8255                  ueCfg->ueCodeBookRstCfg.pmiBitMap, cell->numTxAntPorts);
8256          }
8257          else
8258          {
8259             ueDl->mimoInfo.ri = 1;
8260          }
8261       }
8262       else
8263       {
8264          ueDl->mimoInfo.ri = 1;
8265       }
8266    }
8267    else
8268    {
8269       ueDl->mimoInfo.ri = 1;
8270    }
8271
8272 #else
8273    ueDl->mimoInfo.ri = 1;
8274 #endif /*TFU_UPGRADE */
8275    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
8276    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
8277
8278    return;
8279 }
8280 /***********************************************************
8281  *
8282  *     Func : rgSCHCmnUpdUeUlCqiInfo
8283  *
8284  *     Desc : Updates UL and DL Ue Information
8285  *
8286  *     Ret  :
8287  *
8288  *     Notes:
8289  *
8290  *     File :
8291  *
8292  **********************************************************/
8293 static Void rgSCHCmnUpdUeUlCqiInfo(RgSchCellCb *cell,RgSchUeCb *ue,RgSchCmnUlUe *ueUl,RgSchCmnUe *ueSchCmn,RgSchCmnCell *cellSchd,Bool isEcp)
8294 {
8295
8296 #ifdef TFU_UPGRADE
8297    if(ue->srsCb.srsCfg.type  ==  RGR_SCH_SRS_SETUP)
8298    {
8299      if(ue->ul.ulTxAntSel.pres)
8300      {
8301        ueUl->crntUlCqi[ue->srsCb.selectedAnt] = cellSchd->ul.dfltUlCqi;
8302        ueUl->validUlCqi = ueUl->crntUlCqi[ue->srsCb.selectedAnt];
8303      }
8304      else
8305      {
8306        ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
8307        ueUl->validUlCqi =  ueUl->crntUlCqi[0];
8308      }
8309       ue->validTxAnt = ue->srsCb.selectedAnt;
8310    }
8311    else
8312    {
8313       ueUl->validUlCqi = cellSchd->ul.dfltUlCqi;
8314       ue->validTxAnt = 0;
8315    }
8316 #ifdef UL_LA
8317    ueUl->ulLaCb.cqiBasediTbs = rgSchCmnUlCqiToTbsTbl[isEcp]
8318                                                 [ueUl->validUlCqi] * 100;   
8319    ueUl->ulLaCb.deltaiTbs = 0;
8320 #endif
8321
8322 #else
8323    ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
8324 #endif /*TFU_UPGRADE */
8325    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
8326    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
8327    {
8328       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
8329    }
8330    else
8331    {
8332       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
8333    }
8334
8335    return;
8336 }
8337 /***********************************************************
8338  *
8339  *     Func : rgSCHCmnUpdUeCatCfg
8340  *
8341  *     Desc : Updates UL and DL Ue Information
8342  *
8343  *     Ret  :
8344  *
8345  *     Notes:
8346  *
8347  *     File :
8348  *
8349  **********************************************************/
8350 static Void rgSCHCmnUpdUeCatCfg(RgSchUeCb *ue,RgSchCellCb  *cell)
8351 {
8352    RgSchDlHqEnt *hqE = NULLP;
8353    RgSchCmnUlUe *ueUl     = RG_SCH_CMN_GET_UL_UE(ue,cell);
8354    RgSchCmnDlUe *ueDl     = RG_SCH_CMN_GET_DL_UE(ue,cell);
8355    RgSchCmnUe   *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
8356    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8357
8358
8359    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
8360    
8361    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
8362    /*CA dev-Start*/
8363    uint8_t ri = 0;
8364    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
8365    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
8366             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
8367          && (RG_SCH_MAX_TX_LYRS_4 == ri))
8368    {
8369       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
8370    }
8371    else
8372    {
8373       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
8374    }
8375    /*CA dev-End*/
8376    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
8377                            hqE->numHqPrcs);
8378    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
8379    {
8380       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
8381    }
8382    else
8383    {
8384       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
8385    }
8386    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
8387                    RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
8388    return;
8389 }
8390
8391 /**
8392  * @brief UE reconfiguration for scheduler.
8393  *
8394  * @details
8395  *
8396  *     Function : rgSChCmnRgrUeRecfg
8397  *
8398  *     This functions updates UE specific scheduler
8399  *     information upon UE reconfiguration.
8400  *
8401  *  @param[in]  RgSchCellCb  *cell
8402  *  @param[in]  RgSchUeCb    *ue
8403  *  @param[int] RgrUeRecfg   *ueRecfg
8404  *  @param[out] RgSchErrInfo *err
8405  *  @return  S16
8406  *      -# ROK
8407  *      -# RFAILED
8408  **/
8409 S16 rgSCHCmnRgrUeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,RgSchErrInfo *err)
8410 {
8411    RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
8412    uint32_t     waitPer;
8413
8414    /* Basic validations */
8415    if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
8416    {
8417 #ifdef TFU_UPGRADE
8418       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, cell->numTxAntPorts);
8419 #else
8420       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg);
8421 #endif /* TFU_UPGRADE */
8422    }
8423    if(ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG)
8424    {
8425       ue->csgMmbrSta = ueRecfg->csgMmbrSta;
8426    }
8427    /* Changes for UE Category reconfiguration feature */
8428    if(ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
8429    {
8430        rgSCHCmnUpdUeCatCfg(ue, cell);
8431    }
8432    if (ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG)
8433    {
8434       RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
8435       pCellInfo->acqiCb.aCqiCfg = ueRecfg->aprdDlCqiRecfg;
8436    }
8437 #ifndef TFU_UPGRADE
8438    if (ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG)
8439    {
8440       if ((ueRecfg->prdDlCqiRecfg.pres == TRUE)
8441             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD10)
8442             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD20))
8443       {
8444          DU_LOG("\nERROR  -->  SCH : Unsupported periodic CQI "
8445             "reporting mode %d for old CRNIT:%d", 
8446             (int)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->oldCrnti);
8447          err->errCause = RGSCHERR_SCH_CFG;
8448          return RFAILED;
8449       }
8450      ue->dl.ueDlCqiCfg.prdCqiCfg = ueRecfg->prdDlCqiRecfg;
8451    }
8452 #endif
8453
8454    if (ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG)
8455    {
8456       if (rgSCHPwrUeRecfg(cell, ue, ueRecfg) != ROK)
8457       {
8458          DU_LOG("\nERROR  -->  SCH : Power Reconfiguration Failed for OLD CRNTI:%d",ueRecfg->oldCrnti);
8459          return RFAILED;
8460       }
8461    }
8462
8463    if (ueRecfg->ueRecfgTypes & RGR_UE_QOS_RECFG)
8464    {
8465       /* Uplink Sched related Initialization */
8466       if ((ueRecfg->ueQosRecfg.dlAmbr == 0) && (ueRecfg->ueQosRecfg.ueBr == 0))
8467       {
8468          DU_LOG("\nERROR  -->  SCH : Ul Ambr and DL Ambr "
8469             "configured as 0 for OLD CRNTI:%d",ueRecfg->oldCrnti);
8470          err->errCause = RGSCHERR_SCH_CFG;
8471          return RFAILED;
8472       }
8473       ue->ul.cfgdAmbr = (ueRecfg->ueQosRecfg.ueBr * \
8474       RG_SCH_CMN_REFRESH_TIME)/100;
8475       /* Downlink Sched related Initialization */
8476       ue->dl.ambrCfgd = (ueRecfg->ueQosRecfg.dlAmbr * \
8477       RG_SCH_CMN_REFRESH_TIME)/100;
8478       /* Fix: syed Update the effAmbr and effUeBR fields w.r.t the
8479        * new QOS configuration */
8480       rgSCHCmnDelUeFrmRefreshQ(cell, ue);
8481       /* Fix: syed align multiple UEs to refresh at same time */
8482       rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
8483       rgSCHCmnApplyUeRefresh(cell, ue);
8484       rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
8485    }
8486 #ifdef EMTC_ENABLE   
8487    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
8488    {
8489       if ((cellSchCmn->apisEmtcUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8490       {
8491          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8492          return RFAILED;
8493       }
8494       if ((cellSchCmn->apisEmtcDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8495       {
8496          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8497          return RFAILED;
8498       }
8499    }
8500    else
8501 #endif
8502    {
8503       if ((cellSchCmn->apisUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8504       {
8505          DU_LOG("\nERROR  -->  SCH : Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8506          return RFAILED;
8507       }
8508       if ((cellSchCmn->apisDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
8509       {
8510          DU_LOG("\nERROR  -->  SCH : Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
8511          return RFAILED;
8512       }
8513    }
8514    /* DLFS UE Config */
8515    if (cellSchCmn->dl.isDlFreqSel)
8516    {
8517       if ((cellSchCmn->apisDlfs->rgSCHDlfsUeRecfg(cell, ue, \
8518          ueRecfg, err)) != ROK)
8519       {
8520          DU_LOG("\nERROR  -->  SCH : DLFS UE re-config FAILED for CRNTI:%d",ue->ueId);
8521          return RFAILED;
8522       }
8523    }
8524
8525 #ifdef LTEMAC_SPS
8526    /* Invoke re-configuration on SPS module */
8527    if (rgSCHCmnSpsUeRecfg(cell, ue, ueRecfg, err) != ROK)
8528    {
8529       DU_LOG("\nERROR  -->  SCH : DL SPS ReCFG FAILED for UE CRNTI:%d", ue->ueId);
8530       return RFAILED;
8531    }
8532 #endif
8533
8534    return ROK;
8535 }  /* rgSCHCmnRgrUeRecfg*/
8536
8537 /***********************************************************
8538  *
8539  *     Func : rgSCHCmnUlUeDelAllocs
8540  *
8541  *     Desc : Deletion of all UE allocations.
8542  *
8543  *     Ret  :
8544  *
8545  *     Notes:
8546  *
8547  *     File :
8548  *
8549  **********************************************************/
8550 static Void rgSCHCmnUlUeDelAllocs(RgSchCellCb *cell,RgSchUeCb *ue)
8551 {
8552    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
8553    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
8554    uint8_t i;
8555 #ifdef LTEMAC_SPS
8556    RgSchCmnUlUeSpsInfo   *ulSpsUe   = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
8557 #endif
8558
8559    for (i = 0; i < ueUl->hqEnt.numHqPrcs; ++i)
8560    {
8561       RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, i);
8562
8563 #ifdef ERRCLS_KW
8564       /* proc can't be NULL here */
8565       if (proc)
8566 #endif
8567       {
8568          /* R8 Upgrade */
8569          proc->ndi = 0;
8570          if (proc->alloc)
8571          {
8572             /* Added Insure Fixes Of reading Dangling memory.NULLed crntAlloc */
8573 #ifdef LTEMAC_SPS
8574             if(proc->alloc == ulSpsUe->ulSpsSchdInfo.crntAlloc)
8575             {
8576                ulSpsUe->ulSpsSchdInfo.crntAlloc = NULLP;
8577                ulSpsUe->ulSpsSchdInfo.crntAllocSf = NULLP;
8578             }
8579 #endif
8580 #ifdef EMTC_ENABLE
8581             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
8582                   proc->alloc,ue->isEmtcUe);
8583 #else
8584             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
8585                   proc->alloc);
8586 #endif
8587             /* PHY probably needn't be intimated since
8588              * whatever intimation it needs happens at the last minute
8589              */
8590          }
8591          /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
8592           * from adaptive retx List. */
8593          if (proc->reTxLnk.node)
8594          {
8595             {
8596                //TODO_SID: Need to take care
8597                cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); 
8598                proc->reTxLnk.node = (PTR)NULLP;
8599             }
8600          }
8601       }
8602    }
8603    return;
8604 }
8605
8606 /***********************************************************
8607  *
8608  *     Func : rgSCHCmnDelUeFrmRefreshQ
8609  *
8610  *     Desc : Adds a UE to refresh queue, so that the UE is
8611  *            periodically triggered to refresh it's GBR and
8612  *            AMBR values.
8613  *
8614  *     Ret  :
8615  *
8616  *     Notes:
8617  *
8618  *     File :
8619  *
8620  **********************************************************/
8621 static Void rgSCHCmnDelUeFrmRefreshQ(RgSchCellCb *cell,RgSchUeCb *ue)
8622 {
8623    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
8624    CmTmrArg       arg;
8625    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
8626
8627
8628 #ifdef RGL_SPECIFIC_CHANGES
8629    if(ue->refreshOffset < RGSCH_MAX_REFRESH_GRPSZ)
8630    {
8631       if(cell->refreshUeCnt[ue->refreshOffset])
8632       {
8633          cell->refreshUeCnt[ue->refreshOffset]--;
8634       }
8635    }
8636 #endif
8637
8638
8639    memset(&arg, 0, sizeof(arg));
8640    arg.tqCp   = &sched->tmrTqCp;
8641    arg.tq     = sched->tmrTq;
8642    arg.timers = &ueSchd->tmr;
8643    arg.cb     = (PTR)ue;
8644    arg.tNum   = 0;
8645    arg.max    = 1;
8646    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
8647
8648    cmRmvCbTq(&arg);
8649    return;
8650 }
8651
8652 /***********************************************************
8653  *
8654  *     Func : rgSCHCmnUeCcchSduDel
8655  *
8656  *     Desc : Clear CCCH SDU scheduling context.
8657  *
8658  *     Ret  :
8659  *
8660  *     Notes:
8661  *
8662  *     File :
8663  *
8664  **********************************************************/
8665 static Void rgSCHCmnUeCcchSduDel(RgSchCellCb  *cell,RgSchUeCb *ueCb)
8666 {
8667    RgSchDlHqEnt      *hqE = NULLP;
8668    RgSchDlHqProcCb   *ccchSduHqP = NULLP;
8669    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
8670
8671
8672    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
8673    if (hqE == NULLP)
8674    {
8675       return;
8676    }
8677    ccchSduHqP = hqE->ccchSduProc;
8678    if(ueCb->ccchSduLnk.node != NULLP)
8679    {
8680       /* Remove the ccchSduProc if it is in the Tx list */
8681       cmLListDelFrm(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
8682       ueCb->ccchSduLnk.node = NULLP;   
8683    }
8684    else if(ccchSduHqP != NULLP)
8685    {
8686       /* Fix for crash due to stale pdcch. Release ccch pdcch*/
8687       if(ccchSduHqP->pdcch)
8688       {
8689          cmLListDelFrm(&ccchSduHqP->subFrm->pdcchInfo.pdcchs,
8690                &ccchSduHqP->pdcch->lnk);
8691          cmLListAdd2Tail(&cell->pdcchLst, &ccchSduHqP->pdcch->lnk);
8692          ccchSduHqP->pdcch = NULLP;
8693       }
8694       if(ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node != NULLP)
8695       {
8696          /* Remove the ccchSduProc if it is in the retx list */
8697          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
8698           &ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk);
8699          /* ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node = NULLP; */
8700          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
8701       }
8702       else if ((ccchSduHqP->subFrm != NULLP) &&
8703        (ccchSduHqP->hqPSfLnk.node != NULLP))
8704       {
8705          rgSCHUtlDlHqPTbRmvFrmTx(ccchSduHqP->subFrm, 
8706                ccchSduHqP, 0, FALSE);
8707          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
8708       }
8709    }   
8710    return;
8711 }
8712
8713
8714
8715
8716 /**
8717  * @brief UE deletion for scheduler.
8718  *
8719  * @details
8720  *
8721  *     Function : rgSCHCmnUeDel
8722  *
8723  *     This functions deletes all scheduler information
8724  *     pertaining to an UE.
8725  *
8726  *  @param[in]  RgSchCellCb  *cell
8727  *  @param[in]  RgSchUeCb    *ue
8728  *  @return  Void
8729  **/
8730 Void rgSCHCmnUeDel(RgSchCellCb *cell,RgSchUeCb *ue)
8731 {
8732    RgSchDlHqEnt         *hqE = NULLP;
8733    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
8734    CmLList              *node;
8735    RgSchCmnAllocRecord  *allRcd;
8736    uint8_t              cnt;
8737    RgSchCmnCell         *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
8738    uint32_t             idx = 0;
8739
8740    if (RG_SCH_CMN_GET_UE(ue,cell) == NULLP)
8741    {
8742       /* Common scheduler config has not happened yet */
8743       return;
8744    }
8745    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
8746    if(hqE)
8747    {
8748       /* UE Free can be triggered before MSG4 done when dlHqE is not updated */
8749 #ifdef EMTC_ENABLE
8750       if(ue->isEmtcUe)
8751       {
8752          rgSCHEmtcCmnUeCcchSduDel(cell, ue);
8753       }
8754       else
8755 #endif
8756      {    
8757          rgSCHCmnUeCcchSduDel(cell, ue);
8758      }
8759    }
8760    rgSCHCmnDelUeFrmRefreshQ(cell, ue);
8761
8762    rgSCHCmnUlUeDelAllocs(cell, ue);
8763
8764    rgSCHCmnDelRachInfo(cell, ue);
8765
8766 #ifdef EMTC_ENABLE   
8767    if(TRUE == ue->isEmtcUe)
8768    {
8769       cellSchCmn->apisEmtcUl->rgSCHFreeUlUe(cell, ue);
8770    }
8771    else
8772 #endif
8773    {
8774    cellSchCmn->apisUl->rgSCHFreeUlUe(cell, ue);
8775    }
8776 #ifdef LTE_ADV
8777    if (ue->numSCells)
8778    {
8779       for(idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
8780       {
8781          if(ue->cellInfo[idx] != NULLP) 
8782          {
8783             rgSCHSCellDelUeSCell(cell,ue,idx);
8784          }
8785       }
8786
8787    }
8788 #endif
8789 #ifdef EMTC_ENABLE
8790    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
8791    {
8792       cellSchCmn->apisEmtcDl->rgSCHFreeDlUe(cell, ue);
8793    }
8794    else
8795 #endif
8796    {
8797       cellSchCmn->apisDl->rgSCHFreeDlUe(cell, ue);
8798    }
8799    rgSCHPwrUeDel(cell, ue);
8800
8801 #ifdef LTEMAC_SPS
8802    rgSCHCmnSpsUeDel(cell, ue);
8803 #endif /* LTEMAC_SPS*/
8804
8805    /* CA Dev Start*/
8806    rgSchCmnDlSfHqDel(ue, cell);
8807    /* CA Dev End*/
8808    /* DLFS UE delete */
8809    if (cellSchCmn->dl.isDlFreqSel)
8810    {
8811       cellSchCmn->apisDlfs->rgSCHDlfsUeDel(cell, ue);
8812    }
8813    node = ueUl->ulAllocLst.first;
8814
8815 /* ccpu00117052 - MOD - Passing double pointer in all the places of
8816    rgSCHUtlFreeSBuf function call for proper NULLP assignment*/
8817    while(node)
8818    {
8819       allRcd = (RgSchCmnAllocRecord *)node->node;
8820       node = node->next;
8821       cmLListDelFrm(&ueUl->ulAllocLst, &allRcd->lnk);
8822       rgSCHUtlFreeSBuf(cell->instIdx,
8823          (Data**)(&allRcd), (sizeof(RgSchCmnAllocRecord)));
8824    }
8825
8826    for(cnt = 0; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
8827    {
8828       if (ue->ul.lcgArr[cnt].sch != NULLP)
8829       {
8830          rgSCHUtlFreeSBuf(cell->instIdx,
8831             (Data**)(&(ue->ul.lcgArr[cnt].sch)), (sizeof(RgSchCmnLcg)));
8832       }
8833    }
8834
8835    /* Fix : syed Moved hqEnt deinit to rgSCHCmnDlDeInitHqEnt */
8836    idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId) & (CM_LTE_MAX_CELLS - 1));
8837    rgSCHUtlFreeSBuf(cell->instIdx,
8838          (Data**)(&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch))), (sizeof(RgSchCmnUe)));
8839    return;
8840 }  /* rgSCHCmnUeDel */
8841
8842 \f
8843 /**
8844  * @brief This function handles the common code rate configurations
8845  *        done as part of RgrCellCfg/RgrCellRecfg.
8846  *
8847  * @details
8848  *
8849  *     Function: rgSCHCmnDlCnsdrCmnRt
8850  *     Purpose:  This function handles the common code rate configurations
8851  *        done as part of RgrCellCfg/RgrCellRecfg.
8852  *
8853  *     Invoked by: Scheduler
8854  *
8855  *  @param[in]  RgSchCellCb                *cell
8856  *  @param[in]  RgrDlCmnCodeRateCfg     *dlCmnCodeRate
8857  *  @return     S16
8858  *
8859  **/
8860 static S16 rgSCHCmnDlCnsdrCmnRt(RgSchCellCb *cell,RgrDlCmnCodeRateCfg  *dlCmnCodeRate)
8861 {
8862    RgSchCmnCell *cellDl = RG_SCH_CMN_GET_CELL(cell);
8863    uint32_t     bitsPerRb;
8864    uint32_t     bitsPer2Rb;
8865    uint32_t     bitsPer3Rb;
8866    uint8_t      i, rbNum;
8867    uint32_t     pdcchBits;
8868
8869
8870    /* code rate is bits per 1024 phy bits, since modl'n scheme is 2. it is
8871     * bits per 1024/2 REs */
8872    if (dlCmnCodeRate->bcchPchRaCodeRate != 0)
8873    {
8874       bitsPerRb = ((dlCmnCodeRate->bcchPchRaCodeRate * 2) *
8875             cellDl->dl.noResPerRb[3])/1024;
8876    }
8877    else
8878    {
8879       bitsPerRb = ((RG_SCH_CMN_DEF_BCCHPCCH_CODERATE * 2) *
8880             cellDl->dl.noResPerRb[3])/1024;
8881    }
8882    /* Store bitsPerRb in cellDl->dl to use later to determine
8883     * Number of RBs for UEs with SI-RNTI, P-RNTI and RA-RNTI */
8884    cellDl->dl.bitsPerRb = bitsPerRb;
8885    /* ccpu00115595 end*/
8886    /* calculate the ITbs for 2 RBs. Initialize ITbs to MAX value */
8887    i = 0;
8888    rbNum = 2;
8889    bitsPer2Rb = bitsPerRb * rbNum;
8890    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer2Rb))
8891       i++;
8892
8893    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs2Rbs = 0) :
8894       (cellDl->dl.cmnChITbs.iTbs2Rbs = i-1);
8895
8896    /* calculate the ITbs for 3 RBs. Initialize ITbs to MAX value */
8897    i = 0;
8898    rbNum = 3;
8899    bitsPer3Rb = bitsPerRb * rbNum;
8900    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer3Rb))
8901          i++;
8902
8903    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs3Rbs = 0) :
8904       (cellDl->dl.cmnChITbs.iTbs3Rbs = i-1);
8905
8906
8907    pdcchBits = 1 + /* Flag for format0/format1a differentiation */
8908       1 + /* Localized/distributed VRB assignment flag */
8909       5 + /* For mcs */
8910 #ifndef LTE_TDD
8911       3 + /* Harq process Id */
8912 #else
8913       4 + /* Harq process Id */
8914       2 + /* UL Index or DAI */
8915 #endif
8916       1 + /* New Data Indicator */
8917       2 + /* For RV */
8918       2 + /* For tpc */
8919       1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
8920                (cell->bwCfg.dlTotalBw + 1))/2);
8921    /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
8922       Since VRB is local */
8923    /* For TDD consider DAI */
8924
8925    /* Convert the pdcchBits to actual pdcchBits required for transmission */
8926    if (dlCmnCodeRate->pdcchCodeRate != 0)
8927    {
8928       pdcchBits = (pdcchBits * 1024)/dlCmnCodeRate->pdcchCodeRate;
8929       if (pdcchBits <= 288) /* 288 : Num of pdcch bits for aggrLvl=4 */
8930       {
8931          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
8932       }
8933       else                  /* 576 : Num of pdcch bits for aggrLvl=8 */
8934       {
8935          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL8;
8936       }
8937    }
8938    else
8939    {
8940       cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
8941    }
8942    if (dlCmnCodeRate->ccchCqi == 0)
8943    {
8944       return RFAILED;
8945    }
8946    else
8947    {
8948       cellDl->dl.ccchCqi = dlCmnCodeRate->ccchCqi;
8949    }
8950    return ROK;
8951 }
8952
8953 #ifdef LTE_TDD
8954 /**
8955  * @brief This function handles the configuration of cell for the first
8956  *        time by the scheduler.
8957  *
8958  * @details
8959  *
8960  *     Function: rgSCHCmnDlRgrCellCfg
8961  *     Purpose:  Configuration received is stored into the data structures
8962  *               Also, update the scheduler with the number of frames of
8963  *               RACH preamble transmission.
8964  *
8965  *     Invoked by: BO and Scheduler
8966  *
8967  *  @param[in]  RgSchCellCb*     cell
8968  *  @param[in]  RgrCellCfg*      cfg
8969  *  @return     S16
8970  *
8971  **/
8972 static S16 rgSCHCmnDlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cfg,RgSchErrInfo *err)
8973 {
8974    RgSchCmnCell         *cellSch;
8975    uint8_t              cp;
8976    uint8_t              sfCount;
8977    uint8_t              numPdcchSym;
8978    uint8_t              noSymPerSlot;
8979    uint8_t              maxDlSubfrms = cell->numDlSubfrms;
8980    uint8_t              splSubfrmIdx = cfg->spclSfCfgIdx;
8981    uint8_t              swPtCnt = 0;
8982    Bool                 isSplfrm;
8983    RgSchTddSubfrmInfo   subfrmInfo = rgSchTddMaxUlSubfrmTbl[cell->ulDlCfgIdx];
8984    S16                  ret;
8985    uint8_t              splSfIdx;
8986    uint8_t              antPortIdx;
8987    uint8_t              numCrs;
8988    uint8_t              cfi;  
8989    uint8_t              cfiIdx;
8990    RgSchDlSf            *sf;
8991    uint8_t              splSfCfi;
8992    uint8_t              mPhich;
8993
8994    
8995
8996    cellSch = RG_SCH_CMN_GET_CELL(cell);
8997    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->\
8998                                                   rachCfg.preambleFormat];
8999    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
9000    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
9001    
9002    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
9003                        3 TTI (MAX L1+L2 processing delay at the UE) */
9004    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
9005                                  rgSchCmnHarqRtt[cell->ulDlCfgIdx] + 3; 
9006    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9007    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9008    if (cfg->maxUePerDlSf == 0)
9009    {
9010       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9011    }
9012    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
9013    {
9014       return RFAILED;
9015    }
9016
9017
9018    if (cell->bwCfg.dlTotalBw <= 10)
9019    {
9020       cfiIdx = 1;
9021       numPdcchSym = 2;
9022    }
9023    else
9024    {
9025       cfiIdx = 0;
9026       numPdcchSym = 1;
9027    }
9028    /* DwPTS Scheduling Changes Start */
9029    cellSch->dl.splSfCfg  = splSubfrmIdx;
9030  
9031    if (cfg->isCpDlExtend == TRUE)
9032    {
9033       if((0 == splSubfrmIdx) || (4 == splSubfrmIdx) ||
9034          (7 == splSubfrmIdx) || (8 == splSubfrmIdx)
9035         )
9036       {
9037          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
9038       }
9039       else
9040       {
9041          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
9042       }
9043    }
9044    else
9045    {
9046       /* Refer to 36.213 Section 7.1.7 */
9047       if((0 == splSubfrmIdx) || (5 == splSubfrmIdx))
9048       {
9049          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
9050       }
9051       else
9052       {
9053          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
9054       }
9055    }
9056    /* DwPTS Scheduling Changes End */  
9057
9058    splSfCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
9059    RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
9060    
9061    for (sfCount = 0; sfCount < maxDlSubfrms; sfCount++)
9062    {
9063       sf = cell->subFrms[sfCount];
9064       /* Sfcount matches the first special subframe occurs at Index 0
9065             * or subsequent special subframes */
9066       if(subfrmInfo.switchPoints == 1)
9067       {
9068          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
9069                                  RG_SCH_CMN_10_MS_PRD, &subfrmInfo);
9070       }
9071       else
9072       {
9073          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
9074                                  RG_SCH_CMN_5_MS_PRD, &subfrmInfo);
9075       }
9076       if(isSplfrm == TRUE)
9077       {
9078          swPtCnt++;
9079          /* DwPTS Scheduling Changes Start */        
9080          if (cell->splSubfrmCfg.isDlDataAllowed == TRUE)
9081          {
9082             sf->sfType = RG_SCH_SPL_SF_DATA;
9083          }
9084          else
9085          {
9086             sf->sfType = RG_SCH_SPL_SF_NO_DATA;
9087          }
9088          /* DwPTS Scheduling Changes End */
9089       }
9090       else
9091       {
9092          /* DwPTS Scheduling Changes Start */
9093          if (sf->sfNum != 0)
9094          {
9095             sf->sfType = RG_SCH_DL_SF;
9096          }
9097          else
9098          {
9099             sf->sfType = RG_SCH_DL_SF_0;
9100          }
9101          /* DwPTS Scheduling Changes End */
9102       }
9103       
9104       /* Calculate the number of CCEs per subframe in the cell */
9105       mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][sf->sfNum];
9106       if(cell->dynCfiCb.isDynCfiEnb == TRUE)
9107       {   
9108          /* In case if Dynamic CFI feature is enabled, default CFI 
9109           * value 1 is used  */
9110          sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][1];
9111       }
9112       else
9113       {
9114          if (sf->sfType == RG_SCH_SPL_SF_DATA)
9115          {
9116             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
9117          }
9118          else
9119          {
9120             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi)];
9121          }
9122       }   
9123    }
9124
9125    /* Intialize the RACH response scheduling related infromation */
9126    if(rgSCHCmnDlRachInfoInit(cell) != ROK)
9127    {
9128      return RFAILED;
9129    }
9130
9131    /* Allocate PRACH preamble list */
9132    rgSCHCmnDlCreateRachPrmLst(cell);
9133
9134    /* Initialize PHICH offset information */
9135    rgSCHCmnDlPhichOffsetInit(cell);
9136
9137    /* Update the size of HARQ ACK/NACK feedback table */
9138    /* The array size is increased by 2 to have enough free indices, where other
9139     * indices are busy waiting for HARQ feedback */
9140    cell->ackNackFdbkArrSize = rgSchTddANFdbkMapTbl[cell->ulDlCfgIdx] + 2; 
9141
9142    /* Initialize expected HARQ ACK/NACK feedback time */
9143    rgSCHCmnDlANFdbkInit(cell);
9144
9145    /* Initialize UL association set index */
9146    if(cell->ulDlCfgIdx != 0)
9147    {
9148       rgSCHCmnDlKdashUlAscInit(cell);
9149    }
9150
9151    if (cfg->isCpDlExtend == TRUE)
9152    {
9153       cp = RG_SCH_CMN_EXT_CP;
9154       noSymPerSlot = 6;
9155       cell->splSubfrmCfg.dwPts =
9156           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlDwPts;
9157    
9158       if ( cell->splSubfrmCfg.dwPts == 0 )
9159       {
9160          cell->isDwPtsCnted = FALSE;
9161       }
9162       else
9163       {
9164          cell->isDwPtsCnted = TRUE;
9165       }
9166
9167       if(cfg->isCpUlExtend == TRUE)
9168       {
9169          cell->splSubfrmCfg.upPts =
9170             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlExtUpPts;
9171       }
9172       else
9173       {
9174          cell->splSubfrmCfg.upPts =
9175             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlNorUpPts;
9176       }
9177    }
9178    else
9179    {
9180       cp = RG_SCH_CMN_NOR_CP;
9181       noSymPerSlot = 7;
9182       cell->splSubfrmCfg.dwPts =
9183           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlDwPts;
9184       cell->isDwPtsCnted = TRUE;
9185
9186       if(cfg->isCpUlExtend == TRUE)
9187       {
9188          cell->splSubfrmCfg.upPts =
9189             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlExtUpPts;
9190       }
9191       else
9192       {
9193          cell->splSubfrmCfg.upPts =
9194             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlNorUpPts;
9195       }
9196    }
9197
9198    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
9199    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++,cfiIdx++)
9200    {   
9201       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
9202       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
9203                                                  [cell->numTxAntPorts]][cfiIdx];
9204       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
9205       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
9206                                                  [cell->numTxAntPorts]][cfiIdx];
9207    }
9208
9209    /* Initializing the values of CFI parameters */
9210    if(cell->dynCfiCb.isDynCfiEnb)
9211    {   
9212       /* If DCFI is enabled, current CFI value will start from 1 */
9213       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
9214    }
9215    else
9216    {
9217       /* If DCFI is disabled, current CFI value is set as default max allowed CFI value */
9218       cellSch->dl.currCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
9219       cellSch->dl.newCfi = cellSch->dl.currCfi;
9220    }   
9221
9222    /* Include CRS REs while calculating Efficiency
9223     * The number of Resource Elements occupied by CRS depends on Number of
9224     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
9225     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
9226     * details of the same. Please note that PDCCH overlap symbols would not
9227     * considered in CRS REs deduction */
9228    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
9229    {
9230       cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
9231             - numPdcchSym) *RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
9232    }
9233
9234    /* DwPTS Scheduling Changes Start */
9235    antPortIdx = (cell->numTxAntPorts == 1)? 0: 
9236       ((cell->numTxAntPorts == 2)? 1: 2);     
9237
9238    if (cp == RG_SCH_CMN_NOR_CP)
9239    {
9240       splSfIdx = (splSubfrmIdx == 4)? 1: 0;   
9241    }
9242    else
9243    {
9244       splSfIdx = (splSubfrmIdx == 3)? 1: 0;
9245    }
9246
9247    numCrs = rgSchCmnDwptsCrs[splSfIdx][antPortIdx];
9248
9249    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI-1; cfi++)
9250    { 
9251       /* If CFI is 2 and Ant Port is 4, don't consider the sym 1 CRS REs */  
9252       if (antPortIdx == 2 && cfi == 2)
9253       {
9254          numCrs -= 4;      
9255       }
9256       cellSch->dl.numReDwPts[cfi]  =  ((cell->splSubfrmCfg.dwPts - cfi)*
9257                                   RB_SCH_CMN_NUM_SCS_PER_RB) - numCrs;
9258    }
9259    /* DwPTS Scheduling Changes End */
9260
9261    if (cfg->maxDlBwPerUe == 0)
9262    {
9263       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
9264    }
9265    else
9266    {
9267       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
9268    }
9269    if (cfg->maxDlRetxBw == 0)
9270    {
9271       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
9272    }
9273    else
9274    {
9275       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
9276    }
9277    /* Fix: MUE_PERTTI_DL*/
9278    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9279    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9280    if (cfg->maxUePerDlSf == 0)
9281    {
9282       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9283    }
9284    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
9285    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
9286    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
9287    {
9288       DU_LOG("\nERROR  -->  SCH : Invalid configuration !: "
9289                       "maxCcchPerDlSf %u > maxUePerDlSf %u",
9290                    cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
9291
9292       return RFAILED;
9293    }
9294    else if (!cfg->maxCcchPerDlSf)
9295    {
9296       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
9297        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
9298        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
9299        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
9300        * FLE crash in PHY as PHY has limit of 16 max*/
9301       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
9302    }
9303    else
9304    {
9305       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
9306    }
9307    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
9308    {
9309       return RFAILED;
9310    }
9311
9312    /*ccpu00118273 - ADD - start */
9313    cmLListInit(&cellSch->dl.msg4RetxLst);
9314 #ifdef RGR_V1
9315    cmLListInit(&cellSch->dl.ccchSduRetxLst);
9316 #endif
9317
9318 #ifdef RG_PHASE2_SCHED
9319    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
9320    {
9321       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
9322    }
9323    if (cfg->dlfsCfg.isDlFreqSel)
9324    {
9325       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
9326       if (ret != ROK)
9327       {
9328          return RFAILED;
9329       }
9330    }
9331    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
9332 #endif
9333
9334    /* Power related configuration */
9335    ret = rgSCHPwrCellCfg(cell, cfg);
9336    if (ret != ROK)
9337    {
9338       return RFAILED;
9339    }
9340
9341    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
9342    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
9343    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
9344    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
9345    cellSch->dl.msg4pAVal        = cfg->msg4pAVal;
9346    return ROK;
9347 }
9348 #else /* LTE_TDD */
9349 /**
9350  * @brief This function handles the configuration of cell for the first
9351  *        time by the scheduler.
9352  *
9353  * @details
9354  *
9355  *     Function: rgSCHCmnDlRgrCellCfg
9356  *     Purpose:  Configuration received is stored into the data structures
9357  *               Also, update the scheduler with the number of frames of
9358  *               RACH preamble transmission.
9359  *
9360  *     Invoked by: BO and Scheduler
9361  *
9362  *  @param[in]  RgSchCellCb*   cell
9363  *  @param[in]  RgrCellCfg*    cfg
9364  *  @param[in]  RgSchErrInfo*  err
9365  *  @return     S16
9366  *
9367  **/
9368 static S16 rgSCHCmnDlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cfg,RgSchErrInfo *err)
9369 {
9370    S16          ret;
9371    RgSchCmnCell *cellSch;
9372    uint8_t      cp;
9373    uint8_t      numPdcchSym;
9374    uint8_t      noSymPerSlot;
9375    uint8_t      cfi;  
9376    uint8_t      cfiIdx;
9377
9378
9379    cellSch = RG_SCH_CMN_GET_CELL(cell);
9380
9381    /* Initialize the parameters with the ones received in the */
9382    /* configuration.                                          */
9383
9384    /* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA
9385     * sub-frames from preamble format */
9386    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat];
9387
9388    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
9389    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
9390    
9391    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
9392                        3 TTI (MAX L1+L2 processing delay at the UE) */
9393    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
9394                                  rgSchCmnHarqRtt[7] + 3; 
9395
9396    if (cell->bwCfg.dlTotalBw <= 10)
9397    {
9398       cfiIdx = 1;
9399       numPdcchSym = 2;
9400    }
9401    else
9402    {
9403       cfiIdx = 0;
9404       numPdcchSym = 1;
9405    }
9406
9407    if (cell->isCpDlExtend == TRUE)
9408    {
9409       cp = RG_SCH_CMN_EXT_CP;
9410       noSymPerSlot = 6;
9411    }
9412    else
9413    {
9414       cp = RG_SCH_CMN_NOR_CP;
9415       noSymPerSlot = 7;
9416    }
9417
9418    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
9419    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, cfiIdx++)
9420    {   
9421       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
9422 #ifdef EMTC_ENABLE      
9423       cellSch->dl.emtcCqiToTbsTbl[0][cfi]   = rgSchEmtcCmnCqiToTbs[0][cp][cfiIdx];
9424 #endif      
9425       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
9426                                                  [cell->numTxAntPorts]][cfiIdx];
9427       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
9428 #ifdef EMTC_ENABLE      
9429       cellSch->dl.emtcCqiToTbsTbl[1][cfi]   = rgSchEmtcCmnCqiToTbs[1][cp][cfiIdx];
9430 #endif      
9431       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
9432                                                  [cell->numTxAntPorts]][cfiIdx];
9433    }
9434
9435    /* Initializing the values of CFI parameters */
9436    if(cell->dynCfiCb.isDynCfiEnb)
9437    {   
9438       /* If DCFI is enabled, current CFI value will start from 1 */
9439       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
9440    }
9441    else
9442    {
9443       /* If DCFI is disabled, current CFI value is set as default CFI value */
9444       cellSch->dl.currCfi = cellSch->cfiCfg.cfi;
9445       cellSch->dl.newCfi = cellSch->dl.currCfi;
9446    }   
9447
9448    /* Include CRS REs while calculating Efficiency
9449     * The number of Resource Elements occupied by CRS depends on Number of
9450     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
9451     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
9452     * details of the same. Please note that PDCCH overlap symbols would not
9453     * considered in CRS REs deduction */
9454    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
9455    {
9456        cellSch->dl.noResPerRb[cfi]    = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
9457             - numPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
9458    }           
9459
9460    if (cfg->maxDlBwPerUe == 0)
9461    {
9462       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
9463    }
9464    else
9465    {
9466       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
9467    }
9468    if (cfg->maxDlRetxBw == 0)
9469    {
9470       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
9471    }
9472    else
9473    {
9474       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
9475    }
9476    
9477    /* Fix: MUE_PERTTI_DL*/
9478    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
9479    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
9480    if (cfg->maxUePerDlSf == 0)
9481    {
9482       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
9483    }
9484    /* Fix: MUE_PERTTI_DL syed validating Cell Configuration */
9485    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
9486    {
9487       DU_LOG("\nERROR  -->  SCH : FAILED MaxUePerDlSf(%u) < MaxDlUeNewTxPerTti(%u)",
9488             cellSch->dl.maxUePerDlSf,
9489             cellSch->dl.maxUeNewTxPerTti);
9490       return RFAILED;
9491    }
9492    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
9493    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
9494    {
9495       DU_LOG("\nERROR  -->  SCH : Invalid configuration !: "
9496             "maxCcchPerDlSf %u > maxUePerDlSf %u",
9497             cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
9498
9499       return RFAILED;
9500    }
9501    else if (!cfg->maxCcchPerDlSf)
9502    {
9503       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
9504        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
9505        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
9506        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
9507        * FLE crash in PHY as PHY has limit of 16 max*/
9508       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
9509    }
9510    else
9511    {
9512       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
9513    }
9514
9515
9516    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
9517    {
9518       return RFAILED;
9519    }
9520    cmLListInit(&cellSch->dl.msg4RetxLst);
9521 #ifdef RGR_V1
9522    cmLListInit(&cellSch->dl.ccchSduRetxLst);
9523 #endif
9524
9525 #ifdef RG_PHASE2_SCHED
9526    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
9527    {
9528       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
9529    }
9530    if (cfg->dlfsCfg.isDlFreqSel)
9531    {
9532       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
9533       if (ret != ROK)
9534       {
9535          return RFAILED;
9536       }
9537    }
9538    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
9539 #endif
9540
9541    /* Power related configuration */
9542    ret = rgSCHPwrCellCfg(cell, cfg);
9543    if (ret != ROK)
9544    {
9545       return RFAILED;
9546    }
9547
9548    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
9549    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
9550    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
9551    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
9552    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
9553    return ROK;
9554 }
9555 #endif /* LTE_TDD */
9556
9557 /***********************************************************
9558  *
9559  *     Func : rgSCHCmnUlCalcReqRbCeil
9560  *
9561  *     Desc : Calculate RB required to satisfy 'bytes' for
9562  *            a given CQI.
9563  *            Returns number of RBs such that requirement
9564  *            is necessarily satisfied (does a 'ceiling'
9565  *            computation).
9566  *
9567  *     Ret  : Required RBs (uint8_t)
9568  *
9569  *     Notes:
9570  *
9571  *     File :
9572  *
9573  **********************************************************/
9574 uint8_t rgSCHCmnUlCalcReqRbCeil(uint32_t bytes,uint8_t cqi,RgSchCmnUlCell *cellUl)
9575 {
9576    uint32_t numRe = RGSCH_CEIL((bytes * 8) * 1024, rgSchCmnUlCqiTbl[cqi].eff);
9577    return ((uint8_t)RGSCH_CEIL(numRe, RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl)));
9578 }
9579
9580 /***********************************************************
9581  *
9582  *     Func : rgSCHCmnPrecompMsg3Vars
9583  *
9584  *     Desc : Precomputes the following for msg3 allocation:
9585  *            1. numSb and Imcs for msg size A
9586  *            2. numSb and Imcs otherwise
9587  *
9588  *     Ret  :
9589  *
9590  *     Notes: The corresponding vars in cellUl struct is filled
9591  *            up
9592  *
9593  *     File :
9594  *
9595  **********************************************************/
9596 static S16 rgSCHCmnPrecompMsg3Vars(RgSchCmnUlCell *cellUl,uint8_t ccchCqi,uint16_t msgSzA,uint8_t sbSize,Bool isEcp)
9597 {
9598    uint8_t  numSb;
9599    uint8_t  ccchTbs;
9600    uint8_t  ccchMcs;
9601    uint8_t  numRb = 0;
9602    uint8_t  iTbs = 0;
9603    uint16_t msg3GrntSz = 0;
9604
9605
9606    if (ccchCqi > cellUl->max16qamCqi)
9607    {
9608       ccchCqi = cellUl->max16qamCqi;
9609    }
9610 /* #ifndef RG_SCH_CMN_EXP_CP_SUP For ECP Pick the index 1 */
9611    /* Fix */
9612    ccchTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
9613    ccchMcs = rgSCHCmnUlGetIMcsFrmITbs(ccchTbs, CM_LTE_UE_CAT_1);
9614    
9615    /* MCS should fit in 4 bits in RAR */
9616    if (ccchMcs >= 15)
9617    {
9618       ccchMcs = 15;
9619    }
9620    
9621    /* Limit the ccchMcs to 15 as it
9622     * can be inferred from 36.213, section 6.2 that msg3 imcs
9623     * field is 4 bits.
9624     * Since, UE doesn't exist right now, we use CAT_1 for ue
9625     * category*/
9626    while((ccchMcs = (rgSCHCmnUlGetIMcsFrmITbs(
9627                       rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi],CM_LTE_UE_CAT_1))
9628                     ) >
9629                  RG_SCH_CMN_MAX_MSG3_IMCS)
9630    {
9631       ccchCqi--;
9632    }
9633    
9634    iTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
9635    
9636    if (msgSzA < RGSCH_MIN_MSG3_GRNT_SZ)
9637    {
9638       return RFAILED;
9639    }
9640    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(msgSzA, ccchCqi, cellUl), sbSize);
9641    
9642    numRb   = numSb * sbSize;
9643    msg3GrntSz = 8 * msgSzA;
9644
9645    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
9646    {
9647       ++numSb;
9648       numRb   = numSb * sbSize;
9649    }
9650    while (rgSchCmnMult235Tbl[numSb].match != numSb)
9651    {
9652       ++numSb;
9653    }
9654    /* Reversed(Corrected) the assignment for preamble-GrpA
9655     * Refer- TG36.321- section- 5.1.2*/
9656    cellUl->ra.prmblBNumSb = numSb;
9657    cellUl->ra.prmblBIMcs  = ccchMcs;
9658    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(RGSCH_MIN_MSG3_GRNT_SZ, \
9659                       ccchCqi, cellUl),
9660          sbSize);
9661
9662    numRb   = numSb * sbSize;
9663    msg3GrntSz = 8 * RGSCH_MIN_MSG3_GRNT_SZ;
9664    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
9665    {
9666       ++numSb;
9667       numRb   = numSb * sbSize;
9668    }
9669    while (rgSchCmnMult235Tbl[numSb].match != numSb)
9670    {
9671       ++numSb;
9672    }
9673    /* Reversed(Corrected) the assignment for preamble-GrpA
9674     * Refer- TG36.321- section- 5.1.2*/
9675    cellUl->ra.prmblANumSb = numSb;
9676    cellUl->ra.prmblAIMcs  = ccchMcs;
9677    return ROK;
9678 }
9679
9680 uint32_t gPrntPucchDet=0;
9681
9682 #ifdef LTE_TDD
9683 /***********************************************************
9684  *
9685  *     Func : rgSCHCmnUlCalcAvailBw
9686  *
9687  *     Desc : Calculates bandwidth available for PUSCH scheduling.
9688  *
9689  *     Ret  : S16 (ROK/RFAILED)
9690  *
9691  *     Notes:
9692  *
9693  *     File :
9694  *
9695  **********************************************************/
9696 static S16 rgSCHCmnUlCalcAvailBw(RgSchCellCb *cell,RgrCellCfg *cellCfg,uint8_t cfi,uint8_t *rbStartRef,uint8_t  *bwAvailRef)
9697 {
9698    uint8_t  c        = 3;
9699    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
9700    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
9701    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
9702    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
9703    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
9704    uint8_t  n1PerRb;
9705    uint8_t  totalCce;
9706    uint16_t n1Max;
9707    uint8_t  n1Rb;
9708    uint32_t mixedRb;
9709    uint8_t  exclRb; /* RBs to exclude */
9710    uint8_t  n1RbPart;
9711    uint8_t  puschRbStart;
9712    /* To avoid PUCCH and PUSCH collision issue */
9713    uint8_t  P;
9714    uint8_t  n1PlusOne;
9715    uint8_t  mi;
9716    /* Maximum value of M as per Table 10.1-1 */
9717    uint8_t  M[RGSCH_MAX_TDD_UL_DL_CFG] = {1, 2, 4, 3, 4, 9, 1};
9718
9719
9720    if (cell->isCpUlExtend)
9721    {
9722       c = 2;
9723    }
9724
9725    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
9726
9727    /* Considering the max no. of CCEs for PUSCH BW calculation 
9728     * based on min mi value */
9729    if (cell->ulDlCfgIdx == 0 || cell->ulDlCfgIdx == 6)
9730    {
9731       mi = 1;
9732    }
9733    else
9734    { 
9735       mi = 0;
9736    }
9737    
9738    totalCce = cell->dynCfiCb.cfi2NCceTbl[mi][cfi];
9739
9740    P        = rgSCHCmnGetPValFrmCCE(cell, totalCce-1);
9741    n1PlusOne = cell->rgSchTddNpValTbl[P + 1];
9742    n1Max    = (M[cell->ulDlCfgIdx] - 1)*n1PlusOne + (totalCce-1) + n1Pucch;
9743
9744    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
9745     * TS 36.211  */
9746    n1RbPart = (c*n1Cs)/pucchDeltaShft;
9747    n1Rb = (n1Max - n1RbPart)/ n1PerRb;
9748    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
9749
9750    /* get the total Number of RB's to be excluded for PUSCH */
9751    /* ccpu00137339 */
9752    if(n1Pucch < n1RbPart)
9753    {
9754       exclRb = n2Rb;
9755    }
9756    else
9757    {
9758       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
9759    }
9760    puschRbStart = exclRb/2 + 1; 
9761
9762    /* Num of PUCCH RBs = puschRbStart*2 */
9763    if (puschRbStart * 2 >= ulBw)
9764    {
9765       DU_LOG("\nERROR  -->  SCH : No bw available for PUSCH");
9766       return RFAILED;
9767    }
9768
9769    *rbStartRef = puschRbStart;
9770    *bwAvailRef = ulBw -  puschRbStart * 2;
9771  
9772    if(cell->pucchCfg.maxPucchRb !=0 && 
9773          (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
9774    {
9775       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
9776    }
9777     
9778    return ROK;
9779 }
9780 #else
9781
9782 /***********************************************************
9783  *
9784  *     Func : rgSCHCmnUlCalcAvailBw
9785  *
9786  *     Desc : Calculates bandwidth available for PUSCH scheduling.
9787  *
9788  *     Ret  : S16 (ROK/RFAILED)
9789  *
9790  *     Notes:
9791  *
9792  *     File :
9793  *
9794  **********************************************************/
9795 static S16 rgSCHCmnUlCalcAvailBw(RgSchCellCb *cell,RgrCellCfg *cellCfg,uint8_t cfi,uint8_t *rbStartRef,uint8_t *bwAvailRef)
9796 {
9797    uint8_t  c        = 3;
9798    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
9799    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
9800    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
9801    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
9802    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
9803    uint8_t  n1PerRb;
9804    uint8_t  totalCce;
9805    uint16_t n1Max;
9806    uint8_t  n1Rb;
9807    uint32_t mixedRb;
9808    uint8_t  exclRb; /* RBs to exclude */
9809    uint8_t  n1RbPart;
9810    uint8_t  puschRbStart;
9811 #ifdef LTE_ADV
9812    uint16_t numOfN3PucchRb;
9813    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);  
9814 #endif
9815    
9816
9817    if (cell->isCpUlExtend)
9818    {
9819       c = 2;
9820    }
9821
9822    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
9823
9824    totalCce = cell->dynCfiCb.cfi2NCceTbl[0][cfi];
9825
9826    n1Max    = n1Pucch + totalCce-1;
9827
9828    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
9829     * TS 36.211  */
9830    n1RbPart = (c*n1Cs)/pucchDeltaShft;
9831    n1Rb = (uint8_t)((n1Max - n1RbPart) / n1PerRb);
9832    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
9833
9834    /* get the total Number of RB's to be excluded for PUSCH */
9835    /* ccpu00137339 */
9836    if(n1Pucch < n1RbPart)
9837    {
9838       exclRb = n2Rb;
9839    }
9840    else
9841    {
9842       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
9843    }
9844    /*Support for PUCCH Format 3*/
9845 #ifdef LTE_ADV
9846    if (cell->isPucchFormat3Sptd)
9847    {
9848       numOfN3PucchRb = RGSCH_CEIL(cellSch->dl.maxUePerDlSf,5); 
9849       exclRb = exclRb + numOfN3PucchRb;
9850    }
9851 #endif
9852    puschRbStart = exclRb/2 + 1;
9853
9854    if(gPrntPucchDet)
9855    {
9856 #ifndef ALIGN_64BIT
9857         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",
9858         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
9859 #else
9860         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",
9861         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
9862 #endif
9863    }
9864
9865    if (puschRbStart*2 >= ulBw)
9866    {
9867       DU_LOG("\nERROR  -->  SCH : No bw available for PUSCH");
9868       return RFAILED;
9869    }
9870
9871    *rbStartRef = puschRbStart;
9872    *bwAvailRef = ulBw - puschRbStart * 2;
9873
9874    if(cell->pucchCfg.maxPucchRb !=0 && 
9875       (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
9876    {
9877       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
9878    }
9879    
9880    return ROK;
9881 }
9882 #endif
9883
9884
9885
9886 /***********************************************************
9887  *
9888  *     Func : rgSCHCmnUlCellInit
9889  *
9890  *     Desc : Uplink scheduler initialisation for cell.
9891  *
9892  *     Ret  : S16
9893  *
9894  *     Notes:
9895  *
9896  *     File :
9897  *
9898  **********************************************************/
9899 static S16 rgSCHCmnUlCellInit(RgSchCellCb  *cell,RgrCellCfg *cellCfg)
9900 {
9901    S16            ret;
9902    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
9903    uint8_t maxUePerUlSf = cellCfg->maxUePerUlSf;
9904 #ifdef RGR_V1
9905    /* Added configuration for maximum number of MSG3s */
9906    uint8_t maxMsg3PerUlSf = cellCfg->maxMsg3PerUlSf;
9907 #endif
9908    uint8_t maxUlBwPerUe = cellCfg->maxUlBwPerUe;
9909    uint8_t sbSize       = cellCfg->puschSubBand.size;
9910    uint8_t i;
9911    uint8_t rbStart;
9912    uint8_t bwAvail;
9913    uint8_t cfi;  
9914    uint8_t maxSbPerUe;
9915    uint8_t numSb;
9916 #ifdef LTE_TDD
9917    uint16_t ulDlCfgIdx = cell->ulDlCfgIdx;
9918    /* [ccpu00127294]-MOD-Change the max Ul subfrms size in TDD */
9919    uint8_t  maxSubfrms = 2 * rgSchTddNumUlSf[ulDlCfgIdx]; 
9920    uint8_t  ulToDlMap[12] = {0}; /* maximum 6 Subframes in UL  * 2 */
9921    uint8_t  maxUlsubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
9922                                            [RGSCH_NUM_SUB_FRAMES-1];
9923    uint16_t subfrm;
9924    S8       dlIdx;
9925 #else
9926    uint8_t  maxSubfrms = RG_SCH_CMN_UL_NUM_SF;
9927 #endif
9928 #ifdef LTE_L2_MEAS
9929    uint8_t  idx;
9930 #endif
9931    uint8_t  iTbs;
9932 #if (defined(LTE_L2_MEAS) )
9933    Inst  inst         = cell->instIdx;
9934 #endif /* #if (defined(LTE_L2_MEAS) || defined(DEBUGP) */
9935    RgSchCmnCell      *cellSch =  (RgSchCmnCell *)(cell->sc.sch);
9936    
9937
9938    cellUl->maxUeNewTxPerTti = cellCfg->maxUlUeNewTxPerTti;
9939    if (maxUePerUlSf == 0)
9940    {
9941       maxUePerUlSf = RG_SCH_CMN_MAX_UE_PER_UL_SF;
9942    }
9943 #ifdef RGR_V1
9944    if (maxMsg3PerUlSf == 0)
9945    {
9946       maxMsg3PerUlSf = RG_SCH_CMN_MAX_MSG3_PER_UL_SF;
9947    }
9948    /*  fixed the problem while sending raRsp 
9949     * if maxMsg3PerUlSf is greater than 
9950     * RGSCH_MAX_RNTI_PER_RARNTI 
9951     * */
9952    if(maxMsg3PerUlSf > RGSCH_MAX_RNTI_PER_RARNTI)
9953    {
9954       maxMsg3PerUlSf = RGSCH_MAX_RNTI_PER_RARNTI; 
9955    } 
9956
9957    if(maxMsg3PerUlSf > maxUePerUlSf)
9958    {
9959       maxMsg3PerUlSf =  maxUePerUlSf;   
9960    }
9961    
9962    /*cellUl->maxAllocPerUlSf = maxUePerUlSf + maxMsg3PerUlSf;*/
9963    /*Max MSG3 should be a subset of Max UEs*/
9964    cellUl->maxAllocPerUlSf = maxUePerUlSf;
9965    cellUl->maxMsg3PerUlSf = maxMsg3PerUlSf;
9966 #else
9967    cellUl->maxAllocPerUlSf = maxUePerUlSf;
9968 #endif
9969    /* Fix: MUE_PERTTI_UL syed validating Cell Configuration */
9970    if (cellUl->maxAllocPerUlSf < cellUl->maxUeNewTxPerTti)
9971    {
9972       DU_LOG("\nERROR  -->  SCH : FAILED: MaxUePerUlSf(%u) < MaxUlUeNewTxPerTti(%u)",
9973             cellUl->maxAllocPerUlSf,
9974             cellUl->maxUeNewTxPerTti);
9975       return RFAILED;
9976    }
9977
9978 #ifdef LTE_L2_MEAS
9979 #ifdef LTE_TDD
9980    for(idx = 0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
9981 #else
9982    for(idx = 0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
9983 #endif
9984    {
9985
9986       ret = rgSCHUtlAllocSBuf(inst,  (Data **)&(cell->sfAllocArr[idx].
9987               ulUeInfo.ulAllocInfo), (cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)));
9988       if (ret != ROK)
9989       {
9990          DU_LOG("\nERROR  -->  SCH : Memory allocation failed ");
9991             return (ret);
9992       }
9993    }
9994 #endif
9995    if (maxUlBwPerUe == 0)
9996    {
9997       /* ccpu00139362- Setting to configured UL BW instead of MAX BW(100)*/
9998       maxUlBwPerUe = cell->bwCfg.ulTotalBw;
9999    }
10000    cellUl->maxUlBwPerUe = maxUlBwPerUe;
10001
10002    /* FOR RG_SCH_CMN_EXT_CP_SUP */
10003    if (!cellCfg->isCpUlExtend)
10004    {
10005       cellUl->ulNumRePerRb = 12 * (14 - RGSCH_UL_SYM_DMRS_SRS);
10006    }
10007    else
10008    {
10009       cellUl->ulNumRePerRb = 12 * (12 - RGSCH_UL_SYM_DMRS_SRS);
10010    }
10011
10012    if (sbSize != rgSchCmnMult235Tbl[sbSize].match)
10013    {
10014       DU_LOG("\nERROR  -->  SCH : Invalid subband size %d", sbSize);
10015       return RFAILED;
10016    }
10017         //Setting the subband size to 4 which is size of VRBG in 5GTF
10018 #ifdef RG_5GTF
10019         sbSize = MAX_5GTF_VRBG_SIZE;
10020 #endif
10021         
10022    maxSbPerUe = maxUlBwPerUe / sbSize;
10023    if (maxSbPerUe == 0)
10024    {
10025       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlCellInit(): "
10026          "maxUlBwPerUe/sbSize is zero");
10027       return RFAILED;
10028    }
10029    cellUl->maxSbPerUe = rgSchCmnMult235Tbl[maxSbPerUe].prvMatch;
10030
10031    /* CQI related updations */
10032    if ((!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->ulCmnCodeRate.ccchCqi))
10033          || (!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->trgUlCqi.trgCqi)))
10034    {
10035       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlCellInit(): "
10036          "Invalid cqi");
10037       return RFAILED;
10038    }
10039    cellUl->dfltUlCqi = cellCfg->ulCmnCodeRate.ccchCqi;
10040
10041    /* Changed the logic to determine maxUlCqi.
10042     * For a 16qam UE, maxUlCqi is the CQI Index at which
10043     * efficiency is as close as possible to RG_SCH_MAX_CODE_RATE_16QAM
10044     * Refer to 36.213-8.6.1 */
10045     for (i = RG_SCH_CMN_UL_NUM_CQI - 1;i > 0; --i)
10046    {
10047        DU_LOG("\nINFO  -->  SCH : CQI %u:iTbs %u",i, 
10048             rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]);
10049 #ifdef MAC_SCH_STATS
10050       /* ccpu00128489 ADD Update mcs in hqFailStats here instead of at CRC 
10051        * since CQI to MCS mapping does not change. The only exception is for 
10052        * ITBS = 19 where the MCS can be 20 or 21 based on the UE cat. We 
10053        * choose 20, instead of 21, ie UE_CAT_3 */
10054       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
10055       RG_SCH_CMN_UL_TBS_TO_MCS(iTbs, hqFailStats.ulCqiStat[i - 1].mcs);
10056 #endif
10057    }
10058    for (i = RG_SCH_CMN_UL_NUM_CQI - 1; i != 0; --i)
10059    {
10060       /* Fix for ccpu00123912*/
10061       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
10062       if (iTbs <= RGSCH_UL_16QAM_MAX_ITBS) /* corresponds to 16QAM */
10063       {
10064          DU_LOG("\nINFO  -->  SCH : 16 QAM CQI %u", i);
10065          cellUl->max16qamCqi = i;
10066          break;
10067       }
10068    }
10069
10070 #ifdef EMTC_ENABLE
10071    /* Precompute useful values for RA msg3 */
10072    ret = rgSCHCmnPrecompEmtcMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
10073          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
10074    if (ret != ROK)
10075    {
10076       return (ret);
10077    }
10078 #endif   
10079
10080    /* Precompute useful values for RA msg3 */
10081    ret = rgSCHCmnPrecompMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
10082          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
10083    if (ret != ROK)
10084    {
10085       return (ret);
10086    }
10087
10088    cellUl->sbSize  = sbSize;
10089    
10090 #ifdef LTE_TDD  
10091    cellUl->numUlSubfrms = maxSubfrms;
10092
10093    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->ulSfArr,
10094             cellUl->numUlSubfrms * sizeof(RgSchUlSf));
10095
10096    if (ret != ROK)
10097    {
10098       cellUl->numUlSubfrms = 0;
10099       return (ret);
10100    }
10101
10102    /* store the DL subframe corresponding to the PUSCH offset
10103     * in their respective UL subframe */
10104    for(i=0; i < RGSCH_NUM_SUB_FRAMES; i++)
10105    {
10106       if(rgSchTddPuschTxKTbl[ulDlCfgIdx][i] != 0)
10107       {
10108          subfrm = (i + rgSchTddPuschTxKTbl[ulDlCfgIdx][i]) % \
10109                                  RGSCH_NUM_SUB_FRAMES;
10110          subfrm = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subfrm]-1;
10111          dlIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][i]-1;
10112          RGSCH_ARRAY_BOUND_CHECK( cell->instIdx, ulToDlMap, subfrm);
10113          ulToDlMap[subfrm] = dlIdx;
10114       }
10115    }
10116    /* Copy the information in the remaining UL subframes based
10117     * on number of HARQ processes */
10118    for(i=maxUlsubfrms; i < maxSubfrms; i++)
10119    {
10120       subfrm = i-maxUlsubfrms;
10121       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, i);
10122       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, subfrm)
10123       ulToDlMap[i] = ulToDlMap[subfrm];
10124    }
10125 #endif
10126
10127    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++)
10128    {
10129 #ifdef LTE_TDD        
10130       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
10131 #else
10132       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
10133 #endif
10134       if (ret != ROK)
10135       {
10136          return (ret);
10137       }
10138
10139       if (cfi == 1)
10140       {
10141          cell->ulAvailBw = bwAvail;
10142       }
10143
10144       numSb = bwAvail/sbSize; 
10145
10146       cell->dynCfiCb.bwInfo[cfi].startRb  = rbStart;
10147       cell->dynCfiCb.bwInfo[cfi].numSb    = numSb;
10148    }
10149
10150    if(0 == cell->dynCfiCb.maxCfi)
10151    {
10152       DU_LOG("\nERROR  -->  SCH : Incorrect Default CFI(%u), maxCfi(%u), maxPucchRb(%d)",
10153                cellSch->cfiCfg.cfi, cell->dynCfiCb.maxCfi, 
10154                cell->pucchCfg.maxPucchRb);
10155             
10156       return RFAILED;
10157    }
10158
10159    /* DMRS values */
10160    cellUl->dmrsArrSize = cell->dynCfiCb.bwInfo[1].numSb;
10161    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->dmrsArr,
10162          cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10163    if (ret != ROK)
10164    {
10165       return (ret);
10166    }
10167    for (i = 0; i < cellUl->dmrsArrSize; ++i)
10168    {
10169       cellUl->dmrsArr[i] = cellCfg->puschSubBand.dmrs[i];
10170    }
10171  
10172    /* Init subframes */
10173    for (i = 0; i < maxSubfrms; ++i)
10174    {
10175       ret = rgSCHUtlUlSfInit(cell, &cellUl->ulSfArr[i], i,
10176                              cellUl->maxAllocPerUlSf);
10177       if (ret != ROK)
10178       {
10179          for (; i != 0; --i)
10180          {
10181             rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[i-1]);
10182          }
10183          /* ccpu00117052 - MOD - Passing double pointer
10184             for proper NULLP assignment*/
10185          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(cellUl->dmrsArr)),
10186                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10187 #ifdef LTE_TDD
10188          /* ccpu00117052 - MOD - Passing double pointer
10189             for proper NULLP assignment*/
10190          rgSCHUtlFreeSBuf(cell->instIdx,
10191             (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
10192 #endif
10193          return (ret);
10194       }
10195    }
10196    RG_SCH_RESET_HCSG_UL_PRB_CNTR(cellUl);
10197    return ROK;
10198 }
10199
10200 /**
10201  * @brief Scheduler processing on cell configuration.
10202  *
10203  * @details
10204  *
10205  *     Function : rgSCHCmnRgrCellCfg
10206  *
10207  *     This function does requisite initialisation
10208  *     and setup for scheduler1 when a cell is
10209  *     configured.
10210  *
10211  *  @param[in]  RgSchCellCb   *cell
10212  *  @param[in]  RgrCellCfg    *cellCfg
10213  *  @param[out] RgSchErrInfo  *err
10214  *  @return  S16
10215  *      -# ROK
10216  *      -# RFAILED
10217  **/
10218 S16 rgSCHCmnRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cellCfg,RgSchErrInfo *err)
10219 {
10220    S16 ret;
10221    RgSchCmnCell *cellSch;
10222
10223    /* As part of RGR cell configuration, validate the CRGCellCfg
10224     * There is no trigger for crgCellCfg from SC1 */
10225    /* Removed failure check for Extended CP */
10226
10227    if (((ret = rgSCHUtlAllocSBuf(cell->instIdx,
10228       (Data**)&(cell->sc.sch), (sizeof(RgSchCmnCell)))) != ROK))
10229    {
10230       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED");
10231       err->errCause = RGSCHERR_SCH_CFG;
10232       return (ret);
10233    }
10234    cellSch = (RgSchCmnCell *)(cell->sc.sch);
10235    cellSch->cfiCfg = cellCfg->cfiCfg;
10236    cellSch->trgUlCqi.trgCqi = cellCfg->trgUlCqi.trgCqi;
10237    /* Initialize the scheduler refresh timer queues */
10238    cellSch->tmrTqCp.nxtEnt = 0;
10239    cellSch->tmrTqCp.tmrLen = RG_SCH_CMN_NUM_REFRESH_Q;
10240
10241    /* RACHO Intialize the RACH ded Preamble Information */
10242    rgSCHCmnCfgRachDedPrm(cell);
10243 #ifdef LTE_TDD
10244    /* Initialize 'Np' value for each 'p' used for
10245     * HARQ ACK/NACK reception */
10246    rgSCHCmnDlNpValInit(cell);
10247 #endif
10248
10249    /* Initialize 'Np' value for each 'p' used for
10250     * HARQ ACK/NACK reception */
10251 #ifdef LTE_TDD
10252    rgSCHCmnDlNpValInit(cell);
10253 #endif
10254
10255    /* Now perform uplink related initializations  */
10256    ret = rgSCHCmnUlCellInit(cell, cellCfg);
10257    if (ret != ROK)
10258    {
10259       /* There is no downlink deinit to be performed */
10260       err->errCause = RGSCHERR_SCH_CFG;
10261       return (ret);
10262    }
10263    ret = rgSCHCmnDlRgrCellCfg(cell, cellCfg, err);
10264    if (ret != ROK)
10265    {
10266       err->errCause = RGSCHERR_SCH_CFG;
10267       return (ret);
10268    }
10269    /* DL scheduler has no initializations to make */
10270    /* As of now DL scheduler always returns ROK   */
10271
10272    rgSCHCmnGetDciFrmtSizes(cell);
10273    rgSCHCmnGetCqiDciFrmt2AggrLvl(cell);
10274 #ifdef EMTC_ENABLE 
10275    rgSCHCmnGetEmtcDciFrmtSizes(cell);
10276    rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl(cell);
10277 #endif /* EMTC_ENABLE  */
10278
10279 #ifdef EMTC_ENABLE   
10280    if(TRUE == cellCfg->emtcEnable)
10281    {
10282       cellSch->apisEmtcUl = &rgSchEmtcUlSchdTbl[0];
10283       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
10284       if (ret != ROK)
10285       {
10286          return (ret);
10287       }
10288    }
10289 #endif
10290    cellSch->apisUl = &rgSchUlSchdTbl[RG_SCH_CMN_GET_UL_SCHED_TYPE(cell)];
10291    ret = cellSch->apisUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
10292    if (ret != ROK)
10293    {
10294       return (ret);
10295    }
10296 #ifdef EMTC_ENABLE   
10297    if(TRUE == cellCfg->emtcEnable)
10298    {
10299       cellSch->apisEmtcDl = &rgSchEmtcDlSchdTbl[0];
10300       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
10301       if (ret != ROK)
10302       {
10303          return (ret);
10304       }
10305    }
10306 #endif
10307    cellSch->apisDl = &rgSchDlSchdTbl[RG_SCH_CMN_GET_DL_SCHED_TYPE(cell)];
10308 #ifdef LTEMAC_SPS
10309    /* Perform SPS specific initialization for the cell */
10310    ret = rgSCHCmnSpsCellCfg(cell, cellCfg, err);
10311    if (ret != ROK)
10312    {
10313       return (ret);
10314    }
10315 #endif
10316    ret = cellSch->apisDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
10317    if (ret != ROK)
10318    {
10319       return (ret);
10320    }
10321    rgSCHCmnInitVars(cell);
10322
10323    return ROK;
10324 }  /* rgSCHCmnRgrCellCfg*/
10325
10326 \f
10327 /**
10328  * @brief This function handles the reconfiguration of cell.
10329  *
10330  * @details
10331  *
10332  *     Function: rgSCHCmnRgrCellRecfg
10333  *     Purpose:  Update the reconfiguration parameters.
10334  *
10335  *     Invoked by: Scheduler
10336  *
10337  *  @param[in]  RgSchCellCb*  cell
10338  *  @return  Void
10339  *
10340  **/
10341 S16 rgSCHCmnRgrCellRecfg(RgSchCellCb *cell,RgrCellRecfg *recfg,RgSchErrInfo *err)
10342 {
10343    S16                  ret;
10344    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
10345    RgSchCmnUlCell       *cellUl  = RG_SCH_CMN_GET_UL_CELL(cell);
10346
10347
10348    if (recfg->recfgTypes & RGR_CELL_UL_CMNRATE_RECFG)
10349    {
10350       uint8_t   oldCqi = cellUl->dfltUlCqi;
10351       if (!RG_SCH_CMN_UL_IS_CQI_VALID(recfg->ulCmnCodeRate.ccchCqi))
10352       {
10353          err->errCause = RGSCHERR_SCH_CFG;
10354          DU_LOG("\nERROR  -->  SCH : rgSCHCmnRgrCellRecfg(): "
10355             "Invalid cqi");
10356          return RFAILED;
10357       }
10358       cellUl->dfltUlCqi = recfg->ulCmnCodeRate.ccchCqi;
10359       ret = rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
10360             cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
10361       if (ret != ROK)
10362       {
10363          cellUl->dfltUlCqi = oldCqi;
10364          rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
10365                cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
10366          return (ret);
10367       }
10368    }
10369
10370    if (recfg->recfgTypes & RGR_CELL_DL_CMNRATE_RECFG)
10371    {
10372       if (rgSCHCmnDlCnsdrCmnRt(cell, &recfg->dlCmnCodeRate) != ROK)
10373       {
10374          err->errCause = RGSCHERR_SCH_CFG;
10375          return RFAILED;
10376       }
10377    }
10378  
10379 #ifdef EMTC_ENABLE  
10380    if(TRUE == cell->emtcEnable) 
10381    {
10382       /* Invoke UL sched for cell Recfg */
10383       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
10384       if (ret != ROK)
10385       {
10386          return RFAILED;
10387       }
10388
10389       /* Invoke DL sched for cell Recfg */
10390       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
10391       if (ret != ROK)
10392       {
10393          return RFAILED;
10394       }
10395    }
10396    else
10397 #endif
10398    {
10399    /* Invoke UL sched for cell Recfg */
10400    ret = cellSch->apisUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
10401    if (ret != ROK)
10402    {
10403       return RFAILED;
10404    }
10405
10406    /* Invoke DL sched for cell Recfg */
10407    ret = cellSch->apisDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
10408    if (ret != ROK)
10409    {
10410       return RFAILED;
10411    }
10412    }
10413
10414    if (recfg->recfgTypes & RGR_CELL_DLFS_RECFG)
10415    {
10416       ret = cellSch->apisDlfs->rgSCHDlfsCellRecfg(cell, recfg, err);
10417       if (ret != ROK)
10418       {
10419          return RFAILED;
10420       }
10421       cellSch->dl.isDlFreqSel = recfg->dlfsRecfg.isDlFreqSel;
10422    }
10423
10424    if (recfg->recfgTypes & RGR_CELL_PWR_RECFG)
10425    {
10426       ret = rgSCHPwrCellRecfg(cell, recfg);
10427       if (ret != ROK)
10428       {
10429          return RFAILED;
10430       }
10431    }
10432
10433    return ROK;
10434 }
10435
10436 /***********************************************************
10437  *
10438  *     Func : rgSCHCmnUlCellDeinit
10439  *
10440  *     Desc : Uplink scheduler de-initialisation for cell.
10441  *
10442  *     Ret  : S16
10443  *
10444  *     Notes:
10445  *
10446  *     File :
10447  *
10448  **********************************************************/
10449 static Void rgSCHCmnUlCellDeinit(RgSchCellCb *cell)
10450 {
10451    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
10452    uint8_t          ulSfIdx;
10453 #ifdef LTE_TDD
10454    uint8_t        maxSubfrms = cellUl->numUlSubfrms;
10455 #endif
10456 #ifdef LTE_L2_MEAS
10457    CmLList       *lnk = NULLP;
10458    RgSchL2MeasCb *measCb;
10459 #endif
10460 #ifdef LTE_L2_MEAS
10461 #ifdef LTE_TDD
10462    for(ulSfIdx = 0; ulSfIdx < RGSCH_SF_ALLOC_SIZE; ulSfIdx++)
10463 #else
10464    for(ulSfIdx = 0; ulSfIdx < RGSCH_NUM_SUB_FRAMES; ulSfIdx++)
10465 #endif
10466    {
10467       if(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo != NULLP)
10468       {
10469          /* ccpu00117052 - MOD - Passing double pointer
10470             for proper NULLP assignment*/
10471          rgSCHUtlFreeSBuf(cell->instIdx,
10472          (Data **)(&(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo)),
10473          cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc));
10474
10475          /* ccpu00117052 - DEL - removed explicit NULLP assignment
10476             as it is done in above utility function */
10477       }
10478    }
10479    /* Free the memory allocated to measCb */
10480    lnk = cell->l2mList.first;
10481    while(lnk != NULLP)
10482    {
10483       measCb = (RgSchL2MeasCb *)lnk->node;
10484       cmLListDelFrm(&cell->l2mList, lnk);
10485       lnk = lnk->next;
10486    /* ccpu00117052 - MOD - Passing double pointer
10487    for proper NULLP assignment*/
10488       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\
10489                           sizeof(RgSchL2MeasCb));
10490    }
10491 #endif
10492    if (cellUl->dmrsArr != NULLP)
10493    {
10494       /* ccpu00117052 - MOD - Passing double pointer
10495       for proper NULLP assignment*/
10496       rgSCHUtlFreeSBuf(cell->instIdx,(Data **)(&(cellUl->dmrsArr)),
10497                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
10498    }
10499    /* De-init subframes */
10500 #ifdef LTE_TDD
10501    for (ulSfIdx = 0; ulSfIdx < maxSubfrms; ++ulSfIdx)
10502 #else
10503    for (ulSfIdx = 0; ulSfIdx < RG_SCH_CMN_UL_NUM_SF; ++ulSfIdx)
10504 #endif
10505    {
10506       rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[ulSfIdx]);
10507    }
10508
10509 #ifdef LTE_TDD
10510    if (cellUl->ulSfArr != NULLP)
10511    {
10512       /* ccpu00117052 - MOD - Passing double pointer
10513       for proper NULLP assignment*/
10514       rgSCHUtlFreeSBuf(cell->instIdx,
10515          (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
10516    }
10517 #endif
10518
10519    return;
10520 }
10521
10522 /**
10523  * @brief Scheduler processing for cell delete.
10524  *
10525  * @details
10526  *
10527  *     Function : rgSCHCmnCellDel
10528  *
10529  *     This functions de-initialises and frees memory
10530  *     taken up by scheduler1 for the entire cell.
10531  *
10532  *  @param[in]  RgSchCellCb  *cell
10533  *  @return  Void
10534  **/
10535 Void rgSCHCmnCellDel(RgSchCellCb *cell)
10536 {
10537    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10538
10539 #ifdef LTE_L2_MEAS
10540    glblTtiCnt = 0;
10541 #endif
10542    if (cellSch == NULLP)
10543    {
10544       return;
10545    }
10546    /* Perform the deinit for the UL scheduler */
10547    rgSCHCmnUlCellDeinit(cell);
10548 #ifdef EMTC_ENABLE
10549    if(TRUE == cell->emtcEnable)
10550    {
10551       if (cellSch->apisEmtcUl)
10552       {
10553          cellSch->apisEmtcUl->rgSCHFreeUlCell(cell);
10554       }
10555    }
10556 #endif 
10557    if (cellSch->apisUl)
10558    {
10559       /* api pointer checks added (here and below in
10560        * this function). pl check. - antriksh */
10561       cellSch->apisUl->rgSCHFreeUlCell(cell);
10562    }
10563
10564    /* Perform the deinit for the DL scheduler */
10565    cmLListInit(&cellSch->dl.taLst);
10566    if (cellSch->apisDl)
10567    {
10568       cellSch->apisDl->rgSCHFreeDlCell(cell);
10569    }
10570 #ifdef EMTC_ENABLE
10571    if (cellSch->apisEmtcDl)
10572    {
10573       rgSCHEmtcInitTaLst(&cellSch->dl);
10574
10575       cellSch->apisEmtcDl->rgSCHFreeDlCell(cell);
10576    }
10577 #endif
10578
10579    /* DLFS de-initialization */
10580    if (cellSch->dl.isDlFreqSel && cellSch->apisDlfs)
10581    {
10582       cellSch->apisDlfs->rgSCHDlfsCellDel(cell);
10583    }
10584
10585    rgSCHPwrCellDel(cell);
10586 #ifdef LTEMAC_SPS
10587    rgSCHCmnSpsCellDel(cell);
10588 #endif
10589
10590    /* ccpu00117052 - MOD - Passing double pointer
10591    for proper NULLP assignment*/
10592    rgSCHUtlFreeSBuf(cell->instIdx,
10593       (Data**)(&(cell->sc.sch)), (sizeof(RgSchCmnCell)));
10594    return;
10595 }  /* rgSCHCmnCellDel */
10596
10597 \f
10598 /**
10599  * @brief This function validates QOS parameters for DL.
10600  *
10601  * @details
10602  *
10603  *     Function: rgSCHCmnValidateDlQos
10604  *     Purpose:  This function validates QOS parameters for DL.
10605  *
10606  *     Invoked by: Scheduler
10607  *
10608  *  @param[in] CrgLchQosCfg    *dlQos
10609  *  @return                    S16
10610  *
10611  **/
10612 static S16 rgSCHCmnValidateDlQos(RgrLchQosCfg *dlQos)
10613 {
10614    uint8_t qci = dlQos->qci;
10615    if ( qci < RG_SCH_CMN_MIN_QCI || qci > RG_SCH_CMN_MAX_QCI )
10616    {
10617       return RFAILED;
10618    }
10619
10620    if ((qci >= RG_SCH_CMN_GBR_QCI_START) &&
10621        (qci <= RG_SCH_CMN_GBR_QCI_END))
10622    {
10623       if ((dlQos->mbr == 0) || (dlQos->mbr < dlQos->gbr))
10624       {
10625          return RFAILED;
10626       }
10627    }
10628    return ROK;
10629 }
10630
10631 /**
10632  * @brief Scheduler invocation on logical channel addition.
10633  *
10634  * @details
10635  *
10636  *     Function : rgSCHCmnRgrLchCfg
10637  *
10638  *     This functions does required processing when a new
10639  *     (dedicated) logical channel is added. Assumes lcg
10640  *     pointer in ulLc is set.
10641  *
10642  *  @param[in]  RgSchCellCb  *cell
10643  *  @param[in]  RgSchUeCb    *ue
10644  *  @param[in]  RgSchDlLcCb  *dlLc
10645  *  @param[int] RgrLchCfg    *lcCfg
10646  *  @param[out] RgSchErrInfo *err
10647  *  @return  S16
10648  *      -# ROK
10649  *      -# RFAILED
10650  **/
10651 S16 rgSCHCmnRgrLchCfg
10652 (
10653 RgSchCellCb  *cell,
10654 RgSchUeCb    *ue,
10655 RgSchDlLcCb  *dlLc,
10656 RgrLchCfg *lcCfg,
10657 RgSchErrInfo *err
10658 )
10659 {
10660    S16 ret;
10661
10662    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10663
10664
10665    ret = rgSCHUtlAllocSBuf(cell->instIdx,
10666       (Data**)&((dlLc)->sch), (sizeof(RgSchCmnDlSvc)));
10667    if (ret != ROK)
10668    {
10669       DU_LOG("\nERROR  -->  SCH : rgSCHCmnRgrLchCfg(): "
10670          "SCH struct alloc failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10671       err->errCause = RGSCHERR_SCH_CFG;
10672       return (ret);
10673    }
10674    if(lcCfg->lcType != CM_LTE_LCH_DCCH)
10675    {
10676       ret = rgSCHCmnValidateDlQos(&lcCfg->dlInfo.dlQos);
10677       if (ret != ROK)
10678       {
10679          DU_LOG("\nERROR  -->  SCH : rgSchCmnCrgLcCfg(): "
10680             "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10681          err->errCause = RGSCHERR_SCH_CFG;
10682          return (ret);
10683       }
10684       /* Perform DL service activation in the scheduler */
10685       ((RgSchCmnDlSvc *)(dlLc->sch))->qci = lcCfg->dlInfo.dlQos.qci;
10686       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = rgSchCmnDlQciPrio[lcCfg->dlInfo.dlQos.qci - 1];
10687       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcCfg->dlInfo.dlQos.gbr * \
10688       RG_SCH_CMN_REFRESH_TIME)/100;
10689       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcCfg->dlInfo.dlQos.mbr * \
10690       RG_SCH_CMN_REFRESH_TIME)/100;
10691    }
10692    else
10693    {
10694      /*assigning highest priority to DCCH */
10695     ((RgSchCmnDlSvc *)(dlLc->sch))->prio=RG_SCH_CMN_DCCH_PRIO; 
10696    }   
10697    dlLc->ue = ue;
10698    dlLc->lcType=lcCfg->lcType;
10699
10700 #ifdef EMTC_ENABLE
10701    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
10702    {
10703       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcCfg(cell, ue,dlLc ,lcCfg, err);
10704       if (ret != ROK)
10705       {
10706          return RFAILED;
10707       }
10708    }
10709    else
10710 #endif 
10711    {
10712       ret = cellSch->apisDl->rgSCHRgrDlLcCfg(cell, ue, dlLc, lcCfg, err);
10713       if (ret != ROK)
10714       {
10715          return RFAILED;
10716       }
10717    }
10718    
10719 #ifdef EMTC_ENABLE
10720    if(TRUE == ue->isEmtcUe)
10721    {
10722       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
10723       if (ret != ROK)
10724       {
10725          return RFAILED;
10726       }
10727    }
10728    else
10729 #endif 
10730    {
10731    ret = cellSch->apisUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
10732    if (ret != ROK)
10733    {
10734       return RFAILED;
10735    }
10736    }
10737    
10738 #ifdef LTE_ADV
10739    if (ue->numSCells)
10740    {
10741       rgSCHSCellDlLcCfg(cell, ue, dlLc);
10742    }
10743 #endif
10744
10745
10746 #ifdef LTEMAC_SPS
10747    if(lcCfg->dlInfo.dlSpsCfg.isSpsEnabled)
10748    {
10749       /* Invoke SPS module if SPS is enabled for the service */
10750       ret = rgSCHCmnSpsDlLcCfg(cell, ue, dlLc, lcCfg, err);
10751       if (ret != ROK)
10752       {
10753          DU_LOG("\nERROR  -->  SCH : rgSchCmnRgrLchCfg(): "
10754             "SPS configuration failed for DL LC for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
10755          err->errCause = RGSCHERR_SCH_CFG;
10756          return RFAILED;
10757       }
10758    }
10759 #endif
10760
10761    return ROK;
10762 }
10763
10764 /**
10765  * @brief Scheduler invocation on logical channel addition.
10766  *
10767  * @details
10768  *
10769  *     Function : rgSCHCmnRgrLchRecfg
10770  *
10771  *     This functions does required processing when an existing
10772  *     (dedicated) logical channel is reconfigured. Assumes lcg
10773  *     pointer in ulLc is set to the old value.
10774  *     Independent of whether new LCG is meant to be configured,
10775  *     the new LCG scheduler information is accessed and possibly modified.
10776  *
10777  *  @param[in]  RgSchCellCb  *cell
10778  *  @param[in]  RgSchUeCb    *ue
10779  *  @param[in]  RgSchDlLcCb  *dlLc
10780  *  @param[int] RgrLchRecfg  *lcRecfg
10781  *  @param[out] RgSchErrInfo *err
10782  *  @return  S16
10783  *      -# ROK
10784  *      -# RFAILED
10785  **/
10786 S16 rgSCHCmnRgrLchRecfg
10787 (
10788 RgSchCellCb  *cell,
10789 RgSchUeCb    *ue,
10790 RgSchDlLcCb  *dlLc,
10791 RgrLchRecfg  *lcRecfg,
10792 RgSchErrInfo *err
10793 )
10794 {
10795    S16   ret;
10796    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10797
10798
10799    if(dlLc->lcType != CM_LTE_LCH_DCCH)
10800    {
10801       ret = rgSCHCmnValidateDlQos(&lcRecfg->dlRecfg.dlQos);
10802    
10803       if (ret != ROK)
10804       {
10805          DU_LOG("\nERROR  -->  SCH : DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10806          err->errCause = RGSCHERR_SCH_CFG;
10807          return (ret);
10808       }
10809       if (((RgSchCmnDlSvc *)(dlLc->sch))->qci != lcRecfg->dlRecfg.dlQos.qci)
10810       {
10811          DU_LOG("\nERROR  -->  SCH : Qci, hence lc Priority change "
10812             "not supported for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10813          err->errCause = RGSCHERR_SCH_CFG;
10814          return (ret);
10815       }
10816       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcRecfg->dlRecfg.dlQos.gbr * \
10817       RG_SCH_CMN_REFRESH_TIME)/100;
10818       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcRecfg->dlRecfg.dlQos.mbr * \
10819       RG_SCH_CMN_REFRESH_TIME)/100;
10820    }
10821    else
10822    {
10823       /*assigning highest priority to DCCH */
10824       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = RG_SCH_CMN_DCCH_PRIO; 
10825    }
10826    
10827 #ifdef EMTC_ENABLE
10828    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
10829    {
10830       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10831       if (ret != ROK)
10832       {
10833          return RFAILED;
10834       }
10835       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
10836       if (ret != ROK)
10837       {
10838          return RFAILED;
10839       }
10840    }
10841    else
10842 #endif 
10843    {
10844    ret = cellSch->apisDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10845    if (ret != ROK)
10846    {
10847       return RFAILED;
10848    }
10849    ret = cellSch->apisUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
10850    if (ret != ROK)
10851    {
10852       return RFAILED;
10853    }
10854    }
10855     
10856 #ifdef LTEMAC_SPS
10857    if (lcRecfg->recfgTypes & RGR_DL_LC_SPS_RECFG)
10858    {
10859       /* Invoke SPS module if SPS is enabled for the service */
10860       if(lcRecfg->dlRecfg.dlSpsRecfg.isSpsEnabled)
10861       {
10862          ret = rgSCHCmnSpsDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
10863          if (ret != ROK)
10864          {
10865             DU_LOG("\nERROR  -->  SCH : SPS re-configuration not "
10866                   "supported for dlLC Ignore this CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
10867          }
10868       }
10869       return ROK;
10870    }
10871 #endif
10872
10873    return ROK;
10874 }
10875
10876 /**
10877  * @brief Scheduler invocation on logical channel addition.
10878  *
10879  * @details
10880  *
10881  *     Function : rgSCHCmnRgrLcgCfg
10882  *
10883  *     This functions does required processing when a new
10884  *     (dedicated) logical channel is added. Assumes lcg
10885  *     pointer in ulLc is set.
10886  *
10887  *  @param[in]  RgSchCellCb  *cell,
10888  *  @param[in]  RgSchUeCb    *ue,
10889  *  @param[in]  RgSchLcgCb   *lcg,
10890  *  @param[in]  RgrLcgCfg    *lcgCfg,
10891  *  @param[out] RgSchErrInfo *err
10892  *  @return  S16
10893  *      -# ROK
10894  *      -# RFAILED
10895  **/
10896 S16 rgSCHCmnRgrLcgCfg
10897 (
10898 RgSchCellCb  *cell,
10899 RgSchUeCb    *ue,
10900 RgSchLcgCb   *lcg,
10901 RgrLcgCfg    *lcgCfg,
10902 RgSchErrInfo *err
10903 )
10904 {
10905    S16 ret;
10906    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10907    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].sch));
10908
10909
10910    ulLcg->cfgdGbr = (lcgCfg->ulInfo.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
10911    ulLcg->effGbr  = ulLcg->cfgdGbr;
10912    ulLcg->deltaMbr = ((lcgCfg->ulInfo.mbr - lcgCfg->ulInfo.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
10913    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
10914
10915 #ifdef EMTC_ENABLE
10916    if(TRUE == ue->isEmtcUe)
10917    {
10918       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
10919       if (ret != ROK)
10920       {
10921          return RFAILED;
10922       }
10923    }
10924    else
10925 #endif
10926    {
10927    ret = cellSch->apisUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
10928    if (ret != ROK)
10929    {
10930       return RFAILED;
10931    }
10932    }
10933    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
10934    {
10935       /* Indicate MAC that this LCG is GBR LCG */
10936       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcgCfg->ulInfo.lcgId, TRUE);
10937    }
10938    return ROK;
10939 }
10940
10941 /**
10942  * @brief Scheduler invocation on logical channel addition.
10943  *
10944  * @details
10945  *
10946  *     Function : rgSCHCmnRgrLcgRecfg
10947  *
10948  *     This functions does required processing when a new
10949  *     (dedicated) logical channel is added. Assumes lcg
10950  *     pointer in ulLc is set.
10951  *
10952  *  @param[in]  RgSchCellCb  *cell,
10953  *  @param[in]  RgSchUeCb    *ue,
10954  *  @param[in]  RgSchLcgCb   *lcg,
10955  *  @param[in]  RgrLcgRecfg  *reCfg,
10956  *  @param[out] RgSchErrInfo *err
10957  *  @return  S16
10958  *      -# ROK
10959  *      -# RFAILED
10960  **/
10961 S16 rgSCHCmnRgrLcgRecfg
10962 (
10963 RgSchCellCb  *cell,
10964 RgSchUeCb    *ue,
10965 RgSchLcgCb   *lcg,
10966 RgrLcgRecfg  *reCfg,
10967 RgSchErrInfo *err
10968 )
10969 {
10970    S16 ret;
10971    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
10972    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[reCfg->ulRecfg.lcgId].sch));
10973    
10974
10975    ulLcg->cfgdGbr = (reCfg->ulRecfg.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
10976    ulLcg->effGbr  = ulLcg->cfgdGbr;
10977    ulLcg->deltaMbr = ((reCfg->ulRecfg.mbr - reCfg->ulRecfg.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
10978    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
10979  
10980 #ifdef EMTC_ENABLE
10981    if(TRUE == ue->isEmtcUe)
10982    {
10983       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
10984       if (ret != ROK)
10985       {
10986          return RFAILED;
10987       }
10988    }
10989    else
10990 #endif
10991    {
10992    ret = cellSch->apisUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
10993    if (ret != ROK)
10994    {
10995       return RFAILED;
10996    }
10997    }
10998    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
10999    {
11000       /* Indicate MAC that this LCG is GBR LCG */
11001       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, TRUE);
11002    }
11003    else
11004    {
11005       /* In case of RAB modification */
11006       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, FALSE);
11007    }
11008    return ROK;
11009 }
11010
11011 /***********************************************************
11012  *
11013  *     Func : rgSCHCmnRgrLchDel
11014  *
11015  *     Desc : Scheduler handling for a (dedicated)
11016  *             uplink logical channel being deleted.
11017  *
11018  *     Ret  :
11019  *
11020  *     Notes:
11021  *
11022  *     File :
11023  **********************************************************/
11024 S16 rgSCHCmnRgrLchDel(RgSchCellCb *cell,RgSchUeCb *ue,CmLteLcId lcId,uint8_t lcgId)
11025 {
11026    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11027 #ifdef EMTC_ENABLE
11028    if(TRUE == ue->isEmtcUe)
11029    {
11030       cellSch->apisEmtcUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
11031    }
11032    else
11033 #endif
11034    {
11035    cellSch->apisUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
11036    }
11037    return ROK;
11038 }
11039
11040 /***********************************************************
11041  *
11042  *     Func : rgSCHCmnLcgDel
11043  *
11044  *     Desc : Scheduler handling for a (dedicated)
11045  *             uplink logical channel being deleted.
11046  *
11047  *     Ret  :
11048  *
11049  *     Notes:
11050  *
11051  *     File :
11052  *
11053  **********************************************************/
11054 Void rgSCHCmnLcgDel(RgSchCellCb *cell,RgSchUeCb *ue,RgSchLcgCb *lcg)
11055 {
11056    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11057    RgSchCmnLcg  *lcgCmn = RG_SCH_CMN_GET_UL_LCG(lcg);
11058
11059    if (lcgCmn == NULLP)
11060    {
11061       return;
11062    }
11063
11064    if (RGSCH_IS_GBR_BEARER(lcgCmn->cfgdGbr))
11065    {
11066       /* Indicate MAC that this LCG is GBR LCG */
11067       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcg->lcgId, FALSE);
11068    }
11069
11070 #ifdef LTEMAC_SPS
11071    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
11072    {
11073       rgSCHCmnSpsUlLcgDel(cell, ue, lcg);
11074    }
11075 #endif /* LTEMAC_SPS */
11076
11077    lcgCmn->effGbr     = 0;
11078    lcgCmn->reportedBs = 0;
11079    lcgCmn->cfgdGbr    = 0;
11080    /* set lcg bs to 0. Deletion of control block happens
11081     * at the time of UE deletion. */
11082    lcgCmn->bs = 0;
11083 #ifdef EMTC_ENABLE
11084    if(TRUE == ue->isEmtcUe)
11085    {
11086       cellSch->apisEmtcUl->rgSCHFreeUlLcg(cell, ue, lcg);
11087    }
11088    else
11089 #endif
11090    {
11091    cellSch->apisUl->rgSCHFreeUlLcg(cell, ue, lcg);
11092    }
11093    return;
11094 }
11095
11096 \f
11097 /**
11098  * @brief This function deletes a service from scheduler.
11099  *
11100  * @details
11101  *
11102  *     Function: rgSCHCmnFreeDlLc
11103  *     Purpose:  This function is made available through a FP for
11104  *               making scheduler aware of a service being deleted from UE.
11105  *
11106  *     Invoked by: BO and Scheduler
11107  *
11108  *  @param[in]  RgSchCellCb*  cell
11109  *  @param[in]  RgSchUeCb*    ue
11110  *  @param[in]  RgSchDlLcCb*  svc
11111  *  @return  Void
11112  *
11113  **/
11114 Void rgSCHCmnFreeDlLc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
11115 {
11116    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11117    if (svc->sch == NULLP)
11118    {
11119       return;
11120    }
11121 #ifdef EMTC_ENABLE
11122     if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
11123     {
11124       cellSch->apisEmtcDl->rgSCHFreeDlLc(cell, ue, svc);
11125     }
11126     else
11127 #endif
11128    {
11129       cellSch->apisDl->rgSCHFreeDlLc(cell, ue, svc);
11130    }
11131
11132 #ifdef LTE_ADV
11133    if (ue->numSCells)
11134    {
11135       rgSCHSCellDlLcDel(cell, ue, svc);
11136    }
11137 #endif
11138
11139 #ifdef LTEMAC_SPS
11140    /* If SPS service, invoke SPS module */
11141    if (svc->dlLcSpsCfg.isSpsEnabled)
11142    {
11143       rgSCHCmnSpsDlLcDel(cell, ue, svc);
11144    }
11145 #endif
11146
11147    /* ccpu00117052 - MOD - Passing double pointer
11148    for proper NULLP assignment*/
11149    rgSCHUtlFreeSBuf(cell->instIdx,
11150          (Data**)(&(svc->sch)), (sizeof(RgSchCmnDlSvc)));
11151
11152 #ifdef LTE_ADV
11153    rgSCHLaaDeInitDlLchCb(cell, svc);
11154 #endif
11155
11156    return;
11157 }
11158
11159 #ifdef RGR_V1
11160
11161 /**
11162  * @brief This function Processes the Final Allocations
11163  *        made by the RB Allocator against the requested
11164  *        CCCH SDURetx Allocations.
11165  *
11166  * @details
11167  *
11168  *     Function: rgSCHCmnDlCcchSduRetxFnlz
11169  *     Purpose:  This function Processes the Final Allocations
11170  *               made by the RB Allocator against the requested
11171  *               CCCH Retx Allocations.
11172  *               Scans through the scheduled list of ccchSdu retrans
11173  *               fills the corresponding pdcch, adds the hqProc to
11174  *               the corresponding SubFrm and removes the hqP from
11175  *               cells retx List.
11176  *
11177  *     Invoked by: Common Scheduler
11178  *
11179  *  @param[in]  RgSchCellCb           *cell
11180  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11181  *  @return  Void
11182  *
11183  **/
11184 static Void rgSCHCmnDlCcchSduRetxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11185 {
11186    CmLList           *node;
11187    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11188    RgSchDlRbAlloc    *rbAllocInfo;
11189    RgSchDlHqProcCb   *hqP;
11190    RgSchUeCb         *ue;
11191
11192    /* Traverse through the Scheduled Retx List */
11193    node = allocInfo->ccchSduAlloc.schdCcchSduRetxLst.first;
11194    while (node)
11195    {
11196       hqP = (RgSchDlHqProcCb *)(node->node);
11197       ue = hqP->hqE->ue;
11198       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
11199       node = node->next;
11200       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11201
11202       /* Remove the HqP from cell's ccchSduRetxLst */
11203       cmLListDelFrm(&cmnCellDl->ccchSduRetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
11204       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
11205
11206       /* Fix: syed dlAllocCb reset should be performed.
11207        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11208       rgSCHCmnDlUeResetTemp(ue, hqP);
11209    }
11210    /* Fix: syed dlAllocCb reset should be performed.
11211     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11212    node = allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst.first;
11213    while(node)
11214    {
11215       hqP = (RgSchDlHqProcCb *)(node->node);
11216       ue = hqP->hqE->ue;
11217       node = node->next;
11218       /* reset the UE allocation Information */
11219       rgSCHCmnDlUeResetTemp(ue, hqP);
11220    }
11221    return;
11222 }
11223 #endif
11224 /**
11225  * @brief This function Processes the Final Allocations
11226  *        made by the RB Allocator against the requested
11227  *        CCCH Retx Allocations.
11228  *
11229  * @details
11230  *
11231  *     Function: rgSCHCmnDlCcchRetxFnlz
11232  *     Purpose:  This function Processes the Final Allocations
11233  *               made by the RB Allocator against the requested
11234  *               CCCH Retx Allocations.
11235  *               Scans through the scheduled list of msg4 retrans
11236  *               fills the corresponding pdcch, adds the hqProc to
11237  *               the corresponding SubFrm and removes the hqP from
11238  *               cells retx List.
11239  *
11240  *     Invoked by: Common Scheduler
11241  *
11242  *  @param[in]  RgSchCellCb           *cell
11243  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11244  *  @return  Void
11245  *
11246  **/
11247 static Void rgSCHCmnDlCcchRetxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11248 {
11249    CmLList           *node;
11250    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11251    RgSchDlRbAlloc    *rbAllocInfo;
11252    RgSchDlHqProcCb   *hqP;
11253    RgSchRaCb         *raCb;
11254
11255    /* Traverse through the Scheduled Retx List */
11256    node = allocInfo->msg4Alloc.schdMsg4RetxLst.first;
11257    while (node)
11258    {
11259       hqP = (RgSchDlHqProcCb *)(node->node);
11260       raCb = hqP->hqE->raCb;
11261       rbAllocInfo = &raCb->rbAllocInfo;
11262       node = node->next;
11263       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11264
11265       /* Remove the HqP from cell's msg4RetxLst */
11266       cmLListDelFrm(&cmnCellDl->msg4RetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
11267       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
11268       /* Fix: syed dlAllocCb reset should be performed.
11269        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11270       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
11271       rgSCHCmnDlHqPResetTemp(hqP);
11272    }
11273    /* Fix: syed dlAllocCb reset should be performed.
11274     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11275    node = allocInfo->msg4Alloc.nonSchdMsg4RetxLst.first;
11276    while(node)
11277    {
11278       hqP = (RgSchDlHqProcCb *)(node->node);
11279       raCb = hqP->hqE->raCb;
11280       node = node->next;
11281       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
11282       rgSCHCmnDlHqPResetTemp(hqP);
11283    }
11284    return;
11285 }
11286
11287 #ifdef RGR_V1
11288 /**
11289  * @brief This function Processes the Final Allocations
11290  *        made by the RB Allocator against the requested
11291  *        CCCH SDU tx Allocations.
11292  *
11293  * @details
11294  *
11295  *     Function: rgSCHCmnDlCcchSduTxFnlz
11296  *     Purpose:  This function Processes the Final Allocations
11297  *               made by the RB Allocator against the requested
11298  *               CCCH tx Allocations.
11299  *               Scans through the scheduled list of CCCH SDU trans
11300  *               fills the corresponding pdcch, adds the hqProc to
11301  *               the corresponding SubFrm and removes the hqP from
11302  *               cells tx List.
11303  *
11304  *     Invoked by: Common Scheduler
11305  *
11306  *  @param[in]  RgSchCellCb           *cell
11307  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11308  *  @return  Void
11309  *
11310  **/
11311 static Void rgSCHCmnDlCcchSduTxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11312 {
11313    CmLList           *node;
11314    RgSchUeCb         *ueCb;
11315    RgSchDlRbAlloc    *rbAllocInfo;
11316    RgSchDlHqProcCb   *hqP;
11317    RgSchLchAllocInfo  lchSchdData;
11318
11319    /* Traverse through the Scheduled Retx List */
11320    node = allocInfo->ccchSduAlloc.schdCcchSduTxLst.first;
11321    while (node)
11322    {
11323       hqP = (RgSchDlHqProcCb *)(node->node);
11324       ueCb = hqP->hqE->ue;
11325       node = node->next;
11326       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
11327
11328       /* fill the pdcch and HqProc */
11329       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11330
11331       /* Remove the raCb from cell's toBeSchdLst */
11332       cmLListDelFrm(&cell->ccchSduUeLst, &ueCb->ccchSduLnk);
11333       ueCb->ccchSduLnk.node = (PTR)NULLP;
11334
11335       /* Fix : Resetting this required to avoid complication
11336        * in reestablishment case */
11337       ueCb->dlCcchInfo.bo = 0;
11338
11339       /* Indicate DHM of the CCCH LC scheduling */
11340       hqP->tbInfo[0].contResCe = NOTPRSNT;
11341       lchSchdData.lcId     = 0;
11342       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
11343                              (RGSCH_MSG4_HDRSIZE);
11344       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
11345
11346       /* Fix: syed dlAllocCb reset should be performed.
11347        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11348       rgSCHCmnDlUeResetTemp(ueCb, hqP);
11349    }
11350    /* Fix: syed dlAllocCb reset should be performed.
11351     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11352    node = allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst.first;
11353    while(node)
11354    {
11355       hqP = (RgSchDlHqProcCb *)(node->node);
11356       ueCb = hqP->hqE->ue;
11357       node = node->next;
11358       /* Release HqProc */
11359       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
11360       /*Fix: Removing releasing of TB1 as it will not exist for CCCH SDU and hence caused a crash*/
11361       /*rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
11362       /* reset the UE allocation Information */
11363       rgSCHCmnDlUeResetTemp(ueCb, hqP);
11364    }
11365    return;
11366 }
11367
11368 #endif
11369 /**
11370  * @brief This function Processes the Final Allocations
11371  *        made by the RB Allocator against the requested
11372  *        CCCH tx Allocations.
11373  *
11374  * @details
11375  *
11376  *     Function: rgSCHCmnDlCcchTxFnlz
11377  *     Purpose:  This function Processes the Final Allocations
11378  *               made by the RB Allocator against the requested
11379  *               CCCH tx Allocations.
11380  *               Scans through the scheduled list of msg4 trans
11381  *               fills the corresponding pdcch, adds the hqProc to
11382  *               the corresponding SubFrm and removes the hqP from
11383  *               cells tx List.
11384  *
11385  *     Invoked by: Common Scheduler
11386  *
11387  *  @param[in]  RgSchCellCb           *cell
11388  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11389  *  @return  Void
11390  *
11391  **/
11392 static Void rgSCHCmnDlCcchTxFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11393 {
11394    CmLList           *node;
11395    RgSchRaCb         *raCb;
11396    RgSchDlRbAlloc    *rbAllocInfo;
11397    RgSchDlHqProcCb   *hqP;
11398    RgSchLchAllocInfo  lchSchdData;
11399
11400    /* Traverse through the Scheduled Retx List */
11401    node = allocInfo->msg4Alloc.schdMsg4TxLst.first;
11402    while (node)
11403    {
11404       hqP = (RgSchDlHqProcCb *)(node->node);
11405       raCb = hqP->hqE->raCb;
11406       node = node->next;
11407       rbAllocInfo = &raCb->rbAllocInfo;
11408
11409       /* fill the pdcch and HqProc */
11410       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
11411       /* MSG4 Fix Start */
11412      
11413       rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
11414       /* MSG4 Fix End */     
11415
11416       /* Indicate DHM of the CCCH LC scheduling */
11417       lchSchdData.lcId     = 0;
11418       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
11419          (RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE);
11420       /* TRansmitting presence of cont Res CE across MAC-SCH interface to
11421        * identify CCCH SDU transmissions which need to be done
11422        * without the
11423        * contention resolution CE*/
11424       hqP->tbInfo[0].contResCe = PRSNT_NODEF;
11425       /*Dont add lc if only cont res CE is being transmitted*/
11426       if(raCb->dlCcchInfo.bo)
11427       {
11428          rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
11429       }
11430       else
11431       {
11432       }
11433       /* Fix: syed dlAllocCb reset should be performed.
11434        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
11435       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
11436       rgSCHCmnDlHqPResetTemp(hqP);
11437    }
11438    node = allocInfo->msg4Alloc.nonSchdMsg4TxLst.first;
11439    while(node)
11440    {
11441       hqP = (RgSchDlHqProcCb *)(node->node);
11442       raCb = hqP->hqE->raCb;
11443       node = node->next;
11444       rbAllocInfo = &raCb->rbAllocInfo;
11445       /* Release HqProc */
11446       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
11447       /*Fix: Removing releasing of TB1 as it will not exist for MSG4 and hence caused a crash*/
11448       /*      rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
11449       /* reset the UE allocation Information */
11450       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
11451       rgSCHCmnDlHqPResetTemp(hqP);
11452    }
11453
11454    return;
11455 }
11456 /* R8 Upgrade */
11457 /**
11458  * @brief This function calculates the BI Index to be sent in the Bi header
11459  * field.
11460  *
11461  * @details
11462  *     Function: rgSCHCmnGetBiIndex
11463  *     Purpose:  This function Processes utilizes the previous BI time value
11464  *     calculated and the difference last BI sent time and current time. To
11465  *     calculate the latest BI Index. It also considers the how many UE's
11466  *     Unserved in this subframe.
11467  *
11468  *     Invoked by: Common Scheduler
11469  *
11470  *  @param[in]  RgSchCellCb           *cell
11471  *  @param[in]  uint32_t                   ueCount
11472  *  @return  uint8_t
11473  *
11474  **/
11475 uint8_t rgSCHCmnGetBiIndex(RgSchCellCb *cell,uint32_t ueCount)
11476 {
11477    S16  prevVal = 0;      /* To Store Intermediate Value */
11478    uint16_t  newBiVal = 0;     /* To store Bi Value in millisecond */
11479    uint8_t   idx = 0;
11480    uint16_t  timeDiff = 0;
11481
11482
11483    if (cell->biInfo.prevBiTime != 0)
11484    {
11485 #ifdef EMTC_ENABLE
11486       if(cell->emtcEnable == TRUE)
11487       {
11488          timeDiff =(RGSCH_CALC_SF_DIFF_EMTC(cell->crntTime, cell->biInfo.biTime));
11489       }
11490       else
11491 #endif
11492       {
11493          timeDiff =(RGSCH_CALC_SF_DIFF(cell->crntTime, cell->biInfo.biTime));
11494       }
11495
11496       prevVal = cell->biInfo.prevBiTime - timeDiff;
11497    }
11498    if (prevVal < 0)
11499    {
11500       prevVal = 0;
11501    }
11502    newBiVal = RG_SCH_CMN_GET_BI_VAL(prevVal,ueCount);
11503    /* To be used next time when BI is calculated */
11504 #ifdef EMTC_ENABLE
11505    if(cell->emtcEnable == TRUE)
11506    {
11507       RGSCHCPYTIMEINFO_EMTC(cell->crntTime, cell->biInfo.biTime)
11508    }
11509    else
11510 #endif
11511    {
11512       RGSCHCPYTIMEINFO(cell->crntTime, cell->biInfo.biTime)
11513    }
11514
11515   /* Search the actual BI Index from table Backoff Parameters Value  and
11516    * return that Index */
11517    do
11518    {
11519       if (rgSchCmnBiTbl[idx] > newBiVal)
11520       {
11521          break;
11522       }
11523       idx++;
11524    }while(idx < RG_SCH_CMN_NUM_BI_VAL-1);
11525    cell->biInfo.prevBiTime = rgSchCmnBiTbl[idx];
11526    /* For 16 Entries in Table 7.2.1 36.321.880 - 3 reserved so total 13 Entries */
11527    return (idx); /* Returning reserved value from table UE treats it has 960 ms */
11528 } /* rgSCHCmnGetBiIndex */
11529
11530
11531 /**
11532  * @brief This function Processes the Final Allocations
11533  *        made by the RB Allocator against the requested
11534  *        RAR allocations. Assumption: The reuqested
11535  *        allocations are always satisfied completely.
11536  *        Hence no roll back.
11537  *
11538  * @details
11539  *
11540  *     Function: rgSCHCmnDlRaRspFnlz
11541  *     Purpose:  This function Processes the Final Allocations
11542  *               made by the RB Allocator against the requested.
11543  *               Takes care of PDCCH filling.
11544  *
11545  *     Invoked by: Common Scheduler
11546  *
11547  *  @param[in]  RgSchCellCb           *cell
11548  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11549  *  @return  Void
11550  *
11551  **/
11552 static Void rgSCHCmnDlRaRspFnlz(RgSchCellCb  *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11553 {
11554    uint32_t       rarCnt = 0;
11555    RgSchDlRbAlloc *raRspAlloc;
11556    RgSchDlSf      *subFrm = NULLP;
11557    RgSchRaCb      *raCb;
11558    RgSchErrInfo   err;
11559    CmLListCp      *reqLst;
11560    RgSchRaReqInfo *raReq;
11561    Bool           preamGrpA;
11562    RgSchUlAlloc   *ulAllocRef=NULLP;
11563    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11564    uint8_t        allocRapidCnt = 0;
11565 #ifdef LTE_TDD
11566    uint32_t       msg3SchdIdx = 0;
11567    uint8_t        ulDlCfgIdx = cell->ulDlCfgIdx;
11568    uint8_t        msg3Subfrm;
11569 #endif
11570
11571
11572    for (rarCnt=0; rarCnt<RG_SCH_CMN_MAX_CMN_PDCCH; rarCnt++)
11573    {
11574       raRspAlloc = &allocInfo->raRspAlloc[rarCnt];
11575       /* Having likely condition first for optimization */
11576       if (!raRspAlloc->pdcch)
11577       {
11578          continue;
11579       }
11580       else
11581       {
11582          subFrm = raRspAlloc->dlSf;
11583          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
11584          /* Corrected RACH handling for multiple RAPIDs per RARNTI */
11585          allocRapidCnt = raRspAlloc->numRapids;
11586          while (allocRapidCnt)
11587          {
11588             raReq = (RgSchRaReqInfo *)(reqLst->first->node);
11589             /* RACHO: If dedicated preamble, then allocate UL Grant
11590              * (consequence of handover/pdcchOrder) and continue */
11591             if (RGSCH_IS_DEDPRM(cell, raReq->raReq.rapId))
11592             {
11593                rgSCHCmnHdlHoPo(cell, &subFrm->raRsp[rarCnt].contFreeUeLst,
11594                      raReq);
11595                cmLListDelFrm(reqLst, reqLst->first);
11596                allocRapidCnt--;
11597                /* ccpu00117052 - MOD - Passing double pointer
11598                for proper NULLP assignment*/
11599                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11600                      sizeof(RgSchRaReqInfo));
11601                continue;
11602             }
11603             /* ccpu00139815 */
11604             if(cell->overLoadBackOffEnab)
11605             {/* rach Overlaod conrol is triggerd, Skipping this rach */
11606                cmLListDelFrm(reqLst, reqLst->first);
11607                allocRapidCnt--;
11608                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11609                      sizeof(RgSchRaReqInfo));
11610                continue;
11611             }
11612             /* Attempt to include each RA request into the RSP */
11613             /* Any failure in the procedure is considered to   */
11614             /* affect futher allocations in the same TTI. When */
11615             /* a failure happens, we break out and complete    */
11616             /* the processing for random access                */
11617             if (rgSCHRamCreateRaCb(cell, &raCb, &err) != ROK)
11618             {
11619                break;
11620             }
11621             /* Msg3 allocation request to USM */
11622             if (raReq->raReq.rapId < cell->rachCfg.sizeRaPreambleGrpA)
11623                preamGrpA = TRUE;
11624             else
11625                preamGrpA = FALSE;
11626             /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
11627             rgSCHCmnMsg3GrntReq(cell, raCb->tmpCrnti, preamGrpA, \
11628                   &(raCb->msg3HqProc), &ulAllocRef, &raCb->msg3HqProcId);
11629             if (ulAllocRef == NULLP)
11630             {
11631                rgSCHRamDelRaCb(cell, raCb, TRUE);
11632                break;
11633             }
11634             if (raReq->raReq.cqiPres)
11635             {
11636                raCb->ccchCqi = raReq->raReq.cqiIdx;
11637             }
11638             else
11639             {
11640                raCb->ccchCqi = cellDl->ccchCqi;
11641             }
11642             raCb->rapId = raReq->raReq.rapId;
11643             raCb->ta.pres    = TRUE;
11644             raCb->ta.val = raReq->raReq.ta;
11645             raCb->msg3Grnt = ulAllocRef->grnt;
11646             /* Populating the tpc value received */
11647             raCb->msg3Grnt.tpc = raReq->raReq.tpc;
11648             /* PHR handling for MSG3 */
11649             ulAllocRef->raCb = raCb;
11650 #ifndef LTE_TDD
11651             /* To the crntTime, add the MIN time at which UE will
11652              * actually send MSG3 i.e DL_DELTA+6 */
11653             raCb->msg3AllocTime = cell->crntTime;
11654             RGSCH_INCR_SUB_FRAME(raCb->msg3AllocTime, RG_SCH_CMN_MIN_MSG3_RECP_INTRVL);
11655 #else
11656             msg3SchdIdx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % 
11657                                  RGSCH_NUM_SUB_FRAMES;
11658             /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
11659               special subframe */                       
11660             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][msg3SchdIdx] != 
11661                         RG_SCH_TDD_UL_SUBFRAME)
11662             {
11663                RGSCHCMNADDTOCRNTTIME(cell->crntTime,raCb->msg3AllocTime,
11664                                        RG_SCH_CMN_DL_DELTA)
11665                msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][
11666                                        raCb->msg3AllocTime.slot];
11667                RGSCHCMNADDTOCRNTTIME(raCb->msg3AllocTime, raCb->msg3AllocTime, 
11668                                  msg3Subfrm);
11669             }
11670 #endif
11671             cmLListAdd2Tail(&subFrm->raRsp[rarCnt].raRspLst, &raCb->rspLnk);
11672             raCb->rspLnk.node = (PTR)raCb;
11673             cmLListDelFrm(reqLst, reqLst->first);
11674             allocRapidCnt--;
11675             /* ccpu00117052 - MOD - Passing double pointer
11676             for proper NULLP assignment*/
11677             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
11678                   sizeof(RgSchRaReqInfo));
11679
11680             /* SR_RACH_STATS : RAR scheduled */
11681             rgNumRarSched++;
11682
11683          }
11684          /* R8 Upgrade */
11685          /* Fill subframe data members */
11686          subFrm->raRsp[rarCnt].raRnti = raRspAlloc->rnti;
11687          subFrm->raRsp[rarCnt].pdcch  = raRspAlloc->pdcch;
11688          subFrm->raRsp[rarCnt].tbSz   = raRspAlloc->tbInfo[0].bytesAlloc;
11689          /* Fill PDCCH data members */
11690          rgSCHCmnFillPdcch(cell, subFrm->raRsp[rarCnt].pdcch, raRspAlloc);
11691
11692          /* ccpu00139815 */
11693          if(cell->overLoadBackOffEnab)
11694          {/* rach Overlaod conrol is triggerd, Skipping this rach */
11695             subFrm->raRsp[rarCnt].backOffInd.pres = PRSNT_NODEF;
11696             subFrm->raRsp[rarCnt].backOffInd.val  = cell->overLoadBackOffval;
11697             continue;
11698          }
11699          else
11700          {
11701             subFrm->raRsp[rarCnt].backOffInd.pres = NOTPRSNT;
11702          }
11703
11704          /*[ccpu00125212] Avoiding sending of empty RAR in case of RAR window
11705            is short and UE is sending unauthorised preamble.*/
11706          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
11707          if ((raRspAlloc->biEstmt) && (reqLst->count))
11708          {
11709             subFrm->raRsp[0].backOffInd.pres = PRSNT_NODEF;
11710             /* Added as part of Upgrade */
11711             subFrm->raRsp[0].backOffInd.val =
11712             rgSCHCmnGetBiIndex(cell, reqLst->count);
11713
11714             /* SR_RACH_STATS : Back Off Inds */
11715             rgNumBI++;
11716
11717          }
11718          else if ((subFrm->raRsp[rarCnt].raRspLst.first == NULLP) &&
11719                (subFrm->raRsp[rarCnt].contFreeUeLst.first == NULLP))
11720          {
11721             /* Return the grabbed PDCCH */
11722             rgSCHUtlPdcchPut(cell, &subFrm->pdcchInfo, raRspAlloc->pdcch);
11723             subFrm->raRsp[rarCnt].pdcch = NULLP;
11724             DU_LOG("\nERROR  -->  SCH : rgSCHCmnRaRspAlloc(): "
11725                   "Not even one RaReq.");
11726             return;
11727          }
11728       }
11729       DU_LOG("\nDEBUG  -->  SCH : RNTI:%d Scheduled RAR @ (%u,%u) ",
11730             raRspAlloc->rnti, 
11731             cell->crntTime.sfn,
11732             cell->crntTime.slot);
11733    }
11734    return;
11735 }
11736
11737 /**
11738  * @brief This function computes rv.
11739  *
11740  * @details
11741  *
11742  *     Function: rgSCHCmnDlCalcRvForBcch
11743  *     Purpose:  This function computes rv.
11744  *
11745  *     Invoked by: Common Scheduler
11746  *
11747  *  @param[in]   RgSchCellCb     *cell
11748  *  @param[in]   Bool            si
11749  *  @param[in]   uint16_t             i
11750  *  @return  uint8_t
11751  *
11752  **/
11753 static uint8_t rgSCHCmnDlCalcRvForBcch(RgSchCellCb *cell,Bool si,uint16_t i)
11754 {
11755    uint8_t k, rv;
11756    CmLteTimingInfo   frm;
11757
11758    frm   = cell->crntTime;
11759    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
11760
11761    if(si)
11762    {
11763       k = i % 4;
11764    }
11765    else
11766    {
11767       k = (frm.sfn/2) % 4;
11768    }
11769    rv = RGSCH_CEIL(3*k, 2) % 4;
11770    return (rv);
11771 }
11772
11773 /**
11774  * @brief This function Processes the Final Allocations
11775  *        made by the RB Allocator against the requested
11776  *        BCCH/PCCH allocations. Assumption: The reuqested
11777  *        allocations are always satisfied completely.
11778  *        Hence no roll back.
11779  *
11780  * @details
11781  *
11782  *     Function: rgSCHCmnDlBcchPcchFnlz
11783  *     Purpose:  This function Processes the Final Allocations
11784  *               made by the RB Allocator against the requested.
11785  *               Takes care of PDCCH filling.
11786  *
11787  *     Invoked by: Common Scheduler
11788  *
11789  *  @param[in]  RgSchCellCb           *cell
11790  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
11791  *  @return  Void
11792  *
11793  **/
11794 static Void rgSCHCmnDlBcchPcchFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
11795 {
11796    RgSchDlRbAlloc *rbAllocInfo;
11797    RgSchDlSf      *subFrm;
11798
11799 #ifdef LTE_TDD
11800    uint8_t        nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
11801 #else
11802 #ifdef LTEMAC_HDFDD
11803    uint8_t        nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11804 #else
11805    uint8_t        nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11806 #endif
11807 #endif
11808
11809    /*  Moving variables to available scope for optimization */
11810    RgSchClcDlLcCb *pcch;
11811    RgSchClcBoRpt  *bo;
11812 #ifndef RGR_SI_SCH
11813    RgSchClcDlLcCb  *bcch;
11814    Bool           sendInd=TRUE;
11815 #endif
11816    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
11817
11818
11819    /* handle PCCH */
11820    rbAllocInfo = &allocInfo->pcchAlloc;
11821    if (rbAllocInfo->pdcch)
11822    {
11823       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
11824
11825       /* Added sfIdx calculation for TDD as well */
11826 #ifndef LTE_TDD
11827 #ifdef LTEMAC_HDFDD
11828       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11829 #else
11830       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11831 #endif
11832 #endif
11833       subFrm = rbAllocInfo->dlSf;
11834       pcch = rgSCHDbmGetPcch(cell);
11835       if(pcch == NULLP)
11836       {
11837          DU_LOG("\nERROR  -->  SCH : rgSCHCmnDlBcchPcchFnlz( ): "
11838                "No Pcch Present");
11839          return;
11840       }
11841
11842       /* Added Dl TB count for paging message transmission*/
11843 #ifdef LTE_L2_MEAS
11844       cell->dlUlTbCnt.tbTransDlTotalCnt++;
11845 #endif      
11846       bo = (RgSchClcBoRpt *)pcch->boLst.first->node;
11847       cmLListDelFrm(&pcch->boLst, &bo->boLstEnt);
11848       /* ccpu00117052 - MOD - Passing double pointer
11849          for proper NULLP assignment*/
11850       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
11851       /* Fill subframe data members */
11852       subFrm->pcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
11853       subFrm->pcch.pdcch  = rbAllocInfo->pdcch;
11854       /* Fill PDCCH data members */
11855       rgSCHCmnFillPdcch(cell, subFrm->pcch.pdcch, rbAllocInfo);
11856       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, pcch->lcId, TRUE);
11857       /* ccpu00132314-ADD-Update the tx power allocation info  
11858          TODO-Need to add a check for max tx power per symbol */ 
11859       subfrmAlloc->cmnLcInfo.pcchInfo.txPwrOffset = cellDl->pcchTxPwrOffset;   
11860    }
11861
11862    /* handle BCCH */
11863    rbAllocInfo = &allocInfo->bcchAlloc;
11864    if (rbAllocInfo->pdcch)
11865    {
11866       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
11867 #ifndef LTE_TDD
11868 #ifdef LTEMAC_HDFDD
11869       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
11870 #else
11871       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
11872 #endif
11873 #endif
11874       subFrm = rbAllocInfo->dlSf;
11875
11876       /* Fill subframe data members */
11877       subFrm->bcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
11878       subFrm->bcch.pdcch  = rbAllocInfo->pdcch;
11879       /* Fill PDCCH data members */
11880       rgSCHCmnFillPdcch(cell, subFrm->bcch.pdcch, rbAllocInfo);
11881
11882       if(rbAllocInfo->schdFirst)
11883       {
11884 #ifndef RGR_SI_SCH
11885          bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
11886          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
11887 #else
11888          /*Copy the SIB1 msg buff into interface buffer */
11889          SCpyMsgMsg(cell->siCb.crntSiInfo.sib1Info.sib1,
11890                rgSchCb[cell->instIdx].rgSchInit.region,
11891                rgSchCb[cell->instIdx].rgSchInit.pool,
11892                &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11893 #endif/*RGR_SI_SCH*/
11894          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
11895             rgSCHCmnDlCalcRvForBcch(cell, FALSE, 0);
11896       }
11897       else
11898       {
11899          uint16_t   i;
11900 #ifdef RGR_SI_SCH
11901          Buffer    *pdu;
11902
11903          i = cell->siCb.siCtx.i;
11904          /*Decrement the retransmission count */
11905          cell->siCb.siCtx.retxCntRem--;
11906
11907          /*Copy the SI msg buff into interface buffer */
11908          if(cell->siCb.siCtx.warningSiFlag == FALSE)
11909          {
11910             SCpyMsgMsg(cell->siCb.siArray[cell->siCb.siCtx.siId-1].si,
11911                   rgSchCb[cell->instIdx].rgSchInit.region,
11912                   rgSchCb[cell->instIdx].rgSchInit.pool,
11913                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11914          }
11915          else
11916          {
11917             pdu = rgSCHUtlGetWarningSiPdu(cell);
11918             RGSCH_NULL_CHECK(cell->instIdx, pdu);
11919             SCpyMsgMsg(pdu,
11920                   rgSchCb[cell->instIdx].rgSchInit.region,
11921                   rgSchCb[cell->instIdx].rgSchInit.pool,
11922                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
11923             if(cell->siCb.siCtx.retxCntRem == 0)
11924             {  
11925                rgSCHUtlFreeWarningSiPdu(cell);
11926                cell->siCb.siCtx.warningSiFlag  = FALSE;
11927
11928             }
11929          }
11930 #else
11931          bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
11932          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
11933          bo->retxCnt--;
11934          if(bo->retxCnt != cell->siCfg.retxCnt-1)
11935          {
11936             sendInd=FALSE;
11937          }
11938          i = bo->i;
11939 #endif/*RGR_SI_SCH*/
11940          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
11941             rgSCHCmnDlCalcRvForBcch(cell, TRUE, i);
11942       }
11943
11944       /* Added Dl TB count for SIB1 and SI messages transmission.
11945        * This counter will be incremented only for the first transmission
11946        * (with RV 0) of these messages*/
11947 #ifdef LTE_L2_MEAS
11948       if(subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv == 0)
11949       {   
11950          cell->dlUlTbCnt.tbTransDlTotalCnt++;
11951       }
11952 #endif      
11953 #ifndef RGR_SI_SCH
11954       if(bo->retxCnt == 0)
11955       {
11956          cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
11957          /* ccpu00117052 - MOD - Passing double pointer
11958             for proper NULLP assignment*/
11959          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
11960       }
11961       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, bcch->lcId, sendInd);
11962 #else
11963       /*Fill the interface info */
11964       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, NULLD, NULLD);
11965
11966       /* ccpu00132314-ADD-Update the tx power allocation info  
11967          TODO-Need to add a check for max tx power per symbol */ 
11968       subfrmAlloc->cmnLcInfo.bcchInfo.txPwrOffset = cellDl->bcchTxPwrOffset;   
11969
11970       /*mBuf has been already copied above */
11971 #endif/*RGR_SI_SCH*/
11972    }
11973
11974    return;
11975 }
11976
11977
11978 #if RG_UNUSED
11979 /**
11980  * @brief
11981  *
11982  * @details
11983  *
11984  *     Function: rgSCHCmnUlSetAllUnSched
11985  *     Purpose:
11986  *
11987  *     Invoked by: Common Scheduler
11988  *
11989  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
11990  *  @return  Void
11991  *
11992  **/
11993 static Void rgSCHCmnUlSetAllUnSched(RgSchCmnUlRbAllocInfo *allocInfo)
11994 {
11995    CmLList            *node;
11996
11997
11998    node = allocInfo->contResLst.first;
11999    while (node)
12000    {
12001       rgSCHCmnUlMov2NonSchdCntResLst(allocInfo, (RgSchUeCb *)node->node);
12002       node = allocInfo->contResLst.first;
12003    }
12004
12005    node = allocInfo->retxUeLst.first;
12006    while (node)
12007    {
12008       rgSCHCmnUlMov2NonSchdRetxUeLst(allocInfo, (RgSchUeCb *)node->node);
12009       node = allocInfo->retxUeLst.first;
12010    }
12011
12012    node = allocInfo->ueLst.first;
12013    while (node)
12014    {
12015       rgSCHCmnUlMov2NonSchdUeLst(allocInfo, (RgSchUeCb *)node->node);
12016       node = allocInfo->ueLst.first;
12017    }
12018
12019    return;
12020 }
12021 #endif
12022
12023 /**
12024  * @brief
12025  *
12026  * @details
12027  *
12028  *     Function: rgSCHCmnUlAdd2CntResLst
12029  *     Purpose:
12030  *
12031  *     Invoked by: Common Scheduler
12032  *
12033  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
12034  *  @param[in]  RgSchUeCb             *ue
12035  *  @return  Void
12036  *
12037  **/
12038 Void rgSCHCmnUlAdd2CntResLst(RgSchCmnUlRbAllocInfo *allocInfo,RgSchUeCb *ue)
12039 {
12040    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,ue->cell))->alloc);
12041    cmLListAdd2Tail(&allocInfo->contResLst, &ulAllocInfo->reqLnk);
12042    ulAllocInfo->reqLnk.node = (PTR)ue;
12043    return;
12044 }
12045
12046 /**
12047  * @brief
12048  *
12049  * @details
12050  *
12051  *     Function: rgSCHCmnUlAdd2UeLst
12052  *     Purpose:
12053  *
12054  *     Invoked by: Common Scheduler
12055  *
12056  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
12057  *  @param[in]  RgSchUeCb             *ue
12058  *  @return  Void
12059  *
12060  **/
12061 Void rgSCHCmnUlAdd2UeLst(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUeCb *ue)
12062 {
12063    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,cell))->alloc);
12064    if (ulAllocInfo->reqLnk.node == NULLP)
12065    {
12066       cmLListAdd2Tail(&allocInfo->ueLst, &ulAllocInfo->reqLnk);
12067       ulAllocInfo->reqLnk.node = (PTR)ue;
12068    }
12069    return;
12070 }
12071
12072 /**
12073  * @brief
12074  *
12075  * @details
12076  *
12077  *     Function: rgSCHCmnAllocUlRb
12078  *     Purpose:  To do RB allocations for uplink
12079  *
12080  *     Invoked by: Common Scheduler
12081  *
12082  *  @param[in]  RgSchCellCb           *cell
12083  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12084  *  @return  Void
12085  **/
12086 Void rgSCHCmnAllocUlRb(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
12087 {
12088    RgSchUlSf         *sf = allocInfo->sf;
12089
12090    /* Schedule for new transmissions */
12091    rgSCHCmnUlRbAllocForLst(cell, sf, allocInfo->ueLst.count,
12092          &allocInfo->ueLst, &allocInfo->schdUeLst,
12093          &allocInfo->nonSchdUeLst, (Bool)TRUE);
12094    return;
12095 }
12096
12097 /***********************************************************
12098  *
12099  *     Func : rgSCHCmnUlRbAllocForLst
12100  *
12101  *     Desc : Allocate for a list in cmn rb alloc information passed
12102  *            in a subframe.
12103  *
12104  *     Ret  :
12105  *
12106  *     Notes:
12107  *
12108  *     File :
12109  *
12110  **********************************************************/
12111 static Void rgSCHCmnUlRbAllocForLst
12112 (
12113 RgSchCellCb  *cell,
12114 RgSchUlSf    *sf,
12115 uint32_t     count,
12116 CmLListCp    *reqLst,
12117 CmLListCp    *schdLst,
12118 CmLListCp    *nonSchdLst,
12119 Bool         isNewTx
12120 )
12121 {
12122    CmLList          *lnk;
12123    RgSchUlHole      *hole;
12124 #ifdef LTE_L2_MEAS
12125 #ifdef LTE_TDD
12126    uint8_t               k;
12127    CmLteTimingInfo  timeInfo;
12128 #endif    
12129 #endif    
12130
12131    if(schdLst->count == 0)
12132    {
12133       cmLListInit(schdLst);
12134    }
12135
12136    cmLListInit(nonSchdLst);
12137 #ifdef LTE_L2_MEAS
12138    if(isNewTx == TRUE)
12139    {
12140       cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.numUes = (uint8_t) count;
12141 #ifdef LTE_TDD
12142       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timeInfo, TFU_ULCNTRL_DLDELTA);
12143       k = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][timeInfo.subframe];
12144       RG_SCH_ADD_TO_CRNT_TIME(timeInfo,
12145           cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, k);
12146 #else
12147       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime,cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo,
12148                             (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
12149 #endif
12150    }
12151 #endif
12152
12153    for (lnk = reqLst->first; count; lnk = lnk->next, --count)
12154    {
12155       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
12156       RgSchCmnUlUe          *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
12157       S16                   ret;
12158       uint8_t                    maxRb;
12159
12160
12161       if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
12162       {
12163          break;
12164       }
12165
12166       ueUl->subbandShare = ueUl->subbandRequired;
12167       if(isNewTx == TRUE)
12168       {
12169          maxRb = RGSCH_MIN((ueUl->subbandRequired * MAX_5GTF_VRBG_SIZE), ue->ue5gtfCb.maxPrb);
12170       } 
12171       ret = rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole);
12172       if (ret == ROK)
12173       {
12174          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, schdLst);
12175          rgSCHCmnUlUeFillAllocInfo(cell, ue);
12176       }
12177       else
12178       {
12179          gUl5gtfRbAllocFail++;
12180 #if defined (TENB_STATS) && defined (RG_5GTF)
12181          cell->tenbStats->sch.ul5gtfRbAllocFail++;
12182 #endif
12183          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
12184          ue->isMsg4PdcchWithCrnti = FALSE;
12185          ue->isSrGrant = FALSE;
12186       }
12187 #ifdef LTE_L2_MEAS
12188       if(isNewTx == TRUE)
12189       {
12190          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
12191          ulAllocInfo[count - 1].rnti   = ue->ueId;
12192          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
12193          ulAllocInfo[count - 1].numPrb = ue->ul.nPrb;
12194       }
12195 #endif
12196       ueUl->subbandShare = 0; /* This reset will take care of
12197                                   * all scheduler types */
12198    }
12199    for (; count; lnk = lnk->next, --count)
12200    {
12201       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
12202       rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
12203       ue->isMsg4PdcchWithCrnti = FALSE;
12204    }
12205    return;
12206 }
12207
12208 #ifdef UNUSED_FUNC
12209 #ifdef TFU_UPGRADE
12210 /***********************************************************
12211  *
12212  *     Func : rgSCHCmnUlMdfyGrntForCqi
12213  *
12214  *     Desc : Modify UL Grant to consider presence of 
12215  *            CQI along with PUSCH Data.
12216  *
12217  *     Ret  :
12218  *
12219  *     Notes: 
12220  *          -  Scale down iTbs based on betaOffset and
12221  *             size of Acqi Size.
12222  *          -  Optionally attempt to increase numSb by 1
12223  *             if input payload size does not fit in due 
12224  *             to reduced tbSz as a result of iTbsNew.
12225  *
12226  *     File :
12227  *
12228  **********************************************************/
12229 static S16 rgSCHCmnUlMdfyGrntForCqi
12230 (
12231 RgSchCellCb  *cell,
12232 RgSchUeCb    *ue,
12233 uint32_t     maxRb,
12234 uint32_t     *numSb,
12235 uint8_t      *iTbs,
12236 uint32_t     hqSz,
12237 uint32_t     stepDownItbs,
12238 uint32_t     effTgt
12239 )
12240 {
12241    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(ue->cell);
12242    uint32_t  nPrb;
12243    uint32_t  totREs;
12244    uint32_t  cqiRiREs;
12245    uint32_t  hqREs;
12246    uint32_t  remREsForPusch;
12247    uint32_t  bitsPerRe;
12248    uint32_t  tbSz;
12249    uint32_t  betaOffVal = ue->ul.betaOffstVal;
12250    uint32_t  cqiRiRptSz = ue->ul.cqiRiSz;
12251    uint32_t  betaOffHqVal = rgSchCmnBetaHqOffstTbl[ue->ul.betaHqOffst];
12252    uint32_t  resNumSb = *numSb;
12253    uint32_t  puschEff = 1000;
12254    uint8_t   modOdr;
12255    uint8_t   iMcs;
12256    Bool mdfyiTbsFlg = FALSE;
12257    uint8_t   resiTbs = *iTbs;
12258
12259
12260    
12261    do
12262    {
12263       iMcs  = rgSCHCmnUlGetIMcsFrmITbs(resiTbs, RG_SCH_CMN_GET_UE_CTGY(ue));
12264       RG_SCH_UL_MCS_TO_MODODR(iMcs, modOdr);
12265       if (RG_SCH_CMN_GET_UE_CTGY(ue) != CM_LTE_UE_CAT_5)
12266       {
12267          modOdr = RGSCH_MIN(RGSCH_QM_QPSK, modOdr);
12268       }
12269       else
12270       {
12271          modOdr = RGSCH_MIN(RGSCH_QM_64QAM, modOdr);
12272       }
12273       nPrb = resNumSb * cellUl->sbSize;
12274       /* Restricting the minumum iTbs requried to modify to 10 */
12275       if ((nPrb >= maxRb) && (resiTbs <= 10))
12276       {
12277          /* Could not accomodate ACQI */
12278          return RFAILED;
12279       }
12280       totREs = nPrb * RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
12281       tbSz = rgTbSzTbl[0][resiTbs][nPrb-1];
12282       /*  totalREs/tbSz = num of bits perRE.  */
12283       cqiRiREs = (totREs * betaOffVal * cqiRiRptSz)/(1000 * tbSz); /* betaOffVal is represented 
12284                                                                    as parts per 1000 */
12285       hqREs = (totREs * betaOffHqVal * hqSz)/(1000 * tbSz);
12286       if ((cqiRiREs + hqREs) < totREs)
12287       {
12288          remREsForPusch = totREs - cqiRiREs - hqREs;
12289          bitsPerRe = (tbSz * 1000)/remREsForPusch; /* Multiplying by 1000 for Interger Oper */
12290          puschEff = bitsPerRe/modOdr;
12291       }
12292       if (puschEff < effTgt)
12293       {
12294           /* ensure resultant efficiency for PUSCH Data is within 0.93*/
12295           break;
12296       }
12297       else
12298       {
12299          /* Alternate between increasing SB or decreasing iTbs until eff is met */
12300          if (mdfyiTbsFlg == FALSE)
12301          {
12302             if (nPrb < maxRb)
12303             {
12304               resNumSb = resNumSb + 1;
12305             }
12306             mdfyiTbsFlg = TRUE;
12307          }
12308          else
12309          {
12310             if (resiTbs > 10)
12311             {
12312                resiTbs-= stepDownItbs;
12313             }
12314             mdfyiTbsFlg = FALSE;
12315          }
12316       }
12317    }while (1); /* Loop breaks if efficency is met 
12318                   or returns RFAILED if not able to meet the efficiency */
12319               
12320    *numSb = resNumSb;
12321    *iTbs = resiTbs;
12322
12323    return ROK;
12324 }
12325 #endif
12326 #endif
12327 /***********************************************************
12328  *
12329  *     Func : rgSCHCmnUlRbAllocForUe
12330  *
12331  *     Desc : Do uplink RB allocation for an UE.
12332  *
12333  *     Ret  :
12334  *
12335  *     Notes: Note that as of now, for retx, maxRb
12336  *            is not considered. Alternatives, such
12337  *            as dropping retx if it crosses maxRb
12338  *            could be considered.
12339  *
12340  *     File :
12341  *
12342  **********************************************************/
12343 static S16 rgSCHCmnUlRbAllocForUe
12344 (
12345 RgSchCellCb  *cell,
12346 RgSchUlSf    *sf,
12347 RgSchUeCb    *ue,
12348 uint8_t      maxRb,
12349 RgSchUlHole  *hole
12350 )
12351 {
12352    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
12353    RgSchCmnUlUe   *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
12354    RgSchUlAlloc   *alloc = NULLP;
12355    uint32_t       nPrb = 0;
12356    uint8_t        numVrbg;
12357    uint8_t        iMcs;
12358    uint8_t        iMcsCrnt;
12359 #ifndef RG_5GTF
12360    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->schdHqProcIdx];
12361 #else
12362    RgSchUlHqProcCb  *proc = NULLP;
12363 #endif
12364    RgSchPdcch       *pdcch;
12365    uint32_t              reqVrbg;
12366    uint8_t               numVrbgTemp;
12367 #ifdef RG_5GTF
12368    TfuDciFormat     dciFrmt;
12369    uint8_t               numLyr;
12370 #endif
12371
12372 #ifdef RG_5GTF
12373    rgSCHUhmGetAvlHqProc(cell, ue, &proc);
12374    if (proc == NULLP)
12375    {
12376       //DU_LOG("\nINFO   -->  SCH : UE [%d] HQ Proc unavailable\n", ue->ueId);
12377       return RFAILED;
12378    }
12379 #endif
12380
12381    if (ue->ue5gtfCb.rank == 2)
12382    {
12383       dciFrmt = TFU_DCI_FORMAT_A2;
12384       numLyr = 2;
12385    }
12386    else
12387    {
12388       dciFrmt = TFU_DCI_FORMAT_A1;
12389       numLyr = 1;
12390    }
12391    /* 5gtf TODO : To pass dci frmt to this function */
12392    pdcch = rgSCHCmnPdcchAllocCrntSf(cell, ue);
12393    if(pdcch == NULLP)
12394    {
12395       DU_LOG("\nDEBUG  -->  SCH : rgSCHCmnUlRbAllocForUe(): Could not get PDCCH for CRNTI:%d",ue->ueId);
12396       return RFAILED;
12397    }
12398         gUl5gtfPdcchSchd++;
12399 #if defined (TENB_STATS) && defined (RG_5GTF)
12400    cell->tenbStats->sch.ul5gtfPdcchSchd++;
12401 #endif
12402
12403    //TODO_SID using configured prb as of now
12404    nPrb = ue->ue5gtfCb.maxPrb;
12405    reqVrbg = nPrb/MAX_5GTF_VRBG_SIZE;
12406    iMcs  = ue->ue5gtfCb.mcs; //gSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
12407    iMcsCrnt = iMcs;
12408    numVrbg = reqVrbg;
12409
12410    if((sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart > MAX_5GTF_VRBG)
12411          || (sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated > MAX_5GTF_VRBG))
12412    {
12413       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR vrbg > 25 valstart = %d valalloc %d\n", sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart
12414             , sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated);
12415       int *p=NULLP;
12416       *p = 10;
12417    }
12418
12419    /*TODO_SID: Workaround for alloc. Currently alloc is ulsf based. To handle multiple beams, we need a different
12420      design. Now alloc are formed based on MAX_5GTF_UE_SCH macro. */
12421    numVrbgTemp = MAX_5GTF_VRBG/MAX_5GTF_UE_SCH;
12422    if(numVrbg)
12423    {
12424       alloc = rgSCHCmnUlSbAlloc(sf, numVrbgTemp,\
12425                                 hole);
12426    }
12427    if (alloc == NULLP)
12428    {
12429       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForUe(): Could not get UlAlloc %d CRNTI:%d",numVrbg,ue->ueId);
12430       rgSCHCmnPdcchRlsCrntSf(cell, pdcch);
12431       return RFAILED;
12432    }
12433    gUl5gtfAllocAllocated++;
12434 #if defined (TENB_STATS) && defined (RG_5GTF)
12435    cell->tenbStats->sch.ul5gtfAllocAllocated++;
12436 #endif
12437    alloc->grnt.vrbgStart = sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart;
12438    alloc->grnt.numVrbg = numVrbg;
12439    alloc->grnt.numLyr = numLyr;
12440    alloc->grnt.dciFrmt = dciFrmt;
12441
12442    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart += numVrbg;
12443    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated += numVrbg;
12444
12445    //rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
12446 #ifdef LTE_L2_MEAS
12447    sf->totPrb  += alloc->grnt.numRb;
12448    ue->ul.nPrb = alloc->grnt.numRb;
12449 #endif
12450    if (ue->csgMmbrSta != TRUE)
12451    {
12452       cellUl->ncsgPrbCnt += alloc->grnt.numRb;
12453    }
12454    cellUl->totPrbCnt += (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
12455    alloc->pdcch = pdcch;
12456    alloc->grnt.iMcs = iMcs;
12457    alloc->grnt.iMcsCrnt = iMcsCrnt;
12458    alloc->grnt.hop = 0;
12459    /* Initial Num RBs support for UCI on PUSCH */
12460 #ifdef TFU_UPGRADE
12461    ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
12462 #endif
12463    alloc->forMsg3 = FALSE;
12464    //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTb5gtfSzTbl[0], (iTbs)); 
12465
12466    //ueUl->alloc.allocdBytes = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
12467    /* TODO_SID Allocating based on configured MCS as of now.
12468          Currently for format A2. When doing multi grp per tti, need to update this. */
12469    ueUl->alloc.allocdBytes = (rgSch5gtfTbSzTbl[iMcs]/8) * ue->ue5gtfCb.rank;
12470
12471    alloc->grnt.datSz = ueUl->alloc.allocdBytes;
12472    //TODO_SID Need to check mod order.
12473    RG_SCH_CMN_TBS_TO_MODODR(iMcs, alloc->grnt.modOdr);
12474         //alloc->grnt.modOdr = 6;
12475    alloc->grnt.isRtx = FALSE;
12476
12477    alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
12478    alloc->grnt.SCID = 0;
12479    alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
12480    alloc->grnt.PMI = 0;
12481    alloc->grnt.uciOnxPUSCH = 0;
12482    alloc->grnt.hqProcId = proc->procId;
12483
12484    alloc->hqProc = proc;
12485    alloc->hqProc->ulSfIdx = cellUl->schdIdx;
12486    alloc->ue = ue;
12487    /*commenting to retain the rnti used for transmission SPS/c-rnti */
12488    alloc->rnti = ue->ueId;
12489    ueUl->alloc.alloc = alloc;
12490    /*rntiwari-Adding the debug for generating the graph.*/
12491    /* No grant attr recorded now */
12492    return ROK;
12493 }
12494
12495 /***********************************************************
12496  *
12497  *     Func : rgSCHCmnUlRbAllocAddUeToLst
12498  *
12499  *     Desc : Add UE to list (scheduled/non-scheduled list)
12500  *            for UL RB allocation information.
12501  *
12502  *     Ret  :
12503  *
12504  *     Notes:
12505  *
12506  *     File :
12507  *
12508  **********************************************************/
12509 Void rgSCHCmnUlRbAllocAddUeToLst(RgSchCellCb *cell,RgSchUeCb *ue,CmLListCp *lst)
12510 {
12511    RgSchCmnUlUe   *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
12512    UNUSED(cell);
12513
12514    gUl5gtfUeRbAllocDone++;
12515 #if defined (TENB_STATS) && defined (RG_5GTF)
12516    cell->tenbStats->sch.ul5gtfUeRbAllocDone++;
12517 #endif
12518    cmLListAdd2Tail(lst, &ueUl->alloc.schdLstLnk);
12519    ueUl->alloc.schdLstLnk.node = (PTR)ue;
12520 }
12521
12522
12523 /**
12524  * @brief This function Processes the Final Allocations
12525  *        made by the RB Allocator against the requested.
12526  *
12527  * @details
12528  *
12529  *     Function: rgSCHCmnUlAllocFnlz
12530  *     Purpose:  This function Processes the Final Allocations
12531  *               made by the RB Allocator against the requested.
12532  *
12533  *     Invoked by: Common Scheduler
12534  *
12535  *  @param[in]  RgSchCellCb           *cell
12536  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12537  *  @return  Void
12538  *
12539  **/
12540 static Void rgSCHCmnUlAllocFnlz(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
12541 {
12542    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12543
12544    /* call scheduler specific Finalization */
12545    cellSch->apisUl->rgSCHUlAllocFnlz(cell, allocInfo);
12546
12547    return;
12548 }
12549
12550 /**
12551  * @brief This function Processes the Final Allocations
12552  *        made by the RB Allocator against the requested.
12553  *
12554  * @details
12555  *
12556  *     Function: rgSCHCmnDlAllocFnlz
12557  *     Purpose:  This function Processes the Final Allocations
12558  *               made by the RB Allocator against the requested.
12559  *
12560  *     Invoked by: Common Scheduler
12561  *
12562  *  @param[in]  RgSchCellCb           *cell
12563  *  @return  Void
12564  *
12565  **/
12566 Void rgSCHCmnDlAllocFnlz(RgSchCellCb  *cell)
12567 {
12568    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
12569    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo; 
12570
12571
12572    rgSCHCmnDlCcchRetxFnlz(cell, allocInfo);
12573    rgSCHCmnDlCcchTxFnlz(cell, allocInfo);
12574 #ifdef RGR_V1
12575    /* Added below functions for handling CCCH SDU transmission received
12576     * after
12577     *     * guard timer expiry*/
12578    rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo);
12579    rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo);
12580 #endif
12581    rgSCHCmnDlRaRspFnlz(cell, allocInfo);
12582       /* call scheduler specific Finalization */
12583    cellSch->apisDl->rgSCHDlAllocFnlz(cell, allocInfo);
12584
12585    /* Stack Crash problem for TRACE5 Changes. Added the return below */
12586    return;
12587
12588 }
12589
12590 #ifdef RG_UNUSED
12591 /**
12592  * @brief Update an uplink subframe.
12593  *
12594  * @details
12595  *
12596  *     Function : rgSCHCmnUlUpdSf
12597  *
12598  *     For each allocation
12599  *      - if no more tx needed
12600  *         - Release allocation
12601  *      - else
12602  *         - Perform retransmission
12603  *
12604  *  @param[in]  RgSchUlSf *sf
12605  *  @return  Void
12606  **/
12607 static Void rgSCHCmnUlUpdSf(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUlSf *sf)
12608 {
12609    CmLList        *lnk;
12610
12611    while ((lnk = sf->allocs.first))
12612    {
12613       RgSchUlAlloc  *alloc = (RgSchUlAlloc *)lnk->node;
12614       lnk = lnk->next;
12615
12616       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
12617       {
12618       }
12619       else
12620       {
12621          /* If need to handle all retx together, run another loop separately */
12622          rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc);
12623       }
12624       rgSCHCmnUlRlsUlAlloc(cell, sf, alloc);
12625    }
12626
12627    /* By this time, all allocs would have been cleared and
12628     * SF is reset to be made ready for new allocations. */
12629    rgSCHCmnUlSfReset(cell, sf);
12630    /* In case there are timing problems due to msg3
12631     * allocations being done in advance, (which will
12632     * probably happen with the current FDD code that
12633     * handles 8 subframes) one solution
12634     * could be to hold the (recent) msg3 allocs in a separate
12635     * list, and then possibly add that to the actual
12636     * list later. So at this time while allocations are
12637     * traversed, the recent msg3 ones are not seen. Anytime after
12638     * this (a good time is when the usual allocations
12639     * are made), msg3 allocations could be transferred to the
12640     * normal list. Not doing this now as it is assumed
12641     * that incorporation of TDD shall take care of this.
12642     */
12643
12644
12645    return;
12646 }
12647
12648 /**
12649  * @brief Handle uplink allocation for retransmission.
12650  *
12651  * @details
12652  *
12653  *     Function : rgSCHCmnUlHndlAllocRetx
12654  *
12655  *     Processing Steps:
12656  *     - Add to queue for retx.
12657  *     - Do not release here, release happends as part
12658  *       of the loop that calls this function.
12659  *
12660  *  @param[in]  RgSchCellCb           *cell
12661  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
12662  *  @param[in]  RgSchUlSf *sf
12663  *  @param[in]  RgSchUlAlloc  *alloc
12664  *  @return  Void
12665  **/
12666 static Void rgSCHCmnUlHndlAllocRetx(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo,RgSchUlSf *sf,RgSchUlAlloc  *alloc)
12667 {
12668    uint32_t       bytes;
12669    RgSchCmnUlUe   *ueUl;
12670    bytes = \
12671       rgTbSzTbl[0][rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs)]\
12672                                      [alloc->grnt.numRb-1]/8;
12673    if (!alloc->forMsg3)
12674    {
12675       ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue);
12676       ueUl->alloc.reqBytes = bytes;
12677       rgSCHUhmRetx(alloc->hqProc);
12678       rgSCHCmnUlAdd2RetxUeLst(allocInfo, alloc->ue);
12679    }
12680    else
12681    {
12682       /* RACHO msg3 retx handling. Part of RACH procedure changes. */
12683       retxAlloc = rgSCHCmnUlGetUlAlloc(cell, sf, alloc->numSb);
12684       if (retxAlloc == NULLP)
12685       {
12686          DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForUe():Could not get UlAlloc for msg3Retx RNTI:%d",
12687                alloc->rnti);
12688          return;
12689       }
12690       retxAlloc->grnt.iMcs = alloc->grnt.iMcs;
12691       retxAlloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl\
12692                                  [alloc->hqProc->rvIdx];
12693       retxAlloc->grnt.nDmrs    = 0;
12694       retxAlloc->grnt.hop      = 0;
12695       retxAlloc->grnt.delayBit = 0;
12696       retxAlloc->rnti          = alloc->rnti;
12697       retxAlloc->ue            = NULLP;
12698       retxAlloc->pdcch         = FALSE;
12699       retxAlloc->forMsg3       = TRUE;
12700       retxAlloc->raCb          = alloc->raCb;
12701       retxAlloc->hqProc        = alloc->hqProc;
12702       rgSCHUhmRetx(retxAlloc->hqProc);
12703    }
12704    return;
12705 }
12706 #endif
12707
12708 /**
12709  * @brief Uplink Scheduling Handler.
12710  *
12711  * @details
12712  *
12713  *     Function: rgSCHCmnUlAlloc
12714  *     Purpose:  This function Handles Uplink Scheduling.
12715  *
12716  *     Invoked by: Common Scheduler
12717  *
12718  *  @param[in]  RgSchCellCb *cell
12719  *  @return  Void
12720  **/
12721 /* ccpu00132653- The definition of this function made common for TDD and FDD*/
12722 static Void rgSCHCmnUlAlloc(RgSchCellCb  *cell)
12723 {
12724    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
12725    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
12726    RgSchCmnDlCell         *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12727    RgSchCmnUlRbAllocInfo  allocInfo;
12728    RgSchCmnUlRbAllocInfo  *allocInfoRef = &allocInfo;
12729 #ifdef RG_5GTF
12730    uint8_t idx;
12731
12732 #endif
12733
12734
12735    /* Initializing RgSchCmnUlRbAllocInfo structure */
12736    rgSCHCmnInitUlRbAllocInfo(allocInfoRef);
12737
12738    /* Get Uplink Subframe */
12739    allocInfoRef->sf = &cellUl->ulSfArr[cellUl->schdIdx];
12740 #ifdef LTE_L2_MEAS
12741    /* initializing the UL PRB count */
12742    allocInfoRef->sf->totPrb = 0;
12743 #endif
12744
12745 #ifdef LTEMAC_SPS
12746    rgSCHCmnSpsUlTti(cell, allocInfoRef);
12747 #endif
12748
12749    if(*allocInfoRef->sf->allocCountRef == 0)
12750    {            
12751       RgSchUlHole     *hole;
12752
12753       if ((hole = rgSCHUtlUlHoleFirst(allocInfoRef->sf)) != NULLP)
12754       {
12755          /* Sanity check of holeDb */
12756          if (allocInfoRef->sf->holeDb->count == 1 && hole->start == 0) 
12757          {
12758             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
12759             /* Re-Initialize available subbands because of CFI change*/
12760             allocInfoRef->sf->availSubbands = cell->dynCfiCb.\
12761                                               bwInfo[cellDl->currCfi].numSb;
12762             /*Currently initializing 5gtf ulsf specific initialization here.
12763               need to do at proper place */
12764 #ifdef RG_5GTF
12765        allocInfoRef->sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
12766        allocInfoRef->sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
12767             for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
12768             {
12769                allocInfoRef->sf->sfBeamInfo[idx].totVrbgAllocated = 0;
12770                allocInfoRef->sf->sfBeamInfo[idx].totVrbgRequired = 0;
12771                allocInfoRef->sf->sfBeamInfo[idx].vrbgStart = 0;
12772             }    
12773 #endif
12774          }
12775          else
12776          {
12777             DU_LOG("\nERROR  -->  SCH :  holeDb sanity check failed");
12778          }
12779       }
12780    }
12781
12782    /* Fix: Adaptive re-transmissions prioritised over other transmissions */
12783    /* perform adaptive retransmissions */
12784    rgSCHCmnUlSfReTxAllocs(cell, allocInfoRef->sf);
12785
12786         g5gtfTtiCnt++;
12787
12788    /* Fix: syed Adaptive Msg3 Retx crash. Release all
12789     Harq processes for which adap Retx failed, to avoid 
12790     blocking. This step should be done before New TX 
12791     scheduling to make hqProc available. Right now we
12792     dont check if proc is in adap Retx list for considering
12793     it to be available. But now with this release that 
12794     functionality would be correct. */
12795 #ifndef RG_5GTF
12796    rgSCHCmnUlSfRlsRetxProcs(cell, allocInfoRef->sf);  
12797 #endif
12798
12799    /* Specific UL scheduler to perform UE scheduling */
12800    cellSch->apisUl->rgSCHUlSched(cell, allocInfoRef);
12801
12802    /* Call UL RB allocator module */
12803    rgSCHCmnAllocUlRb(cell, allocInfoRef);
12804
12805    /* Do group power control for PUSCH */
12806    rgSCHCmnGrpPwrCntrlPusch(cell, allocInfoRef->sf);
12807
12808    cell->sc.apis->rgSCHDrxStrtInActvTmrInUl(cell);
12809
12810    rgSCHCmnUlAllocFnlz(cell, allocInfoRef);
12811         if(5000 == g5gtfTtiCnt)
12812         {
12813       ul5gtfsidDlAlreadyMarkUl = 0;
12814                 ul5gtfsidDlSchdPass = 0;
12815                 ul5gtfsidUlMarkUl = 0;
12816       ul5gtfTotSchdCnt = 0;
12817                 g5gtfTtiCnt = 0;
12818         }
12819
12820    return;
12821 }
12822
12823 /**
12824  * @brief send Subframe Allocations.
12825  *
12826  * @details
12827  *
12828  *     Function: rgSCHCmnSndCnsldtInfo
12829  *     Purpose:  Send the scheduled
12830  *     allocations to MAC for StaInd generation to Higher layers and
12831  *     for MUXing. PST's RgInfSfAlloc to MAC instance.
12832  *
12833  *     Invoked by: Common Scheduler
12834  *
12835  *  @param[in]  RgSchCellCb *cell
12836  *  @return  Void
12837  **/
12838 Void rgSCHCmnSndCnsldtInfo(RgSchCellCb *cell)
12839 {
12840    RgInfSfAlloc  *subfrmAlloc;
12841    Pst           pst;
12842    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
12843
12844
12845    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
12846
12847    /* Send the allocations to MAC for MUXing */
12848    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
12849    subfrmAlloc->cellId = cell->cellId;
12850    /* Populate the List of UEs needing PDB-based Flow control */
12851    cellSch->apisDl->rgSCHDlFillFlwCtrlInfo(cell, subfrmAlloc);
12852 #ifdef LTE_L2_MEAS
12853    if((subfrmAlloc->rarInfo.numRaRntis) ||
12854 #ifdef EMTC_ENABLE
12855       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
12856       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
12857       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
12858 #endif
12859       (subfrmAlloc->ueInfo.numUes)      ||
12860       (subfrmAlloc->cmnLcInfo.bitMask)  ||
12861          (subfrmAlloc->ulUeInfo.numUes)    ||
12862          (subfrmAlloc->flowCntrlInfo.numUes))
12863 #else
12864    if((subfrmAlloc->rarInfo.numRaRntis) ||
12865 #ifdef EMTC_ENABLE
12866       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
12867       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
12868       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
12869 #endif
12870       (subfrmAlloc->ueInfo.numUes)      ||
12871             (subfrmAlloc->cmnLcInfo.bitMask)  ||
12872             (subfrmAlloc->flowCntrlInfo.numUes))
12873 #endif
12874    {
12875       RgSchMacSfAlloc(&pst, subfrmAlloc);
12876    }
12877 #ifndef LTE_TDD
12878    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
12879 #else
12880    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_SF_ALLOC_SIZE;
12881 #endif
12882    
12883    return;
12884 }
12885 /**
12886  * @brief Consolidate Subframe Allocations.
12887  *
12888  * @details
12889  *
12890  *     Function: rgSCHCmnCnsldtSfAlloc
12891  *     Purpose:  Consolidate Subframe Allocations.
12892  *
12893  *     Invoked by: Common Scheduler
12894  *
12895  *  @param[in]  RgSchCellCb *cell
12896  *  @return  Void
12897  **/
12898 Void rgSCHCmnCnsldtSfAlloc(RgSchCellCb  *cell)
12899 {
12900    RgInfSfAlloc     *subfrmAlloc;
12901    CmLteTimingInfo  frm;
12902    RgSchDlSf        *dlSf;
12903    CmLListCp        dlDrxInactvTmrLst;
12904    CmLListCp        dlInActvLst;
12905    CmLListCp        ulInActvLst;
12906    RgSchCmnCell     *cellSch = NULLP;
12907
12908
12909    cmLListInit(&dlDrxInactvTmrLst);
12910    cmLListInit(&dlInActvLst);
12911    cmLListInit(&ulInActvLst);
12912
12913    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
12914
12915    /* Get Downlink Subframe */
12916    frm   = cell->crntTime;
12917    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
12918    dlSf = rgSCHUtlSubFrmGet(cell, frm);
12919
12920    /* Fill the allocation Info */
12921    rgSCHUtlFillRgInfRarInfo(dlSf, subfrmAlloc, cell);
12922
12923   /* CA dev Start */
12924    rgSCHUtlFillRgInfUeInfo(dlSf, cell, &dlDrxInactvTmrLst, 
12925                            &dlInActvLst, &ulInActvLst);
12926 #ifdef RG_PFS_STATS
12927    cell->totalPrb += dlSf->bwAssigned;
12928 #endif
12929    /* Mark the following Ues inactive for UL*/
12930    cellSch = RG_SCH_CMN_GET_CELL(cell);
12931
12932    /* Calling Scheduler specific function with DRX inactive UE list*/
12933    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInActvLst);
12934    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInActvLst);
12935     
12936   /* CA dev End */
12937    /*re/start DRX inactivity timer for the UEs*/
12938    (Void)rgSCHDrxStrtInActvTmr(cell,&dlDrxInactvTmrLst,RG_SCH_DRX_DL);
12939
12940    return;
12941 }
12942
12943 /**
12944  * @brief Initialize the DL Allocation Information Structure.
12945  *
12946  * @details
12947  *
12948  *     Function: rgSCHCmnInitDlRbAllocInfo
12949  *     Purpose:  Initialize the DL Allocation Information Structure.
12950  *
12951  *     Invoked by: Common Scheduler
12952  *
12953  *  @param[out]  RgSchCmnDlRbAllocInfo  *allocInfo
12954  *  @return  Void
12955  **/
12956 static Void rgSCHCmnInitDlRbAllocInfo(RgSchCmnDlRbAllocInfo  *allocInfo)
12957 {
12958    memset(&allocInfo->pcchAlloc, 0, sizeof(RgSchDlRbAlloc));
12959    memset(&allocInfo->bcchAlloc, 0, sizeof(RgSchDlRbAlloc));
12960    memset(allocInfo->raRspAlloc, 0, RG_SCH_CMN_MAX_CMN_PDCCH*sizeof(RgSchDlRbAlloc));
12961
12962    allocInfo->msg4Alloc.msg4DlSf = NULLP;
12963    cmLListInit(&allocInfo->msg4Alloc.msg4TxLst);
12964    cmLListInit(&allocInfo->msg4Alloc.msg4RetxLst);
12965    cmLListInit(&allocInfo->msg4Alloc.schdMsg4TxLst);
12966    cmLListInit(&allocInfo->msg4Alloc.schdMsg4RetxLst);
12967    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4TxLst);
12968    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4RetxLst);
12969 #ifdef RGR_V1
12970    allocInfo->ccchSduAlloc.ccchSduDlSf = NULLP;
12971    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduTxLst);
12972    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduRetxLst);
12973    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduTxLst);
12974    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduRetxLst);
12975    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst);
12976    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst);
12977 #endif
12978
12979    allocInfo->dedAlloc.dedDlSf = NULLP;
12980    cmLListInit(&allocInfo->dedAlloc.txHqPLst);
12981    cmLListInit(&allocInfo->dedAlloc.retxHqPLst);
12982    cmLListInit(&allocInfo->dedAlloc.schdTxHqPLst);
12983    cmLListInit(&allocInfo->dedAlloc.schdRetxHqPLst);
12984    cmLListInit(&allocInfo->dedAlloc.nonSchdTxHqPLst);
12985    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxHqPLst);
12986
12987    cmLListInit(&allocInfo->dedAlloc.txRetxHqPLst);
12988    cmLListInit(&allocInfo->dedAlloc.schdTxRetxHqPLst);
12989    cmLListInit(&allocInfo->dedAlloc.nonSchdTxRetxHqPLst);
12990 #ifdef LTEMAC_SPS
12991    cmLListInit(&allocInfo->dedAlloc.txSpsHqPLst);
12992    cmLListInit(&allocInfo->dedAlloc.retxSpsHqPLst);
12993    cmLListInit(&allocInfo->dedAlloc.schdTxSpsHqPLst);
12994    cmLListInit(&allocInfo->dedAlloc.schdRetxSpsHqPLst);
12995    cmLListInit(&allocInfo->dedAlloc.nonSchdTxSpsHqPLst);
12996    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxSpsHqPLst);
12997 #endif
12998
12999 #ifdef LTE_ADV
13000    rgSCHLaaCmnInitDlRbAllocInfo (allocInfo);
13001 #endif
13002
13003    cmLListInit(&allocInfo->dedAlloc.errIndTxHqPLst);
13004    cmLListInit(&allocInfo->dedAlloc.schdErrIndTxHqPLst);
13005    cmLListInit(&allocInfo->dedAlloc.nonSchdErrIndTxHqPLst);
13006    return;
13007 }
13008
13009 /**
13010  * @brief Initialize the UL Allocation Information Structure.
13011  *
13012  * @details
13013  *
13014  *     Function: rgSCHCmnInitUlRbAllocInfo
13015  *     Purpose:  Initialize the UL Allocation Information Structure.
13016  *
13017  *     Invoked by: Common Scheduler
13018  *
13019  *  @param[out]  RgSchCmnUlRbAllocInfo  *allocInfo
13020  *  @return  Void
13021  **/
13022 Void rgSCHCmnInitUlRbAllocInfo(RgSchCmnUlRbAllocInfo  *allocInfo)
13023 {
13024    allocInfo->sf = NULLP;
13025    cmLListInit(&allocInfo->contResLst);
13026    cmLListInit(&allocInfo->schdContResLst);
13027    cmLListInit(&allocInfo->nonSchdContResLst);
13028    cmLListInit(&allocInfo->ueLst);
13029    cmLListInit(&allocInfo->schdUeLst);
13030    cmLListInit(&allocInfo->nonSchdUeLst);
13031
13032    return;
13033 }
13034
13035 /**
13036  * @brief Scheduling for PUCCH group power control.
13037  *
13038  * @details
13039  *
13040  *     Function: rgSCHCmnGrpPwrCntrlPucch
13041  *     Purpose: This function does group power control for PUCCH
13042  *     corresponding to the subframe for which DL UE allocations
13043  *     have happended.
13044  *
13045  *     Invoked by: Common Scheduler
13046  *
13047  *  @param[in]  RgSchCellCb *cell
13048  *  @return  Void
13049  **/
13050 static Void rgSCHCmnGrpPwrCntrlPucch(RgSchCellCb *cell,RgSchDlSf *dlSf)
13051 {
13052    rgSCHPwrGrpCntrlPucch(cell, dlSf);
13053    return;
13054 }
13055
13056 /**
13057  * @brief Scheduling for PUSCH group power control.
13058  *
13059  * @details
13060  *
13061  *     Function: rgSCHCmnGrpPwrCntrlPusch
13062  *     Purpose: This function does group power control, for
13063  *     the subframe for which UL allocation has (just) happened.
13064  *
13065  *     Invoked by: Common Scheduler
13066  *
13067  *  @param[in]  RgSchCellCb *cell
13068  *  @param[in]  RgSchUlSf   *ulSf
13069  *  @return  Void
13070  **/
13071 static Void rgSCHCmnGrpPwrCntrlPusch(RgSchCellCb *cell,RgSchUlSf *ulSf)
13072 {
13073    /*removed unused variable *cellSch*/
13074    CmLteTimingInfo        frm;
13075    RgSchDlSf              *dlSf;
13076
13077
13078    /* Got to pass DL SF corresponding to UL SF, so get that first.
13079     * There is no easy way of getting dlSf by having the RgSchUlSf*,
13080     * so use the UL delta from current time to get the DL SF. */
13081    frm   = cell->crntTime;
13082
13083 #ifdef EMTC_ENABLE
13084    if(cell->emtcEnable == TRUE)
13085    {
13086       RGSCH_INCR_SUB_FRAME_EMTC(frm, TFU_DLCNTRL_DLDELTA);
13087    }
13088    else
13089 #endif
13090    {
13091       RGSCH_INCR_SUB_FRAME(frm, TFU_DLCNTRL_DLDELTA);
13092    }
13093    /* Del filling of dl.time */
13094    dlSf = rgSCHUtlSubFrmGet(cell, frm);
13095
13096    rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf);
13097
13098    return;
13099 }
13100
13101 /* Fix: syed align multiple UEs to refresh at same time */
13102 /***********************************************************
13103  *
13104  *     Func : rgSCHCmnApplyUeRefresh 
13105  *
13106  *     Desc : Apply UE refresh in CMN and Specific 
13107  *     schedulers. Data rates and corresponding 
13108  *     scratchpad variables are updated.
13109  *
13110  *     Ret  :
13111  *
13112  *     Notes:
13113  *
13114  *     File :
13115  *
13116  **********************************************************/
13117 static S16 rgSCHCmnApplyUeRefresh(RgSchCellCb *cell,RgSchUeCb  *ue)
13118 {
13119    RgSchCmnCell *cellSch     = RG_SCH_CMN_GET_CELL(cell);
13120    uint32_t     effGbrBsr    = 0;
13121    uint32_t     effNonGbrBsr = 0;
13122    uint32_t     lcgId;
13123
13124
13125    /* Reset the refresh cycle variableCAP */
13126    ue->ul.effAmbr = ue->ul.cfgdAmbr;
13127
13128    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
13129    {
13130       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
13131       {
13132          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
13133
13134          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
13135          {
13136             cmnLcg->effGbr = cmnLcg->cfgdGbr;
13137             cmnLcg->effDeltaMbr = cmnLcg->deltaMbr;
13138             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
13139             /* Considering GBR LCG will be prioritised by UE */
13140             effGbrBsr += cmnLcg->bs;
13141          }/* Else no remaing BS so nonLcg0 will be updated when BSR will be received */
13142          else
13143          {
13144             effNonGbrBsr += cmnLcg->reportedBs;
13145             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
13146          }
13147       }
13148    }
13149    effNonGbrBsr = RGSCH_MIN(effNonGbrBsr,ue->ul.effAmbr);
13150    ue->ul.nonGbrLcgBs = effNonGbrBsr;
13151
13152    ue->ul.nonLcg0Bs = effGbrBsr + effNonGbrBsr;
13153    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
13154                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
13155
13156
13157    /* call scheduler specific event handlers
13158     * for refresh timer expiry */
13159    cellSch->apisUl->rgSCHUlUeRefresh(cell, ue);
13160    cellSch->apisDl->rgSCHDlUeRefresh(cell, ue);
13161
13162    return ROK;
13163 }
13164
13165 /***********************************************************
13166  *
13167  *     Func : rgSCHCmnTmrExpiry
13168  *
13169  *     Desc : Adds an UE to refresh queue, so that the UE is
13170  *            periodically triggered to refresh it's GBR and
13171  *            AMBR values.
13172  *
13173  *     Ret  :
13174  *
13175  *     Notes:
13176  *
13177  *     File :
13178  *
13179  **********************************************************/
13180 static S16 rgSCHCmnTmrExpiry
13181 (
13182 PTR cb,               /* Pointer to timer control block */
13183 S16 tmrEvnt           /* Timer Event */
13184 )
13185 {
13186    RgSchUeCb       *ue = (RgSchUeCb *)cb;
13187    RgSchCellCb     *cell = ue->cell;
13188 #if (ERRCLASS & ERRCLS_DEBUG)
13189 #endif
13190
13191
13192 #if (ERRCLASS & ERRCLS_DEBUG)
13193    if (tmrEvnt != RG_SCH_CMN_EVNT_UE_REFRESH)
13194    {
13195       DU_LOG("\nERROR  -->  SCH : rgSCHCmnTmrExpiry(): Invalid "
13196          "timer event CRNTI:%d",ue->ueId);
13197       return RFAILED;
13198    }
13199 #else
13200    UNUSED(tmrEvnt);
13201 #endif
13202
13203    rgSCHCmnApplyUeRefresh(cell, ue);
13204
13205    rgSCHCmnAddUeToRefreshQ(cell, ue, RG_SCH_CMN_REFRESH_TIME);
13206
13207    return ROK;
13208 }
13209
13210 /***********************************************************
13211  *
13212  *     Func : rgSCHCmnTmrProc
13213  *
13214  *     Desc : Timer entry point per cell. Timer
13215  *            processing is triggered at every frame boundary
13216  *            (every 10 ms).
13217  *
13218  *     Ret  :
13219  *
13220  *     Notes:
13221  *
13222  *     File :
13223  *
13224  **********************************************************/
13225 static S16 rgSCHCmnTmrProc(RgSchCellCb *cell)
13226 {
13227    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
13228    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
13229    /* Moving the assignment of scheduler pointer
13230      to available scope for optimization */
13231
13232    if ((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES_5G) == 0)
13233    {
13234       /* Reset the counters periodically */
13235       if ((cell->crntTime.sfn % RG_SCH_CMN_CSG_REFRESH_TIME) == 0)
13236       {
13237          RG_SCH_RESET_HCSG_DL_PRB_CNTR(cmnDlCell);
13238          RG_SCH_RESET_HCSG_UL_PRB_CNTR(cmnUlCell);
13239       }
13240       if ((cell->crntTime.sfn % RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME) == 0)
13241       {
13242
13243          cell->measurements.ulTpt =  ((cell->measurements.ulTpt * 95) + ( cell->measurements.ulBytesCnt * 5))/100;
13244          cell->measurements.dlTpt =  ((cell->measurements.dlTpt * 95) + ( cell->measurements.dlBytesCnt * 5))/100;
13245
13246          rgSCHUtlCpuOvrLdAdjItbsCap(cell);
13247          /* reset cell level tpt measurements for next cycle */
13248          cell->measurements.ulBytesCnt = 0;
13249          cell->measurements.dlBytesCnt = 0;
13250       }
13251       /* Comparing with Zero instead of % is being done for efficiency.
13252        * If Timer resolution changes then accordingly update the
13253        * macro RG_SCH_CMN_REFRESH_TIMERES */    
13254       RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
13255       cmPrcTmr(&sched->tmrTqCp, sched->tmrTq, (PFV)rgSCHCmnTmrExpiry);
13256    }
13257
13258    return ROK;
13259 }
13260
13261
13262 /***********************************************************
13263  *
13264  *     Func : rgSchCmnUpdCfiVal 
13265  *
13266  *     Desc : Update the CFI value if CFI switch was done 
13267  *
13268  *     Ret  :
13269  *
13270  *     Notes:
13271  *
13272  *     File :
13273  *
13274  **********************************************************/
13275 static Void rgSchCmnUpdCfiVal(RgSchCellCb *cell,uint8_t delta)
13276 {
13277    RgSchDlSf        *dlSf;
13278    CmLteTimingInfo  pdsch;
13279    RgSchCmnDlCell   *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); 
13280    uint8_t          dlIdx;
13281 #ifdef LTE_TDD
13282    uint8_t          mPhich;
13283    RgSchDlSf        *tddSf;
13284    uint8_t          idx;
13285    uint8_t          splSfCfi = 0;
13286 #endif    
13287
13288
13289    pdsch  = cell->crntTime;
13290    RGSCH_INCR_SUB_FRAME(pdsch, delta);
13291    dlSf = rgSCHUtlSubFrmGet(cell, pdsch);
13292    /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
13293     *change happens in that SF then UL PDCCH allocation happens with old CFI
13294     *but CFI in control Req goes updated one since it was stored in the CELL
13295     */
13296    dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
13297    if(cell->dynCfiCb.pdcchSfIdx != 0xFF) 
13298    {
13299 #ifdef LTE_TDD
13300       dlIdx = rgSCHUtlGetDlSfIdx(cell, &pdsch);
13301 #else
13302       dlIdx = (((pdsch.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (pdsch.slot % RGSCH_NUM_SUB_FRAMES));
13303       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
13304 #endif  
13305       /* If current downlink subframe index is same as pdcch SF index,
13306        * perform the switching of CFI in this subframe */
13307       if(cell->dynCfiCb.pdcchSfIdx == dlIdx)
13308       {
13309          cellCmnDl->currCfi  = cellCmnDl->newCfi;
13310          cell->dynCfiCb.pdcchSfIdx = 0xFF;
13311
13312          /* Updating the nCce value based on the new CFI */
13313 #ifdef LTE_TDD
13314          splSfCfi = cellCmnDl->newCfi;
13315          for(idx = 0; idx < cell->numDlSubfrms; idx++)
13316          {   
13317             tddSf = cell->subFrms[idx];
13318
13319             mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][tddSf->sfNum];
13320
13321             if(tddSf->sfType == RG_SCH_SPL_SF_DATA)
13322             {
13323                RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
13324
13325                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
13326             }
13327             else
13328             {   
13329                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][cellCmnDl->currCfi];
13330             }
13331          }
13332          /* Setting the switch over window length based on config index.
13333           * During switch over period all the UL trnsmissions are Acked 
13334           * to UEs */
13335          cell->dynCfiCb.switchOvrWinLen = 
13336                rgSchCfiSwitchOvrWinLen[cell->ulDlCfgIdx];
13337 #else
13338          cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCmnDl->currCfi];
13339          /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
13340           *change happens in that SF then UL PDCCH allocation happens with old CFI
13341           *but CFI in control Req goes updated one since it was stored in the CELL
13342           */
13343          dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
13344          cell->dynCfiCb.switchOvrWinLen = rgSchCfiSwitchOvrWinLen[7];
13345 #endif
13346       }   
13347    }   
13348
13349    return;
13350 }
13351
13352 /***********************************************************
13353  *
13354  *     Func : rgSchCmnUpdtPdcchSfIdx 
13355  *
13356  *     Desc : Update the switch over window length
13357  *
13358  *     Ret  : void
13359  *
13360  *     Notes:
13361  *
13362  *     File :
13363  *
13364  **********************************************************/
13365 #ifdef LTE_TDD
13366 static Void rgSchCmnUpdtPdcchSfIdx(RgSchCellCb *cell,uint8_t dlIdx,uint8_t sfNum)
13367 #else
13368 static Void rgSchCmnUpdtPdcchSfIdx(RgSchCellCb *cell,uint8_t dlIdx)
13369 #endif
13370 {
13371    uint8_t  idx;
13372
13373
13374    /* Resetting the parameters on CFI switching */
13375    cell->dynCfiCb.cceUsed = 0;
13376    cell->dynCfiCb.lowCceCnt = 0;
13377
13378    cell->dynCfiCb.cceFailSum = 0;
13379    cell->dynCfiCb.cceFailCnt = 0;
13380    cell->dynCfiCb.prevCceFailIdx = 0;
13381
13382    cell->dynCfiCb.switchOvrInProgress = TRUE;
13383
13384    for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++)
13385    {
13386       cell->dynCfiCb.cceFailSamples[idx] = 0;
13387    }   
13388
13389    cell->dynCfiCb.ttiCnt = 0;
13390
13391    cell->dynCfiCb.cfiSwitches++;
13392    cfiSwitchCnt = cell->dynCfiCb.cfiSwitches;
13393
13394 #ifdef LTE_TDD 
13395    cell->dynCfiCb.pdcchSfIdx = (dlIdx + 
13396       rgSchTddPdcchSfIncTbl[cell->ulDlCfgIdx][sfNum]) % cell->numDlSubfrms;
13397 #else
13398    cell->dynCfiCb.pdcchSfIdx = (dlIdx + RG_SCH_CFI_APPLY_DELTA) % \
13399         RGSCH_NUM_DL_slotS;
13400 #endif
13401 }
13402
13403 /***********************************************************
13404  *
13405  *     Func : rgSchCmnUpdCfiDb 
13406  *
13407  *     Desc : Update the counters related to dynamic
13408  *            CFI feature in cellCb. 
13409  *
13410  *     Ret  :
13411  *
13412  *     Notes:
13413  *
13414  *     File :
13415  *
13416  **********************************************************/
13417 Void rgSchCmnUpdCfiDb(RgSchCellCb *cell,uint8_t delta)
13418 {
13419    CmLteTimingInfo   frm;
13420    RgSchDlSf         *dlSf;
13421 #ifdef LTE_TDD
13422    uint8_t           mPhich;
13423    Bool              isHiDci0; 
13424 #endif      
13425    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell); 
13426    uint8_t           nCceLowerCfi = 0;
13427    uint8_t           currCfi;
13428    uint8_t           cceFailIdx;
13429    uint32_t          totalCce;
13430    uint8_t           dlIdx;
13431    uint16_t          ttiMod;
13432
13433
13434    /* Get Downlink Subframe */   
13435    frm   = cell->crntTime;
13436    RGSCH_INCR_SUB_FRAME(frm, delta);
13437
13438 #ifdef LTE_TDD
13439    dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
13440    dlSf = cell->subFrms[dlIdx];
13441    isHiDci0 = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][dlSf->sfNum];
13442 #else
13443    /* Changing the idexing
13444       so that proper subframe is selected */
13445    dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
13446    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
13447    dlSf = cell->subFrms[dlIdx];
13448 #endif 
13449
13450    currCfi = cellSch->dl.currCfi;
13451
13452    if(!cell->dynCfiCb.switchOvrInProgress)
13453    {   
13454       do{
13455          if(!cell->dynCfiCb.isDynCfiEnb)
13456          {
13457             if(currCfi != cellSch->cfiCfg.cfi)
13458             {
13459                if(currCfi < cellSch->cfiCfg.cfi)
13460                {
13461                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
13462                   cfiIncr = cell->dynCfiCb.cfiIncr;   
13463                }
13464                else
13465                {
13466                   RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
13467                   cfiDecr = cell->dynCfiCb.cfiDecr;
13468                }
13469             }
13470             break;
13471          }
13472
13473 #ifdef LTE_TDD         
13474          /* Setting ttiMod to 0 for ttiCnt > 1000 in case if this 
13475           * function was not called in UL subframe*/
13476          if(cell->dynCfiCb.ttiCnt > RGSCH_CFI_TTI_MON_INTRVL)
13477          {   
13478             ttiMod = 0;
13479          }
13480          else
13481 #endif
13482          {   
13483             ttiMod = cell->dynCfiCb.ttiCnt % RGSCH_CFI_TTI_MON_INTRVL;
13484          }
13485
13486          dlSf->dlUlBothCmplt++;
13487 #ifdef LTE_TDD      
13488          if((dlSf->dlUlBothCmplt == 2) || (!isHiDci0))
13489 #else
13490          if(dlSf->dlUlBothCmplt == 2)
13491 #endif         
13492          {
13493             /********************STEP UP CRITERIA********************/
13494             /* Updating the CCE failure count parameter */
13495             cell->dynCfiCb.cceFailCnt += dlSf->isCceFailure;
13496             cell->dynCfiCb.cceFailSum += dlSf->isCceFailure;
13497
13498             /* Check if cfi step up can be performed */
13499             if(currCfi < cell->dynCfiCb.maxCfi)
13500             {
13501                if(cell->dynCfiCb.cceFailSum >= cell->dynCfiCb.cfiStepUpTtiCnt) 
13502                {
13503                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
13504                   cfiIncr = cell->dynCfiCb.cfiIncr;   
13505                   break;
13506                }
13507             } 
13508
13509             /********************STEP DOWN CRITERIA********************/
13510
13511             /* Updating the no. of CCE used in this dl subframe */
13512             cell->dynCfiCb.cceUsed += dlSf->cceCnt;
13513
13514             if(currCfi > RGSCH_MIN_CFI_VAL)
13515             {   
13516                /* calculating the number of CCE for next lower CFI */
13517 #ifdef LTE_TDD      
13518                mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][dlSf->sfNum];
13519                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[mPhich][currCfi-1];
13520 #else
13521                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[0][currCfi-1];
13522 #endif     
13523                if(dlSf->cceCnt < nCceLowerCfi)
13524                {
13525                   /* Updating the count of TTIs in which no. of CCEs
13526                    * used were less than the CCEs of next lower CFI */
13527                   cell->dynCfiCb.lowCceCnt++;
13528                }   
13529
13530                if(ttiMod == 0)
13531                {
13532                   totalCce = (nCceLowerCfi * cell->dynCfiCb.cfiStepDownTtiCnt * 
13533                         RGSCH_CFI_CCE_PERCNTG)/100;
13534
13535                   if((!cell->dynCfiCb.cceFailSum) && 
13536                         (cell->dynCfiCb.lowCceCnt >= 
13537                          cell->dynCfiCb.cfiStepDownTtiCnt) && 
13538                         (cell->dynCfiCb.cceUsed < totalCce))  
13539                   {
13540                      RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
13541                      cfiDecr = cell->dynCfiCb.cfiDecr; 
13542                      break;
13543                   }
13544                }   
13545             }
13546
13547             cceFailIdx = ttiMod/cell->dynCfiCb.failSamplePrd;
13548
13549             if(cceFailIdx != cell->dynCfiCb.prevCceFailIdx)
13550             {   
13551                /* New sample period has started. Subtract the old count  
13552                 * from the new sample period */
13553                cell->dynCfiCb.cceFailSum -= cell->dynCfiCb.cceFailSamples[cceFailIdx];
13554
13555                /* Store the previous sample period data */
13556                cell->dynCfiCb.cceFailSamples[cell->dynCfiCb.prevCceFailIdx]
13557                   = cell->dynCfiCb.cceFailCnt;
13558
13559                cell->dynCfiCb.prevCceFailIdx = cceFailIdx;
13560
13561                /* Resetting the CCE failure count as zero for next sample period */
13562                cell->dynCfiCb.cceFailCnt = 0;  
13563             }
13564
13565             if(ttiMod == 0)
13566             {   
13567                /* Restting the parametrs after Monitoring Interval expired */
13568                cell->dynCfiCb.cceUsed = 0;
13569                cell->dynCfiCb.lowCceCnt = 0;
13570                cell->dynCfiCb.ttiCnt = 0;
13571             }
13572
13573             cell->dynCfiCb.ttiCnt++;
13574          }
13575       }while(0);
13576
13577       if(cellSch->dl.newCfi != cellSch->dl.currCfi)
13578       {
13579 #ifdef LTE_TDD      
13580          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, dlSf->sfNum);
13581 #else
13582          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx);
13583 #endif      
13584       }  
13585    }
13586 }   
13587
13588 /**
13589  * @brief Dl Scheduler for Broadcast and Common channel scheduling.
13590  *
13591  * @details
13592  *
13593  *     Function: rgSCHCmnDlCommonChSch
13594  *     Purpose:  This function schedules DL Common channels for LTE. 
13595  *               Invoked by TTI processing in TOM. Scheduling is done for 
13596  *               BCCH, PCCH, Msg4, CCCH SDU, RAR in that order 
13597  *
13598  *     Invoked by: TOM (TTI processing)
13599  *
13600  *  @param[in]  RgSchCellCb *cell
13601  *  @return  Void
13602  **/
13603 Void rgSCHCmnDlCommonChSch(RgSchCellCb  *cell)
13604 {
13605    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
13606
13607
13608    cellSch->apisDl->rgSCHDlTickForPdbTrkng(cell);
13609    rgSchCmnUpdCfiVal(cell, RG_SCH_CMN_DL_DELTA);
13610
13611    /* handle Inactive UEs for DL */
13612    rgSCHCmnHdlDlInactUes(cell);
13613
13614    /* Send a Tick to Refresh Timer */
13615    rgSCHCmnTmrProc(cell);
13616
13617    if (cell->isDlDataAllwd && (cell->stopSiSch == FALSE)) 
13618    {
13619       rgSCHCmnInitRbAlloc(cell); 
13620       /* Perform DL scheduling of BCCH, PCCH */
13621       rgSCHCmnDlBcchPcchAlloc(cell);
13622    }
13623    else
13624    {
13625       if(cell->siCb.inWindow != 0)
13626       {
13627          cell->siCb.inWindow--;
13628       }
13629    }
13630    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
13631    {
13632       rgSCHCmnDlCcchRarAlloc(cell);
13633    }
13634    return;
13635 }
13636
13637 /**
13638  * @brief Scheduler invocation per TTI.
13639  *
13640  * @details
13641  *
13642  *     Function: rgSCHCmnUlSch
13643  *     Purpose:  This function implements UL scheduler alone. This is to
13644  *               be able to perform scheduling with more flexibility.
13645  *
13646  *     Invoked by: TOM (TTI processing)
13647  *
13648  *  @param[in]  RgSchCellCb *cell
13649  *  @return  Void
13650  **/
13651 Void rgSCHCmnUlSch(RgSchCellCb  *cell)
13652 {
13653    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
13654    
13655
13656 #ifdef LTE_ADV
13657    /* LAA_SCELL: */
13658    if(TRUE == rgSCHLaaSCellEnabled(cell))
13659    {
13660       return;   
13661    }
13662 #endif
13663    
13664    if(cellSch->ul.schdIdx != RGSCH_INVALID_INFO)
13665    {   
13666       rgSchCmnUpdCfiVal(cell, TFU_ULCNTRL_DLDELTA);
13667
13668       /* Handle Inactive UEs for UL */
13669       rgSCHCmnHdlUlInactUes(cell);
13670       /* Perform UL Scheduling EVERY TTI */
13671       rgSCHCmnUlAlloc(cell);
13672
13673       /* Calling function to update CFI parameters*/
13674       rgSchCmnUpdCfiDb(cell, TFU_ULCNTRL_DLDELTA);   
13675
13676       if(cell->dynCfiCb.switchOvrWinLen > 0)
13677       {
13678          /* Decrementing the switchover window length */
13679          cell->dynCfiCb.switchOvrWinLen--;
13680
13681          if(!cell->dynCfiCb.switchOvrWinLen)
13682          {   
13683             if(cell->dynCfiCb.dynCfiRecfgPend)
13684             {  
13685                /* Toggling the Dynamic CFI enabling */
13686                cell->dynCfiCb.isDynCfiEnb ^= 1;
13687                rgSCHDynCfiReCfg(cell, cell->dynCfiCb.isDynCfiEnb); 
13688                cell->dynCfiCb.dynCfiRecfgPend = FALSE;
13689             }   
13690             cell->dynCfiCb.switchOvrInProgress = FALSE;
13691          }
13692       }
13693    }
13694 #ifdef LTE_TDD
13695 #ifdef LTEMAC_SPS
13696    else
13697    {
13698       rgSCHCmnSpsUlTti(cell, NULLP); 
13699    }
13700 #endif
13701 #endif
13702
13703    return;
13704 }
13705
13706 \f
13707 /**
13708  * @brief This function updates the scheduler with service for an UE.
13709  *
13710  * @details
13711  *
13712  *     Function: rgSCHCmnDlDedBoUpd
13713  *     Purpose:  This function should be called whenever there is a
13714  *               change BO for a service.
13715  *
13716  *     Invoked by: BO and Scheduler
13717  *
13718  *  @param[in]  RgSchCellCb*  cell
13719  *  @param[in]  RgSchUeCb*    ue
13720  *  @param[in]  RgSchDlLcCb*  svc
13721  *  @return  Void
13722  *
13723  **/
13724 Void rgSCHCmnDlDedBoUpd(RgSchCellCb *cell,RgSchUeCb   *ue,RgSchDlLcCb *svc)
13725 {
13726    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13727
13728    /* RACHO : if UEs idle time exceeded and a BO update
13729     * is received, then add UE to the pdcch Order Q */
13730    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
13731    {
13732       RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
13733       /* If PDCCH order is already triggered and we are waiting for
13734        * RACH from UE then do not add to PdcchOdrQ. */
13735       if (ueDl->rachInfo.rapIdLnk.node == NULLP)
13736       {
13737          rgSCHCmnDlAdd2PdcchOdrQ(cell, ue);
13738       }
13739    }
13740
13741 #ifdef LTEMAC_SPS
13742
13743    /* If SPS service, invoke SPS module */
13744    if (svc->dlLcSpsCfg.isSpsEnabled)
13745    {
13746       rgSCHCmnSpsDlDedBoUpd(cell, ue, svc);
13747       /* Note: Retrun from here, no update needed in other schedulers */
13748       return;
13749    }
13750 #endif
13751 #ifdef EMTC_ENABLE
13752    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
13753    {
13754       cellSch->apisEmtcDl->rgSCHDlDedBoUpd(cell, ue, svc);
13755       //DU_LOG("\nINFO   -->  SCH : rgSCHEMTCDlDedBoUpd\n");
13756    }
13757    else
13758 #endif
13759    {
13760       cellSch->apisDl->rgSCHDlDedBoUpd(cell, ue, svc);
13761    }
13762 #ifdef LTE_ADV
13763    if (ue->numSCells)
13764    {
13765       rgSCHSCellDlDedBoUpd(cell, ue, svc);
13766    }
13767 #endif
13768    return;
13769 }
13770
13771 \f
13772 /**
13773  * @brief Removes an UE from Cell's TA List.
13774  *
13775  * @details
13776  *
13777  *     Function: rgSCHCmnRmvFrmTaLst
13778  *     Purpose:  Removes an UE from Cell's TA List.
13779  *
13780  *     Invoked by: Specific Scheduler
13781  *
13782  *  @param[in]  RgSchCellCb*     cell
13783  *  @param[in]  RgSchUeCb*       ue
13784  *  @return  Void
13785  *
13786  **/
13787 Void rgSCHCmnRmvFrmTaLst(RgSchCellCb *cell,RgSchUeCb *ue)
13788 {
13789    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
13790
13791 #ifdef EMTC_ENABLE
13792    if(cell->emtcEnable && ue->isEmtcUe)
13793    {
13794       rgSCHEmtcRmvFrmTaLst(cellCmnDl,ue);
13795    }
13796    else
13797 #endif
13798    {
13799       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
13800       ue->dlTaLnk.node = (PTR)NULLP;
13801    }
13802    return;
13803 }
13804
13805 /* Fix: syed Remove the msg4Proc from cell
13806  * msg4Retx Queue. I have used CMN scheduler function
13807  * directly. Please define a new API and call this
13808  * function through that. */        
13809 \f
13810 /**
13811  * @brief This function removes MSG4 HARQ process from cell RETX Queues.
13812  *
13813  * @details
13814  *
13815  *     Function: rgSCHCmnDlMsg4ProcRmvFrmRetx
13816  *     Purpose:  This function removes MSG4 HARQ process from cell RETX Queues.
13817  *
13818  *     Invoked by: UE/RACB deletion. 
13819  *
13820  *  @param[in]  RgSchCellCb*     cell
13821  *  @param[in]  RgSchDlHqProc*   hqP
13822  *  @return  Void
13823  *
13824  **/
13825 Void rgSCHCmnDlMsg4ProcRmvFrmRetx(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
13826 {
13827    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13828
13829    if (hqP->tbInfo[0].ccchSchdInfo.retxLnk.node)
13830    {
13831       if (hqP->hqE->msg4Proc == hqP)
13832       {
13833          cmLListDelFrm(&cellSch->dl.msg4RetxLst, \
13834                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13835          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
13836       }
13837 #ifdef RGR_V1
13838       else if(hqP->hqE->ccchSduProc == hqP)
13839       {
13840          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
13841                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13842          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
13843       }
13844 #endif
13845    }
13846    return;
13847 }
13848
13849 \f
13850 /**
13851  * @brief This function adds a HARQ process for retx.
13852  *
13853  * @details
13854  *
13855  *     Function: rgSCHCmnDlProcAddToRetx
13856  *     Purpose:  This function adds a HARQ process to retransmission
13857  *               queue. This may be performed when a HARQ ack is
13858  *               unsuccessful.
13859  *
13860  *     Invoked by: HARQ feedback processing
13861  *
13862  *  @param[in]  RgSchCellCb*     cell
13863  *  @param[in]  RgSchDlHqProc*   hqP
13864  *  @return  Void
13865  *
13866  **/
13867 Void rgSCHCmnDlProcAddToRetx(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
13868 {
13869    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
13870
13871    if (hqP->hqE->msg4Proc == hqP) /* indicating msg4 transmission */
13872    {
13873       cmLListAdd2Tail(&cellSch->dl.msg4RetxLst, \
13874             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13875       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
13876    }
13877 #ifdef RGR_V1
13878    else if(hqP->hqE->ccchSduProc == hqP)
13879    {
13880       /*If CCCH SDU being transmitted without cont res CE*/
13881       cmLListAdd2Tail(&cellSch->dl.ccchSduRetxLst,
13882             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
13883       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
13884    }
13885 #endif
13886    else
13887    {
13888 #ifdef LTEMAC_SPS
13889       if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
13890       {
13891          /* Invoke SPS module for SPS HARQ proc re-transmission handling */
13892          rgSCHCmnSpsDlProcAddToRetx(cell, hqP);
13893          return;
13894       }
13895 #endif /* LTEMAC_SPS */
13896 #ifdef EMTC_ENABLE      
13897       if((TRUE == cell->emtcEnable)
13898          && (TRUE == hqP->hqE->ue->isEmtcUe))
13899       {
13900          cellSch->apisEmtcDl->rgSCHDlProcAddToRetx(cell, hqP);
13901       }
13902       else
13903 #endif         
13904       {
13905          cellSch->apisDl->rgSCHDlProcAddToRetx(cell, hqP);
13906       }
13907    }
13908    return;
13909 }
13910
13911 \f
13912 /**
13913  * @brief This function performs RI validation and
13914  *        updates it to the ueCb.
13915  *
13916  * @details
13917  *
13918  *     Function: rgSCHCmnDlSetUeRi
13919  *     Purpose:  This function performs RI validation and
13920  *        updates it to the ueCb.
13921  *
13922  *     Invoked by: rgSCHCmnDlCqiInd
13923  *
13924  *  @param[in]  RgSchCellCb        *cell
13925  *  @param[in]  RgSchUeCb          *ue
13926  *  @param[in]  uint8_t                 ri
13927  *  @param[in]  Bool               isPeriodic
13928  *  @return  Void
13929  *
13930  **/
13931 static Void rgSCHCmnDlSetUeRi(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t ri,Bool isPer)
13932 {
13933    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
13934    RgSchCmnUeInfo *ueSchCmn = RG_SCH_CMN_GET_CMN_UE(ue);
13935    
13936 #ifdef TFU_UPGRADE
13937    RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell);
13938    UNUSED(isPer);
13939 #endif
13940
13941
13942    /* FIX for RRC Reconfiguration issue */
13943    /* ccpu00140894- During Tx Mode transition RI report will not entertained for 
13944     * specific during which SCH expecting UE can complete TX mode transition*/
13945    if (ue->txModeTransCmplt == FALSE)
13946    {
13947       return;
13948    }
13949
13950    /* Restrict the Number of TX layers to cell->numTxAntPorts.
13951     * Protection from invalid RI values. */
13952    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
13953    
13954    /* Special case of converting PMI to sane value when
13955     * there is a switch in RI from 1 to 2 and PMI reported 
13956     * for RI=1 is invalid for RI=2 */
13957    if ((cell->numTxAntPorts == 2) && (ue->mimoInfo.txMode == RGR_UE_TM_4))
13958    {
13959       if ((ri == 2) && ( ueDl->mimoInfo.ri == 1))
13960       {
13961          ueDl->mimoInfo.pmi = (ueDl->mimoInfo.pmi < 2)? 1:2;
13962       }
13963    }
13964
13965    /* Restrict the Number of TX layers according to the UE Category */
13966    ueDl->mimoInfo.ri = RGSCH_MIN(ri, rgUeCatTbl[ueSchCmn->ueCat].maxTxLyrs);
13967 #ifdef TENB_STATS
13968    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].riCnt[ueDl->mimoInfo.ri-1]++;
13969    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
13970 #endif
13971
13972 #ifdef TENB_STATS
13973    ue->tenbStats->stats.nonPersistent.sch[0].riCnt[ueDl->mimoInfo.ri-1]++;
13974    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
13975 #endif
13976
13977 #ifdef TFU_UPGRADE
13978    if (isPer)
13979    {
13980       /* If RI is from Periodic CQI report */
13981       cqiCb->perRiVal = ueDl->mimoInfo.ri;
13982       /* Reset at every Periodic RI Reception */ 
13983       cqiCb->invalidateCqi = FALSE;
13984    }
13985    else
13986    {
13987       /* If RI is from Aperiodic CQI report */
13988       if (cqiCb->perRiVal != ueDl->mimoInfo.ri)
13989       {
13990          /* if this aperRI is different from last reported
13991           * perRI then invalidate all CQI reports till next
13992           * perRI */
13993          cqiCb->invalidateCqi = TRUE;
13994       }
13995       else
13996       {
13997          cqiCb->invalidateCqi = FALSE;
13998       }
13999    }
14000 #endif   
14001
14002    if (ueDl->mimoInfo.ri > 1)
14003    {
14004       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
14005    }
14006    else if (ue->mimoInfo.txMode == RGR_UE_TM_3) /* ri == 1 */
14007    {
14008       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
14009    }
14010
14011    return;
14012 }
14013
14014 \f
14015 /**
14016  * @brief This function performs PMI validation and
14017  *        updates it to the ueCb.
14018  *
14019  * @details
14020  *
14021  *     Function: rgSCHCmnDlSetUePmi
14022  *     Purpose:  This function performs PMI validation and
14023  *        updates it to the ueCb.
14024  *
14025  *     Invoked by: rgSCHCmnDlCqiInd
14026  *
14027  *  @param[in]  RgSchCellCb        *cell
14028  *  @param[in]  RgSchUeCb          *ue
14029  *  @param[in]  uint8_t                 pmi
14030  *  @return  Void
14031  *
14032  **/
14033 static S16 rgSCHCmnDlSetUePmi(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t pmi)
14034 {
14035    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14036
14037    if (ue->txModeTransCmplt == FALSE)
14038    {
14039        return RFAILED;
14040    }
14041  
14042    if (cell->numTxAntPorts == 2)
14043    {
14044       if (pmi > 3)
14045       {
14046          return RFAILED;
14047       }
14048       if (ueDl->mimoInfo.ri == 2)
14049       {
14050          /*ccpu00118150 - MOD - changed pmi value validation from 0 to 2*/
14051          /* PMI 2 and 3 are invalid incase of 2 TxAnt and 2 Layered SM */
14052          if (pmi == 2 || pmi == 3)
14053          {
14054             return RFAILED;
14055          }
14056          ueDl->mimoInfo.pmi = pmi+1;
14057       }
14058       else
14059       {
14060          ueDl->mimoInfo.pmi = pmi;
14061       }
14062    }
14063    else if (cell->numTxAntPorts == 4)
14064    {
14065       if (pmi > 15)
14066       {
14067          return RFAILED;
14068       }
14069       ueDl->mimoInfo.pmi = pmi;
14070    }
14071    /* Reset the No PMI Flag in forceTD */
14072    RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
14073    return ROK;
14074 }
14075
14076 /**
14077  * @brief This function Updates the DL CQI on PUCCH for the UE.
14078  *
14079  * @details
14080  *
14081  *     Function: rgSCHCmnDlProcCqiMode10
14082  *
14083  *     This function updates the DL CQI on PUCCH for the UE.
14084  *
14085  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14086  *
14087  *     Processing Steps:
14088  *
14089  *  @param[in] RgSchCellCb     *cell
14090  *  @param[in] RgSchUeCb       *ue
14091  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14092  *  @return  S16
14093  *      -# ROK
14094  *      -# RFAILED
14095  **/
14096 #ifdef RGR_CQI_REPT
14097 static inline Void rgSCHCmnDlProcCqiMode10
14098 (
14099 RgSchCellCb   *cell,
14100 RgSchUeCb     *ue,
14101 TfuDlCqiPucch *pucchCqi,
14102 Bool          *isCqiAvail
14103 )
14104 #else
14105 static inline Void rgSCHCmnDlProcCqiMode10
14106 (
14107 RgSchCellCb   *cell,
14108 RgSchUeCb     *ue,
14109 TfuDlCqiPucch *pucchCqi
14110 )
14111 #endif
14112 {
14113    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14114
14115    if (pucchCqi->u.mode10Info.type == TFU_RPT_CQI)
14116    {
14117       /*ccpu00109787 - ADD - Check for non-zero CQI*/
14118       /* Checking whether the decoded CQI is a value between 1 and 15*/
14119       if((pucchCqi->u.mode10Info.u.cqi) && (pucchCqi->u.mode10Info.u.cqi
14120                < RG_SCH_CMN_MAX_CQI))
14121       {
14122          ueDl->cqiFlag = TRUE;
14123          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode10Info.u.cqi;
14124          ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14125          /* ccpu00117452 - MOD - Changed macro name from
14126             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14127 #ifdef RGR_CQI_REPT
14128          *isCqiAvail = TRUE;
14129 #endif
14130       }
14131       else
14132       {
14133          return;
14134       }
14135    }
14136    else if (pucchCqi->u.mode10Info.type == TFU_RPT_RI)
14137    {
14138       if ( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode10Info.u.ri) )
14139       {
14140          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode10Info.u.ri,
14141                            TRUE);
14142       }
14143       else
14144       {
14145          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14146             pucchCqi->u.mode10Info.u.ri,ue->ueId);
14147          return;
14148       }
14149    }
14150 }
14151
14152 /**
14153  * @brief This function Updates the DL CQI on PUCCH for the UE.
14154  *
14155  * @details
14156  *
14157  *     Function: rgSCHCmnDlProcCqiMode11
14158  *
14159  *     This function updates the DL CQI on PUCCH for the UE.
14160  *
14161  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14162  *
14163  *     Processing Steps:
14164  *       Process CQI MODE 11
14165  *  @param[in] RgSchCellCb     *cell
14166  *  @param[in] RgSchUeCb       *ue
14167  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14168  *  @return  S16
14169  *      -# ROK
14170  *      -# RFAILED
14171  **/
14172 #ifdef RGR_CQI_REPT
14173 static inline Void rgSCHCmnDlProcCqiMode11
14174 (
14175 RgSchCellCb    *cell,
14176 RgSchUeCb      *ue,
14177 TfuDlCqiPucch  *pucchCqi,
14178 Bool           *isCqiAvail,
14179 Bool           *is2ndCwCqiAvail
14180 )
14181 #else
14182 static inline Void rgSCHCmnDlProcCqiMode11
14183 (
14184 RgSchCellCb    *cell,
14185 RgSchUeCb      *ue,
14186 TfuDlCqiPucch  *pucchCqi
14187 )
14188 #endif
14189 {
14190    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14191
14192    if (pucchCqi->u.mode11Info.type == TFU_RPT_CQI)
14193    {
14194       ue->mimoInfo.puschFdbkVld  = FALSE;
14195       /*ccpu00109787 - ADD - Check for non-zero CQI*/
14196       if((pucchCqi->u.mode11Info.u.cqi.cqi) &&
14197             (pucchCqi->u.mode11Info.u.cqi.cqi < RG_SCH_CMN_MAX_CQI))
14198       {
14199          ueDl->cqiFlag = TRUE;
14200          /* ccpu00117452 - MOD - Changed macro name from
14201             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14202 #ifdef RGR_CQI_REPT
14203          *isCqiAvail = TRUE;
14204 #endif
14205          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode11Info.u.cqi.cqi;
14206          if (pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.pres)
14207          {
14208             RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
14209                                      ueDl->mimoInfo.cwInfo[1].cqi, \
14210                                      pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.val);
14211 #ifdef RGR_CQI_REPT
14212             /* ccpu00117259 - ADD - Considering second codeword CQI info
14213                incase of MIMO for CQI Reporting */
14214             *is2ndCwCqiAvail = TRUE;
14215 #endif
14216          }
14217       }
14218       else
14219       {
14220          return;
14221       }
14222       rgSCHCmnDlSetUePmi(cell, ue, \
14223             pucchCqi->u.mode11Info.u.cqi.pmi);
14224    }
14225    else if (pucchCqi->u.mode11Info.type == TFU_RPT_RI)
14226    {
14227       if( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode11Info.u.ri))
14228       {
14229          rgSCHCmnDlSetUeRi(cell, ue,  pucchCqi->u.mode11Info.u.ri,
14230                            TRUE);
14231       }
14232       else
14233       {
14234          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14235             pucchCqi->u.mode11Info.u.ri,ue->ueId);
14236          return;
14237       }
14238    }
14239 }
14240
14241 /**
14242  * @brief This function Updates the DL CQI on PUCCH for the UE.
14243  *
14244  * @details
14245  *
14246  *     Function: rgSCHCmnDlProcCqiMode20
14247  *
14248  *     This function updates the DL CQI on PUCCH for the UE.
14249  *
14250  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14251  *
14252  *     Processing Steps:
14253  *       Process CQI MODE 20
14254  *  @param[in] RgSchCellCb     *cell
14255  *  @param[in] RgSchUeCb       *ue
14256  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14257  *  @return  S16
14258  *      -# ROK
14259  *      -# RFAILED
14260  **/
14261 #ifdef RGR_CQI_REPT
14262 static inline Void rgSCHCmnDlProcCqiMode20
14263 (
14264 RgSchCellCb   *cell,
14265 RgSchUeCb     *ue,
14266 TfuDlCqiPucch *pucchCqi,
14267 Bool          *isCqiAvail
14268 )
14269 #else
14270 static inline Void rgSCHCmnDlProcCqiMode20
14271 (
14272 RgSchCellCb   *cell,
14273 RgSchUeCb     *ue,
14274 TfuDlCqiPucch *pucchCqi
14275 )
14276 #endif
14277 {
14278    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14279
14280    if (pucchCqi->u.mode20Info.type == TFU_RPT_CQI)
14281    {
14282       if (pucchCqi->u.mode20Info.u.cqi.isWideband)
14283       {
14284          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14285          if((pucchCqi->u.mode20Info.u.cqi.u.wideCqi) &&
14286                (pucchCqi->u.mode20Info.u.cqi.u.wideCqi < RG_SCH_CMN_MAX_CQI))
14287          {
14288             ueDl->cqiFlag = TRUE;
14289             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode20Info.u.cqi.\
14290                                            u.wideCqi;
14291             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14292             /* ccpu00117452 - MOD - Changed macro name from
14293                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14294 #ifdef RGR_CQI_REPT
14295             *isCqiAvail = TRUE;
14296 #endif
14297          }
14298          else
14299          {
14300             return;
14301          }
14302       }
14303    }
14304    else if (pucchCqi->u.mode20Info.type == TFU_RPT_RI)
14305    {
14306       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode20Info.u.ri))
14307       {
14308          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode20Info.u.ri, 
14309                            TRUE);
14310       }
14311       else
14312       {
14313          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14314             pucchCqi->u.mode20Info.u.ri,ue->ueId);
14315          return;
14316       }
14317    }
14318 }
14319
14320
14321 /**
14322  * @brief This function Updates the DL CQI on PUCCH for the UE.
14323  *
14324  * @details
14325  *
14326  *     Function: rgSCHCmnDlProcCqiMode21
14327  *
14328  *     This function updates the DL CQI on PUCCH for the UE.
14329  *
14330  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
14331  *
14332  *     Processing Steps:
14333  *       Process CQI MODE 21
14334  *  @param[in] RgSchCellCb     *cell
14335  *  @param[in] RgSchUeCb       *ue
14336  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14337  *  @return  S16
14338  *      -# ROK
14339  *      -# RFAILED
14340  **/
14341 #ifdef RGR_CQI_REPT
14342 static inline Void rgSCHCmnDlProcCqiMode21
14343 (
14344 RgSchCellCb   *cell,
14345 RgSchUeCb     *ue,
14346 TfuDlCqiPucch *pucchCqi,
14347 Bool          *isCqiAvail,
14348 Bool          *is2ndCwCqiAvail
14349 )
14350 #else
14351 static inline Void rgSCHCmnDlProcCqiMode21
14352 (
14353 RgSchCellCb   *cell,
14354 RgSchUeCb     *ue,
14355 TfuDlCqiPucch *pucchCqi
14356 )
14357 #endif
14358 {
14359    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14360
14361    if (pucchCqi->u.mode21Info.type == TFU_RPT_CQI)
14362    {
14363       ue->mimoInfo.puschFdbkVld  = FALSE;
14364       if (pucchCqi->u.mode21Info.u.cqi.isWideband)
14365       {
14366          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14367          if((pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi) &&
14368                (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi < RG_SCH_CMN_MAX_CQI))
14369          {
14370             ueDl->cqiFlag = TRUE;
14371             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode21Info.u.cqi.\
14372                                            u.wideCqi.cqi;
14373             if (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.pres)
14374             {
14375                RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
14376                                      ueDl->mimoInfo.cwInfo[1].cqi, \
14377                                      pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.val);
14378 #ifdef RGR_CQI_REPT
14379                /* ccpu00117259 - ADD - Considering second codeword CQI info
14380                   incase of MIMO for CQI Reporting */
14381                *is2ndCwCqiAvail = TRUE;
14382 #endif
14383             }
14384             /* ccpu00117452 - MOD - Changed macro name from
14385                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14386 #ifdef RGR_CQI_REPT
14387             *isCqiAvail = TRUE;
14388 #endif
14389          }
14390          else
14391          {
14392             return;
14393          }
14394          rgSCHCmnDlSetUePmi(cell, ue, \
14395                pucchCqi->u.mode21Info.u.cqi.u.wideCqi.pmi);
14396       }
14397    }
14398    else if (pucchCqi->u.mode21Info.type == TFU_RPT_RI)
14399    {
14400       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode21Info.u.ri))
14401       {
14402          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode21Info.u.ri,
14403                            TRUE);
14404       }
14405       else
14406       {
14407          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14408             pucchCqi->u.mode21Info.u.ri,ue->ueId);
14409          return;
14410       }
14411    }
14412 }
14413
14414
14415 /**
14416  * @brief This function Updates the DL CQI on PUCCH for the UE.
14417  *
14418  * @details
14419  *
14420  *     Function: rgSCHCmnDlCqiOnPucchInd
14421  *
14422  *     This function updates the DL CQI on PUCCH for the UE.
14423  *
14424  *     Invoked by: rgSCHCmnDlCqiInd
14425  *
14426  *     Processing Steps:
14427  *     - Depending on the reporting mode of the PUCCH, the CQI/PMI/RI values
14428  *       are updated and stored for each UE
14429  *
14430  *  @param[in] RgSchCellCb     *cell
14431  *  @param[in] RgSchUeCb       *ue
14432  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14433  *  @return  S16
14434  *      -# ROK
14435  *      -# RFAILED
14436  **/
14437 #ifdef RGR_CQI_REPT
14438 static Void rgSCHCmnDlCqiOnPucchInd
14439 (
14440 RgSchCellCb   *cell,
14441 RgSchUeCb     *ue,
14442 TfuDlCqiPucch *pucchCqi,
14443 RgrUeCqiRept  *ueCqiRept,
14444 Bool          *isCqiAvail,
14445 Bool          *is2ndCwCqiAvail
14446 )
14447 #else
14448 static Void rgSCHCmnDlCqiOnPucchInd
14449 (
14450 RgSchCellCb   *cell,
14451 RgSchUeCb     *ue,
14452 TfuDlCqiPucch *pucchCqi
14453 )
14454 #endif
14455 {
14456    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14457
14458    /* ccpu00117452 - MOD - Changed
14459       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14460 #ifdef RGR_CQI_REPT
14461    /* Save CQI mode information in the report */
14462    ueCqiRept->cqiMode = pucchCqi->mode;
14463 #endif
14464
14465    switch(pucchCqi->mode)
14466    {
14467       case TFU_PUCCH_CQI_MODE10:
14468 #ifdef RGR_CQI_REPT
14469          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail);
14470 #else
14471          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi);
14472 #endif
14473          ueDl->cqiFlag = TRUE;
14474          break;
14475       case TFU_PUCCH_CQI_MODE11:
14476 #ifdef RGR_CQI_REPT
14477          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail,
14478                 is2ndCwCqiAvail);
14479 #else
14480          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi);
14481 #endif
14482          ueDl->cqiFlag = TRUE;
14483          break;
14484       case TFU_PUCCH_CQI_MODE20:
14485 #ifdef RGR_CQI_REPT
14486          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail);
14487 #else
14488          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi);
14489 #endif
14490          ueDl->cqiFlag = TRUE;
14491          break;
14492       case TFU_PUCCH_CQI_MODE21:
14493 #ifdef RGR_CQI_REPT
14494          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail,
14495                 is2ndCwCqiAvail);
14496 #else
14497          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi);
14498 #endif
14499          ueDl->cqiFlag = TRUE;
14500          break;
14501       default:
14502          {
14503             DU_LOG("\nERROR  -->  SCH : Unknown CQI Mode %d of UE %d",
14504                pucchCqi->mode,ue->ueId);
14505             /* ccpu00117452 - MOD - Changed macro name from
14506                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14507 #ifdef RGR_CQI_REPT
14508             *isCqiAvail = FALSE;
14509 #endif
14510          }
14511          break;
14512    }
14513
14514   return;
14515 }  /* rgSCHCmnDlCqiOnPucchInd */
14516
14517
14518 /**
14519  * @brief This function Updates the DL CQI on PUSCH for the UE.
14520  *
14521  * @details
14522  *
14523  *     Function: rgSCHCmnDlCqiOnPuschInd
14524  *
14525  *     This function updates the DL CQI on PUSCH for the UE.
14526  *
14527  *     Invoked by: rgSCHCmnDlCqiInd
14528  *
14529  *     Processing Steps:
14530  *     - Depending on the reporting mode of the PUSCH, the CQI/PMI/RI values
14531  *       are updated and stored for each UE
14532  *
14533  *  @param[in] RgSchCellCb     *cell
14534  *  @param[in] RgSchUeCb       *ue
14535  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
14536  *  @return  S16
14537  *      -# ROK
14538  *      -# RFAILED
14539  **/
14540 #ifdef RGR_CQI_REPT
14541 static Void rgSCHCmnDlCqiOnPuschInd
14542 (
14543 RgSchCellCb   *cell,
14544 RgSchUeCb     *ue,
14545 TfuDlCqiPusch *puschCqi,
14546 RgrUeCqiRept  *ueCqiRept,
14547 Bool          *isCqiAvail,
14548 Bool          *is2ndCwCqiAvail
14549 )
14550 #else
14551 static Void rgSCHCmnDlCqiOnPuschInd
14552 (
14553 RgSchCellCb   *cell,
14554 RgSchUeCb     *ue,
14555 TfuDlCqiPusch *puschCqi
14556 )
14557 #endif
14558 {
14559    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14560    uint32_t prevRiVal = 0; 
14561    if (puschCqi->ri.pres == PRSNT_NODEF)
14562    {
14563       if (RG_SCH_CMN_IS_RI_VALID(puschCqi->ri.val))
14564       {
14565          /* Saving the previous ri value to revert back
14566             in  case PMI update failed */
14567          if (RGR_UE_TM_4 == ue->mimoInfo.txMode ) /* Cheking for TM4. TM8 check later */
14568          {
14569             prevRiVal = ueDl->mimoInfo.ri;
14570          }
14571          rgSCHCmnDlSetUeRi(cell, ue, puschCqi->ri.val, FALSE);
14572       }
14573       else
14574       {
14575          DU_LOG("\nERROR  -->  SCH : Invalid RI value(%x) CRNTI:%d",
14576             puschCqi->ri.val,ue->ueId);
14577          return;
14578       }
14579    }
14580    ue->mimoInfo.puschFdbkVld  = FALSE;
14581    /* ccpu00117452 - MOD - Changed macro name from
14582       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14583 #ifdef RGR_CQI_REPT
14584    /* Save CQI mode information in the report */
14585    ueCqiRept->cqiMode = puschCqi->mode;
14586    /* ccpu00117259 - DEL - removed default setting of isCqiAvail to TRUE */
14587 #endif
14588
14589    switch(puschCqi->mode)
14590    {
14591       case TFU_PUSCH_CQI_MODE_20:
14592          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14593          /* Checking whether the decoded CQI is a value between 1 and 15*/
14594          if((puschCqi->u.mode20Info.wideBandCqi) &&
14595                (puschCqi->u.mode20Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
14596          {
14597             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode20Info.wideBandCqi;
14598             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14599             /* ccpu00117452 - MOD - Changed macro name from
14600                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14601 #ifdef RGR_CQI_REPT
14602            *isCqiAvail = TRUE;
14603 #endif
14604          }
14605          else
14606          {
14607             return;
14608          }
14609          break;
14610       case TFU_PUSCH_CQI_MODE_30:
14611          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14612          if((puschCqi->u.mode30Info.wideBandCqi) &&
14613                (puschCqi->u.mode30Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
14614          {
14615             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode30Info.wideBandCqi;
14616             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
14617             /* ccpu00117452 - MOD - Changed macro name from
14618                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14619 #ifdef RGR_CQI_REPT
14620             *isCqiAvail = TRUE;
14621 #endif
14622 #ifdef CA_DBG
14623             {
14624                uint32_t gACqiRcvdCount;
14625                gACqiRcvdCount++;
14626             
14627             }
14628 #endif
14629          }
14630          else
14631          {
14632             return;
14633          }
14634          break;
14635       case TFU_PUSCH_CQI_MODE_12:
14636          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14637          if((puschCqi->u.mode12Info.cqiIdx[0]) &&
14638                (puschCqi->u.mode12Info.cqiIdx[0] < RG_SCH_CMN_MAX_CQI))
14639          {
14640             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode12Info.cqiIdx[0];
14641             /* ccpu00117452 - MOD - Changed macro name from
14642                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14643 #ifdef RGR_CQI_REPT
14644             *isCqiAvail = TRUE;
14645 #endif
14646          }
14647          else
14648          {
14649             return;
14650          }
14651          if((puschCqi->u.mode12Info.cqiIdx[1]) &&
14652                (puschCqi->u.mode12Info.cqiIdx[1] < RG_SCH_CMN_MAX_CQI))
14653          {
14654             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode12Info.cqiIdx[1];
14655             /* ccpu00117452 - MOD - Changed macro name from
14656                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14657 #ifdef RGR_CQI_REPT
14658             /* ccpu00117259 - ADD - Considering second codeword CQI info
14659                incase of MIMO for CQI Reporting */
14660             *is2ndCwCqiAvail = TRUE;
14661 #endif
14662          }
14663          else
14664          {
14665             return;
14666          }
14667          ue->mimoInfo.puschFdbkVld  = TRUE;
14668          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_12;
14669          ue->mimoInfo.puschPmiInfo.u.mode12Info = puschCqi->u.mode12Info;
14670          /*  : resetting this is time based. Make use of CQI reporting
14671           * periodicity, DELTA's in determining the exact time at which this
14672           * need to be reset. */
14673          break;
14674       case TFU_PUSCH_CQI_MODE_22:
14675          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14676          if((puschCqi->u.mode22Info.wideBandCqi[0]) &&
14677                (puschCqi->u.mode22Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
14678          {
14679             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode22Info.wideBandCqi[0];
14680             /* ccpu00117452 - MOD - Changed macro name from
14681                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14682 #ifdef RGR_CQI_REPT
14683             *isCqiAvail = TRUE;
14684 #endif
14685          }
14686          else
14687          {
14688             return;
14689          }
14690          if((puschCqi->u.mode22Info.wideBandCqi[1]) &&
14691                (puschCqi->u.mode22Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
14692          {
14693             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode22Info.wideBandCqi[1];
14694             /* ccpu00117452 - MOD - Changed macro name from
14695                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14696 #ifdef RGR_CQI_REPT
14697             /* ccpu00117259 - ADD - Considering second codeword CQI info
14698                incase of MIMO for CQI Reporting */
14699             *is2ndCwCqiAvail = TRUE;
14700 #endif
14701          }
14702          else
14703          {
14704             return;
14705          }
14706          rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode22Info.wideBandPmi);
14707          ue->mimoInfo.puschFdbkVld  = TRUE;
14708          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_22;
14709          ue->mimoInfo.puschPmiInfo.u.mode22Info = puschCqi->u.mode22Info;
14710          break;
14711       case TFU_PUSCH_CQI_MODE_31:
14712          /*ccpu00109787 - ADD - Check for non-zero CQI*/
14713          if((puschCqi->u.mode31Info.wideBandCqi[0]) &&
14714                (puschCqi->u.mode31Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
14715          {
14716             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode31Info.wideBandCqi[0];
14717             /* ccpu00117452 - MOD - Changed macro name from
14718                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14719 #ifdef RGR_CQI_REPT
14720             *isCqiAvail = TRUE;
14721 #endif
14722          }
14723          if (ueDl->mimoInfo.ri > 1)
14724          {
14725            if((puschCqi->u.mode31Info.wideBandCqi[1]) &&
14726                (puschCqi->u.mode31Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
14727            {
14728              ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode31Info.wideBandCqi[1];
14729             /* ccpu00117452 - MOD - Changed macro name from
14730                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14731 #ifdef RGR_CQI_REPT
14732             /* ccpu00117259 - ADD - Considering second codeword CQI info
14733                incase of MIMO for CQI Reporting */
14734              *is2ndCwCqiAvail = TRUE;
14735 #endif
14736            }
14737          }
14738          if (rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode31Info.pmi) != ROK)
14739          {
14740             /* To avoid Rank and PMI inconsistency */
14741             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
14742                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
14743             {
14744                ueDl->mimoInfo.ri = prevRiVal;
14745             }
14746          }
14747          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_31;
14748          ue->mimoInfo.puschPmiInfo.u.mode31Info = puschCqi->u.mode31Info;
14749          break;
14750       default:
14751          {
14752             DU_LOG("\nERROR  -->  SCH : Unknown CQI Mode %d CRNTI:%d",
14753                puschCqi->mode,ue->ueId);
14754             /*  CQI decoding failed revert the RI to previous value */
14755             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
14756                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
14757             {
14758                ueDl->mimoInfo.ri = prevRiVal;
14759             }
14760             /* ccpu00117452 - MOD - Changed macro name from
14761                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14762 #ifdef RGR_CQI_REPT
14763            *isCqiAvail = FALSE;
14764             /* ccpu00117259 - ADD - Considering second codeword CQI info
14765                incase of MIMO for CQI Reporting */
14766             *is2ndCwCqiAvail = FALSE;
14767 #endif
14768          }
14769          break;
14770    }
14771
14772    return;
14773 }  /* rgSCHCmnDlCqiOnPuschInd */
14774
14775 \f
14776 /**
14777  * @brief This function Updates the DL CQI for the UE.
14778  *
14779  * @details
14780  *
14781  *     Function: rgSCHCmnDlCqiInd
14782  *     Purpose:  Updates the DL CQI for the UE
14783  *
14784  *     Invoked by: TOM
14785  *
14786  *  @param[in]  RgSchCellCb        *cell
14787  *  @param[in]  RgSchUeCb          *ue
14788  *  @param[in]  TfuDlCqiRpt        *dlCqi
14789  *  @return  Void
14790  *
14791  **/
14792 Void rgSCHCmnDlCqiInd
14793 (
14794 RgSchCellCb     *cell,
14795 RgSchUeCb       *ue,
14796 Bool            isPucchInfo,
14797 Void            *dlCqi,
14798 CmLteTimingInfo timingInfo
14799 )
14800 {
14801    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
14802 /* ccpu00117452 - MOD - Changed macro name from
14803    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14804 #ifdef RGR_CQI_REPT
14805    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
14806    RgrUeCqiRept   ueCqiRept = {{0}};
14807    Bool           isCqiAvail = FALSE;
14808    /* ccpu00117259 - ADD - Considering second codeword CQI info
14809       incase of MIMO for CQI Reporting */
14810    Bool           is2ndCwCqiAvail = FALSE;
14811 #endif
14812
14813
14814 #ifdef RGR_CQI_REPT
14815    if (isPucchInfo)
14816    {
14817       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail);
14818    }
14819    else
14820    {
14821       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi, &ueCqiRept,  &isCqiAvail, &is2ndCwCqiAvail);
14822    }
14823 #else
14824    if (isPucchInfo)
14825    {
14826       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi);
14827    }
14828    else
14829    {
14830       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi);
14831    }
14832 #endif
14833
14834 #ifdef CQI_CONFBITMASK_DROP
14835    if(!ue->cqiConfBitMask)
14836    {
14837       if (ueDl->mimoInfo.cwInfo[0].cqi >15)
14838       {
14839          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
14840          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
14841       }
14842       else if ( ueDl->mimoInfo.cwInfo[0].cqi >= ue->prevCqi)
14843       {
14844          ue->prevCqi = ueDl->mimoInfo.cwInfo[0].cqi;
14845       }
14846       else
14847       {
14848          uint8_t dlCqiDeltaPrev = 0;
14849          dlCqiDeltaPrev = ue->prevCqi - ueDl->mimoInfo.cwInfo[0].cqi;
14850          if (dlCqiDeltaPrev > 3)
14851             dlCqiDeltaPrev = 3;
14852          if ((ue->prevCqi - dlCqiDeltaPrev) < 6)
14853          {
14854             ue->prevCqi = 6;
14855          }
14856          else 
14857          {
14858             ue->prevCqi = ue->prevCqi - dlCqiDeltaPrev;
14859          }
14860          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
14861          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
14862
14863       }
14864    }
14865 #endif
14866
14867 /* ccpu00117452 - MOD - Changed macro name from
14868    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
14869 #ifdef RGR_CQI_REPT
14870    /* ccpu00117259 - ADD - Considering second codeword CQI info
14871       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail\
14872       in 'if' condition*/
14873    if (RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(ue) && (isCqiAvail || is2ndCwCqiAvail))
14874    {
14875       ueCqiRept.cqi[0] = ueDl->mimoInfo.cwInfo[0].cqi;
14876
14877    /* ccpu00117259 - ADD - Considering second codeword CQI info
14878       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail
14879       in 'if' condition*/
14880       ueCqiRept.cqi[1] = 0;
14881       if(is2ndCwCqiAvail)
14882       {
14883          ueCqiRept.cqi[1] = ueDl->mimoInfo.cwInfo[1].cqi;
14884       }
14885       rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, &ueCqiRept);
14886
14887    }
14888 #endif
14889 #ifdef DL_LA
14890    rgSCHCmnDlSetUeAllocLmtLa(cell, ue);
14891    rgSCHCheckAndSetTxScheme(cell, ue);
14892 #else
14893 #ifdef EMTC_ENABLE   
14894    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), ue->isEmtcUe);
14895 #else 
14896    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), FALSE);
14897 #endif   
14898 #endif
14899
14900    if (cellSch->dl.isDlFreqSel)
14901    {
14902       cellSch->apisDlfs->rgSCHDlfsDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo);
14903    }
14904 #ifdef LTEMAC_SPS
14905    /* Call SPS module to update CQI indication */
14906    rgSCHCmnSpsDlCqiIndHndlr(cell, ue, timingInfo);
14907 #endif
14908    /* Call Specific scheduler to process on dlCqiInd */
14909 #ifdef EMTC_ENABLE
14910    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
14911    {
14912       cellSch->apisEmtcDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
14913    }
14914    else
14915 #endif
14916    {
14917       cellSch->apisDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
14918    }
14919
14920 #ifdef RG_PFS_STATS
14921    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].avgCqi += 
14922       ueDl->mimoInfo.cwInfo[0].cqi;
14923    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].totalCqiOcc++; 
14924 #endif
14925
14926 #ifdef SCH_STATS
14927    ueDl->avgCqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14928    ueDl->numCqiOccns++;
14929    if (ueDl->mimoInfo.ri == 1)
14930    {
14931       ueDl->numRi1++;
14932    }
14933    else
14934    {
14935       ueDl->numRi2++;
14936    }
14937 #endif
14938
14939 #ifdef TENB_STATS
14940    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14941    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
14942    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw0Cqi ++;
14943    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw1Cqi ++;
14944    cell->tenbStats->sch.dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
14945    cell->tenbStats->sch.dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
14946    cell->tenbStats->sch.dlNumCw0Cqi ++;
14947    cell->tenbStats->sch.dlNumCw1Cqi ++;
14948 #endif
14949    return;
14950 }
14951
14952 #ifdef TFU_UPGRADE
14953 /**
14954  * @brief This function calculates the wideband CQI from SNR
14955  *            reported for each RB.
14956  *
14957  * @details
14958  *
14959  *     Function: rgSCHCmnCalcWcqiFrmSnr
14960  *     Purpose:  Wideband CQI calculation from SNR
14961  *
14962  *     Invoked by: RG SCH
14963  *
14964  *  @param[in]  RgSchCellCb        *cell
14965  *  @param[in]  TfuSrsRpt        *srsRpt,
14966  *  @return  Wideband CQI
14967  *
14968  **/
14969 static uint8_t rgSCHCmnCalcWcqiFrmSnr(RgSchCellCb *cell, TfuSrsRpt *srsRpt)
14970 {
14971    uint8_t wideCqi=1; /*Calculated value from SNR*/
14972    /*Need to map a certain SNR with a WideCQI value.
14973     * The CQI calculation is still primitive. Further, need to
14974     * use a improvized method for calculating WideCQI from SNR*/
14975        if (srsRpt->snr[0] <=50)
14976        {
14977            wideCqi=3;
14978        }
14979        else if (srsRpt->snr[0]>=51 && srsRpt->snr[0] <=100)
14980        {
14981            wideCqi=6;
14982        }
14983        else if (srsRpt->snr[0]>=101 && srsRpt->snr[0] <=150)
14984        {
14985            wideCqi=9;
14986        }
14987        else if (srsRpt->snr[0]>=151 && srsRpt->snr[0] <=200)
14988        {
14989            wideCqi=12;
14990        }
14991        else if (srsRpt->snr[0]>=201 && srsRpt->snr[0] <=250)
14992        {
14993            wideCqi=14;
14994        }
14995        else
14996        {
14997            wideCqi=15;
14998        }
14999    return (wideCqi);
15000 }/*rgSCHCmnCalcWcqiFrmSnr*/
15001
15002
15003 /**
15004  * @brief This function Updates the SRS for the UE.
15005  *
15006  * @details
15007  *
15008  *     Function: rgSCHCmnSrsInd
15009  *     Purpose:  Updates the UL SRS for the UE
15010  *
15011  *     Invoked by: TOM
15012  *
15013  *  @param[in]  RgSchCellCb        *cell
15014  *  @param[in]  RgSchUeCb          *ue
15015  *  @param[in]  TfuSrsRpt        *srsRpt,
15016  *  @return  Void
15017  *
15018  **/
15019 Void rgSCHCmnSrsInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuSrsRpt  *srsRpt,CmLteTimingInfo  timingInfo)
15020 {
15021     uint8_t wideCqi; /*Calculated value from SNR*/
15022     uint32_t recReqTime; /*Received Time in TTI*/
15023
15024     recReqTime = (timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + timingInfo.slot;
15025     ue->srsCb.selectedAnt = (recReqTime/ue->srsCb.peri)%2;
15026     if(srsRpt->wideCqiPres)
15027     {
15028         wideCqi = srsRpt->wideCqi;
15029     }
15030     else
15031     {
15032         wideCqi = rgSCHCmnCalcWcqiFrmSnr(cell, srsRpt);
15033     }
15034     rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi);
15035     return;
15036 }/*rgSCHCmnSrsInd*/
15037 #endif
15038
15039 \f
15040 /**
15041  * @brief This function is a handler for TA report for an UE.
15042  *
15043  * @details
15044  *
15045  *     Function: rgSCHCmnDlTARpt
15046  *     Purpose:  Determine based on UE_IDLE_TIME threshold,
15047  *     whether UE needs to be Linked to the scheduler's TA list OR
15048  *     if it needs a PDCCH Order.
15049  *
15050  *
15051  *     Invoked by: TOM
15052  *
15053  *  @param[in]  RgSchCellCb        *cell
15054  *  @param[in]  RgSchUeCb          *ue
15055  *  @return  Void
15056  *
15057  **/
15058 Void rgSCHCmnDlTARpt(RgSchCellCb *cell,RgSchUeCb *ue)
15059 {
15060    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
15061    RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
15062    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15063    CmLListCp       poInactvLst;
15064
15065
15066    /* RACHO: If UE idle time is more than threshold, then
15067     * set its poInactv pdcch order inactivity  */
15068    /* Fix : syed Ignore if TaTmr is not configured */
15069    if ((ue->dl.taCb.cfgTaTmr) && (rgSCHCmnUeIdleExdThrsld(cell, ue) == ROK))
15070    {
15071       uint32_t prevDlMsk = ue->dl.dlInactvMask;
15072       uint32_t prevUlMsk = ue->ul.ulInactvMask;
15073       ue->dl.dlInactvMask |= RG_PDCCHODR_INACTIVE;
15074       ue->ul.ulInactvMask |= RG_PDCCHODR_INACTIVE;
15075       /* Indicate Specific scheduler for this UEs inactivity */
15076       cmLListInit(&poInactvLst);
15077       cmLListAdd2Tail(&poInactvLst, &ueDl->rachInfo.inActUeLnk);
15078       ueDl->rachInfo.inActUeLnk.node = (PTR)ue;
15079       /* Send inactivate ind only if not already sent */
15080       if (prevDlMsk == 0)
15081       {
15082          cellSch->apisDl->rgSCHDlInactvtUes(cell, &poInactvLst);
15083       }
15084       if (prevUlMsk == 0)
15085       {
15086          cellSch->apisUl->rgSCHUlInactvtUes(cell, &poInactvLst);
15087       }
15088    }
15089    else
15090    {
15091       /* Fix: ccpu00124009 Fix for loop in the linked list "cellDl->taLst" */
15092       if (!ue->dlTaLnk.node)
15093       {
15094 #ifdef EMTC_ENABLE
15095          if(cell->emtcEnable)
15096          {
15097             if(ue->isEmtcUe)
15098             {
15099                rgSCHEmtcAddToTaLst(cellDl,ue);
15100             }
15101          }
15102          else
15103 #endif
15104          {
15105
15106             cmLListAdd2Tail(&cellDl->taLst, &ue->dlTaLnk);
15107             ue->dlTaLnk.node = (PTR)ue;
15108          }
15109       }
15110       else
15111       {
15112          DU_LOG("\nERROR  -->  SCH : <TA>TA duplicate entry attempt failed: UEID:%u", 
15113                ue->ueId);
15114       }
15115    }
15116    return;
15117 }
15118
15119 #ifdef TFU_UPGRADE
15120 /**
15121  * @brief Indication of UL CQI.
15122  *
15123  * @details
15124  *
15125  *     Function : rgSCHCmnFindUlCqiUlTxAnt
15126  *
15127  *     - Finds the Best Tx Antenna amongst the CQIs received
15128  *         from Two Tx Antennas.
15129  *
15130  *  @param[in]  RgSchCellCb         *cell
15131  *  @param[in]  RgSchUeCb           *ue
15132  *  @param[in]   uint8_t                 wideCqi
15133  *  @return  Void
15134  **/
15135 static Void rgSCHCmnFindUlCqiUlTxAnt(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t wideCqi)
15136 {
15137    ue->validTxAnt = 1;
15138    return;
15139 }  /* rgSCHCmnFindUlCqiUlTxAnt */
15140 #endif
15141
15142 /**
15143  * @brief Indication of UL CQI.
15144  *
15145  * @details
15146  *
15147  *     Function : rgSCHCmnUlCqiInd
15148  *
15149  *     - Updates uplink CQI information for the UE. Computes and
15150  *       stores the lowest CQI of CQIs reported in all subbands.
15151  *
15152  *  @param[in]  RgSchCellCb         *cell
15153  *  @param[in]  RgSchUeCb           *ue
15154  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
15155  *  @return  Void
15156  **/
15157 Void rgSCHCmnUlCqiInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuUlCqiRpt *ulCqiInfo)
15158 {
15159    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15160    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
15161 #ifdef UL_LA
15162    uint8_t       iTbsNew;
15163    S32           previTbs;
15164 #endif
15165 #if (defined(SCH_STATS) || defined(TENB_STATS))
15166      CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
15167 #endif   
15168                   
15169    /*  consider inputs from SRS handlers about SRS occassions
15170     * in determining the UL TX Antenna selection */
15171    ueUl->crntUlCqi[0] = ulCqiInfo->wideCqi;
15172 #ifdef TFU_UPGRADE
15173    ueUl->validUlCqi = ueUl->crntUlCqi[0];
15174    ue->validTxAnt = 0;
15175 #ifdef UL_LA
15176    iTbsNew  =  rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][ueUl->validUlCqi];
15177    previTbs =  (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
15178
15179    if (RG_ITBS_DIFF(iTbsNew, previTbs) > 5)
15180    {
15181       /* Ignore this iTBS report and mark that last iTBS report was */
15182       /* ignored so that subsequently we reset the LA algorithm     */
15183       ueUl->ulLaCb.lastiTbsIgnored = TRUE;
15184    }
15185    else
15186    {
15187       if (ueUl->ulLaCb.lastiTbsIgnored != TRUE)
15188       {
15189          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
15190                                        (80 * ueUl->ulLaCb.cqiBasediTbs))/100;
15191       }
15192       else
15193       {
15194          /* Reset the LA as iTbs in use caught up with the value   */
15195          /* reported by UE.                                        */
15196          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
15197                                         (80 * previTbs * 100))/100;
15198          ueUl->ulLaCb.deltaiTbs = 0;
15199          ueUl->ulLaCb.lastiTbsIgnored = FALSE;
15200       }
15201    }
15202 #endif 
15203 #endif
15204    rgSCHPwrUlCqiInd(cell, ue);
15205 #ifdef LTEMAC_SPS
15206    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
15207    {
15208       rgSCHCmnSpsUlCqiInd(cell, ue);
15209    }
15210 #endif
15211    /* Applicable to only some schedulers */
15212 #ifdef EMTC_ENABLE
15213    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
15214    {
15215       cellSch->apisEmtcUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
15216    }
15217    else
15218 #endif
15219    {
15220       cellSch->apisUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
15221    }
15222
15223 #ifdef SCH_STATS
15224    ueUl->numCqiOccns++;
15225    ueUl->avgCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15226 #endif
15227
15228 #ifdef TENB_STATS
15229    {
15230       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15231       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNumCqi ++;
15232       cell->tenbStats->sch.ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
15233       cell->tenbStats->sch.ulNumCqi ++;
15234    }
15235 #endif
15236
15237    return;
15238 }  /* rgSCHCmnUlCqiInd */
15239
15240 /**
15241  * @brief Returns HARQ proc for which data expected now.
15242  *
15243  * @details
15244  *
15245  *     Function: rgSCHCmnUlHqProcForUe
15246  *     Purpose:  This function returns the harq process for
15247  *               which data is expected in the current subframe.
15248  *               It does not validate that the HARQ process
15249  *               has an allocation.
15250  *
15251  *     Invoked by: TOM
15252  *
15253  *  @param[in]  RgSchCellCb        *cell
15254  *  @param[in]  CmLteTimingInfo    frm
15255  *  @param[in]  RgSchUeCb          *ue
15256  *  @param[out] RgSchUlHqProcCb    **procRef
15257  *  @return  Void
15258  **/
15259 Void rgSCHCmnUlHqProcForUe
15260 (
15261 RgSchCellCb     *cell,
15262 CmLteTimingInfo frm,
15263 RgSchUeCb       *ue,
15264 RgSchUlHqProcCb **procRef
15265 )
15266 {
15267 #ifndef RG_5GTF
15268    uint8_t procId = rgSCHCmnGetUlHqProcIdx(&frm, cell);
15269 #endif
15270 #ifndef RG_5GTF
15271    *procRef = rgSCHUhmGetUlHqProc(cell, ue, procId);
15272 #else
15273    *procRef = rgSCHUhmGetUlProcByTime(cell, ue, frm);
15274 #endif
15275    return;
15276 }
15277
15278 #ifdef RG_UNUSED
15279 /**
15280  * @brief Update harq process for allocation.
15281  *
15282  * @details
15283  *
15284  *     Function : rgSCHCmnUpdUlHqProc
15285  *
15286  *     This function is invoked when harq process
15287  *     control block is now in a new memory location
15288  *     thus requiring a pointer/reference update.
15289  *
15290  *  @param[in] RgSchCellCb      *cell
15291  *  @param[in] RgSchUlHqProcCb  *curProc
15292  *  @param[in] RgSchUlHqProcCb  *oldProc
15293  *  @return  S16
15294  *      -# ROK
15295  *      -# RFAILED
15296  **/
15297 S16 rgSCHCmnUpdUlHqProc
15298 (
15299 RgSchCellCb      *cell,
15300 RgSchUlHqProcCb  *curProc,
15301 RgSchUlHqProcCb  *oldProc
15302 )
15303 {
15304
15305    UNUSED(cell);
15306    UNUSED(oldProc);
15307 #if (ERRCLASS & ERRCLS_DEBUG)
15308    if (curProc->alloc == NULLP)
15309    {
15310       return RFAILED;
15311    }
15312 #endif
15313    curProc->alloc->hqProc = curProc;
15314    return ROK;
15315 }  /* rgSCHCmnUpdUlHqProc */
15316 #endif
15317
15318 /*MS_WORKAROUND for CR FIXME */
15319 /**
15320  * @brief Hsndles BSR timer expiry
15321  *
15322  * @details
15323  *
15324  *     Function : rgSCHCmnBsrTmrExpry
15325  *
15326  *     This function is invoked when periodic BSR timer expires for a UE.
15327  *
15328  *  @param[in] RgSchUeCb        *ue
15329  *  @return  S16
15330  *      -# ROK
15331  *      -# RFAILED
15332  **/
15333 S16 rgSCHCmnBsrTmrExpry(RgSchUeCb  *ueCb)
15334 {
15335    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ueCb->cell);
15336
15337
15338    ueCb->isSrGrant = TRUE;
15339
15340 #ifdef EMTC_ENABLE
15341    emtcStatsUlBsrTmrTxp++;
15342 #endif
15343
15344 #ifdef EMTC_ENABLE
15345    if(ueCb->cell->emtcEnable)
15346    {
15347       if(ueCb->isEmtcUe)
15348       {
15349          cellSch->apisEmtcUl->rgSCHSrRcvd(ueCb->cell, ueCb);
15350          return ROK;
15351       }
15352    }
15353    else
15354 #endif
15355    {
15356       cellSch->apisUl->rgSCHSrRcvd(ueCb->cell, ueCb);
15357    }
15358
15359    return  (ROK);
15360 }
15361
15362 /**
15363  * @brief Short BSR update.
15364  *
15365  * @details
15366  *
15367  *     Function : rgSCHCmnUpdBsrShort
15368  *
15369  *     This functions does requisite updates to handle short BSR reporting.
15370  *
15371  *  @param[in]  RgSchCellCb  *cell
15372  *  @param[in]  RgSchUeCb    *ue
15373  *  @param[in]  RgSchLcgCb *ulLcg
15374  *  @param[in]  uint8_t           bsr
15375  *  @param[out] RgSchErrInfo *err
15376  *  @return  S16
15377  *      -# ROK
15378  *      -# RFAILED
15379  **/
15380 S16 rgSCHCmnUpdBsrShort
15381 (
15382 RgSchCellCb  *cell,
15383 RgSchUeCb    *ue,
15384 RgSchLcgCb   *ulLcg,
15385 uint8_t      bsr,
15386 RgSchErrInfo *err
15387 )
15388 {
15389    uint8_t  lcgCnt;
15390 #ifdef LTE_L2_MEAS
15391    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15392 #endif
15393    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15394    RgSchCmnLcg  *cmnLcg  = NULLP;
15395
15396 #ifdef LTE_L2_MEAS
15397    uint8_t             idx;
15398 #endif
15399
15400    if (!RGSCH_LCG_ISCFGD(ulLcg))
15401    {
15402       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
15403       return RFAILED;
15404    }
15405    for (lcgCnt=0; lcgCnt<4; lcgCnt++)
15406    {
15407 #ifdef LTE_L2_MEAS
15408       /* Set BS of all other LCGs to Zero.
15409          If Zero BSR is reported in Short BSR include this LCG too */
15410       if ((lcgCnt != ulLcg->lcgId) ||
15411             (!bsr && !ueUl->hqEnt.numBusyHqProcs))
15412       {
15413          /* If old BO is zero do nothing */
15414          if(((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs != 0)
15415          {
15416             for(idx = 0; idx < ue->ul.lcgArr[lcgCnt].numLch; idx++)
15417             {
15418                if((ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount) &&
15419                  (ue->ulActiveLCs & (1 << 
15420                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1))))
15421                {
15422           /* L2_COUNTER */
15423                  ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount--;
15424                  ue->ulActiveLCs &= ~(1 << 
15425                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1));
15426                }
15427             }
15428          }
15429       }
15430 #endif
15431       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgCnt]))
15432       {
15433          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs = 0;
15434          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->reportedBs = 0;
15435       }
15436    }
15437
15438 #ifdef LTE_L2_MEAS
15439    if(ulLcg->lcgId && bsr && (((RgSchCmnLcg *)(ulLcg->sch))->bs == 0))
15440    {
15441       for(idx = 0; idx < ulLcg->numLch; idx++)
15442       {
15443           /* L2_COUNTER */
15444           if (!(ue->ulActiveLCs & (1 << (ulLcg->lcArray[idx]->qciCb->qci -1))))
15445           {
15446              ulLcg->lcArray[idx]->qciCb->ulUeCount++;
15447              ue->ulActiveLCs |= (1 << (ulLcg->lcArray[idx]->qciCb->qci -1));
15448           }
15449       }
15450    }
15451 #endif
15452    /* Resetting the nonGbrLcgBs info here */
15453    ue->ul.nonGbrLcgBs = 0;
15454    ue->ul.nonLcg0Bs = 0;
15455
15456    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
15457    
15458    if (TRUE == ue->ul.useExtBSRSizes)
15459    {
15460       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
15461    }
15462    else
15463    {
15464       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
15465    }
15466    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15467    {
15468       /* TBD check for effGbr != 0 */    
15469       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15470    }
15471    else if (0 == ulLcg->lcgId) 
15472    {
15473       /* This is added for handling LCG0 */
15474       cmnLcg->bs = cmnLcg->reportedBs;
15475    }
15476    else 
15477    {
15478       /* Update non GBR LCG's BS*/
15479       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
15480       cmnLcg->bs     = ue->ul.nonGbrLcgBs;
15481    }
15482    ue->ul.totalBsr = cmnLcg->bs;
15483
15484 #ifdef RGR_V1
15485    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (bsr == 0))
15486    {
15487       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
15488    }
15489 #endif
15490 #ifdef LTEMAC_SPS
15491    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
15492    {
15493       rgSCHCmnSpsBsrRpt(cell, ue, ulLcg);
15494    }
15495 #endif
15496    rgSCHCmnUpdUlCompEffBsr(ue);
15497
15498 #ifdef EMTC_ENABLE
15499    if(cell->emtcEnable)
15500    {
15501       if(ue->isEmtcUe)
15502       {
15503          cellSch->apisEmtcUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
15504          return ROK;
15505       }
15506    }
15507    else
15508 #endif
15509    {
15510    cellSch->apisUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
15511    }
15512
15513 #ifdef LTE_ADV
15514    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15515    {
15516       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
15517       {
15518 #ifndef PAL_ENABLE_UL_CA
15519          if((ue->cellInfo[sCellIdx] != NULLP) &&
15520                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
15521 #else
15522          if(ue->cellInfo[sCellIdx] != NULLP)
15523 #endif
15524          {
15525             cellSch->apisUl->rgSCHUpdBsrShort(ue->cellInfo[sCellIdx]->cell, 
15526                   ue, ulLcg, bsr);
15527          }
15528       }
15529    }
15530 #endif 
15531
15532    return ROK;
15533 }
15534
15535 /**
15536  * @brief Truncated BSR update.
15537  *
15538  * @details
15539  *
15540  *     Function : rgSCHCmnUpdBsrTrunc
15541  *
15542  *     This functions does required updates to handle truncated BSR report.
15543  *
15544  *
15545  *  @param[in]  RgSchCellCb  *cell
15546  *  @param[in]  RgSchUeCb    *ue
15547  *  @param[in]  RgSchLcgCb *ulLcg
15548  *  @param[in]  uint8_t           bsr
15549  *  @param[out] RgSchErrInfo *err
15550  *  @return  S16
15551  *      -# ROK
15552  *      -# RFAILED
15553  **/
15554 S16 rgSCHCmnUpdBsrTrunc
15555 (
15556 RgSchCellCb  *cell,
15557 RgSchUeCb    *ue,
15558 RgSchLcgCb   *ulLcg,
15559 uint8_t      bsr,
15560 RgSchErrInfo *err
15561 )
15562 {
15563    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15564    RgSchCmnLcg  *cmnLcg = NULLP;
15565    S32          cnt;
15566 #ifdef LTE_L2_MEAS
15567    uint8_t     idx;
15568 #endif
15569
15570
15571    if (!RGSCH_LCG_ISCFGD(ulLcg))
15572    {
15573       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
15574       return RFAILED;
15575    }
15576    /* set all higher prio lcgs bs to 0 and update this lcgs bs and
15577       total bsr= sumofall lcgs bs */
15578    if (ulLcg->lcgId)
15579    {
15580       for (cnt = ulLcg->lcgId-1; cnt >= 0; cnt--)
15581       {
15582 #ifdef LTE_L2_MEAS
15583          /* If Existing BO is zero the don't do anything */
15584          if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs != 0)
15585          {
15586             for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
15587             {
15588                /* L2_COUNTERS */
15589                if((ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount) &&
15590                      (ue->ulActiveLCs & (1 << 
15591                                          (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
15592                {
15593                   ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount--;
15594                   ue->ulActiveLCs &= ~(1 << 
15595                         (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
15596                }
15597             }
15598          }
15599 #endif
15600          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs = 0;
15601          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->reportedBs = 0;
15602       }
15603    }
15604
15605 #ifdef LTE_L2_MEAS
15606    for (cnt = ulLcg->lcgId; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
15607    {
15608       if (ulLcg->lcgId == 0)
15609       {
15610          continue;
15611       }
15612       /* If Existing BO is zero the don't do anything */
15613       if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs == 0)
15614       {
15615          for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
15616          {
15617             /* L2_COUNTERS */
15618             if (!(ue->ulActiveLCs & (1 << 
15619                (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
15620             {
15621                ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount++;
15622                ue->ulActiveLCs |= (1 << 
15623                      (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
15624             }
15625          }
15626       }
15627    }
15628 #endif
15629    ue->ul.nonGbrLcgBs = 0;
15630    ue->ul.nonLcg0Bs = 0;
15631    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
15632    if (TRUE == ue->ul.useExtBSRSizes)
15633    {
15634       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
15635    }
15636    else
15637    {
15638       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
15639    }
15640    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15641    {
15642       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15643    }
15644    else if(ulLcg->lcgId == 0)
15645    {
15646       /* This is for handeling LCG0 */
15647       cmnLcg->bs = cmnLcg->reportedBs;
15648    }
15649    else
15650    {
15651       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
15652       cmnLcg->bs = ue->ul.nonGbrLcgBs;
15653    }
15654    ue->ul.totalBsr = cmnLcg->bs;
15655
15656    for (cnt = ulLcg->lcgId+1; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
15657    {
15658       /* TODO: The bs for the other LCGs may be stale because some or all of
15659        * the part of bs may have been already scheduled/data received. Please 
15660        * consider this when truncated BSR is tested/implemented */
15661       ue->ul.totalBsr += ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs;
15662    }
15663
15664    rgSCHCmnUpdUlCompEffBsr(ue);
15665
15666 #ifdef EMTC_ENABLE
15667    if(cell->emtcEnable)
15668    {
15669       if(ue->isEmtcUe)
15670       {
15671          cellSch->apisEmtcUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
15672          return ROK;
15673       }
15674    }
15675    else
15676 #endif
15677    {
15678       cellSch->apisUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
15679    }
15680
15681 #ifdef LTE_ADV
15682    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15683    {
15684       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
15685       {
15686 #ifndef PAL_ENABLE_UL_CA
15687          if((ue->cellInfo[sCellIdx] != NULLP) &&
15688                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
15689 #else
15690          if(ue->cellInfo[sCellIdx] != NULLP)
15691 #endif
15692          {
15693             cellSch->apisUl->rgSCHUpdBsrTrunc(ue->cellInfo[sCellIdx]->cell, ue, ulLcg, bsr);
15694          }
15695       }
15696    }
15697 #endif 
15698
15699    return ROK;
15700 }
15701
15702 /**
15703  * @brief Long BSR update.
15704  *
15705  * @details
15706  *
15707  *     Function : rgSCHCmnUpdBsrLong
15708  *
15709  *     - Update BSRs for all configured LCGs.
15710  *     - Update priority of LCGs if needed.
15711  *     - Update UE's position within/across uplink scheduling queues.
15712  *
15713  *
15714  *  @param[in]  RgSchCellCb  *cell
15715  *  @param[in]  RgSchUeCb    *ue
15716  *  @param[in]  uint8_t bsArr[]
15717  *  @param[out] RgSchErrInfo *err
15718  *  @return  S16
15719  *      -# ROK
15720  *      -# RFAILED
15721  **/
15722 S16 rgSCHCmnUpdBsrLong
15723 (
15724 RgSchCellCb  *cell,
15725 RgSchUeCb    *ue,
15726 uint8_t      *bsArr,
15727 RgSchErrInfo *err
15728 )
15729 {
15730    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15731    uint32_t     tmpBsArr[4] = {0, 0, 0, 0};
15732    uint32_t     nonGbrBs = 0;
15733 #ifdef LTE_L2_MEAS
15734    uint8_t      idx1;
15735    uint8_t      idx2;
15736 #endif
15737    uint32_t     lcgId;
15738
15739 #ifdef LTE_L2_MEAS
15740    for(idx1 = 1; idx1 < RGSCH_MAX_LCG_PER_UE; idx1++)
15741    {
15742      /* If Old BO is non zero then do nothing */
15743      if ((((RgSchCmnLcg *)(ue->ul.lcgArr[idx1].sch))->bs == 0)
15744         && bsArr[idx1] )
15745      {
15746        for(idx2 = 0; idx2 < ue->ul.lcgArr[idx1].numLch; idx2++)
15747        {
15748           /* L2_COUNTERS */
15749           if (!(ue->ulActiveLCs & (1 << 
15750              (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1))))
15751           {
15752              ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->ulUeCount++;
15753              ue->ulActiveLCs |= (1 << 
15754                (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1));
15755           }
15756        }
15757      }
15758    }
15759 #endif
15760    ue->ul.nonGbrLcgBs = 0;
15761    ue->ul.nonLcg0Bs = 0;
15762
15763    if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[0]))
15764    {
15765       if (TRUE == ue->ul.useExtBSRSizes)
15766       {
15767          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnExtBsrTbl[bsArr[0]];
15768          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnExtBsrTbl[bsArr[0]];
15769          tmpBsArr[0] = rgSchCmnExtBsrTbl[bsArr[0]];
15770       }
15771       else
15772       {
15773          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnBsrTbl[bsArr[0]];
15774          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnBsrTbl[bsArr[0]];
15775          tmpBsArr[0] = rgSchCmnBsrTbl[bsArr[0]];
15776       }
15777    }
15778    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
15779    {
15780       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
15781       {
15782          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
15783
15784          if (TRUE == ue->ul.useExtBSRSizes)
15785          {
15786             cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsArr[lcgId]];
15787          }
15788          else
15789          {
15790             cmnLcg->reportedBs = rgSchCmnBsrTbl[bsArr[lcgId]];
15791          }
15792          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
15793          {
15794             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
15795             tmpBsArr[lcgId] = cmnLcg->bs;
15796          }
15797          else
15798          {
15799             nonGbrBs += cmnLcg->reportedBs;
15800             tmpBsArr[lcgId] = cmnLcg->reportedBs;
15801             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
15802          }
15803       }
15804    }
15805    ue->ul.nonGbrLcgBs = RGSCH_MIN(nonGbrBs,ue->ul.effAmbr);
15806
15807    ue->ul.totalBsr = tmpBsArr[0] + tmpBsArr[1] + tmpBsArr[2] + tmpBsArr[3];
15808 #ifdef RGR_V1
15809    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (ue->ul.totalBsr == 0))
15810    {
15811       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
15812    }
15813 #endif
15814
15815 #ifdef LTEMAC_SPS
15816    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) /* SPS_FIX */
15817    {
15818      if(ue->ul.totalBsr - tmpBsArr[1] == 0)
15819      {/* Updaing the BSR to SPS only if LCG1 BS is present in sps active state */
15820         rgSCHCmnSpsBsrRpt(cell, ue, &ue->ul.lcgArr[1]);
15821      }
15822    }
15823 #endif
15824    rgSCHCmnUpdUlCompEffBsr(ue);
15825
15826 #ifdef EMTC_ENABLE
15827    if(cell->emtcEnable)
15828    {
15829       if(ue->isEmtcUe)
15830       {
15831          cellSch->apisEmtcUl->rgSCHUpdBsrLong(cell, ue, bsArr);
15832          return ROK;
15833       }
15834    }
15835    else
15836 #endif
15837    {
15838    cellSch->apisUl->rgSCHUpdBsrLong(cell, ue, bsArr);
15839    }
15840
15841 #ifdef LTE_ADV
15842    if (ue->ul.isUlCaEnabled  && ue->numSCells)
15843    {
15844       for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
15845       {
15846 #ifndef PAL_ENABLE_UL_CA
15847          if((ue->cellInfo[idx] != NULLP) &&
15848                (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE))
15849 #else
15850          if(ue->cellInfo[idx] != NULLP)
15851 #endif
15852          {
15853             cellSch->apisUl->rgSCHUpdBsrLong(ue->cellInfo[idx]->cell, ue, bsArr);
15854          }
15855       }
15856    }
15857 #endif 
15858
15859    return ROK;
15860 }
15861
15862 /**
15863  * @brief PHR update.
15864  *
15865  * @details
15866  *
15867  *     Function : rgSCHCmnUpdExtPhr
15868  *
15869  *     Updates extended power headroom information for an UE.
15870  *
15871  *  @param[in]  RgSchCellCb  *cell
15872  *  @param[in]  RgSchUeCb    *ue
15873  *  @param[in]  uint8_t           phr
15874  *  @param[out] RgSchErrInfo *err
15875  *  @return  S16
15876  *      -# ROK
15877  *      -# RFAILED
15878  **/
15879 S16 rgSCHCmnUpdExtPhr
15880 (
15881 RgSchCellCb    *cell,
15882 RgSchUeCb      *ue,
15883 RgInfExtPhrCEInfo *extPhr,
15884 RgSchErrInfo   *err
15885 )
15886 {
15887    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15888    RgSchCmnAllocRecord *allRcd;
15889    CmLList             *node = ueUl->ulAllocLst.last;
15890
15891 #ifdef LTEMAC_SPS
15892    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
15893 #endif
15894
15895    UNUSED(err);
15896
15897    while (node)
15898    {
15899       allRcd = (RgSchCmnAllocRecord *)node->node;
15900       node = node->prev;
15901       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
15902       {
15903          rgSCHPwrUpdExtPhr(cell, ue, extPhr, allRcd);
15904          break;
15905       }
15906    }
15907 #ifdef LTEMAC_SPS
15908    if(ulSpsUe->isUlSpsActv)
15909    {
15910       rgSCHCmnSpsPhrInd(cell,ue);
15911    }
15912 #endif
15913
15914    return ROK;
15915 }  /* rgSCHCmnUpdExtPhr */
15916
15917
15918
15919
15920 /**
15921  * @brief PHR update.
15922  *
15923  * @details
15924  *
15925  *     Function : rgSCHCmnUpdPhr
15926  *
15927  *     Updates power headroom information for an UE.
15928  *
15929  *  @param[in]  RgSchCellCb  *cell
15930  *  @param[in]  RgSchUeCb    *ue
15931  *  @param[in]  uint8_t           phr
15932  *  @param[out] RgSchErrInfo *err
15933  *  @return  S16
15934  *      -# ROK
15935  *      -# RFAILED
15936  **/
15937 S16 rgSCHCmnUpdPhr
15938 (
15939 RgSchCellCb    *cell,
15940 RgSchUeCb      *ue,
15941 uint8_t        phr,
15942 RgSchErrInfo   *err
15943 )
15944 {
15945    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
15946    RgSchCmnAllocRecord *allRcd;
15947    CmLList             *node = ueUl->ulAllocLst.last;
15948
15949 #ifdef LTEMAC_SPS
15950    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
15951 #endif
15952
15953    UNUSED(err);
15954
15955    while (node)
15956    {
15957       allRcd = (RgSchCmnAllocRecord *)node->node;
15958       node = node->prev;
15959       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
15960       {
15961          rgSCHPwrUpdPhr(cell, ue, phr, allRcd, RG_SCH_CMN_PWR_USE_CFG_MAX_PWR);
15962          break;
15963       }
15964    }
15965 #ifdef LTEMAC_SPS
15966    if(ulSpsUe->isUlSpsActv)
15967    {
15968       rgSCHCmnSpsPhrInd(cell,ue);
15969    }
15970 #endif
15971
15972    return ROK;
15973 }  /* rgSCHCmnUpdPhr */
15974
15975 /**
15976  * @brief UL grant for contention resolution.
15977  *
15978  * @details
15979  *
15980  *     Function : rgSCHCmnContResUlGrant
15981  *
15982  *     Add UE to another queue specifically for CRNTI based contention
15983  *     resolution.
15984  *
15985  *
15986  *  @param[in]  RgSchUeCb    *ue
15987  *  @param[out] RgSchErrInfo *err
15988  *  @return  S16
15989  *      -# ROK
15990  *      -# RFAILED
15991  **/
15992 S16 rgSCHCmnContResUlGrant
15993 (
15994 RgSchCellCb  *cell,
15995 RgSchUeCb    *ue,
15996 RgSchErrInfo *err
15997 )
15998 {
15999    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
16000
16001    #ifdef EMTC_ENABLE
16002    if(cell->emtcEnable)
16003    {
16004       if(ue->isEmtcUe)
16005       {
16006          cellSch->apisEmtcUl->rgSCHContResUlGrant(cell, ue);
16007          return ROK;
16008       }
16009    }
16010    else
16011 #endif
16012    {
16013       cellSch->apisUl->rgSCHContResUlGrant(cell, ue);
16014    }
16015    return ROK;
16016 }
16017
16018 /**
16019  * @brief SR reception handling.
16020  *
16021  * @details
16022  *
16023  *     Function : rgSCHCmnSrRcvd
16024  *
16025  *     - Update UE's position within/across uplink scheduling queues
16026  *     - Update priority of LCGs if needed.
16027  *
16028  *  @param[in]  RgSchCellCb  *cell
16029  *  @param[in]  RgSchUeCb    *ue
16030  *  @param[in]  CmLteTimingInfo frm
16031  *  @param[out] RgSchErrInfo *err
16032  *  @return  S16
16033  *      -# ROK
16034  *      -# RFAILED
16035  **/
16036 S16 rgSCHCmnSrRcvd
16037 (
16038 RgSchCellCb  *cell,
16039 RgSchUeCb    *ue,
16040 CmLteTimingInfo frm,
16041 RgSchErrInfo *err
16042 )
16043 {
16044    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
16045    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
16046    CmLList      *node    = ueUl->ulAllocLst.last;
16047
16048
16049 #ifdef EMTC_ENABLE
16050    emtcStatsUlTomSrInd++;
16051 #endif
16052
16053    RGSCH_INCR_SUB_FRAME(frm, 1); /* 1 TTI after the time SR was sent */
16054    while (node)
16055    {
16056       RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)node->node;
16057       if (RGSCH_TIMEINFO_SAME(frm, allRcd->allocTime))
16058       {
16059          break;
16060       }
16061       node = node->prev;
16062    }
16063    //TODO_SID Need to check when it is getting triggered
16064    ue->isSrGrant = TRUE;
16065 #ifdef EMTC_ENABLE
16066    if(cell->emtcEnable)
16067    {
16068       if(ue->isEmtcUe)
16069       {
16070          cellSch->apisEmtcUl->rgSCHSrRcvd(cell, ue);
16071          return ROK;
16072       }
16073    }
16074    else
16075 #endif
16076    {
16077       cellSch->apisUl->rgSCHSrRcvd(cell, ue);
16078    }
16079    return ROK;
16080 }
16081
16082 /**
16083  * @brief Returns first uplink allocation to send reception
16084  *        request to PHY.
16085  *
16086  * @details
16087  *
16088  *     Function: rgSCHCmnFirstRcptnReq(cell)
16089  *     Purpose:  This function returns the first uplink allocation
16090  *               (or NULLP if there is none) in the subframe
16091  *               in which is expected to prepare and send reception
16092  *               request to PHY.
16093  *
16094  *     Invoked by: TOM
16095  *
16096  *  @param[in]  RgSchCellCb      *cell
16097  *  @return  RgSchUlAlloc*
16098  **/
16099 RgSchUlAlloc *rgSCHCmnFirstRcptnReq(RgSchCellCb *cell)
16100 {
16101    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16102 /* ACC_TDD */
16103    RgSchUlAlloc* alloc = NULLP;
16104
16105
16106    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
16107    {
16108            RgSchUlSf* sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16109            alloc = rgSCHUtlUlAllocFirst(sf);
16110
16111            if (alloc && alloc->hqProc == NULLP)
16112            {
16113                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16114            }
16115    }
16116
16117    return (alloc);
16118 }
16119
16120 /**
16121  * @brief Returns first uplink allocation to send reception
16122  *        request to PHY.
16123  *
16124  * @details
16125  *
16126  *     Function: rgSCHCmnNextRcptnReq(cell)
16127  *     Purpose:  This function returns the next uplink allocation
16128  *               (or NULLP if there is none) in the subframe
16129  *               in which is expected to prepare and send reception
16130  *               request to PHY.
16131  *
16132  *     Invoked by: TOM
16133  *
16134  *  @param[in]  RgSchCellCb      *cell
16135  *  @return  RgSchUlAlloc*
16136  **/
16137 RgSchUlAlloc *rgSCHCmnNextRcptnReq(RgSchCellCb *cell,RgSchUlAlloc *alloc)
16138 {
16139    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16140 /* ACC-TDD */
16141    //RgSchUlSf      *sf   = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16142
16143 /* ACC-TDD */
16144    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
16145    {
16146            RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
16147
16148            alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16149            if (alloc && alloc->hqProc == NULLP)
16150            {
16151                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16152            }
16153    }
16154    else
16155    {
16156            alloc = NULLP;
16157    }
16158
16159    return (alloc);
16160 }
16161 /**
16162  * @brief Collates DRX enabled UE's scheduled in this SF
16163  *
16164  * @details
16165  *
16166  *     Function: rgSCHCmnDrxStrtInActvTmrInUl(cell)
16167  *     Purpose:  This function collates the link
16168  *               of UE's scheduled in this SF who
16169  *               have drx enabled. It then calls
16170  *               DRX specific function to start/restart
16171  *               inactivity timer in Ul
16172  *
16173  *     Invoked by: TOM
16174  *
16175  *  @param[in]  RgSchCellCb      *cell
16176  *  @return Void
16177  **/
16178 Void rgSCHCmnDrxStrtInActvTmrInUl(RgSchCellCb *cell)
16179 {
16180    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16181    RgSchUlSf      *sf     = &(cellUl->ulSfArr[cellUl->schdIdx]);
16182    RgSchUlAlloc   *alloc  = rgSCHUtlUlAllocFirst(sf);
16183    CmLListCp       ulUeLst;
16184    RgSchUeCb       *ueCb;
16185
16186
16187    cmLListInit(&ulUeLst);
16188
16189    while(alloc)
16190    {
16191       ueCb = alloc->ue;
16192
16193       if (ueCb)
16194       {
16195          if (!(alloc->grnt.isRtx) && ueCb->isDrxEnabled && !(ueCb->isSrGrant)
16196 #ifdef LTEMAC_SPS
16197              /* ccpu00139513- DRX inactivity timer should not be started for 
16198               * UL SPS occasions */
16199              && (alloc->hqProc->isSpsOccnHqP == FALSE) 
16200 #endif
16201              )
16202          {
16203             cmLListAdd2Tail(&ulUeLst,&(ueCb->ulDrxInactvTmrLnk));
16204             ueCb->ulDrxInactvTmrLnk.node = (PTR)ueCb;
16205          }
16206       }
16207
16208       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16209    }/*while(alloc)*/
16210
16211    (Void)rgSCHDrxStrtInActvTmr(cell,&ulUeLst,RG_SCH_DRX_UL);
16212
16213    return;
16214 }
16215
16216
16217 /**
16218  * @brief Returns first uplink allocation to send HARQ feedback
16219  *        request to PHY.
16220  *
16221  * @details
16222  *
16223  *     Function: rgSCHCmnFirstHqFdbkAlloc
16224  *     Purpose:  This function returns the first uplink allocation
16225  *               (or NULLP if there is none) in the subframe
16226  *               for which it is expected to prepare and send HARQ
16227  *               feedback to PHY.
16228  *
16229  *     Invoked by: TOM
16230  *
16231  *  @param[in]  RgSchCellCb      *cell
16232  *  @param[in]  uint8_t               idx
16233  *  @return  RgSchUlAlloc*
16234  **/
16235 RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc(RgSchCellCb  *cell,uint8_t idx)
16236 {
16237    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16238 /* ACC-TDD */
16239    RgSchUlAlloc  *alloc = NULLP;
16240
16241
16242    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
16243    {
16244           RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
16245           alloc    = rgSCHUtlUlAllocFirst(sf);
16246
16247           while (alloc && (alloc->hqProc == NULLP))
16248           {
16249                   alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16250           }
16251    }
16252
16253    return (alloc);
16254 }
16255
16256 /**
16257  * @brief Returns next allocation to send HARQ feedback for.
16258  *
16259  * @details
16260  *
16261  *     Function: rgSCHCmnNextHqFdbkAlloc(cell)
16262  *     Purpose:  This function returns the next uplink allocation
16263  *               (or NULLP if there is none) in the subframe
16264  *               for which HARQ feedback needs to be sent.
16265  *
16266  *     Invoked by: TOM
16267  *
16268  *  @param[in]  RgSchCellCb      *cell
16269  *  @return  RgSchUlAlloc*
16270  **/
16271 RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc(RgSchCellCb *cell,RgSchUlAlloc *alloc,uint8_t idx)
16272 {
16273    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16274
16275    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
16276    {
16277       RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
16278
16279       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16280       while (alloc && (alloc->hqProc == NULLP))
16281       {
16282          alloc = rgSCHUtlUlAllocNxt(sf, alloc);
16283       }
16284    }
16285    else
16286    {
16287           alloc = NULLP;
16288    }
16289    return (alloc);
16290 }
16291
16292 /***********************************************************
16293  *
16294  *     Func : rgSCHCmnUlGetITbsFrmIMcs
16295  *
16296  *     Desc : Returns the Itbs that is mapped to an Imcs
16297  *            for the case of uplink.
16298  *
16299  *     Ret  :
16300  *
16301  *     Notes:
16302  *
16303  *     File :
16304  *
16305  **********************************************************/
16306 uint8_t rgSCHCmnUlGetITbsFrmIMcs(uint8_t iMcs)
16307 {
16308    return (rgUlIMcsTbl[iMcs].iTbs);
16309 }
16310
16311 /***********************************************************
16312  *
16313  *     Func : rgSCHCmnUlGetIMcsFrmITbs
16314  *
16315  *     Desc : Returns the Imcs that is mapped to an Itbs
16316  *            for the case of uplink.
16317  *
16318  *     Ret  :
16319  *
16320  *     Notes: For iTbs 19, iMcs is dependant on modulation order.
16321  *            Refer to 36.213, Table 8.6.1-1 and 36.306 Table 4.1-2
16322  *            for UE capability information
16323  *
16324  *     File :
16325  *
16326  **********************************************************/
16327 uint8_t rgSCHCmnUlGetIMcsFrmITbs(uint8_t iTbs,CmLteUeCategory ueCtg)
16328 {
16329    uint8_t iMcs;
16330
16331    if (iTbs <= 10)
16332    {
16333       iMcs = iTbs;
16334    }
16335    /*a higher layer can force a 64QAM UE to transmit at 16QAM.
16336     * We currently do not support this. Once the support for such
16337     * is added, ueCtg should be replaced by current transmit
16338     * modulation configuration.Refer to 36.213 -8.6.1
16339     */
16340    else if ( iTbs < 19 )
16341    {
16342       iMcs = iTbs + 1;
16343    }
16344    else if ((iTbs == 19) && (ueCtg != CM_LTE_UE_CAT_5))
16345    {
16346       iMcs = iTbs + 1;
16347    }
16348    else
16349    {
16350       iMcs = iTbs + 2;
16351    }
16352
16353 #ifdef LTE_TDD
16354    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
16355       was seen when IMCS exceeds 20  on T2k TDD*/
16356    if (iMcs > 20)
16357    {
16358       iMcs = 20;
16359    }
16360 #endif
16361
16362    return (iMcs);
16363 }
16364
16365 /***********************************************************
16366  *
16367  *     Func : rgSCHCmnUlMinTbBitsForITbs
16368  *
16369  *     Desc : Returns the minimum number of bits that can
16370  *            be given as grant for a specific CQI.
16371  *
16372  *     Ret  :
16373  *
16374  *     Notes:
16375  *
16376  *     File :
16377  *
16378  **********************************************************/
16379 uint32_t rgSCHCmnUlMinTbBitsForITbs(RgSchCmnUlCell *cellUl,uint8_t  iTbs)
16380 {
16381
16382    RGSCH_ARRAY_BOUND_CHECK(0, rgTbSzTbl[0], iTbs); 
16383
16384    return (rgTbSzTbl[0][iTbs][cellUl->sbSize-1]);
16385 }
16386
16387 /***********************************************************
16388  *
16389  *     Func : rgSCHCmnUlSbAlloc
16390  *
16391  *     Desc : Given a required 'number of subbands' and a hole,
16392  *            returns a suitable alloc such that the subband
16393  *            allocation size is valid
16394  *
16395  *     Ret  :
16396  *
16397  *     Notes: Does not assume either passed numSb or hole size
16398  *            to be valid for allocation, and hence arrives at
16399  *            an acceptable value.
16400  *     File :
16401  *
16402  **********************************************************/
16403 RgSchUlAlloc *rgSCHCmnUlSbAlloc
16404 (
16405 RgSchUlSf    *sf,
16406 uint8_t      numSb,
16407 RgSchUlHole  *hole
16408 )
16409 {
16410    uint8_t      holeSz; /* valid hole size */
16411    RgSchUlAlloc *alloc;
16412
16413    if ((holeSz = rgSchCmnMult235Tbl[hole->num].prvMatch) == hole->num)
16414    {
16415       numSb = rgSchCmnMult235Tbl[numSb].match;
16416       if (numSb >= holeSz)
16417       {
16418          alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
16419       }
16420       else
16421       {
16422          alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
16423       }
16424    }
16425    else
16426    {
16427       if (numSb < holeSz)
16428       {
16429          numSb = rgSchCmnMult235Tbl[numSb].match;
16430       }
16431       else
16432       {
16433          numSb = rgSchCmnMult235Tbl[numSb].prvMatch;
16434       }
16435
16436       if ( numSb >= holeSz )
16437       {
16438          numSb = holeSz;
16439       }
16440       alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
16441    }
16442    return (alloc);
16443 }
16444
16445 /**
16446  * @brief To fill the RgSchCmnUeUlAlloc structure of UeCb.
16447  *
16448  * @details
16449  *
16450  *     Function: rgSCHCmnUlUeFillAllocInfo
16451  *     Purpose:  Specific scheduler to call this API to fill the alloc
16452  *               information.
16453  *
16454  *     Invoked by: Scheduler
16455  *
16456  *  @param[in]  RgSchCellCb      *cell
16457  *  @param[out] RgSchUeCb        *ue
16458  *  @return   Void
16459  **/
16460 Void rgSCHCmnUlUeFillAllocInfo(RgSchCellCb *cell,RgSchUeCb *ue)
16461 {
16462    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16463    RgSchCmnUeUlAlloc  *ulAllocInfo;
16464    RgSchCmnUlUe       *ueUl;
16465
16466
16467    ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16468    ulAllocInfo = &ueUl->alloc;
16469
16470    /* Fill alloc structure */
16471    rgSCHCmnUlAllocFillTpc(cell, ue, ulAllocInfo->alloc);
16472    rgSCHCmnUlAllocFillNdmrs(cellUl, ulAllocInfo->alloc);
16473    rgSCHCmnUlAllocLnkHqProc(ue, ulAllocInfo->alloc, ulAllocInfo->alloc->hqProc,
16474                      ulAllocInfo->alloc->hqProc->isRetx);
16475    /* Fill PDCCH */
16476    rgSCHCmnUlFillPdcchWithAlloc(ulAllocInfo->alloc->pdcch,
16477          ulAllocInfo->alloc, ue);
16478    /* Recording information about this allocation */
16479    rgSCHCmnUlRecordUeAlloc(cell, ue);
16480
16481    /* Update the UE's outstanding allocation */
16482    if (!ulAllocInfo->alloc->hqProc->isRetx)
16483    {
16484       rgSCHCmnUlUpdOutStndAlloc(cell, ue, ulAllocInfo->allocdBytes);
16485    }
16486
16487    return;
16488 }
16489
16490 /**
16491  * @brief Update the UEs outstanding alloc based on the BSR report's timing.
16492  *
16493  *
16494  * @details
16495  *
16496  *     Function: rgSCHCmnUpdUlCompEffBsr
16497  *     Purpose:  Clear off all the allocations from outstanding allocation that
16498  *     are later than or equal to BSR timing information (stored in UEs datIndTime).
16499  *
16500  *     Invoked by: Scheduler
16501  *
16502  *  @param[in]  RgSchUeCb *ue
16503  *  @return  Void
16504  **/
16505 static Void rgSCHCmnUpdUlCompEffBsr(RgSchUeCb *ue)
16506 {
16507    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,ue->cell);
16508    CmLList   *node = ueUl->ulAllocLst.last;
16509    RgSchCmnAllocRecord *allRcd;
16510    uint32_t outStndAlloc=0;
16511    uint32_t nonLcg0OutStndAllocBs=0;
16512    uint32_t nonLcg0Bsr=0;
16513    uint8_t  lcgId;
16514    RgSchCmnLcg *cmnLcg = NULLP;
16515
16516    while (node)
16517    {
16518       allRcd = (RgSchCmnAllocRecord *)node->node;
16519       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
16520       {
16521          node = node->next;
16522          break;
16523       }
16524       node = node->prev;
16525    }
16526    while (node)
16527    {
16528       allRcd = (RgSchCmnAllocRecord *)node->node;
16529       node = node->next;
16530       outStndAlloc += allRcd->alloc;
16531    }
16532  
16533    cmnLcg = (RgSchCmnLcg *)(ue->ul.lcgArr[0].sch);
16534    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
16535    if (cmnLcg->bs > outStndAlloc)
16536    {
16537       cmnLcg->bs -= outStndAlloc;
16538       ue->ul.minReqBytes = cmnLcg->bs;
16539       outStndAlloc = 0;
16540    }
16541    else
16542    {
16543       nonLcg0OutStndAllocBs = outStndAlloc - cmnLcg->bs;
16544       cmnLcg->bs = 0;
16545    }
16546
16547    for(lcgId = 1;lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
16548    {
16549       if(RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
16550       {
16551          cmnLcg = ((RgSchCmnLcg *) (ue->ul.lcgArr[lcgId].sch));
16552          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
16553          {
16554             nonLcg0Bsr += cmnLcg->bs;
16555          }
16556       }
16557    }
16558    nonLcg0Bsr += ue->ul.nonGbrLcgBs;  
16559    if (nonLcg0OutStndAllocBs > nonLcg0Bsr)
16560    {
16561       nonLcg0Bsr = 0;
16562    }
16563    else
16564    {
16565       nonLcg0Bsr -= nonLcg0OutStndAllocBs;
16566    }
16567    ue->ul.nonLcg0Bs = nonLcg0Bsr;
16568    /* Cap effBsr with nonLcg0Bsr and append lcg0 bs.
16569     * nonLcg0Bsr limit applies only to lcg1,2,3 */
16570    /* better be handled in individual scheduler */
16571    ue->ul.effBsr = nonLcg0Bsr +\
16572                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16573    return;
16574 }
16575
16576 /**
16577  * @brief  Records information about the current allocation.
16578  *
16579  * @details
16580  *
16581  *     Function: rgSCHCmnUlRecordUeAlloc
16582  *     Purpose:  Records information about the curent allocation.
16583  *               This includes the allocated bytes, as well
16584  *               as some power information.
16585  *
16586  *     Invoked by: Scheduler
16587  *
16588  *  @param[in]  RgSchCellCb *cell
16589  *  @param[in]  RgSchUeCb   *ue
16590  *  @return  Void
16591  **/
16592 Void rgSCHCmnUlRecordUeAlloc(RgSchCellCb *cell,RgSchUeCb   *ue)
16593 {
16594 #ifdef LTE_TDD
16595    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
16596 #endif
16597    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16598    CmLListCp           *lst = &ueUl->ulAllocLst;
16599    CmLList             *node = ueUl->ulAllocLst.first;
16600    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
16601    RgSchCmnUeUlAlloc  *ulAllocInfo = &ueUl->alloc;
16602    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
16603
16604    cmLListDelFrm(lst, &allRcd->lnk);
16605 #ifndef LTE_TDD
16606    /* To the crntTime, add the MIN time at which UE will
16607     * actually send the BSR i.e DELTA+4 */
16608    allRcd->allocTime = cell->crntTime;
16609    /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
16610 #ifdef EMTC_ENABLE
16611    if(ue->isEmtcUe == TRUE)
16612    {
16613       RGSCH_INCR_SUB_FRAME_EMTC(allRcd->allocTime,
16614                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
16615    }
16616    else
16617 #endif
16618    {
16619       RGSCH_INCR_SUB_FRAME(allRcd->allocTime,
16620                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
16621    }
16622 #else
16623    allRcd->allocTime = cellUl->schdTime;
16624 #endif
16625    cmLListAdd2Tail(lst, &allRcd->lnk);
16626
16627    /* Filling in the parameters to be recorded */
16628    allRcd->alloc = ulAllocInfo->allocdBytes;
16629    //allRcd->numRb = ulAllocInfo->alloc->grnt.numRb;
16630    allRcd->numRb = (ulAllocInfo->alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
16631    /*Recording the UL CQI derived from the maxUlCqi */
16632    allRcd->cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
16633    allRcd->tpc   = ulAllocInfo->alloc->grnt.tpc;
16634
16635    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
16636
16637    cell->measurements.ulBytesCnt += ulAllocInfo->allocdBytes;
16638
16639    return;
16640 }
16641
16642 /** PHR handling for MSG3
16643  * @brief  Records allocation information of msg3 in the the UE.
16644  *
16645  * @details
16646  *
16647  *     Function: rgSCHCmnUlRecMsg3Alloc
16648  *     Purpose:  Records information about msg3 allocation.
16649  *               This includes the allocated bytes, as well
16650  *               as some power information.
16651  *
16652  *     Invoked by: Scheduler
16653  *
16654  *  @param[in]  RgSchCellCb *cell
16655  *  @param[in]  RgSchUeCb   *ue
16656  *  @param[in]  RgSchRaCb   *raCb
16657  *  @return  Void
16658  **/
16659 Void rgSCHCmnUlRecMsg3Alloc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchRaCb *raCb)
16660 {
16661    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
16662    CmLListCp           *lst = &ueUl->ulAllocLst;
16663    CmLList             *node = ueUl->ulAllocLst.first;
16664    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
16665
16666    /* Stack Crash problem for TRACE5 changes */
16667
16668    cmLListDelFrm(lst, node);
16669    allRcd->allocTime = raCb->msg3AllocTime;
16670    cmLListAdd2Tail(lst, node);
16671
16672    /* Filling in the parameters to be recorded */
16673    allRcd->alloc = raCb->msg3Grnt.datSz;
16674    allRcd->numRb = raCb->msg3Grnt.numRb;
16675    allRcd->cqi   = raCb->ccchCqi;
16676    allRcd->tpc   = raCb->msg3Grnt.tpc;
16677
16678    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
16679
16680    return;
16681 }
16682 /**
16683  * @brief Keeps track of the most recent RG_SCH_CMN_MAX_ALLOC_TRACK
16684  * allocations to track. Adds this allocation to the ueUl's ulAllocLst.
16685  *
16686  *
16687  * @details
16688  *
16689  *     Function: rgSCHCmnUlUpdOutStndAlloc
16690  *     Purpose:  Recent Allocation shall be at First Pos'n.
16691  *               Remove the last node, update the fields
16692  *                with the new allocation and add at front.
16693  *
16694  *     Invoked by: Scheduler
16695  *
16696  *  @param[in]  RgSchCellCb *cell
16697  *  @param[in]  RgSchUeCb   *ue
16698  *  @param[in]  uint32_t alloc
16699  *  @return  Void
16700  **/
16701 Void rgSCHCmnUlUpdOutStndAlloc(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t alloc)
16702 {
16703    uint32_t  nonLcg0Alloc=0;
16704
16705    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
16706    if (((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs > alloc)
16707    {
16708       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs -= alloc;
16709    }
16710    else
16711    {
16712       nonLcg0Alloc = alloc - ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16713       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = 0;
16714    }
16715
16716    if (nonLcg0Alloc >= ue->ul.nonLcg0Bs)
16717    {
16718       ue->ul.nonLcg0Bs  = 0;
16719    }
16720    else
16721    {
16722       ue->ul.nonLcg0Bs  -= nonLcg0Alloc;
16723    }
16724    /* Cap effBsr with effAmbr and append lcg0 bs.
16725     * effAmbr limit applies only to lcg1,2,3 non GBR LCG's*/
16726    /* better be handled in individual scheduler */
16727    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
16728                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
16729 #ifdef RGR_V1
16730    if (ue->ul.effBsr == 0)
16731    {
16732       if (ue->bsrTmr.tmrEvnt != TMR_NONE)
16733       {
16734          rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
16735       }
16736       /* ccpu00133008 */
16737       if (FALSE == ue->isSrGrant)
16738       {
16739          if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
16740          {
16741             /*
16742             rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR,
16743                   ue->ul.bsrTmrCfg.prdBsrTmr);
16744             */
16745          }
16746       }
16747    }
16748 #endif
16749    /* Resetting UEs lower Cap */
16750    ue->ul.minReqBytes = 0;
16751
16752    return;
16753 }
16754
16755
16756 /**
16757  * @brief Returns the "Itbs" for a given UE.
16758  *
16759  * @details
16760  *
16761  *     Function: rgSCHCmnUlGetITbs
16762  *     Purpose:  This function returns the "Itbs" for a given UE.
16763  *
16764  *     Invoked by: Scheduler
16765  *
16766  *  @param[in]  RgSchUeCb        *ue
16767  *  @return     uint8_t
16768  **/
16769 uint8_t rgSCHCmnUlGetITbs
16770 (
16771 RgSchCellCb *cell,
16772 RgSchUeCb   *ue,
16773 Bool        isEcp
16774 )
16775 {
16776    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
16777    /* CQI will be capped to maxUlCqi for 16qam UEs */
16778    CmLteUeCategory  ueCtgy = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
16779    uint8_t          cqi;
16780 #ifdef UL_LA
16781    S32            iTbs;
16782    uint8_t        maxiTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ueUl->maxUlCqi]; 
16783 #endif
16784
16785
16786    /* #ifdef RG_SCH_CMN_EXT_CP_SUP For ECP pick index 1 */
16787 #ifdef TFU_UPGRADE
16788    if ( (ueCtgy != CM_LTE_UE_CAT_5) &&
16789         (ueUl->validUlCqi > ueUl->maxUlCqi)
16790       )
16791    {
16792       cqi = ueUl->maxUlCqi;
16793    }
16794    else
16795    {
16796       cqi = ueUl->validUlCqi;
16797    }
16798
16799 #ifdef UL_LA
16800    iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
16801
16802    RG_SCH_CHK_ITBS_RANGE(iTbs, maxiTbs); 
16803
16804    iTbs = RGSCH_MIN(iTbs,  ue->cell->thresholds.maxUlItbs);
16805
16806 #ifdef LTE_TDD
16807    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
16808       was seen when IMCS exceeds 20 on T2k TDD */
16809    if (iTbs > 19)
16810    {
16811       iTbs = 19;
16812    }
16813 #endif
16814    return (iTbs);
16815 #endif 
16816 #else
16817    if ( (ueCtgy != CM_LTE_UE_CAT_5) && (ueUl->crntUlCqi[0] > ueUl->maxUlCqi ))
16818    {
16819       cqi = ueUl->maxUlCqi;
16820    }
16821    else
16822    {
16823       cqi = ueUl->crntUlCqi[0];
16824    }
16825 #endif
16826    return (rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][cqi]);
16827 }
16828
16829 /**
16830  * @brief This function adds the UE to DLRbAllocInfo TX lst.
16831  *
16832  * @details
16833  *
16834  *     Function: rgSCHCmnDlRbInfoAddUeTx
16835  *     Purpose:  This function adds the UE to DLRbAllocInfo TX lst.
16836  *
16837  *     Invoked by: Common Scheduler
16838  *
16839  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16840  *  @param[in]  RgSchUeCb             *ue
16841  *  @param[in]  RgSchDlHqProcCb       *hqP
16842  *  @return  Void
16843  *
16844  **/
16845 static Void rgSCHCmnDlRbInfoAddUeTx
16846 (
16847 RgSchCellCb        *cell,
16848 RgSchCmnDlRbAllocInfo *allocInfo,
16849 RgSchUeCb             *ue,
16850 RgSchDlHqProcCb       *hqP
16851 )
16852 {
16853    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
16854
16855
16856    if (hqP->reqLnk.node == NULLP)
16857    {
16858       if (cellSch->dl.isDlFreqSel)
16859       {
16860          cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16861            &allocInfo->dedAlloc.txHqPLst, hqP);
16862       }
16863       else
16864       {
16865          {
16866             cmLListAdd2Tail(&allocInfo->dedAlloc.txHqPLst, &hqP->reqLnk);
16867          }
16868          hqP->reqLnk.node = (PTR)hqP;
16869       }
16870    }
16871    return;
16872 }
16873
16874 /**
16875  * @brief This function adds the UE to DLRbAllocInfo RETX lst.
16876  *
16877  * @details
16878  *
16879  *     Function: rgSCHCmnDlRbInfoAddUeRetx
16880  *     Purpose:  This function adds the UE to DLRbAllocInfo RETX lst.
16881  *
16882  *     Invoked by: Common Scheduler
16883  *
16884  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16885  *  @param[in]  RgSchUeCb             *ue
16886  *  @param[in]  RgSchDlHqProcCb       *hqP
16887  *  @return  Void
16888  *
16889  **/
16890 static Void rgSCHCmnDlRbInfoAddUeRetx
16891 (
16892 RgSchCellCb        *cell,
16893 RgSchCmnDlRbAllocInfo *allocInfo,
16894 RgSchUeCb             *ue,
16895 RgSchDlHqProcCb       *hqP
16896 )
16897 {
16898    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
16899
16900
16901    if (cellSch->dl.isDlFreqSel)
16902    {
16903       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16904         &allocInfo->dedAlloc.retxHqPLst, hqP);
16905    }
16906    else
16907    {
16908       /* checking UE's presence in this lst is unnecessary */
16909       cmLListAdd2Tail(&allocInfo->dedAlloc.retxHqPLst, &hqP->reqLnk);
16910       hqP->reqLnk.node = (PTR)hqP;
16911    }
16912    return;
16913 }
16914
16915 /**
16916  * @brief This function adds the UE to DLRbAllocInfo TX-RETX lst.
16917  *
16918  * @details
16919  *
16920  *     Function: rgSCHCmnDlRbInfoAddUeRetxTx
16921  *     Purpose:  This adds the UE to DLRbAllocInfo TX-RETX lst.
16922  *
16923  *     Invoked by: Common Scheduler
16924  *
16925  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16926  *  @param[in]  RgSchUeCb             *ue
16927  *  @param[in]  RgSchDlHqProcCb       *hqP
16928  *  @return  Void
16929  *
16930  **/
16931 static Void rgSCHCmnDlRbInfoAddUeRetxTx
16932 (
16933 RgSchCellCb        *cell,
16934 RgSchCmnDlRbAllocInfo *allocInfo,
16935 RgSchUeCb             *ue,
16936 RgSchDlHqProcCb       *hqP
16937 )
16938 {
16939    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
16940
16941
16942    if (cellSch->dl.isDlFreqSel)
16943    {
16944       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
16945         &allocInfo->dedAlloc.txRetxHqPLst, hqP);
16946    }
16947    else
16948    {
16949       cmLListAdd2Tail(&allocInfo->dedAlloc.txRetxHqPLst, &hqP->reqLnk);
16950       hqP->reqLnk.node = (PTR)hqP;
16951    }
16952    return;
16953 }
16954
16955 /**
16956  * @brief This function adds the UE to DLRbAllocInfo NonSchdRetxLst.
16957  *
16958  * @details
16959  *
16960  *     Function: rgSCHCmnDlAdd2NonSchdRetxLst 
16961  *     Purpose:  During RB estimation for RETX, if allocation fails
16962  *               then appending it to NonSchdRetxLst, the further
16963  *               action is taken as part of Finalization in
16964  *               respective schedulers.
16965  *
16966  *     Invoked by: Common Scheduler
16967  *
16968  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
16969  *  @param[in]  RgSchUeCb             *ue
16970  *  @param[in]  RgSchDlHqProcCb       *hqP
16971  *  @return  Void
16972  *
16973  **/
16974 static Void rgSCHCmnDlAdd2NonSchdRetxLst 
16975 (
16976 RgSchCmnDlRbAllocInfo *allocInfo,
16977 RgSchUeCb             *ue,
16978 RgSchDlHqProcCb       *hqP
16979 )
16980 {
16981    CmLList         *schdLnkNode;
16982
16983
16984 #ifdef LTEMAC_SPS
16985    if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && 
16986          (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)))
16987    {
16988       return;
16989    }
16990 #endif
16991
16992    schdLnkNode = &hqP->schdLstLnk;
16993    RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
16994    cmLListAdd2Tail(&allocInfo->dedAlloc.nonSchdRetxHqPLst, schdLnkNode);
16995
16996    return;
16997 }
16998
16999
17000
17001 /**
17002  * @brief This function adds the UE to DLRbAllocInfo NonSchdTxRetxLst.
17003  *
17004  * @details
17005  *
17006  *     Function: rgSCHCmnDlAdd2NonSchdTxRetxLst 
17007  *     Purpose:  During RB estimation for TXRETX, if allocation fails
17008  *               then appending it to NonSchdTxRetxLst, the further
17009  *               action is taken as part of Finalization in
17010  *               respective schedulers.
17011  *
17012  *     Invoked by: Common Scheduler
17013  *
17014  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
17015  *  @param[in]  RgSchUeCb             *ue
17016  *  @param[in]  RgSchDlHqProcCb       *hqP
17017  *  @return  Void
17018  *
17019  **/
17020 #ifdef LTE_TDD
17021 /**
17022  * @brief This function handles the initialisation of DL HARQ/ACK feedback
17023  *        timing information for eaach DL subframe.
17024  *
17025  * @details
17026  *
17027  *     Function: rgSCHCmnDlANFdbkInit
17028  *     Purpose:  Each DL subframe stores the sfn and subframe
17029  *               information of UL subframe in which it expects
17030  *               HARQ ACK/NACK feedback for this subframe.It
17031  *               generates the information based on Downlink
17032  *               Association Set Index table.
17033  *
17034  *     Invoked by: Scheduler
17035  *
17036  *  @param[in]  RgSchCellCb*     cell
17037  *  @return     S16
17038  *
17039  **/
17040 static S16 rgSCHCmnDlANFdbkInit(RgSchCellCb  *cell)
17041 {
17042  uint8_t              sfCount;
17043  uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17044  uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17045  uint8_t              sfNum;
17046  uint8_t              idx;
17047  uint8_t              dlIdx;
17048  uint8_t              calcSfnOffset;
17049  S8                   calcSfNum;
17050  uint8_t              ulSfCnt =0;
17051  RgSchTddSubfrmInfo   ulSubfrmInfo;
17052  uint8_t              maxUlSubfrms;
17053
17054
17055    ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17056    maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17057
17058    /* Generate HARQ ACK/NACK feedback information for each DL sf in a radio frame
17059     * Calculate this information based on DL Association set Index table */
17060    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17061    {
17062       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17063             RG_SCH_TDD_UL_SUBFRAME)
17064       {
17065          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17066       }
17067       ulSfCnt++;
17068
17069       for(idx=0; idx < rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
17070             numFdbkSubfrms; idx++)
17071       {
17072          calcSfNum = sfNum - rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
17073                      subfrmNum[idx];
17074          if(calcSfNum < 0)
17075          {
17076             calcSfnOffset = RGSCH_CEIL(-calcSfNum, RGSCH_NUM_SUB_FRAMES);
17077          }
17078          else
17079          {
17080             calcSfnOffset = 0;
17081          }
17082
17083          calcSfNum = ((RGSCH_NUM_SUB_FRAMES * calcSfnOffset) + calcSfNum)\
17084                      % RGSCH_NUM_SUB_FRAMES;
17085
17086          if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17087          {
17088             dlIdx = calcSfNum;
17089          }
17090          else if((ulSubfrmInfo.switchPoints == 2) && (calcSfNum <= \
17091                   RG_SCH_CMN_SPL_SUBFRM_6))
17092          {
17093             dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17094          }
17095          else
17096          {
17097             dlIdx = calcSfNum - maxUlSubfrms;
17098          }
17099
17100          cell->subFrms[dlIdx]->dlFdbkInfo.subframe = sfNum;
17101          cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = calcSfnOffset;
17102          cell->subFrms[dlIdx]->dlFdbkInfo.m = idx;
17103       }
17104       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17105    }
17106
17107    /* DL subframes in the subsequent radio frames are initialized
17108     * with the previous radio frames  */
17109    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;\
17110          dlIdx++)
17111    {
17112       sfNum = dlIdx - rgSchTddNumDlSubfrmTbl[ulDlCfgIdx]\
17113               [RGSCH_NUM_SUB_FRAMES-1];
17114       cell->subFrms[dlIdx]->dlFdbkInfo.subframe = \
17115                                                   cell->subFrms[sfNum]->dlFdbkInfo.subframe;
17116       cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = \
17117                                                    cell->subFrms[sfNum]->dlFdbkInfo.sfnOffset;
17118       cell->subFrms[dlIdx]->dlFdbkInfo.m = cell->subFrms[sfNum]->dlFdbkInfo.m;
17119    }
17120    return ROK;
17121 }
17122
17123 /**
17124  * @brief This function handles the initialization of uplink association
17125  *        set information for each DL subframe.
17126  *
17127  *
17128  * @details
17129  *
17130  *     Function: rgSCHCmnDlKdashUlAscInit
17131  *     Purpose:  Each DL sf stores the sfn and sf information of UL sf
17132  *               in which it expects HQ ACK/NACK trans. It generates the information
17133  *               based on k` in UL association set index table.
17134  *
17135  *     Invoked by: Scheduler
17136  *
17137  *  @param[in]  RgSchCellCb*     cell
17138  *  @return     S16
17139  *
17140  **/
17141 static S16 rgSCHCmnDlKdashUlAscInit(RgSchCellCb *cell)
17142 {
17143  uint8_t              sfCount;
17144  uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17145  uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17146  uint8_t              sfNum;
17147  uint8_t              dlIdx;
17148  S8                   calcSfnOffset;
17149  S8                   calcSfNum;
17150  uint8_t              ulSfCnt =0;
17151  RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17152  uint8_t              maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17153  uint8_t              dlPres = 0;
17154
17155
17156    /* Generate ACK/NACK offset information for each DL subframe in a radio frame
17157     * Calculate this information based on K` in UL Association Set table */
17158    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17159    {
17160       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17161             RG_SCH_TDD_UL_SUBFRAME)
17162       {
17163          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17164       }
17165       ulSfCnt++;
17166
17167       calcSfNum = (sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum] + \
17168             RGSCH_NUM_SUB_FRAMES) % RGSCH_NUM_SUB_FRAMES;
17169       calcSfnOffset = sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum];
17170       if(calcSfnOffset < 0)
17171       {
17172          calcSfnOffset = RGSCH_CEIL(-calcSfnOffset, RGSCH_NUM_SUB_FRAMES);
17173       }
17174       else
17175       {
17176          calcSfnOffset = 0;
17177       }
17178
17179       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17180       {
17181          dlIdx = calcSfNum;
17182       }
17183       else if((ulSubfrmInfo.switchPoints == 2) &&
17184             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
17185       {
17186          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17187       }
17188       else
17189       {
17190          dlIdx = calcSfNum - maxUlSubfrms;
17191       }
17192
17193       cell->subFrms[dlIdx]->ulAscInfo.subframe = sfNum;
17194       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = calcSfnOffset;
17195
17196       /* set dlIdx for which ulAscInfo is updated */
17197       dlPres = dlPres | (1 << dlIdx);
17198       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17199    }
17200
17201    /* Set Invalid information for which ulAscInfo is not present */
17202    for (sfCount = 0;
17203          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17204          sfCount++)
17205    {
17206       /* If dlPres is 0, ulAscInfo is not present in that DL index */
17207       if(! ((dlPres >> sfCount)&0x01))
17208       {
17209          cell->subFrms[sfCount]->ulAscInfo.sfnOffset =
17210             RGSCH_INVALID_INFO;
17211          cell->subFrms[sfCount]->ulAscInfo.subframe =
17212             RGSCH_INVALID_INFO;
17213       }
17214    }
17215
17216    /* DL subframes in the subsequent radio frames are initialized
17217     * with the previous radio frames  */
17218    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;
17219          dlIdx++)
17220    {
17221       sfNum = dlIdx - \
17222               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17223       cell->subFrms[dlIdx]->ulAscInfo.subframe =
17224          cell->subFrms[sfNum]->ulAscInfo.subframe;
17225       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset =
17226          cell->subFrms[sfNum]->ulAscInfo.sfnOffset;
17227    }
17228    return ROK;
17229 }
17230
17231
17232 /**
17233  * @brief This function initialises the 'Np' value for 'p'
17234  *
17235  * @details
17236  *
17237  *     Function: rgSCHCmnDlNpValInit
17238  *     Purpose:  To initialise the 'Np' value for each 'p'. It is used
17239  *               to find the mapping between nCCE and 'p' and used in
17240  *               HARQ ACK/NACK reception.
17241  *
17242  *     Invoked by: Scheduler
17243  *
17244  *  @param[in]  RgSchCellCb*     cell
17245  *  @return     S16
17246  *
17247  **/
17248 static S16 rgSCHCmnDlNpValInit(RgSchCellCb *cell)
17249 {
17250    uint8_t    idx;
17251    uint16_t   np;
17252
17253    /* Always Np is 0 for p=0 */
17254    cell->rgSchTddNpValTbl[0] = 0;
17255
17256    for(idx=1; idx < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; idx++)
17257    {
17258       np = cell->bwCfg.dlTotalBw * (idx * RG_SCH_CMN_NUM_SUBCAR - 4);
17259       cell->rgSchTddNpValTbl[idx] = (uint8_t) (np/36);
17260    }
17261
17262    return ROK;
17263 }
17264
17265 /**
17266  * @brief This function handles the creation of RACH preamble
17267  *        list to queue the preambles and process at the scheduled
17268  *        time.
17269  *
17270  * @details
17271  *
17272  *     Function: rgSCHCmnDlCreateRachPrmLst
17273  *     Purpose:  To create RACH preamble list based on RA window size.
17274  *               It is used to queue the preambles and process it at the
17275  *               scheduled time.
17276  *
17277  *     Invoked by: Scheduler
17278  *
17279  *  @param[in]  RgSchCellCb*     cell
17280  *  @return     S16
17281  *
17282  **/
17283 static S16 rgSCHCmnDlCreateRachPrmLst(RgSchCellCb *cell)
17284 {
17285    uint8_t   raArrSz;
17286    S16       ret;
17287    uint8_t   lstSize;
17288
17289    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
17290
17291    lstSize = raArrSz * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES;
17292
17293    cell->raInfo.maxRaSize = raArrSz;
17294    ret = rgSCHUtlAllocSBuf(cell->instIdx,
17295          (Data **)(&cell->raInfo.raReqLst), (Size)(lstSize * sizeof(CmLListCp)));
17296    if (ret != ROK)
17297    {
17298       return (ret);
17299    }
17300
17301    cell->raInfo.lstSize = lstSize;
17302
17303    return ROK;
17304 }
17305
17306
17307 /**
17308  * @brief This function handles the initialization of RACH Response
17309  *        information at each DL subframe.
17310  *
17311  * @details
17312  *
17313  *     Function: rgSCHCmnDlRachInfoInit
17314  *     Purpose:  Each DL subframe stores the sfn and subframe information of
17315  *               possible RACH response allowed for UL subframes. It generates
17316  *               the information based on PRACH configuration.
17317  *
17318  *     Invoked by: Scheduler
17319  *
17320  *  @param[in]  RgSchCellCb*     cell
17321  *  @return     S16
17322  *
17323  **/
17324 static S16 rgSCHCmnDlRachInfoInit(RgSchCellCb  *cell)
17325 {
17326    uint8_t                   sfCount;
17327    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
17328    uint8_t                   sfNum;
17329    uint8_t                   ulSfCnt =0;
17330    uint8_t                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
17331                                        [RGSCH_NUM_SUB_FRAMES-1];
17332    uint8_t                   raArrSz;
17333    RgSchTddRachRspLst        rachRspLst[3][RGSCH_NUM_SUB_FRAMES];
17334    uint8_t                   startWin;
17335    uint8_t                   endWin;
17336    uint8_t                   sfnIdx;
17337    uint8_t                   subfrmIdx;
17338    uint8_t                   endSubfrmIdx;
17339    uint8_t                   startSubfrmIdx;
17340    S16                       ret;
17341    RgSchTddRachDelInfo       *delInfo;
17342    S8                        sfnOffset;
17343    uint8_t                   numSubfrms;
17344
17345
17346    memset(rachRspLst, 0, sizeof(rachRspLst));
17347
17348    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
17349
17350    /* Include Special subframes */
17351    maxUlSubfrms = maxUlSubfrms + \
17352                   rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx].switchPoints;
17353    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17354    {
17355       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
17356             RG_SCH_TDD_DL_SUBFRAME)
17357       {
17358          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17359       }
17360       ulSfCnt++;
17361
17362       startWin = (sfNum + RG_SCH_CMN_RARSP_WAIT_PRD + \
17363             ((RgSchCmnCell *)cell->sc.sch)->dl.numRaSubFrms);
17364       endWin = (startWin + cell->rachCfg.raWinSize - 1);
17365       startSubfrmIdx =
17366          rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][startWin%RGSCH_NUM_SUB_FRAMES];
17367       /* Find the next DL subframe starting from Subframe 0 */
17368       if((startSubfrmIdx % RGSCH_NUM_SUB_FRAMES) == 0)
17369       {
17370          startWin = RGSCH_CEIL(startWin, RGSCH_NUM_SUB_FRAMES);
17371          startWin = startWin * RGSCH_NUM_SUB_FRAMES;
17372       }
17373
17374       endSubfrmIdx =
17375          rgSchTddLowDlSubfrmIdxTbl[ulDlCfgIdx][endWin%RGSCH_NUM_SUB_FRAMES];
17376       endWin = (endWin/RGSCH_NUM_SUB_FRAMES) * RGSCH_NUM_SUB_FRAMES \
17377                + endSubfrmIdx;
17378       if(startWin > endWin)
17379       {
17380          continue;
17381       }
17382       /* Find all the possible RACH Response transmission
17383        * time within the RA window size */
17384       startSubfrmIdx = startWin%RGSCH_NUM_SUB_FRAMES;
17385       for(sfnIdx = startWin/RGSCH_NUM_SUB_FRAMES;
17386             sfnIdx <= endWin/RGSCH_NUM_SUB_FRAMES; sfnIdx++)
17387       {
17388          if(sfnIdx == endWin/RGSCH_NUM_SUB_FRAMES)
17389          {
17390             endSubfrmIdx = endWin%RGSCH_NUM_SUB_FRAMES;
17391          }
17392          else
17393          {
17394             endSubfrmIdx = RGSCH_NUM_SUB_FRAMES-1;
17395          }
17396
17397          /* Find all the possible RACH Response transmission
17398           * time within radio frame */
17399          for(subfrmIdx = startSubfrmIdx;
17400                subfrmIdx <= endSubfrmIdx; subfrmIdx++)
17401          {
17402             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][subfrmIdx] ==
17403                   RG_SCH_TDD_UL_SUBFRAME)
17404             {
17405                continue;
17406             }
17407             subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
17408             /* Find the next DL subframe starting from Subframe 0 */
17409             if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
17410             {
17411                break;
17412             }
17413             RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx], subfrmIdx);
17414             numSubfrms =
17415                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
17416             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset = sfnIdx;
17417             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].subframe[numSubfrms]
17418                = sfNum;
17419             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms++;
17420          }
17421          startSubfrmIdx = RG_SCH_CMN_SUBFRM_0;
17422       }
17423       /* Update the subframes to be deleted at this subframe */
17424       /* Get the subframe after the end of RA window size */
17425       endWin++;
17426       endSubfrmIdx++;
17427       sfnOffset = endWin/RGSCH_NUM_SUB_FRAMES;
17428       if(sfnOffset < 0)
17429       {
17430          sfnOffset += raArrSz;
17431       }
17432       sfnIdx = (endWin/RGSCH_NUM_SUB_FRAMES) % raArrSz;
17433
17434       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx],endSubfrmIdx-1);
17435       if((endSubfrmIdx == RGSCH_NUM_SUB_FRAMES) ||
17436             (rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx] ==
17437              RGSCH_NUM_SUB_FRAMES))
17438       {
17439          subfrmIdx =
17440             rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][RG_SCH_CMN_SUBFRM_0];
17441       }
17442       else
17443       {
17444          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx];
17445       }
17446
17447       delInfo = &rachRspLst[sfnIdx][subfrmIdx].delInfo;
17448       delInfo->sfnOffset = sfnOffset;
17449       delInfo->subframe[delInfo->numSubfrms] = sfNum;
17450       delInfo->numSubfrms++;
17451
17452       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17453    }
17454
17455    ret = rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz);
17456    if (ret != ROK)
17457    {
17458       return (ret);
17459    }
17460
17461    return ROK;
17462 }
17463
17464 /**
17465  * @brief This function handles the initialization of PHICH information
17466  *        for each DL subframe based on PHICH table.
17467  *
17468  * @details
17469  *
17470  *     Function: rgSCHCmnDlPhichOffsetInit
17471  *     Purpose:  Each DL subf stores the sfn and subf information of UL subframe
17472  *               for which it trnsmts PHICH in this subframe. It generates the information
17473  *               based on PHICH table.
17474  *
17475  *     Invoked by: Scheduler
17476  *
17477  *  @param[in]  RgSchCellCb*     cell
17478  *  @return     S16
17479  *
17480  **/
17481 static S16 rgSCHCmnDlPhichOffsetInit(RgSchCellCb *cell)
17482 {
17483    uint8_t              sfCount;
17484    uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
17485    uint8_t              maxDlSubfrms = cell->numDlSubfrms;
17486    uint8_t              sfNum;
17487    uint8_t              dlIdx;
17488    uint8_t              dlPres = 0;
17489    uint8_t              calcSfnOffset;
17490    uint8_t              calcSfNum;
17491    uint8_t              ulSfCnt =0;
17492    RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
17493    uint8_t              maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
17494                                        [RGSCH_NUM_SUB_FRAMES-1];
17495
17496
17497    /* Generate PHICH offset information for each DL subframe in a radio frame
17498     * Calculate this information based on K in PHICH table */
17499    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
17500    {
17501       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
17502             RG_SCH_TDD_UL_SUBFRAME)
17503       {
17504          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17505       }
17506       ulSfCnt++;
17507
17508       calcSfNum = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) % \
17509                   RGSCH_NUM_SUB_FRAMES;
17510       calcSfnOffset = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) / \
17511                       RGSCH_NUM_SUB_FRAMES;
17512
17513       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
17514       {
17515          dlIdx = calcSfNum;
17516       }
17517       else if((ulSubfrmInfo.switchPoints == 2) &&
17518             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
17519       {
17520          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
17521       }
17522       else
17523       {
17524          dlIdx = calcSfNum - maxUlSubfrms;
17525       }
17526
17527       cell->subFrms[dlIdx]->phichOffInfo.subframe = sfNum;
17528       cell->subFrms[dlIdx]->phichOffInfo.numSubfrms = 1;
17529
17530       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = calcSfnOffset;
17531
17532       /* set dlIdx for which phich offset is updated */
17533       dlPres = dlPres | (1 << dlIdx);
17534       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
17535    }
17536
17537    /* Set Invalid information for which phich offset is not present */
17538    for (sfCount = 0;
17539          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17540          sfCount++)
17541    {
17542       /* If dlPres is 0, phich offset is not present in that DL index */
17543       if(! ((dlPres >> sfCount)&0x01))
17544       {
17545          cell->subFrms[sfCount]->phichOffInfo.sfnOffset =
17546             RGSCH_INVALID_INFO;
17547          cell->subFrms[sfCount]->phichOffInfo.subframe =
17548             RGSCH_INVALID_INFO;
17549          cell->subFrms[sfCount]->phichOffInfo.numSubfrms = 0;
17550       }
17551    }
17552
17553    /* DL subframes in the subsequent radio frames are
17554     * initialized with the previous radio frames  */
17555    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms;
17556          dlIdx < maxDlSubfrms; dlIdx++)
17557    {
17558       sfNum = dlIdx - \
17559               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
17560
17561       cell->subFrms[dlIdx]->phichOffInfo.subframe =
17562          cell->subFrms[sfNum]->phichOffInfo.subframe;
17563
17564       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset =
17565          cell->subFrms[sfNum]->phichOffInfo.sfnOffset;
17566    }
17567    return ROK;
17568 }
17569
17570
17571 /**
17572  * @brief Updation of Sch vars per TTI.
17573  *
17574  * @details
17575  *
17576  *     Function: rgSCHCmnUpdVars
17577  *     Purpose:  Updation of Sch vars per TTI.
17578  *
17579  *  @param[in]  RgSchCellCb *cell
17580  *  @return  Void
17581  *
17582  **/
17583 Void rgSCHCmnUpdVars(RgSchCellCb *cell)
17584 {
17585    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
17586    CmLteTimingInfo        timeInfo;
17587    uint8_t                idx;
17588    uint8_t                ulSubframe;
17589    uint8_t                ulDlCfgIdx = cell->ulDlCfgIdx;
17590    uint8_t                msg3Subfrm;
17591    uint8_t                Mval;
17592  
17593    /* ccpu00132654-ADD- Initializing all the indices in every subframe*/ 
17594    rgSCHCmnInitVars(cell);
17595
17596    idx = (cell->crntTime.slot + TFU_ULCNTRL_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
17597    /* Calculate the UL scheduling subframe idx based on the 
17598       Pusch k table */
17599    if(rgSchTddPuschTxKTbl[ulDlCfgIdx][idx] != 0)
17600    {
17601       /* PUSCH transmission is based on offset from DL
17602        * PDCCH scheduling */
17603       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); 
17604       ulSubframe = rgSchTddPuschTxKTbl[ulDlCfgIdx][timeInfo.subframe];
17605       /* Add the DCI-0 to PUSCH time to get the time of UL subframe */
17606       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, ulSubframe);
17607 #ifdef LTEMAC_SPS
17608       cellUl->schdTti = timeInfo.sfn * 10 + timeInfo.subframe;
17609 #endif
17610       /* Fetch the corresponding  UL subframe Idx in UL sf array */ 
17611       cellUl->schdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17612       /* Fetch the corresponding  UL Harq Proc ID */ 
17613       cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
17614       cellUl->schdTime = timeInfo;
17615    }
17616    Mval = rgSchTddPhichMValTbl[ulDlCfgIdx][idx]; 
17617    if(Mval)
17618    {
17619       /* Fetch the tx time for DL HIDCI-0 */
17620       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA);
17621       /* Fetch the corresponding n-k tx time of PUSCH */
17622       cellUl->hqFdbkIdx[0] = rgSCHCmnGetPhichUlSfIdx(&timeInfo, cell);
17623       /* Retx will happen according to the Pusch k table */
17624       cellUl->reTxIdx[0] = cellUl->schdIdx;
17625       
17626       if(ulDlCfgIdx == 0) 
17627       {
17628          /* Calculate the ReTxIdx corresponding to hqFdbkIdx[0] */
17629          cellUl->reTxIdx[0] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
17630                                                 cellUl->hqFdbkIdx[0]);
17631          if(Mval == 2)
17632          {
17633             /* At Idx 1 store the UL SF adjacent(left) to the UL SF
17634                given at idx 0 */  
17635             cellUl->hqFdbkIdx[1] = (cellUl->hqFdbkIdx[0]-1 + 
17636                                    cellUl->numUlSubfrms) % cellUl->numUlSubfrms;
17637             /* Calculate the ReTxIdx corresponding to hqFdbkIdx[1] */
17638             cellUl->reTxIdx[1] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
17639                                                 cellUl->hqFdbkIdx[1]);
17640          }                               
17641       }
17642    }
17643
17644    idx = (cell->crntTime.slot + TFU_RECPREQ_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
17645    if (rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == RG_SCH_TDD_UL_SUBFRAME)
17646    {
17647       RGSCHCMNADDTOCRNTTIME(cell->crntTime, timeInfo, TFU_RECPREQ_DLDELTA)
17648       cellUl->rcpReqIdx   = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17649    }
17650    idx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % RGSCH_NUM_SUB_FRAMES;
17651    
17652    /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
17653      special subframe */                       
17654    if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] != RG_SCH_TDD_UL_SUBFRAME)
17655    {
17656       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
17657       msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
17658       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, msg3Subfrm);
17659       cellUl->msg3SchdIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17660       cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
17661    }
17662 #ifdef LTEMAC_SPS
17663    if(!rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][idx])
17664    {
17665       cellUl->spsUlRsrvIdx = RGSCH_INVALID_INFO;
17666    }
17667    else
17668    {
17669       /* introduce some reuse with above code? */
17670       uint8_t    offst;
17671       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
17672       //offst = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
17673       offst = rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][timeInfo.subframe];
17674       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, offst);
17675       cellUl->spsUlRsrvIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
17676       /* The harq proc continues to be accessed and used the same delta before
17677        * actual data occurance, and hence use the same idx */
17678       cellUl->spsUlRsrvHqProcIdx = cellUl->schdHqProcIdx;
17679    }
17680 #endif
17681
17682    /* RACHO: update cmn sched specific RACH variables,
17683     * mainly the prachMaskIndex */
17684    rgSCHCmnUpdRachParam(cell);
17685
17686    return;
17687 }
17688
17689 /**
17690  * @brief To get 'p' value from nCCE.
17691  *
17692  * @details
17693  *
17694  *     Function: rgSCHCmnGetPValFrmCCE
17695  *     Purpose:  Gets 'p' value for HARQ ACK/NACK reception from CCE.
17696  *
17697  *  @param[in]  RgSchCellCb   *cell
17698  *  @param[in]  uint8_t            cce
17699  *  @return uint8_t
17700  *
17701  **/
17702 uint8_t  rgSCHCmnGetPValFrmCCE(RgSchCellCb *cell,uint8_t cce)
17703 {
17704    uint8_t i;
17705
17706    for(i=1; i < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; i++)
17707    {
17708       if(cce < cell->rgSchTddNpValTbl[i])
17709       {
17710          return (i-1);
17711       }
17712    }
17713    return (0);
17714 }
17715 #endif
17716
17717 /***********************************************************
17718  *
17719  *     Func : rgSCHCmnUlAdapRetx
17720  *
17721  *     Desc : Adaptive retransmission for an allocation.
17722  *
17723  *     Ret  :
17724  *
17725  *     Notes:
17726  *
17727  *     File :
17728  *
17729  **********************************************************/
17730 static Void rgSCHCmnUlAdapRetx(RgSchUlAlloc  *alloc,RgSchUlHqProcCb *proc)
17731 {
17732
17733    rgSCHUhmRetx(proc, alloc);
17734 #ifndef RG_5GTF
17735    if (proc->rvIdx != 0)
17736    {
17737       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[proc->rvIdx];
17738    }
17739    else
17740 #endif
17741    {
17742       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
17743    }
17744    return;
17745 }
17746
17747 /**
17748  * @brief Scheduler invocation per TTI.
17749  *
17750  * @details
17751  *
17752  *     Function: rgSCHCmnHdlUlInactUes
17753  *     Purpose:
17754  *
17755  *     Invoked by: Common Scheduler
17756  *
17757  *  @param[in]  RgSchCellCb *cell
17758  *  @return  Void
17759  **/
17760 static Void rgSCHCmnHdlUlInactUes(RgSchCellCb  *cell)
17761 {
17762    RgSchCmnCell  *cellSch  = RG_SCH_CMN_GET_CELL(cell);
17763    CmLListCp     ulInactvLst;
17764    /* Get a List of Inactv UEs for UL*/
17765    cmLListInit(&ulInactvLst);
17766
17767    /* Trigger Spfc Schedulers with Inactive UEs */
17768    rgSCHMeasGapANRepGetUlInactvUe (cell, &ulInactvLst);
17769    /* take care of this in UL retransmission */
17770    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst);
17771
17772    return;
17773 }
17774
17775 /**
17776  * @brief Scheduler invocation per TTI.
17777  *
17778  * @details
17779  *
17780  *     Function: rgSCHCmnHdlDlInactUes
17781  *     Purpose:
17782  *
17783  *     Invoked by: Common Scheduler
17784  *
17785  *  @param[in]  RgSchCellCb *cell
17786  *  @return  Void
17787  **/
17788 static Void rgSCHCmnHdlDlInactUes(RgSchCellCb  *cell)
17789 {
17790    RgSchCmnCell *cellSch  = RG_SCH_CMN_GET_CELL(cell);
17791    CmLListCp    dlInactvLst;
17792    /* Get a List of Inactv UEs for DL */
17793    cmLListInit(&dlInactvLst);
17794
17795    /* Trigger Spfc Schedulers with Inactive UEs */
17796    rgSCHMeasGapANRepGetDlInactvUe (cell, &dlInactvLst);
17797
17798    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst);
17799    return;
17800 }
17801
17802 /* RACHO: Rach handover functions start here */
17803 /***********************************************************
17804  *
17805  *     Func : rgSCHCmnUeIdleExdThrsld
17806  *
17807  *     Desc : RETURN ROK if UE has been idle more
17808  *            than threshold.
17809  *
17810  *     Ret  :
17811  *
17812  *     Notes:
17813  *
17814  *     File :
17815  *
17816  **********************************************************/
17817 static S16 rgSCHCmnUeIdleExdThrsld(RgSchCellCb *cell,RgSchUeCb *ue)
17818 {
17819    /* Time difference in subframes */
17820    uint32_t sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, ue->ul.ulTransTime);
17821
17822    if (sfDiff > (uint32_t)RG_SCH_CMN_UE_IDLE_THRSLD(ue))
17823    {
17824       return ROK;
17825    }
17826    else
17827    {
17828       return RFAILED;
17829    }
17830 }
17831
17832 \f
17833 /**
17834  * @brief Scheduler processing for Ded Preambles on cell configuration.
17835  *
17836  * @details
17837  *
17838  *     Function : rgSCHCmnCfgRachDedPrm
17839  *
17840  *     This function does requisite initialisation
17841  *     for RACH Ded Preambles.
17842  *
17843  *
17844  *  @param[in]  RgSchCellCb   *cell
17845  *  @return  Void
17846  **/
17847 static Void rgSCHCmnCfgRachDedPrm(RgSchCellCb   *cell)
17848 {
17849    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
17850    uint32_t     gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
17851    uint32_t     sfDiff;
17852    uint8_t      cnt;
17853
17854    if (cell->macPreambleSet.pres == NOTPRSNT)
17855    {
17856       return;
17857    }
17858    cellSch->rachCfg.numDedPrm = cell->macPreambleSet.size;
17859    cellSch->rachCfg.dedPrmStart = cell->macPreambleSet.start;
17860    /* Initialize handover List */
17861    cmLListInit(&cellSch->rachCfg.hoUeLst);
17862    /* Initialize pdcch Order List */
17863    cmLListInit(&cellSch->rachCfg.pdcchOdrLst);
17864
17865    /* Intialize the rapId to UE mapping structure */
17866    for (cnt = 0; cnt<cellSch->rachCfg.numDedPrm; cnt++)
17867    {
17868       cellSch->rachCfg.rapIdMap[cnt].rapId = cellSch->rachCfg.dedPrmStart + \
17869                                              cnt;
17870       cmLListInit(&cellSch->rachCfg.rapIdMap[cnt].assgndUes);
17871    }
17872    /* Perform Prach Mask Idx, remDedPrm, applFrm initializations */
17873    /* Set remDedPrm as numDedPrm */
17874    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
17875    /* Initialize applFrm */
17876    cellSch->rachCfg.prachMskIndx = 0;
17877    if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_EVEN)
17878    {
17879       cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + \
17880             (cell->crntTime.sfn % 2)) % RGSCH_MAX_SFN;
17881    }
17882 #ifdef LTE_TDD
17883    else if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ODD)
17884    {
17885       if((cell->crntTime.sfn%2) == 0)
17886       {
17887          cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + 1)\
17888                                         % RGSCH_MAX_SFN;
17889       }
17890    }
17891 #endif
17892    else /* ANY sfn */
17893    {
17894       cellSch->rachCfg.applFrm.sfn = cell->crntTime.sfn;
17895    }
17896    /* Initialize cellSch->rachCfg.applFrm as >= crntTime.
17897     * This is because of RGSCH_CALC_SF_DIFF logic */
17898    if (cellSch->rachCfg.applFrm.sfn == cell->crntTime.sfn)
17899    {
17900       while (cellSch->rachCfg.prachMskIndx < cell->rachCfg.raOccasion.size)
17901       {
17902          if (cell->crntTime.slot <\
17903                cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx])
17904          {
17905             break;
17906          }
17907          cellSch->rachCfg.prachMskIndx++;
17908       }
17909       if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size)
17910       {
17911          if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
17912          {
17913             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) %\
17914                                            RGSCH_MAX_SFN;
17915          }
17916          else
17917          {
17918             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) %\
17919                                            RGSCH_MAX_SFN;
17920          }
17921          cellSch->rachCfg.prachMskIndx = 0;
17922       }
17923       cellSch->rachCfg.applFrm.slot = \
17924                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17925    }
17926    else
17927    {
17928       cellSch->rachCfg.applFrm.slot = \
17929                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17930    }
17931
17932    /* Note first param to this macro should always be the latest in time */
17933    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
17934    while (sfDiff <= gap)
17935    {
17936       rgSCHCmnUpdNxtPrchMskIdx(cell);
17937       sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
17938    }
17939
17940    return;
17941 }
17942
17943 /**
17944  * @brief Updates the PRACH MASK INDEX.
17945  *
17946  * @details
17947  *
17948  *     Function: rgSCHCmnUpdNxtPrchMskIdx
17949  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
17950  *     CFG is always >= "n"+"DELTA", where "n" is the crntTime
17951  *     of the cell. If not, applFrm is updated to the next avl
17952  *     PRACH oppurtunity as per the PRACH Cfg Index configuration.
17953  *
17954  *
17955  *     Invoked by: Common Scheduler
17956  *
17957  *  @param[in]  RgSchCellCb *cell
17958  *  @return  Void
17959  **/
17960 static Void rgSCHCmnUpdNxtPrchMskIdx(RgSchCellCb  *cell)
17961 {
17962    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
17963
17964    /* Determine the next prach mask Index */
17965    if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size - 1)
17966    {
17967       /* PRACH within applFrm.sfn are done, go to next AVL sfn */
17968       cellSch->rachCfg.prachMskIndx = 0;
17969       if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
17970       {
17971          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) % \
17972                                         RGSCH_MAX_SFN;
17973       }
17974       else/* RGR_SFN_EVEN or RGR_SFN_ODD */
17975       {
17976          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) % \
17977                                         RGSCH_MAX_SFN;
17978       }
17979       cellSch->rachCfg.applFrm.slot = cell->rachCfg.raOccasion.\
17980                                           subFrameNum[0];
17981    }
17982    else /* applFrm.sfn is still valid */
17983    {
17984       cellSch->rachCfg.prachMskIndx += 1;
17985       if ( cellSch->rachCfg.prachMskIndx < RGR_MAX_SUBFRAME_NUM )
17986       {
17987          cellSch->rachCfg.applFrm.slot = \
17988                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
17989       }
17990    }
17991    return;
17992 }
17993
17994 /**
17995  * @brief Updates the Ded preamble RACH parameters
17996  *        every TTI.
17997  *
17998  * @details
17999  *
18000  *     Function: rgSCHCmnUpdRachParam
18001  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
18002  *     CFG is always >= "n"+"6"+"DELTA", where "n" is the crntTime
18003  *     of the cell. If not, applFrm is updated to the next avl
18004  *     PRACH oppurtunity as per the PRACH Cfg Index configuration,
18005  *     accordingly the "remDedPrm" is reset to "numDedPrm" and
18006  *     "prachMskIdx" field is updated as per "applFrm".
18007  *
18008  *
18009  *     Invoked by: Common Scheduler
18010  *
18011  *  @param[in]  RgSchCellCb *cell
18012  *  @return  Void
18013  **/
18014 static Void rgSCHCmnUpdRachParam(RgSchCellCb  *cell)
18015 {
18016
18017    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18018    uint32_t     gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
18019    uint32_t     sfDiff;
18020
18021    if (cell->macPreambleSet.pres == NOTPRSNT)
18022    {
18023       return;
18024    }
18025    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, \
18026          cell->crntTime);
18027    if (sfDiff > gap)
18028    {
18029       /* applFrm is still a valid next Prach Oppurtunity */
18030       return;
18031    }
18032    rgSCHCmnUpdNxtPrchMskIdx(cell);
18033    /* Reset remDedPrm as numDedPrm */
18034    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
18035
18036    return;
18037 }
18038
18039 /**
18040  * @brief Dedicated Preamble allocation function.
18041  *
18042  * @details
18043  *
18044  *     Function: rgSCHCmnAllocPOParam
18045  *     Purpose:  Allocate pdcch, rapId and PrachMskIdx.
18046  *     Set mapping of UE with the allocated rapId.
18047  *
18048  *     Invoked by: Common Scheduler
18049  *
18050  *  @param[in]   RgSchCellCb *cell
18051  *  @param[in]   RgSchDlSf   *dlSf
18052  *  @param[in]   RgSchUeCb   *ue
18053  *  @param[out]  RgSchPdcch  **pdcch
18054  *  @param[out]  uint8_t          *rapId
18055  *  @param[out]  uint8_t          *prachMskIdx
18056  *  @return  Void
18057  **/
18058 static S16 rgSCHCmnAllocPOParam
18059 (
18060 RgSchCellCb  *cell,
18061 RgSchDlSf    *dlSf,
18062 RgSchUeCb    *ue,
18063 RgSchPdcch   **pdcch,
18064 uint8_t      *rapId,
18065 uint8_t      *prachMskIdx
18066 )
18067 {
18068
18069    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18070    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18071
18072
18073    if (cell->macPreambleSet.pres == PRSNT_NODEF)
18074    {
18075       if (cellSch->rachCfg.remDedPrm == 0)
18076       {
18077          return RFAILED;
18078       }
18079       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
18080       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
18081       {
18082          return RFAILED;
18083       }
18084       /* The stored prachMskIdx is the index of PRACH Oppurtunities in
18085        * raOccasions.subframes[].
18086        * Converting the same to the actual PRACHMskIdx to be transmitted. */
18087       *prachMskIdx = cellSch->rachCfg.prachMskIndx + 1;
18088       /* Distribution starts from dedPrmStart till dedPrmStart + numDedPrm */
18089       *rapId =  cellSch->rachCfg.dedPrmStart +
18090          cellSch->rachCfg.numDedPrm - cellSch->rachCfg.remDedPrm;
18091       cellSch->rachCfg.remDedPrm--;
18092       /* Map UE with the allocated RapId */
18093       ueDl->rachInfo.asgnOppr = cellSch->rachCfg.applFrm;
18094       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, cellSch->rachCfg.rapIdMap, (*rapId - cellSch->rachCfg.dedPrmStart));
18095       cmLListAdd2Tail(&cellSch->rachCfg.rapIdMap[*rapId - cellSch->rachCfg.dedPrmStart].assgndUes, 
18096              &ueDl->rachInfo.rapIdLnk);
18097       ueDl->rachInfo.rapIdLnk.node = (PTR)ue;
18098       ueDl->rachInfo.poRapId = *rapId;
18099    }
18100    else /* if dedicated preambles not configured */
18101    {
18102       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
18103       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
18104       {
18105          return RFAILED;
18106       }
18107       *prachMskIdx = 0;
18108       *rapId       = 0;
18109    }
18110
18111    return ROK;
18112 }
18113
18114 /**
18115  * @brief Dowlink Scheduling Handler.
18116  *
18117  * @details
18118  *
18119  *     Function: rgSCHCmnGenPdcchOrder
18120  *     Purpose:  For each UE in PO Q, grab a PDCCH,
18121  *     get an available ded RapId and fill PDCCH
18122  *     with PO information.
18123  *
18124  *     Invoked by: Common Scheduler
18125  *
18126  *  @param[in]  RgSchCellCb *cell
18127  *  @param[in]  RgSchDlSf   *dlSf
18128  *  @return  Void
18129  **/
18130 static Void rgSCHCmnGenPdcchOrder(RgSchCellCb  *cell,RgSchDlSf    *dlSf)
18131 {
18132    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
18133    CmLList       *node = cellSch->rachCfg.pdcchOdrLst.first;
18134    RgSchUeCb     *ue;
18135    uint8_t       rapId;
18136    uint8_t       prachMskIdx;
18137    RgSchPdcch    *pdcch = NULLP;
18138
18139    while (node)
18140    {
18141       ue = (RgSchUeCb *)node->node;
18142       node = node->next;
18143       /* Skip sending for this subframe is Measuring or inActive in UL due
18144        * to MeasGap or inactie due to DRX
18145        */
18146       if  ((ue->measGapCb.isMeasuring == TRUE) ||
18147            (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) ||
18148            (ue->isDrxEnabled &&
18149              ue->dl.dlInactvMask & RG_DRX_INACTIVE)
18150            )
18151       {
18152          continue;
18153       }
18154       if (rgSCHCmnAllocPOParam(cell, dlSf, ue, &pdcch, &rapId,\
18155                &prachMskIdx) != ROK)
18156       {
18157          /* No More rapIds left for the valid next avl Oppurtunity.
18158           * Unsatisfied UEs here would be given a chance, when the
18159           * prach Mask Index changes as per rachUpd every TTI */
18160
18161          /* PDDCH can also be ordered with rapId=0, prachMskIdx=0
18162           * so that UE triggers a RACH procedure with non-dedicated preamble.
18163           * But the implementation here does not do this. Instead, the "break"
18164           * here implies, that PDCCH Odr always given with valid rapId!=0,
18165           * prachMskIdx!=0 if dedicated preambles are configured.
18166           * If not configured, then trigger a PO with rapId=0,prchMskIdx=0*/
18167          break;
18168       }
18169       /* Fill pdcch with pdcch odr information */
18170       rgSCHCmnFillPdcchOdr2Sf(cell, ue, pdcch, rapId, prachMskIdx);
18171       /* Remove this UE from the PDCCH ORDER QUEUE */
18172       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
18173       /* Reset UE's power state */
18174       rgSCHPwrUeReset(cell, ue);
18175    }
18176    return;
18177 }
18178
18179 \f
18180 /**
18181  * @brief This function add UE to PdcchOdr Q if not already present.
18182  *
18183  * @details
18184  *
18185  *     Function: rgSCHCmnDlAdd2PdcchOdrQ
18186  *     Purpose:
18187  *
18188  *     Invoked by: CMN Scheduler
18189  *
18190  *  @param[in]  RgSchCellCb*  cell
18191  *  @param[in]  RgSchUeCb*    ue
18192  *  @return  Void
18193  *
18194  **/
18195 static Void rgSCHCmnDlAdd2PdcchOdrQ(RgSchCellCb *cell,RgSchUeCb *ue)
18196 {
18197    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18198    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18199
18200
18201    if (ueDl->rachInfo.poLnk.node == NULLP)
18202    {
18203       cmLListAdd2Tail(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
18204       ueDl->rachInfo.poLnk.node = (PTR)ue;
18205    }
18206    return;
18207 }
18208
18209 \f
18210 /**
18211  * @brief This function rmvs UE to PdcchOdr Q if not already present.
18212  *
18213  * @details
18214  *
18215  *     Function: rgSCHCmnDlRmvFrmPdcchOdrQ
18216  *     Purpose:
18217  *
18218  *     Invoked by: CMN Scheduler
18219  *
18220  *  @param[in]  RgSchCellCb*  cell
18221  *  @param[in]  RgSchUeCb*    ue
18222  *  @return  Void
18223  *
18224  **/
18225 static Void rgSCHCmnDlRmvFrmPdcchOdrQ(RgSchCellCb *cell,RgSchUeCb  *ue)
18226 {
18227    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18228    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18229
18230    cmLListDelFrm(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
18231    ueDl->rachInfo.poLnk.node = NULLP;
18232    return;
18233 }
18234
18235 /**
18236  * @brief Fill pdcch with PDCCH order information.
18237  *
18238  * @details
18239  *
18240  *     Function: rgSCHCmnFillPdcchOdr2Sf
18241  *     Purpose:  Fill PDCCH with PDCCH order information,
18242  *
18243  *     Invoked by: Common Scheduler
18244  *
18245  *  @param[in]  RgSchUeCb   *ue
18246  *  @param[in]  RgSchPdcch  *pdcch
18247  *  @param[in]  uint8_t          rapId
18248  *  @param[in]  uint8_t          prachMskIdx
18249  *  @return  Void
18250  **/
18251 static Void rgSCHCmnFillPdcchOdr2Sf
18252 (
18253 RgSchCellCb *cell,
18254 RgSchUeCb   *ue,
18255 RgSchPdcch  *pdcch,
18256 uint8_t     rapId,
18257 uint8_t     prachMskIdx
18258 )
18259 {
18260    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
18261
18262
18263    pdcch->rnti                                         = ue->ueId;
18264    pdcch->dci.dciFormat                                = TFU_DCI_FORMAT_1A;
18265    pdcch->dci.u.format1aInfo.isPdcchOrder = TRUE;
18266    pdcch->dci.u.format1aInfo.t.pdcchOrder.preambleIdx  = rapId;
18267    pdcch->dci.u.format1aInfo.t.pdcchOrder.prachMaskIdx = prachMskIdx;
18268
18269    /* Request for APer CQI immediately after PDCCH Order */
18270    /* CR ccpu00144525 */
18271 #ifdef TFU_UPGRADE
18272    if(ue->dl.ueDlCqiCfg.aprdCqiCfg.pres)
18273    {
18274       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
18275       acqiCb->aCqiTrigWt = 0;
18276    }
18277 #endif   
18278
18279    return;
18280 }
18281
18282 \f
18283 /**
18284  * @brief UE deletion for scheduler.
18285  *
18286  * @details
18287  *
18288  *     Function : rgSCHCmnDelRachInfo
18289  *
18290  *     This functions deletes all scheduler information
18291  *     pertaining to an UE.
18292  *
18293  *  @param[in]  RgSchCellCb  *cell
18294  *  @param[in]  RgSchUeCb    *ue
18295  *  @return  Void
18296  **/
18297 static Void rgSCHCmnDelRachInfo(RgSchCellCb *cell,RgSchUeCb *ue)
18298 {
18299    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18300    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18301    uint8_t            rapIdIdx;
18302
18303
18304    if (ueDl->rachInfo.poLnk.node)
18305    {
18306       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
18307    }
18308    if (ueDl->rachInfo.hoLnk.node)
18309    {
18310       cmLListDelFrm(&cellSch->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
18311       ueDl->rachInfo.hoLnk.node = NULLP;
18312    }
18313    if (ueDl->rachInfo.rapIdLnk.node)
18314    {
18315       rapIdIdx = ueDl->rachInfo.poRapId - cellSch->rachCfg.dedPrmStart;
18316       cmLListDelFrm(&cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes, 
18317           &ueDl->rachInfo.rapIdLnk);
18318       ueDl->rachInfo.rapIdLnk.node = NULLP;
18319    }
18320    return;
18321 }
18322
18323 /**
18324  * @brief This function retrieves the ue which has sent this raReq
18325  * and it allocates grant for UEs undergoing (for which RAR
18326  * is being generated) HandOver/PdcchOrder.
18327  *
18328  *
18329  * @details
18330  *
18331  *     Function: rgSCHCmnHdlHoPo
18332  *     Purpose:  This function  retrieves the ue which has sent this raReq
18333  *               and it allocates grant for UEs undergoing (for which RAR
18334  *               is being generated) HandOver/PdcchOrder.
18335  *
18336  *     Invoked by: Common Scheduler
18337  *
18338  *  @param[in]  RgSchCellCb           *cell
18339  *  @param[out] CmLListCp             *raRspLst
18340  *  @param[in]  RgSchRaReqInfo        *raReq
18341  *  @return  Void
18342  *
18343  **/
18344 static Void rgSCHCmnHdlHoPo
18345 (
18346 RgSchCellCb           *cell,
18347 CmLListCp             *raRspLst,
18348 RgSchRaReqInfo        *raReq
18349 )
18350 {
18351    RgSchUeCb             *ue = raReq->ue;
18352
18353    if ( ue->isDrxEnabled )
18354    {
18355       rgSCHDrxDedRa(cell,ue);
18356    }
18357    rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq);
18358    return;
18359 }
18360
18361 /**
18362  * @brief This function retrieves the UE which has sent this raReq
18363  * for handover case.
18364  *
18365  *
18366  * @details
18367  *
18368  *     Function: rgSCHCmnGetHoUe
18369  *     Purpose:  This function retrieves the UE which has sent this raReq
18370  *     for handover case.
18371  *
18372  *     Invoked by: Common Scheduler
18373  *
18374  *  @param[in]  RgSchCellCb           *cell
18375  *  @param[in]  RgSchRaReqInfo        *raReq
18376  *  @return  RgSchUeCb*
18377  *
18378  **/
18379 RgSchUeCb* rgSCHCmnGetHoUe(RgSchCellCb *cell,uint16_t rapId)
18380 {
18381    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18382    CmLList         *node;
18383    CmLListCp       *ueLst;
18384    RgSchUeCb       *ue;
18385    RgSchCmnDlUe    *ueDl;
18386
18387    ueLst = &cellSch->rachCfg.hoUeLst;
18388    node = ueLst->first;
18389    while (node)
18390    {
18391       ue = (RgSchUeCb *)node->node;
18392       node = node->next;
18393       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18394       if (ueDl->rachInfo.hoRapId == rapId)
18395       {
18396          return (ue);
18397       }
18398    }
18399    return (NULLP);
18400 }
18401
18402 static Void rgSCHCmnDelDedPreamble(RgSchCellCb *cell,uint8_t preambleId)
18403 {
18404    RgSchCmnCell  *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18405    CmLList       *node;
18406    CmLListCp     *ueLst;
18407    RgSchUeCb     *ue;
18408    RgSchCmnDlUe  *ueDl;
18409
18410    ueLst = &cellSch->rachCfg.hoUeLst;
18411    node = ueLst->first;
18412    while (node)
18413    {
18414       ue = (RgSchUeCb *)node->node;
18415       node = node->next;
18416       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18417       if (ueDl->rachInfo.hoRapId == preambleId)
18418       {
18419          cmLListDelFrm(ueLst, &ueDl->rachInfo.hoLnk);
18420          ueDl->rachInfo.hoLnk.node = (PTR)NULLP;
18421       }
18422    }
18423 }
18424
18425 /**
18426  * @brief This function retrieves the UE which has sent this raReq
18427  * for PDCCh Order case.
18428  *
18429  *
18430  * @details
18431  *
18432  *     Function: rgSCHCmnGetPoUe
18433  *     Purpose:  This function retrieves the UE which has sent this raReq
18434  *     for PDCCH Order case.
18435  *
18436  *     Invoked by: Common Scheduler
18437  *
18438  *  @param[in]  RgSchCellCb           *cell
18439  *  @param[in]  RgSchRaReqInfo        *raReq
18440  *  @return  RgSchUeCb*
18441  *
18442  **/
18443 RgSchUeCb* rgSCHCmnGetPoUe
18444 (
18445 RgSchCellCb     *cell,
18446 uint16_t        rapId,
18447 CmLteTimingInfo timingInfo
18448 )
18449 {
18450    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
18451    CmLList      *node;
18452    CmLListCp    *ueLst;
18453    RgSchUeCb    *ue;
18454    RgSchCmnDlUe *ueDl;
18455    uint8_t      rapIdIdx;
18456
18457    rapIdIdx = rapId -cellSch->rachCfg.dedPrmStart;
18458    ueLst = &cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes;
18459    node = ueLst->first;
18460    while (node)
18461    {
18462       ue = (RgSchUeCb *)node->node;
18463       node = node->next;
18464       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
18465       /* Remove UEs irrespective.
18466        * Old UE associations are removed.*/
18467       cmLListDelFrm(ueLst, &ueDl->rachInfo.rapIdLnk);
18468       ueDl->rachInfo.rapIdLnk.node = (PTR)NULLP;
18469       if (RGSCH_TIMEINFO_SAME(ueDl->rachInfo.asgnOppr, timingInfo))
18470       {
18471          return (ue);
18472       }
18473    }
18474
18475    return (NULLP);
18476 }
18477
18478
18479 /**
18480  * @brief This function returns the valid UL cqi for a given UE.
18481  *
18482  * @details
18483  *
18484  *     Function: rgSCHCmnUlGetCqi
18485  *     Purpose:  This function returns the "valid UL cqi" for a given UE
18486  *               based on UE category
18487  *
18488  *     Invoked by: Scheduler
18489  *     
18490  *  @param[in]  RgSchUeCb        *ue
18491  *  @param[in]  uint8_t               ueCtgy
18492  *  @return     uint8_t 
18493  **/
18494 uint8_t rgSCHCmnUlGetCqi
18495 (
18496 RgSchCellCb      *cell,
18497 RgSchUeCb        *ue,
18498 CmLteUeCategory  ueCtgy
18499 )
18500 {
18501    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18502    uint8_t            cqi;
18503
18504    
18505    cqi = ueUl->maxUlCqi;
18506 #ifdef TFU_UPGRADE
18507    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
18508         (ueUl->validUlCqi > ueUl->maxUlCqi)))
18509    {
18510       cqi = ueUl->validUlCqi;
18511    }
18512 #else   
18513    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
18514          (ueUl->crntUlCqi[0] > ueUl->maxUlCqi )))
18515    {
18516       cqi = ueUl->crntUlCqi[0];
18517    }
18518 #endif    
18519    return (cqi);
18520 }/* End of rgSCHCmnUlGetCqi */
18521
18522 /***********************************************************
18523  *
18524  *     Func : rgSCHCmnUlRbAllocForPoHoUe
18525  *
18526  *     Desc : Do uplink RB allocation for a HO/PO UE.
18527  *
18528  *     Ret  :
18529  *
18530  *     Notes: Note that as of now, for retx, maxRb
18531  *            is not considered. Alternatives, such
18532  *            as dropping retx if it crosses maxRb
18533  *            could be considered.
18534  *
18535  *     File :
18536  *
18537  **********************************************************/
18538 static S16 rgSCHCmnUlRbAllocForPoHoUe
18539 (
18540 RgSchCellCb  *cell,
18541 RgSchUlSf    *sf,
18542 RgSchUeCb    *ue,
18543 uint8_t      maxRb
18544 )
18545 {
18546    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18547    RgSchCmnUlUe      *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18548    uint8_t           sbSize  = cellUl->sbSize;
18549    uint32_t          maxBits = ue->ul.maxBytesPerUePerTti*8;
18550    uint32_t          bits;
18551    RgSchUlAlloc      *alloc;
18552    uint32_t          nPrb;
18553    uint8_t           iTbs;
18554    uint32_t          eff;
18555    uint32_t          numSb;
18556    uint8_t           iMcs;
18557    uint8_t           iMcsCrnt;
18558    uint8_t           cqi;
18559    uint8_t           modOdr;
18560    RgSchUlHole      *hole;
18561    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->msg3SchdHqProcIdx];
18562    CmLteUeCategory  ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
18563
18564    if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
18565    {
18566       return RFAILED;
18567    }
18568    /*MS_WORKAROUND for HO ccpu00121116*/
18569    cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
18570    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend], cqi);
18571    iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
18572    iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
18573    while(iMcs > RG_SCH_CMN_MAX_MSG3_IMCS)
18574    {
18575        cqi--;
18576        iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
18577        iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg);
18578    }
18579    /* Filling the modorder in the grant structure*/
18580    RG_SCH_UL_MCS_TO_MODODR(iMcs,modOdr);
18581    if (!cell->isCpUlExtend)
18582    {
18583       eff   = rgSchCmnNorUlEff[0][iTbs];
18584    }
18585    else
18586    {
18587       eff   = rgSchCmnExtUlEff[0][iTbs];
18588    }
18589
18590    bits = ueUl->alloc.reqBytes * 8;
18591
18592 #if (ERRCLASS & ERRCLS_DEBUG)
18593    if (!bits)
18594    {
18595       return RFAILED;
18596    }
18597 #endif
18598
18599    if (bits < rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs))
18600    {
18601       numSb = 1;
18602       nPrb = numSb * sbSize;
18603    }
18604    else
18605    {
18606       if (bits > maxBits)
18607       {
18608          bits  = maxBits;
18609          nPrb  = bits * 1024 / eff / RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
18610          if (nPrb > maxRb)
18611          {
18612             nPrb = maxRb;
18613          }
18614          numSb = nPrb / sbSize;
18615       }
18616       else
18617       {
18618          /*ccpu00128775:MOD-Change to get upper threshold nPrb*/
18619          nPrb = RGSCH_CEIL((RGSCH_CEIL(bits * 1024, eff)),
18620                   RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl));
18621          if (nPrb > maxRb)
18622          {
18623             nPrb = maxRb;
18624          }
18625          numSb = RGSCH_DIV_ROUND(nPrb, sbSize);
18626       }
18627    }
18628    iMcsCrnt = iMcs;
18629
18630    alloc = rgSCHCmnUlSbAlloc(sf, (uint8_t)RGSCH_MIN(numSb, cellUl->maxSbPerUe),\
18631                              hole);
18632    if (alloc == NULLP)
18633    {
18634       DU_LOG("\nERROR  -->  SCH : rgSCHCmnUlRbAllocForPoHoUe(): Could not get UlAlloc");
18635       return RFAILED;
18636    }
18637    rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
18638    
18639    /* Filling the modorder in the grant structure start*/
18640    alloc->grnt.modOdr = (TfuModScheme) modOdr;
18641    alloc->grnt.iMcs = iMcs;
18642    alloc->grnt.iMcsCrnt = iMcsCrnt;
18643    alloc->grnt.hop = 0;
18644    /* Fix for ccpu00123915*/
18645    alloc->forMsg3 = TRUE;
18646    alloc->hqProc = proc;
18647    alloc->hqProc->ulSfIdx = cellUl->msg3SchdIdx;
18648    alloc->ue = ue;
18649    alloc->rnti = ue->ueId;
18650    /* updating initNumRbs in case of HO */
18651 #ifdef TFU_UPGRADE
18652    ue->initNumRbs = alloc->grnt.numRb;
18653 #endif
18654    ueUl->alloc.alloc = alloc;
18655    iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
18656    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs);
18657    alloc->grnt.datSz    = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
18658    /* MS_WORKAROUND for HO ccpu00121124*/
18659    /*[Adi temp change] Need to fil modOdr */
18660    RG_SCH_UL_MCS_TO_MODODR(alloc->grnt.iMcsCrnt,alloc->grnt.modOdr);
18661    rgSCHUhmNewTx(proc, ueUl->hqEnt.maxHqRetx, alloc);
18662    /* No grant attr recorded now */
18663    return ROK;
18664 }
18665
18666 /**
18667  * @brief This function allocates grant for UEs undergoing (for which RAR
18668  * is being generated) HandOver/PdcchOrder.
18669  *
18670  *
18671  * @details
18672  *
18673  *     Function: rgSCHCmnAllocPoHoGrnt
18674  *     Purpose:  This function allocates grant for UEs undergoing (for which RAR
18675  *               is being generated) HandOver/PdcchOrder.
18676  *
18677  *     Invoked by: Common Scheduler
18678  *
18679  *  @param[in]  RgSchCellCb           *cell
18680  *  @param[out] CmLListCp             *raRspLst,
18681  *  @param[in]  RgSchUeCb             *ue
18682  *  @param[in]  RgSchRaReqInfo        *raReq
18683  *  @return  Void
18684  *
18685  **/
18686 static Void rgSCHCmnAllocPoHoGrnt
18687 (
18688 RgSchCellCb     *cell,
18689 CmLListCp       *raRspLst,
18690 RgSchUeCb       *ue,
18691 RgSchRaReqInfo  *raReq
18692 )
18693 {
18694    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18695    RgSchCmnUlUe    *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
18696    RgSchUlGrnt     *grnt;
18697    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
18698
18699
18700    /* Clearing previous allocs if any*/
18701    rgSCHCmnUlUeDelAllocs(cell, ue);
18702    /* Fix : syed allocs are limited */
18703    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
18704    {
18705       return;
18706    }
18707    ueUl->alloc.reqBytes = RG_SCH_MIN_GRNT_HOPO;
18708    if (rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, RGSCH_MAX_UL_RB) != ROK)
18709    {
18710       return;
18711    }
18712
18713    /* Fill grant information */
18714    grnt = &ueUl->alloc.alloc->grnt;
18715
18716    /* KWork fix */
18717    if (grnt == NULLP)
18718    {
18719       DU_LOG("\nERROR  -->  SCH : Failed to get"
18720         "the grant for HO/PDCCH Order. CRNTI:%d",ue->ueId);
18721       return;
18722    }
18723    ue->ul.rarGrnt.rapId = raReq->raReq.rapId;
18724    ue->ul.rarGrnt.hop = grnt->hop;
18725    ue->ul.rarGrnt.rbStart = grnt->rbStart;
18726    ue->ul.rarGrnt.numRb = grnt->numRb;
18727    ue->ul.rarGrnt.tpc = grnt->tpc;
18728    ue->ul.rarGrnt.iMcsCrnt = grnt->iMcsCrnt;
18729    ue->ul.rarGrnt.ta.pres = TRUE;
18730    ue->ul.rarGrnt.ta.val = raReq->raReq.ta;
18731    ue->ul.rarGrnt.datSz = grnt->datSz;
18732    if((sf->numACqiCount < RG_SCH_MAX_ACQI_PER_ULSF) && (RG_SCH_APCQI_NO != ue->dl.reqForCqi)) 
18733    {
18734 #ifdef LTE_ADV
18735       uint8_t    idx = 0; 
18736       /* Send two bits cqireq field if more than one cells are configured else one*/
18737       for (idx = 1;idx < CM_LTE_MAX_CELLS;idx++)
18738       {
18739          if (ue->cellInfo[idx] != NULLP)
18740          {
18741             ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
18742             break;
18743          }
18744       }
18745       if (idx == CM_LTE_MAX_CELLS)
18746 #endif
18747       {
18748          ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
18749       }
18750       ue->dl.reqForCqi = RG_SCH_APCQI_NO;
18751       sf->numACqiCount++;
18752    }
18753    else
18754    {
18755       ue->ul.rarGrnt.cqiReqBit = 0;
18756    }
18757    /* Attach Ho/Po allocation to RAR Rsp cont free Lst */
18758    cmLListAdd2Tail(raRspLst, &ue->ul.rarGrnt.raRspLnk);
18759    ue->ul.rarGrnt.raRspLnk.node = (PTR)ue;
18760
18761    return;
18762 }
18763
18764 /**
18765  * @brief This is a utility function to set the fields in
18766  * an UL harq proc which is identified for non-adaptive retx
18767  *
18768  * @details
18769  *
18770  *     Function: rgSCHCmnUlNonadapRetx 
18771  *     Purpose:  Sets the fields in UL Harq  proc for non-adaptive retx 
18772  *
18773  * @param[in]  RgSchCmnUlCell  *cellUl 
18774  * @param[out] RgSchUlAlloc    *alloc
18775  * @param[in]  uint8_t              idx 
18776  * @return  Void
18777  *
18778  **/
18779 #ifdef UNUSED_FUNC
18780 static Void rgSCHCmnUlNonadapRetx
18781 (
18782 RgSchCmnUlCell  *cellUl,
18783 RgSchUlAlloc    *alloc,
18784 uint8_t         idx
18785 )
18786 {
18787    rgSCHUhmRetx(alloc->hqProc, alloc);
18788
18789    /* Update alloc to retx */
18790    alloc->hqProc->isRetx = TRUE;
18791    alloc->hqProc->ulSfIdx = cellUl->reTxIdx[idx];
18792
18793    if (alloc->hqProc->rvIdx != 0)
18794    {
18795       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[alloc->hqProc->rvIdx];
18796    }
18797    else
18798    {
18799       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
18800    }
18801    alloc->grnt.isRtx = TRUE;
18802    alloc->pdcch = NULLP;
18803    return;
18804 }
18805 /**
18806  * @brief Check if 2 allocs overlap
18807  *
18808  * @details
18809  *
18810  *     Function : rgSCHCmnUlAllocsOvrLap
18811  *
18812  *      - Return TRUE if alloc1 and alloc2 overlap.
18813  *
18814  *  @param[in]  RgSchUlAlloc  *alloc1
18815  *  @param[in]  RgSchUlAlloc  *alloc2
18816  *  @return  Bool
18817  **/
18818 static Bool rgSCHCmnUlAllocsOvrLap(RgSchUlAlloc *alloc1,RgSchUlAlloc *alloc2)
18819 {
18820
18821    if (((alloc1->sbStart >= alloc2->sbStart) &&
18822          (alloc1->sbStart <= alloc2->sbStart + alloc2->numSb-1)) ||
18823         ((alloc2->sbStart >= alloc1->sbStart) &&
18824          (alloc2->sbStart <= alloc1->sbStart + alloc1->numSb-1)))
18825    {
18826       return (TRUE);
18827    }
18828    return (FALSE);
18829 }
18830 /**
18831  * @brief Copy allocation Info from src to dst.
18832  *
18833  * @details
18834  *
18835  *     Function : rgSCHCmnUlCpyAllocInfo
18836  *
18837  *      - Copy allocation Info from src to dst.
18838  *
18839  *  @param[in]  RgSchUlAlloc  *srcAlloc
18840  *  @param[in]  RgSchUlAlloc  *dstAlloc
18841  *  @return  Void
18842  **/
18843 static Void rgSCHCmnUlCpyAllocInfo(RgSchCellCb *cell,RgSchUlAlloc *srcAlloc,RgSchUlAlloc *dstAlloc)
18844 {
18845    RgSchCmnUlUe *ueUl;
18846
18847    dstAlloc->grnt = srcAlloc->grnt;
18848    dstAlloc->hqProc = srcAlloc->hqProc;
18849    /* Fix : syed During UE context release, hqProc->alloc
18850     * was pointing to srcAlloc instead of dstAlloc and
18851     * freeing from incorrect sf->allocDb was
18852     * corrupting the list. */
18853     /* In case of SPS Occasion Allocation is done in advance and 
18854        at a later time Hq Proc is linked. Hence HqProc
18855        pointer in alloc shall be NULL */
18856 #ifdef LTEMAC_SPS
18857    if (dstAlloc->hqProc)
18858 #endif
18859    {
18860       dstAlloc->hqProc->alloc = dstAlloc;
18861    }
18862    dstAlloc->ue = srcAlloc->ue;
18863    dstAlloc->rnti = srcAlloc->rnti;
18864    dstAlloc->forMsg3 = srcAlloc->forMsg3;
18865    dstAlloc->raCb  = srcAlloc->raCb;
18866    dstAlloc->pdcch = srcAlloc->pdcch;
18867    /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
18868    if (dstAlloc->ue)
18869    {
18870       ueUl = RG_SCH_CMN_GET_UL_UE(dstAlloc->ue,cell);
18871       ueUl->alloc.alloc = dstAlloc;
18872 #ifdef LTEMAC_SPS
18873       if (dstAlloc->ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
18874       {
18875          if((dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc != NULLP)
18876                && (dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc == srcAlloc))
18877          {
18878             dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc = dstAlloc;
18879          }
18880       }
18881 #endif
18882    }
18883
18884    return;
18885 }
18886 /**
18887  * @brief Update TX and RETX subframe's allocation
18888  *        markings.
18889  *
18890  * @details
18891  *
18892  *     Function : rgSCHCmnUlInsAllocFrmNewSf2OldSf
18893  *
18894  *      - Release all preassigned allocations of newSf and merge
18895  *        them to oldSf.
18896  *      - If alloc of newSf collide with one or more allocs of oldSf
18897  *        - mark all such allocs of oldSf for Adaptive Retx.
18898  *      - Swap the alloc and hole DB references of oldSf and newSf.
18899  *
18900  *  @param[in]  RgSchCellCb   *cell
18901  *  @param[in]  RgSchUlSf     *newSf
18902  *  @param[in]  RgSchUlSf     *oldSf
18903  *  @param[in]  RgSchUlAlloc  *srcAlloc
18904  *  @return  Void
18905  **/
18906 static Void rgSCHCmnUlInsAllocFrmNewSf2OldSf
18907 (
18908 RgSchCellCb     *cell,
18909 RgSchUlSf       *newSf,
18910 RgSchUlSf       *oldSf,
18911 RgSchUlAlloc    *srcAlloc
18912 )
18913 {
18914    RgSchUlAlloc   *alloc, *dstAlloc, *nxtAlloc;
18915
18916    /* MS_WORKAROUND ccpu00120827 */
18917    RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
18918    uint8_t remAllocs;
18919
18920    if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
18921    {
18922       do
18923       {
18924          nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);
18925          /* If there is an overlap between alloc and srcAlloc
18926           * then alloc is marked for Adaptive retx and it is released
18927           * from txSf */
18928          if (rgSCHCmnUlAllocsOvrLap(alloc, srcAlloc) == TRUE)
18929          {
18930             rgSCHCmnUlUpdAllocRetx(cell, alloc);
18931             rgSCHUtlUlAllocRls(oldSf, alloc);
18932          }
18933          /* No further allocs spanning the srcAlloc subbands */
18934          if (srcAlloc->sbStart + srcAlloc->numSb - 1  <= alloc->sbStart)
18935          {
18936             break;
18937          }
18938       } while ((alloc = nxtAlloc) != NULLP);
18939    }
18940
18941    /* After freeing all the colliding allocs, request for an allocation
18942     * specifying the start and numSb with in txSf. This function should
18943     * always return positively with a nonNULL dstAlloc */
18944     /* MS_WORKAROUND ccpu00120827 */
18945    remAllocs = schCmnCell->ul.maxAllocPerUlSf - *oldSf->allocCountRef;
18946    if (!remAllocs)
18947    {
18948       /* Fix : If oldSf already has max Allocs then release the
18949        * old RETX alloc to make space for new alloc of newSf.
18950        * newSf allocs(i.e new Msg3s) are given higher priority
18951        * over retx allocs. */      
18952       if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
18953       {
18954          do
18955          {
18956             nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);           
18957             if (!alloc->mrgdNewTxAlloc)
18958             {
18959                /* If alloc is for RETX */                   
18960                /* TODO: Incase of this ad also in case of choosing
18961                 * and alloc for ADAP RETX, we need to send ACK for
18962                 * the corresponding alloc in PHICH */               
18963 #ifndef EMTC_ENABLE
18964                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc);
18965 #else
18966                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc,FALSE);
18967 #endif
18968                break;
18969             }               
18970          }while((alloc = nxtAlloc) != NULLP);
18971       }
18972    }
18973    dstAlloc = rgSCHUtlUlGetSpfcAlloc(oldSf, srcAlloc->sbStart, srcAlloc->numSb);
18974 #ifdef ERRCLS_KW
18975    /* This should never happen */
18976    if (dstAlloc == NULLP)
18977    {
18978       DU_LOG("\nERROR  -->  SCH : CRNTI:%d "
18979          "rgSCHUtlUlGetSpfcAlloc failed in rgSCHCmnUlInsAllocFrmNewSf2OldSf",
18980          srcAlloc->rnti);
18981       return;
18982    }
18983 #endif
18984    /* Copy the srcAlloc's state information in to dstAlloc */
18985    rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc);
18986    /* Set new Tx merged Alloc Flag to TRUE, indicating that this
18987     * alloc shall not be processed for non-adaptive retransmission */
18988    dstAlloc->mrgdNewTxAlloc = TRUE;
18989    return;
18990 }
18991 /**
18992  * @brief Merge all allocations of newSf to oldSf.
18993  *
18994  * @details
18995  *
18996  *     Function : rgSCHCmnUlMergeSfAllocs
18997  *
18998  *      - Merge all allocations of newSf to oldSf.
18999  *      - If newSf's alloc collides with oldSf's alloc
19000  *        then oldSf's alloc is marked for adaptive Retx
19001  *        and is released from oldSf to create space for
19002  *        newSf's alloc.
19003  *
19004  *  @param[in]  RgSchCellCb  *cell
19005  *  @param[in]  RgSchUlSf    *oldSf
19006  *  @param[in]  RgSchUlSf    *newSf
19007  *  @return  Void
19008  **/
19009 static Void rgSCHCmnUlMergeSfAllocs(RgSchCellCb *cell,RgSchUlSf  *oldSf,RgSchUlSf  *newSf)
19010 {
19011    RgSchUlAlloc    *alloc, *nxtAlloc;
19012    UNUSED(cell);
19013
19014    /* Merge each alloc of newSf in to oldSf
19015     * and release it from newSf */
19016    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
19017    {
19018       do
19019       {
19020          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
19021          rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, alloc);
19022          rgSCHUtlUlAllocRls(newSf, alloc);
19023       } while((alloc = nxtAlloc) != NULLP);
19024    }
19025    return;
19026 }
19027 /**
19028  * @brief Swap Hole/Alloc DB context of newSf and oldSf.
19029  *
19030  * @details
19031  *
19032  *     Function : rgSCHCmnUlSwapSfAllocs
19033  *
19034  *      - Swap Hole/Alloc DB context of newSf and oldSf.
19035  *
19036  *  @param[in]  RgSchCellCb  *cell
19037  *  @param[in]  RgSchUlSf    *oldSf
19038  *  @param[in]  RgSchUlSf    *newSf
19039  *  @return  Void
19040  **/
19041 static Void rgSCHCmnUlSwapSfAllocs(RgSchCellCb *cell,RgSchUlSf  *oldSf,RgSchUlSf  *newSf)
19042 {
19043    RgSchUlAllocDb *tempAllocDb  = newSf->allocDb;
19044    RgSchUlHoleDb  *tempHoleDb   = newSf->holeDb;
19045    uint8_t        tempAvailSbs = newSf->availSubbands;
19046
19047    UNUSED(cell);
19048
19049    newSf->allocDb       = oldSf->allocDb;
19050    newSf->holeDb        = oldSf->holeDb;
19051    newSf->availSubbands = oldSf->availSubbands;
19052
19053    oldSf->allocDb = tempAllocDb;
19054    oldSf->holeDb  = tempHoleDb;
19055    oldSf->availSubbands = tempAvailSbs;
19056       
19057    /* Fix ccpu00120610*/
19058    newSf->allocCountRef = &newSf->allocDb->count;
19059    oldSf->allocCountRef = &oldSf->allocDb->count;
19060    return;
19061 }
19062 /**
19063  * @brief Perform non-adaptive RETX for non-colliding allocs.
19064  *
19065  * @details
19066  *
19067  *     Function : rgSCHCmnUlPrcNonAdptRetx
19068  *
19069  *      - Perform non-adaptive RETX for non-colliding allocs.
19070  *
19071  *  @param[in]  RgSchCellCb  *cell
19072  *  @param[in]  RgSchUlSf    *newSf
19073  *  @param[in]  uint8_t           idx
19074  *  @return  Void
19075  **/
19076 static Void rgSCHCmnUlPrcNonAdptRetx(RgSchCellCb *cell,RgSchUlSf  *newSf,uint8_t idx)
19077 {
19078    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19079    RgSchUlAlloc    *alloc, *nxtAlloc;
19080
19081    /* perform non-adaptive retx allocation(adjustment) */
19082    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
19083    {
19084       do
19085       {
19086          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
19087          /* A merged new TX alloc, reset the state and skip */
19088          if (alloc->mrgdNewTxAlloc)
19089          {
19090             alloc->mrgdNewTxAlloc = FALSE;
19091             continue;
19092          }
19093          
19094
19095          rgSCHCmnUlNonadapRetx(cellUl, alloc, idx);
19096
19097       } while((alloc = nxtAlloc) != NULLP);
19098    }
19099    return;
19100 }
19101
19102 /**
19103  * @brief Update TX and RETX subframe's allocation
19104  *        markings.
19105  *
19106  * @details
19107  *
19108  *     Function : rgSCHCmnUlPrfmSfMerge
19109  *
19110  *      - Release all preassigned allocations of newSf and merge
19111  *        them to oldSf.
19112  *      - If alloc of newSf collide with one or more allocs of oldSf
19113  *        - mark all such allocs of oldSf for Adaptive Retx.
19114  *      - Swap the alloc and hole DB references of oldSf and newSf.
19115  *      - The allocs which did not collide with pre-assigned msg3
19116  *        allocs are marked for non-adaptive RETX.
19117  *
19118  *  @param[in]  RgSchCellCb  *cell
19119  *  @param[in]  RgSchUlSf    *oldSf
19120  *  @param[in]  RgSchUlSf    *newSf
19121  *  @param[in]  uint8_t           idx 
19122  *  @return  Void
19123  **/
19124 static Void rgSCHCmnUlPrfmSfMerge
19125 (
19126 RgSchCellCb  *cell,
19127 RgSchUlSf    *oldSf,
19128 RgSchUlSf    *newSf,
19129 uint8_t      idx
19130 )
19131 {
19132    /* Preassigned resources for msg3 in newSf.
19133     * Hence do adaptive retx for all NACKED TXs */
19134    rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf);
19135    /* swap alloc and hole DBs of oldSf and newSf. */
19136    rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf);
19137    /* Here newSf has the resultant merged allocs context */
19138    /* Perform non-adaptive RETX for non-colliding allocs */
19139    rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx);
19140    
19141    return;
19142 }
19143 #endif
19144 /**
19145  * @brief Update TX and RETX subframe's allocation
19146  *        markings.
19147  *
19148  * @details
19149  *
19150  *     Function : rgSCHCmnUlRmvCmpltdAllocs
19151  *
19152  *      - Free all Transmission which are ACKED
19153  *        OR for which MAX retransmission have
19154  *        occurred.
19155  *
19156  *
19157  *  @param[in]  RgSchCellCb    *cell,
19158  *  @param[in]  RgSchUlSf      *sf
19159  *  @return  Void
19160  **/
19161 static Void rgSCHCmnUlRmvCmpltdAllocs(RgSchCellCb *cell,RgSchUlSf *sf)
19162 {
19163    RgSchUlAlloc    *alloc, *nxtAlloc;
19164
19165    if ((alloc = rgSCHUtlUlAllocFirst(sf)) == NULLP)
19166    {
19167       return;
19168    }
19169    do
19170    {
19171       nxtAlloc = rgSCHUtlUlAllocNxt(sf, alloc);
19172 #ifdef UL_ADPT_DBG      
19173       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);
19174 #endif
19175       alloc->hqProc->rcvdCrcInd = TRUE;
19176       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
19177       {
19178
19179         /* SR_RACH_STATS : MSG 3 MAX RETX FAIL*/
19180          if ((alloc->forMsg3 == TRUE) && (alloc->hqProc->remTx == 0))
19181          {
19182             rgNumMsg3FailMaxRetx++;
19183 #ifdef TENB_STATS
19184             cell->tenbStats->sch.msg3Fail++;
19185 #endif
19186          }
19187
19188 #ifdef MAC_SCH_STATS
19189     if(alloc->ue != NULLP)
19190     {
19191        /* access from ulHarqProc*/
19192        RgSchUeCb       *ueCb  = alloc->ue;
19193        RgSchCmnUe      *cmnUe = (RgSchCmnUe*)ueCb->sch;
19194        RgSchCmnUlUe    *ulUe  = &(cmnUe->ul);
19195        uint8_t              cqi    = ulUe->crntUlCqi[0];  
19196        uint16_t             numUlRetx = ueCb->ul.hqEnt.maxHqRetx - alloc->hqProc->remTx;
19197
19198        hqRetxStats.ulCqiStat[(cqi - 1)].mcs = alloc->grnt.iMcs;
19199
19200        switch (numUlRetx)
19201        {
19202           case 1:
19203              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1++;
19204              break;
19205           case 2:
19206              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2++;
19207              break;
19208          case 3:
19209             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3++;
19210             break;
19211          case 4:
19212             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4++;
19213             break;
19214       }
19215       hqRetxStats.ulCqiStat[(cqi - 1)].totalTx = \
19216              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1 + \
19217             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
19218             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
19219             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4 * 4);
19220    }
19221
19222 #endif /*MAC_SCH_STATS*/
19223          rgSCHCmnUlFreeAllocation(cell, sf, alloc);
19224       }
19225       /*ccpu00106104 MOD added check for AckNackRep */
19226       /*added check for acknack so that adaptive retx considers ue
19227        inactivity due to ack nack repetition*/
19228       else if((alloc->ue != NULLP) && (TRUE != alloc->forMsg3))
19229       {
19230         rgSCHCmnUlUpdAllocRetx(cell, alloc);
19231         rgSCHUtlUlAllocRls(sf, alloc);
19232       }
19233    } while ((alloc = nxtAlloc) != NULLP);
19234
19235    return;
19236 }
19237
19238 /**
19239  * @brief Update an uplink subframe.
19240  *
19241  * @details
19242  *
19243  *     Function : rgSCHCmnRlsUlSf
19244  *
19245  *     For each allocation
19246  *      - if no more tx needed
19247  *         - Release allocation
19248  *      - else
19249  *         - Perform retransmission
19250  *
19251  *  @param[in]  RgSchUlSf *sf
19252  *  @param[in]  uint8_t        idx 
19253  *  @return  Void
19254  **/
19255 Void rgSCHCmnRlsUlSf(RgSchCellCb *cell,uint8_t idx)
19256 {
19257
19258    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19259    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) 
19260    {
19261       RgSchUlSf   *oldSf  = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
19262
19263       /* Initialize the reTxLst of UL HqProcs for RETX subframe */
19264       if (rgSCHUtlUlAllocFirst(oldSf) == NULLP)
19265       {
19266          return;
19267       }
19268       /* Release all completed TX allocs from sf */
19269       rgSCHCmnUlRmvCmpltdAllocs(cell, oldSf);
19270
19271       oldSf->numACqiCount = 0;
19272    }
19273    return;
19274 }
19275
19276 /**
19277  * @brief Handle uplink allocation for retransmission.
19278  *
19279  * @details
19280  *
19281  *     Function : rgSCHCmnUlUpdAllocRetx
19282  *
19283  *     - Perform adaptive retransmission
19284  *
19285  *  @param[in]  RgSchUlSf *sf
19286  *  @param[in]  RgSchUlAlloc  *alloc
19287  *  @return  Void
19288  **/
19289 static Void rgSCHCmnUlUpdAllocRetx(RgSchCellCb *cell,RgSchUlAlloc *alloc)
19290 {
19291    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
19292
19293    alloc->hqProc->reTxAlloc.rnti    =  alloc->rnti;
19294    alloc->hqProc->reTxAlloc.numSb   =  alloc->numSb;
19295    alloc->hqProc->reTxAlloc.iMcs   =  alloc->grnt.iMcs;
19296 #ifdef RG_5GTF
19297    alloc->hqProc->reTxAlloc.dciFrmt =  alloc->grnt.dciFrmt;
19298    alloc->hqProc->reTxAlloc.numLyr   =  alloc->grnt.numLyr;
19299    alloc->hqProc->reTxAlloc.vrbgStart =  alloc->grnt.vrbgStart;
19300    alloc->hqProc->reTxAlloc.numVrbg   =  alloc->grnt.numVrbg;
19301    alloc->hqProc->reTxAlloc.modOdr   =  alloc->grnt.modOdr;
19302 #endif
19303    //iTbs = rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
19304    //iTbs = alloc->grnt.iMcs;
19305    //RGSCH_ARRAY_BOUND_CHECK( 0, rgTbSzTbl[0], iTbs);
19306    alloc->hqProc->reTxAlloc.tbSz = alloc->grnt.datSz;
19307       //rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1]/8;
19308    alloc->hqProc->reTxAlloc.ue      = alloc->ue;
19309    alloc->hqProc->reTxAlloc.forMsg3 = alloc->forMsg3;
19310    alloc->hqProc->reTxAlloc.raCb = alloc->raCb;
19311
19312    /* Set as retransmission is pending */
19313    alloc->hqProc->isRetx = TRUE;
19314    alloc->hqProc->alloc = NULLP;
19315    alloc->hqProc->ulSfIdx = RGSCH_INVALID_INFO;
19316 #ifdef UL_ADPT_DBG  
19317    DU_LOG("\nDEBUG  -->  SCH : Adding Harq Proc Id in the retx list  hqProcId %d \n",alloc->grnt.hqProcId); 
19318 #endif
19319    cmLListAdd2Tail(&cmnUlCell->reTxLst, &alloc->hqProc->reTxLnk);
19320    alloc->hqProc->reTxLnk.node = (PTR)alloc->hqProc;
19321    return;
19322 }
19323
19324 /**
19325  * @brief Attempts allocation for msg3s for which ADAP retransmissions
19326  *     are required.
19327  *
19328  * @details
19329  *
19330  *     Function : rgSCHCmnUlAdapRetxAlloc
19331  *
19332  *     Attempts allocation for msg3s for which ADAP retransmissions
19333  *     are required.
19334  *
19335  *  @param[in]  RgSchCellCb       *cell
19336  *  @param[in]  RgSchUlSf         *sf
19337  *  @param[in]  RgSchUlHqProcCb   *proc;
19338  *  @param[in]  RgSchUlHole       *hole;
19339  *  @return  uint8_t
19340  **/
19341 static Bool rgSCHCmnUlAdapRetxAlloc
19342 (
19343 RgSchCellCb       *cell,
19344 RgSchUlSf         *sf,
19345 RgSchUlHqProcCb   *proc,
19346 RgSchUlHole       *hole
19347 )
19348 {
19349    uint8_t         numSb = proc->reTxAlloc.numSb;
19350    uint8_t         iMcs  = proc->reTxAlloc.iMcs;
19351    CmLteTimingInfo frm = cell->crntTime;
19352    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19353    RgSchDlSf       *dlSf;
19354    RgSchPdcch      *pdcch;
19355    RgSchUlAlloc    *alloc;
19356
19357    /* Fetch PDCCH for msg3 */
19358    /* ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
19359    /* Introduced timing delta for UL control */
19360    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
19361    dlSf = rgSCHUtlSubFrmGet(cell, frm);
19362    pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
19363    if (pdcch == NULLP)
19364    {
19365       return (FALSE);
19366    }
19367
19368    /* Fetch UL Alloc for msg3 */
19369    if (numSb <= hole->num)
19370    {
19371       alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
19372       
19373       /* KWork fix */
19374          if(alloc == NULLP)
19375          {
19376             rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
19377             DU_LOG("\nERROR  -->  SCH : UL Alloc fail for msg3 retx for rnti: %d\n", 
19378                   proc->reTxAlloc.rnti);
19379             return (FALSE);
19380          }
19381
19382       rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
19383       alloc->grnt.iMcs     = iMcs;
19384       alloc->grnt.datSz    = proc->reTxAlloc.tbSz;
19385 #ifdef RG_5GTF
19386 #else
19387       //RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
19388 #endif
19389       /* Fill UL Alloc for msg3 */
19390       /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
19391       alloc->grnt.nDmrs    = 0;
19392       alloc->grnt.hop      = 0;
19393       alloc->grnt.delayBit = 0;
19394       alloc->grnt.isRtx    = TRUE;
19395       proc->ulSfIdx        = cellUl->schdIdx;
19396 #ifdef RG_5GTF
19397       proc->schdTime = cellUl->schdTime;
19398       alloc->grnt.hqProcId = proc->procId;
19399       alloc->grnt.dciFrmt = proc->reTxAlloc.dciFrmt;
19400       alloc->grnt.numLyr = proc->reTxAlloc.numLyr;
19401       alloc->grnt.vrbgStart = proc->reTxAlloc.vrbgStart;
19402       alloc->grnt.numVrbg = proc->reTxAlloc.numVrbg;
19403       alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
19404       alloc->grnt.modOdr = proc->reTxAlloc.modOdr;
19405
19406       /* TODO : Hardcoding these as of now */
19407       alloc->grnt.hop = 0;
19408       alloc->grnt.SCID = 0;
19409       alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
19410       alloc->grnt.PMI = 0;
19411       alloc->grnt.uciOnxPUSCH = 0;
19412 #endif
19413       alloc->rnti          = proc->reTxAlloc.rnti;
19414       /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
19415       alloc->ue            = proc->reTxAlloc.ue;
19416       alloc->pdcch         = pdcch;
19417       alloc->forMsg3       = proc->reTxAlloc.forMsg3;
19418       alloc->raCb          = proc->reTxAlloc.raCb;
19419       alloc->hqProc        = proc;
19420       alloc->isAdaptive    = TRUE;
19421 #ifdef LTE_L2_MEAS
19422       sf->totPrb  += alloc->grnt.numRb;
19423 #endif
19424       /* FIX : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
19425       if (alloc->raCb)
19426       {
19427          alloc->raCb->msg3Grnt= alloc->grnt;
19428 #ifndef LTE_TDD
19429          /* To the crntTime, add the time at which UE will
19430           * actually send MSG3 */
19431          alloc->raCb->msg3AllocTime = cell->crntTime;
19432          RGSCH_INCR_SUB_FRAME(alloc->raCb->msg3AllocTime, RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL);
19433 #else
19434          alloc->raCb->msg3AllocTime =  cellUl->schdTime;
19435 #endif
19436          rgSCHCmnUlAdapRetx(alloc, proc);
19437          /* Fill PDCCH with alloc info */
19438          pdcch->rnti                           = alloc->rnti;
19439          pdcch->dci.dciFormat                  = TFU_DCI_FORMAT_0;
19440          pdcch->dci.u.format0Info.hoppingEnbld = alloc->grnt.hop;
19441          pdcch->dci.u.format0Info.rbStart      = alloc->grnt.rbStart;
19442          pdcch->dci.u.format0Info.numRb        = alloc->grnt.numRb;
19443          pdcch->dci.u.format0Info.mcs          = alloc->grnt.iMcsCrnt;
19444          pdcch->dci.u.format0Info.ndi          = alloc->hqProc->ndi;
19445          pdcch->dci.u.format0Info.nDmrs        = alloc->grnt.nDmrs;
19446          pdcch->dci.u.format0Info.tpcCmd       = alloc->grnt.tpc;
19447
19448 #ifdef LTE_TDD
19449 #ifdef TFU_TDD
19450          /* ulIdx setting for cfg 0 shall be appropriately fixed thru ccpu00109015 */
19451          pdcch->dci.u.format0Info.ulIdx = RG_SCH_ULIDX_MSB;
19452          pdcch->dci.u.format0Info.dai = RG_SCH_MAX_DAI_IDX;
19453 #endif
19454 #endif
19455          pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_0];
19456       }
19457       else
19458       {
19459          RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(alloc->ue,cell);
19460 #ifdef TFU_UPGRADE
19461          alloc->ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
19462 #endif
19463 #ifdef LTE_L2_MEAS
19464          ue->ul.nPrb = alloc->grnt.numRb;
19465 #endif
19466          ueUl->alloc.alloc = alloc;
19467          /* FIx: Removed the call to rgSCHCmnUlAdapRetx */
19468          rgSCHCmnUlUeFillAllocInfo(cell, alloc->ue);
19469          /* Setting csireq as false for Adaptive Retx*/
19470          ueUl->alloc.alloc->pdcch->dci.u.format0Info.cqiReq = RG_SCH_APCQI_NO;
19471          pdcch->dciNumOfBits = alloc->ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
19472       }
19473       /* Reset as retransmission is done */
19474       proc->isRetx = FALSE;
19475    }
19476    else /* Intg fix */
19477    {
19478       rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
19479       DU_LOG("\nERROR  -->  SCH : Num SB not suffiecient for adap retx for rnti: %d", 
19480                proc->reTxAlloc.rnti);
19481       return (FALSE);
19482    }
19483    return (TRUE);
19484 }
19485
19486 /* Fix: syed Adaptive Msg3 Retx crash. */
19487 /**
19488  * @brief Releases all Adaptive Retx HqProcs which failed for
19489  *        allocations in this scheduling occassion.
19490  *
19491  * @details
19492  *
19493  *     Function : rgSCHCmnUlSfRlsRetxProcs
19494  *
19495  *
19496  *  @param[in]  RgSchCellCb *cell
19497  *  @param[in]  RgSchUlSf   *sf
19498  *  @return  uint8_t
19499  **/
19500 #ifdef UNUSED_FUNC
19501 static Void rgSCHCmnUlSfRlsRetxProcs(RgSchCellCb *cell,RgSchUlSf *sf)
19502 {
19503    CmLListCp         *cp;
19504    CmLList           *node;
19505    RgSchUlHqProcCb   *proc;
19506    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19507
19508    cp = &(cellUl->reTxLst);
19509    node = cp->first;
19510    while (node)
19511    {
19512       proc  = (RgSchUlHqProcCb *)node->node;
19513       node = node->next;
19514       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
19515       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
19516       proc->reTxLnk.node = (PTR)NULLP;
19517    }
19518    return;
19519 }
19520 #endif   
19521
19522 /**
19523  * @brief Attempts allocation for UEs for which retransmissions
19524  *     are required.
19525  *
19526  * @details
19527  *
19528  *     Function : rgSCHCmnUlSfReTxAllocs
19529  *
19530  *     Attempts allocation for UEs for which retransmissions
19531  *     are required.
19532  *
19533  *  @param[in]  RgSchCellCb *cell
19534  *  @param[in]  RgSchUlSf   *sf
19535  *  @return  uint8_t
19536  **/
19537 static Void rgSCHCmnUlSfReTxAllocs(RgSchCellCb *cell,RgSchUlSf  *sf)
19538 {
19539    CmLListCp         *cp;
19540    CmLList           *node;
19541    RgSchUlHqProcCb   *proc;
19542    RgSchUlHole       *hole;
19543    RgSchUeCb         *ue;
19544    RgSchCmnCell      *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
19545    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19546
19547    cp = &(cellUl->reTxLst);
19548    node = cp->first;
19549    while ((node))
19550    {
19551       proc  = (RgSchUlHqProcCb *)node->node;
19552       ue = proc->reTxAlloc.ue;
19553       node = node->next;
19554       /*ccpu00106104 MOD added check for AckNackRep */
19555       /*added check for acknack so that adaptive retx considers ue
19556        inactivity due to ack nack repetition*/
19557       if((ue != NULLP) &&
19558             ((ue->measGapCb.isMeasuring == TRUE)||
19559                (ue->ackNakRepCb.isAckNakRep == TRUE)))
19560       {
19561          continue;
19562       }
19563       /* Fix for ccpu00123917: Check if maximum allocs per UL sf have been exhausted */
19564       if (((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
19565             || (sf->allocDb->count == schCmnCell->ul.maxAllocPerUlSf))
19566       {
19567          /* No more UL BW then return */
19568          break;
19569       }
19570       /* perform adaptive retx for UE's */
19571       if (rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) == FALSE)
19572       {
19573          continue;
19574       }
19575       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
19576       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
19577       /* Fix: syed Adaptive Msg3 Retx crash. */
19578       proc->reTxLnk.node = (PTR)NULLP;
19579    }
19580    return;
19581 }
19582
19583 /**
19584  * @brief Handles RB allocation for downlink.
19585  *
19586  * @details
19587  *
19588  *     Function : rgSCHCmnDlRbAlloc
19589  *
19590  *     Invoking Module Processing:
19591  *     - This function is invoked for DL RB allocation
19592  *
19593  *     Processing Steps:
19594  *     - If cell is frequency selecive,
19595  *       - Call rgSCHDlfsAllocRb().
19596  *     - else,
19597  *       - Call rgSCHCmnNonDlfsRbAlloc().
19598  *
19599  *  @param[in]  RgSchCellCb        *cell
19600  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
19601  *  @return  Void
19602  **/
19603
19604 static Void rgSCHCmnDlRbAlloc(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
19605 {
19606    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
19607
19608    if (cellSch->dl.isDlFreqSel)
19609    {
19610       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR DLFS SCH Enabled\n");
19611       cellSch->apisDlfs->rgSCHDlfsAllocRb(cell, allocInfo);
19612    }
19613    else
19614    {
19615       rgSCHCmnNonDlfsRbAlloc(cell, allocInfo);
19616    }
19617    return;
19618 }
19619
19620 #ifdef LTEMAC_SPS
19621
19622 /**
19623  * @brief Determines number of RBGs and RBG subset sizes for the given DL
19624  * bandwidth and rbgSize
19625  *
19626  * @details
19627  *     Function : rgSCHCmnDlGetRbgInfo
19628  *
19629  *
19630  *     Processing Steps:
19631  *     - Fill-up rbgInfo data structure for given DL bandwidth and rbgSize
19632  *
19633  *   @param[in]  uint8_t             dlTotalBw
19634  *   @param[in]  uint8_t             dlSubsetBw
19635  *   @param[in]  uint8_t             maxRaType1SubsetBw
19636  *   @param[in]  uint8_t             rbgSize
19637  *   @param[out] RgSchBwRbgInfo *rbgInfo
19638  *  @return Void
19639  **/
19640 Void rgSCHCmnDlGetRbgInfo
19641 (
19642 uint8_t        dlTotalBw,
19643 uint8_t        dlSubsetBw,
19644 uint8_t        maxRaType1SubsetBw,
19645 uint8_t        rbgSize,
19646 RgSchBwRbgInfo *rbgInfo
19647 )
19648 {
19649 #ifdef RGSCH_SPS_UNUSED
19650    uint8_t    idx           = 0;
19651    uint8_t    lastRbgIdx    = ((dlTotalBw + rbgSize - 1)/rbgSize) - 1;
19652    uint8_t    currRbgSize   = rbgSize;
19653    uint8_t    subsetSizeIdx = 0;
19654    uint8_t    subsetSize[RG_SCH_NUM_RATYPE1_SUBSETS] = {0};
19655    uint8_t    lastRbgSize = rbgSize - (dlTotalBw - ((dlTotalBw/rbgSize) * rbgSize));
19656    uint8_t    numRaType1Rbgs = (maxRaType1SubsetBw + rbgSize - 1)/rbgSize;
19657 #endif
19658
19659    /* Compute maximum number of SPS RBGs for the cell */
19660    rbgInfo->numRbgs =  ((dlSubsetBw + rbgSize - 1)/rbgSize);
19661
19662 #ifdef RGSCH_SPS_UNUSED
19663    /* Distribute RBGs across subsets except last RBG */
19664    for (;idx < numRaType1Rbgs - 1; ++idx)
19665    {
19666       subsetSize[subsetSizeIdx] += currRbgSize;
19667       subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
19668    }
19669
19670    /* Computation for last RBG */
19671    if (idx == lastRbgIdx)
19672    {
19673       currRbgSize = lastRbgSize;
19674    }
19675    subsetSize[subsetSizeIdx] += currRbgSize;
19676    subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
19677 #endif
19678
19679    /* Update the computed sizes */
19680 #ifdef RGSCH_SPS_UNUSED
19681    rbgInfo->lastRbgSize = currRbgSize;
19682 #endif
19683    rbgInfo->lastRbgSize = rbgSize - 
19684             (dlSubsetBw - ((dlSubsetBw/rbgSize) * rbgSize));
19685 #ifdef RGSCH_SPS_UNUSED
19686    memcpy(rbgInfo->rbgSubsetSize, subsetSize, 4 * sizeof(uint8_t));
19687 #endif
19688    rbgInfo->numRbs = (rbgInfo->numRbgs * rbgSize > dlTotalBw) ?
19689       dlTotalBw:(rbgInfo->numRbgs * rbgSize);
19690    rbgInfo->rbgSize = rbgSize;
19691 }
19692
19693 /**
19694  * @brief Handles RB allocation for Resource allocation type 0
19695  *
19696  * @details
19697  *
19698  *     Function : rgSCHCmnDlRaType0Alloc
19699  *
19700  *     Invoking Module Processing:
19701  *     - This function is invoked for DL RB allocation for resource allocation
19702  *     type 0
19703  *
19704  *     Processing Steps:
19705  *     - Determine the available positions in the rbgMask.
19706  *     - Allocate RBGs in the available positions.
19707  *     - Update RA Type 0, RA Type 1 and RA type 2 masks.
19708  *
19709  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
19710  *  @param[in]   uint8_t             rbsReq
19711  *  @param[in]   RgSchBwRbgInfo *rbgInfo
19712  *  @param[out]  uint8_t             *numAllocRbs
19713  *  @param[out]  RgSchDlSfAllocInfo *resAllocInfo
19714  *  @param[in]   Bool           isPartialAlloc
19715  *
19716  *  @return  Void
19717  **/
19718
19719 uint8_t rgSCHCmnDlRaType0Alloc
19720 (
19721 RgSchDlSfAllocInfo *allocedInfo,
19722 uint8_t            rbsReq,
19723 RgSchBwRbgInfo     *rbgInfo,
19724 uint8_t            *numAllocRbs,
19725 RgSchDlSfAllocInfo *resAllocInfo,
19726 Bool               isPartialAlloc
19727 )
19728 {
19729    /* Note: This function atttempts allocation only full allocation */
19730    uint32_t      remNumRbs, rbgPosInRbgMask, ueRaType2Mask;
19731    uint8_t       type2MaskIdx, cnt, rbIdx;
19732    uint8_t       maskSize, rbg;
19733    uint8_t       bestNumAvailRbs = 0;
19734    uint8_t       usedRbs = 0;
19735    uint8_t       numAllocRbgs = 0;
19736    uint8_t       rbgSize = rbgInfo->rbgSize;
19737    uint32_t      *rbgMask = &(resAllocInfo->raType0Mask);
19738 #ifdef RGSCH_SPS_UNUSED
19739    uint8_t       rbgSubset;
19740    uint32_t      ueRaType1Mask;
19741    uint32_t      *raType1Mask = resAllocInfo->raType1Mask;
19742    uint32_t      *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
19743 #endif
19744    uint32_t      *raType2Mask = resAllocInfo->raType2Mask;
19745
19746    uint32_t      allocedMask = allocedInfo->raType0Mask;
19747
19748    maskSize = rbgInfo->numRbgs;
19749
19750    *numAllocRbs = 0;
19751    RG_SCH_CMN_DL_COUNT_ONES(allocedMask, maskSize, &usedRbs);
19752    if (maskSize == usedRbs)
19753    {
19754       /* All RBGs are allocated, including the last one */
19755       remNumRbs = 0;
19756    }
19757    else
19758    {
19759       remNumRbs = (maskSize - usedRbs - 1) * rbgSize; /* vamsee: removed minus 1 */
19760
19761       /* If last RBG is available, add last RBG size */
19762       if (!(allocedMask & (1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(maskSize - 1))))
19763       {
19764          remNumRbs += rbgInfo->lastRbgSize;
19765       }
19766    }
19767
19768    /* If complete allocation is needed, check if total requested RBs are available else
19769     * check the best available RBs */
19770    if (!isPartialAlloc)
19771    {
19772       if (remNumRbs >= rbsReq)
19773       {
19774          bestNumAvailRbs = rbsReq;
19775       }
19776    }
19777    else
19778    {
19779       bestNumAvailRbs = remNumRbs > rbsReq ? rbsReq : remNumRbs;
19780    }
19781
19782    /* Allocate for bestNumAvailRbs */
19783    if (bestNumAvailRbs)
19784    {
19785       for (rbg = 0; rbg < maskSize - 1; ++rbg)
19786       {
19787          rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
19788          if (!(allocedMask & rbgPosInRbgMask))
19789          {
19790             /* Update RBG mask */
19791             *rbgMask |= rbgPosInRbgMask;
19792
19793             /* Compute RB index of the first RB of the RBG allocated */
19794             rbIdx = rbg * rbgSize;
19795
19796             for (cnt = 0; cnt < rbgSize; ++cnt)
19797             {
19798 #ifdef RGSCH_SPS_UNUSED
19799                ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
19800 #endif
19801                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19802 #ifdef RGSCH_SPS_UNUSED
19803                /* Update RBG mask for RA type 1 */
19804                raType1Mask[rbgSubset] |= ueRaType1Mask;
19805                raType1UsedRbs[rbgSubset]++;
19806 #endif
19807                /* Update RA type 2 mask */
19808                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19809                rbIdx++;
19810             }
19811             *numAllocRbs += rbgSize;
19812             remNumRbs -= rbgSize;
19813             ++numAllocRbgs;
19814             if (*numAllocRbs >= bestNumAvailRbs)
19815             {
19816                break;
19817             }
19818          }
19819       }
19820       /* If last RBG available and allocation is not completed, allocate
19821        * last RBG */
19822       if (*numAllocRbs < bestNumAvailRbs)
19823       {
19824          rbgPosInRbgMask =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
19825          *rbgMask |= rbgPosInRbgMask;
19826          *numAllocRbs += rbgInfo->lastRbgSize;
19827
19828          /* Compute RB index of the first RB of the last RBG */
19829          rbIdx = ((rbgInfo->numRbgs - 1 ) * rbgSize ); /* removed minus 1  vamsee */
19830
19831          for (cnt = 0; cnt < rbgInfo->lastRbgSize; ++cnt)
19832          {
19833 #ifdef RGSCH_SPS_UNUSED
19834             ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
19835 #endif
19836             ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19837 #ifdef RGSCH_SPS_UNUSED
19838             /* Update RBG mask for RA type 1 */
19839             raType1Mask[rbgSubset] |=  ueRaType1Mask;
19840             raType1UsedRbs[rbgSubset]++;
19841 #endif
19842             /* Update RA type 2 mask */
19843             raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19844             rbIdx++;
19845          }
19846          remNumRbs -= rbgInfo->lastRbgSize;
19847          ++numAllocRbgs;
19848       }
19849       /* Note: this should complete allocation, not checking for the
19850        * same */
19851    }
19852
19853    return (numAllocRbgs);
19854 }
19855
19856 #ifdef RGSCH_SPS_UNUSED
19857 /**
19858  * @brief Handles RB allocation for Resource allocation type 1
19859  *
19860  * @details
19861  *
19862  *     Function : rgSCHCmnDlRaType1Alloc
19863  *
19864  *     Invoking Module Processing:
19865  *     - This function is invoked for DL RB allocation for resource allocation
19866  *     type 1
19867  *
19868  *     Processing Steps:
19869  *     - Determine the available positions in the subsets.
19870  *     - Allocate RB in the available subset.
19871  *     - Update RA Type1, RA type 0 and RA type 2 masks.
19872  *
19873  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
19874  *  @param[in]   uint8_t                 rbsReq
19875  *  @param[in]   RgSchBwRbgInfo     *rbgInfo
19876  *  @param[in]   uint8_t                 startRbgSubset
19877  *  @param[in]   uint8_t                 *allocRbgSubset
19878  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
19879  *  @param[in]   Bool               isPartialAlloc
19880  *
19881  *  @return  uint8_t
19882  *  Number of allocated RBs
19883  **/
19884
19885 uint8_t rgSCHCmnDlRaType1Alloc
19886 (
19887 RgSchDlSfAllocInfo *allocedInfo,
19888 uint8_t            rbsReq,
19889 RgSchBwRbgInfo     *rbgInfo,
19890 uint8_t            startRbgSubset,
19891 uint8_t            *allocRbgSubset,
19892 RgSchDlSfAllocInfo *resAllocInfo,
19893 Bool               isPartialAlloc
19894 )
19895 {
19896    /* Note: This function atttempts only full allocation */
19897    uint8_t   *rbgSubsetSzArr;
19898    uint8_t   type2MaskIdx, subsetIdx, rbIdx, rbInSubset, rbgInSubset;
19899    uint8_t   offset, rbg, maskSize, bestSubsetIdx;
19900    uint8_t   startPos = 0;
19901    uint8_t   bestNumAvailRbs = 0;
19902    uint8_t   numAllocRbs = 0;
19903    uint32_t  ueRaType2Mask, ueRaType0Mask, rbPosInSubset;
19904    uint32_t  remNumRbs, allocedMask;
19905    uint8_t   usedRbs = 0;
19906    uint8_t   rbgSize = rbgInfo->rbgSize;
19907    uint8_t   rbgSubset = startRbgSubset;
19908    uint32_t  *rbgMask = &resAllocInfo->raType0Mask;
19909    uint32_t  *raType1Mask = resAllocInfo->raType1Mask;
19910    uint32_t  *raType2Mask = resAllocInfo->raType2Mask;
19911    uint32_t  *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
19912    uint32_t  *allocMask = allocedInfo->raType1Mask;
19913
19914    /* Initialize the subset size Array */
19915    rbgSubsetSzArr = rbgInfo->rbgSubsetSize;
19916
19917    /* Perform allocation for RA type 1 */
19918    for (subsetIdx = 0;subsetIdx < rbgSize; ++subsetIdx)
19919    {
19920       allocedMask = allocMask[rbgSubset];
19921       maskSize = rbgSubsetSzArr[rbgSubset];
19922
19923       /* Determine number of available RBs in the subset */
19924       usedRbs = allocedInfo->raType1UsedRbs[subsetIdx];
19925       remNumRbs = maskSize - usedRbs;
19926
19927       if (remNumRbs >= rbsReq)
19928       {
19929          bestNumAvailRbs = rbsReq;
19930          bestSubsetIdx = rbgSubset;
19931          break;
19932       }
19933       else if (isPartialAlloc && (remNumRbs > bestNumAvailRbs))
19934       {
19935          bestNumAvailRbs = remNumRbs;
19936          bestSubsetIdx = rbgSubset;
19937       }
19938
19939       rbgSubset = (rbgSubset + 1) % rbgSize;
19940    } /* End of for (each rbgsubset) */
19941
19942    if (bestNumAvailRbs)
19943    {
19944       /* Initialize alloced mask and subsetSize depending on the RBG
19945        * subset of allocation */
19946       uint8_t        startIdx = 0;
19947       maskSize = rbgSubsetSzArr[bestSubsetIdx];
19948       allocedMask = allocMask[bestSubsetIdx];
19949       RG_SCH_CMN_DL_GET_START_POS(allocedMask, maskSize,
19950             &startPos);
19951       for (; startIdx < rbgSize; ++startIdx, ++startPos)
19952       {
19953          for (rbInSubset = startPos; rbInSubset < maskSize;
19954                rbInSubset = rbInSubset + rbgSize)
19955          {
19956             rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
19957             if (!(allocedMask & rbPosInSubset))
19958             {
19959                raType1Mask[bestSubsetIdx] |= rbPosInSubset;
19960                raType1UsedRbs[bestSubsetIdx]++;
19961
19962                /* Compute RB index value for the RB being allocated */
19963                rbgInSubset = rbInSubset /rbgSize;
19964                offset = rbInSubset % rbgSize;
19965                rbg = (rbgInSubset * rbgSize) + bestSubsetIdx;
19966                rbIdx = (rbg * rbgSize) + offset;
19967
19968                /* Update RBG mask for RA type 0 allocation */
19969                ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
19970                *rbgMask |= ueRaType0Mask;
19971
19972                /* Update RA type 2 mask */
19973                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
19974                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
19975
19976                /* Update the counters */
19977                numAllocRbs++;
19978                remNumRbs--;
19979                if (numAllocRbs == bestNumAvailRbs)
19980                {
19981                   break;
19982                }
19983             }
19984          } /* End of for (each position in the subset mask) */
19985          if (numAllocRbs == bestNumAvailRbs)
19986          {
19987             break;
19988          }
19989       } /* End of for startIdx = 0 to rbgSize */
19990
19991       *allocRbgSubset = bestSubsetIdx;
19992    } /* End of if (bestNumAvailRbs) */
19993
19994    return (numAllocRbs);
19995 }
19996 #endif
19997 /**
19998  * @brief Handles RB allocation for Resource allocation type 2
19999  *
20000  * @details
20001  *
20002  *     Function : rgSCHCmnDlRaType2Alloc
20003  *
20004  *     Invoking Module Processing:
20005  *     - This function is invoked for DL RB allocation for resource allocation
20006  *     type 2
20007  *
20008  *     Processing Steps:
20009  *     - Determine the available positions in the mask
20010  *     - Allocate best fit cosecutive RBs.
20011  *     - Update RA Type2, RA type 1 and RA type 0 masks.
20012  *
20013  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
20014  *  @param[in]   uint8_t             rbsReq
20015  *  @param[in]   RgSchBwRbgInfo *rbgInfo
20016  *  @param[out]  uint8_t             *rbStart
20017  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
20018  *  @param[in]   Bool           isPartialAlloc
20019  *
20020  *  @return  uint8_t
20021  *  Number of allocated RBs
20022  **/
20023
20024 uint8_t rgSCHCmnDlRaType2Alloc
20025 (
20026 RgSchDlSfAllocInfo *allocedInfo,
20027 uint8_t            rbsReq,
20028 RgSchBwRbgInfo     *rbgInfo,
20029 uint8_t            *rbStart,
20030 RgSchDlSfAllocInfo *resAllocInfo,
20031 Bool               isPartialAlloc
20032 )
20033 {
20034    uint8_t    numAllocRbs = 0;
20035    uint8_t    rbIdx;
20036    uint8_t    rbgSize = rbgInfo->rbgSize;
20037    uint32_t   *rbgMask = &resAllocInfo->raType0Mask;
20038 #ifdef RGSCH_SPS_UNUSED
20039    uint32_t   *raType1Mask = resAllocInfo->raType1Mask;
20040 #endif
20041    uint32_t   *raType2Mask = resAllocInfo->raType2Mask;
20042 #ifdef RGSCH_SPS_UNUSED
20043    uint32_t   *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
20044 #endif
20045    uint32_t   *allocedMask = allocedInfo->raType2Mask;
20046
20047    /* Note: This function atttempts only full allocation */
20048    rgSCHCmnDlGetBestFitHole(allocedMask, rbgInfo->numRbs,
20049          raType2Mask, rbsReq, rbStart, &numAllocRbs, isPartialAlloc);
20050    if (numAllocRbs)
20051    {
20052       /* Update the allocation in RA type 0 and RA type 1 masks */
20053       uint8_t rbCnt = numAllocRbs;
20054 #ifdef RGSCH_SPS_UNUSED
20055       uint8_t rbgSubset;
20056       uint32_t ueRaType1Mask;
20057 #endif
20058       uint32_t ueRaType0Mask;
20059       rbIdx = *rbStart;
20060
20061       while(rbCnt)
20062       {
20063          /* Update RBG mask for RA type 0 allocation */
20064          ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
20065          *rbgMask |= ueRaType0Mask;
20066
20067 #ifdef RGSCH_SPS_UNUSED
20068          /* Update RBG mask for RA type 1 */
20069          ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
20070          raType1Mask[rbgSubset] |= ueRaType1Mask;
20071          raType1UsedRbs[rbgSubset]++;
20072 #endif
20073          /* Update the counters */
20074          --rbCnt;
20075          rbIdx++;
20076       }
20077    }
20078
20079    return (numAllocRbs);
20080 }
20081
20082 /**
20083  * @brief Determines RA type 0 mask from given RB index.
20084  *
20085  * @details
20086  *
20087  *     Function : rgSCHCmnGetRaType0Mask
20088  *
20089  *
20090  *     Processing Steps:
20091  *     - Determine RA Type 0 mask for given rbIdex and rbg size.
20092  *
20093  *  @param[in]  uint8_t          rbIdx
20094  *  @param[in]  uint8_t          rbgSize
20095  *  @return  uint32_t RA type 0 mask
20096  **/
20097 static uint32_t rgSCHCmnGetRaType0Mask(uint8_t rbIdx,uint8_t rbgSize)
20098 {
20099    uint8_t rbg;
20100    uint32_t rbgPosInRbgMask = 0;
20101
20102    rbg = rbIdx/rbgSize;
20103    rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
20104
20105    return (rbgPosInRbgMask);
20106 }
20107
20108 #ifdef RGSCH_SPS_UNUSED
20109 /**
20110  * @brief Determines RA type 1 mask from given RB index.
20111  *
20112  * @details
20113  *
20114  *     Function : rgSCHCmnGetRaType1Mask
20115  *
20116  *
20117  *     Processing Steps:
20118  *     - Determine RA Type 1 mask for given rbIdex and rbg size.
20119  *
20120  *  @param[in]  uint8_t          rbIdx
20121  *  @param[in]  uint8_t          rbgSize
20122  *  @param[out] uint8_t          *type1Subset
20123  *  @return  uint32_t RA type 1 mask
20124  **/
20125 static uint32_t rgSCHCmnGetRaType1Mask(uint8_t  rbIdx,uint8_t  rbgSize,uint8_t  *type1Subset)
20126 {
20127    uint8_t rbg, rbgSubset, rbgInSubset, offset, rbInSubset;
20128    uint32_t rbPosInSubset;
20129
20130    rbg = rbIdx/rbgSize;
20131    rbgSubset = rbg % rbgSize;
20132    rbgInSubset = rbg/rbgSize;
20133    offset = rbIdx % rbgSize;
20134    rbInSubset = rbgInSubset * rbgSize + offset;
20135    rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
20136
20137    *type1Subset = rbgSubset;
20138    return (rbPosInSubset);
20139
20140 #endif /* RGSCH_SPS_UNUSED */
20141 /**
20142  * @brief Determines RA type 2 mask from given RB index.
20143  *
20144  * @details
20145  *
20146  *     Function : rgSCHCmnGetRaType2Mask
20147  *
20148  *
20149  *     Processing Steps:
20150  *     - Determine RA Type 2 mask for given rbIdx and rbg size.
20151  *
20152  *  @param[in]  uint8_t          rbIdx
20153  *  @param[out] uint8_t          *maskIdx
20154  *  @return  uint32_t RA type 2 mask
20155  **/
20156 static uint32_t rgSCHCmnGetRaType2Mask(uint8_t rbIdx,uint8_t *maskIdx)
20157 {
20158    uint32_t rbPosInType2;
20159
20160    *maskIdx = rbIdx / 32;
20161    rbPosInType2 =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbIdx % 32);
20162
20163    return (rbPosInType2);
20164 }
20165
20166 /**
20167  * @brief Performs resource allocation for a non-SPS UE in SPS bandwidth
20168  *
20169  * @details
20170  *
20171  *     Function : rgSCHCmnAllocUeInSpsBw
20172  *
20173  *
20174  *     Processing Steps:
20175  *       - Determine allocation for the UE.
20176  *       - Use resource allocation type 0, 1 and 2 for allocation
20177  *         within maximum SPS bandwidth.
20178  *
20179  *  @param[in]  RgSchDlSf       *dlSf
20180  *  @param[in]  RgSchCellCb     *cell
20181  *  @param[in]  RgSchUeCb       *ue
20182  *  @param[in]  RgSchDlRbAlloc  *rbAllocInfo
20183  *  @param[in]  Bool            isPartialAlloc
20184  *  @return  Bool
20185  *             ROK      success
20186  *             RFAILED  failed
20187  **/
20188 Bool rgSCHCmnAllocUeInSpsBw
20189 (
20190 RgSchDlSf           *dlSf,
20191 RgSchCellCb         *cell,
20192 RgSchUeCb           *ue,
20193 RgSchDlRbAlloc      *rbAllocInfo,
20194 Bool                isPartialAlloc
20195 )
20196 {
20197    uint8_t            rbgSize = cell->rbgSize;
20198    uint8_t            numAllocRbs = 0;
20199    uint8_t            numAllocRbgs = 0;
20200    uint8_t            rbStart = 0;
20201    uint8_t            idx, noLyr, iTbs;
20202    RgSchCmnDlUe       *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
20203    RgSchDlSfAllocInfo *dlSfAlloc = &rbAllocInfo->dlSf->dlSfAllocInfo;
20204    RgSchBwRbgInfo     *spsRbgInfo = &cell->spsBwRbgInfo;
20205
20206    /* SPS_FIX : Check if this Hq proc is scheduled */
20207    if ((0 == rbAllocInfo->tbInfo[0].schdlngForTb) &&
20208          (0 == rbAllocInfo->tbInfo[1].schdlngForTb))
20209    {
20210       return (TRUE);
20211    }
20212
20213    /* Check if the requirement can be accomodated in SPS BW */
20214    if (dlSf->spsAllocdBw == spsRbgInfo->numRbs)
20215    {
20216       /* SPS Bandwidth has been exhausted: no further allocations possible */
20217       return (FALSE);
20218    }
20219    if (!isPartialAlloc)
20220    {
20221       if((dlSf->spsAllocdBw + rbAllocInfo->rbsReq) > spsRbgInfo->numRbs)
20222       {
20223          return (TRUE);
20224       }
20225    }
20226
20227    /* Perform allocation for RA type 0 if rbsReq is multiple of RBG size (also
20228     * if RBG size = 1) */
20229    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20230    {
20231       rbAllocInfo->rbsReq += (rbgSize - rbAllocInfo->rbsReq % rbgSize);
20232       numAllocRbgs = rgSCHCmnDlRaType0Alloc(dlSfAlloc,
20233             rbAllocInfo->rbsReq, spsRbgInfo, &numAllocRbs,
20234             &rbAllocInfo->resAllocInfo, isPartialAlloc);
20235    }
20236 #ifdef RGSCH_SPS_UNUSED
20237    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
20238    {
20239       /* If no RBS could be allocated, attempt RA TYPE 1 */
20240
20241       numAllocRbs = rgSCHCmnDlRaType1Alloc(dlSfAlloc,
20242             rbAllocInfo->rbsReq, spsRbgInfo, (uint8_t)dlSfAlloc->nxtRbgSubset,
20243             &rbAllocInfo->allocInfo.raType1.rbgSubset,
20244             &rbAllocInfo->resAllocInfo, isPartialAlloc);
20245
20246       if(numAllocRbs)
20247       {
20248          dlSfAlloc->nxtRbgSubset =
20249             (rbAllocInfo->allocInfo.raType1.rbgSubset + 1 ) % rbgSize;
20250       }
20251    }
20252 #endif
20253    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20254    {
20255       numAllocRbs = rgSCHCmnDlRaType2Alloc(dlSfAlloc,
20256             rbAllocInfo->rbsReq, spsRbgInfo,
20257             &rbStart, &rbAllocInfo->resAllocInfo, isPartialAlloc);
20258    }
20259    if (!numAllocRbs)
20260    {
20261       return (TRUE);
20262    }
20263
20264    if (!(rbAllocInfo->pdcch =
20265             rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi,\
20266                rbAllocInfo->dciFormat, FALSE)))
20267    {
20268       /* Note: Returning TRUE since PDCCH might be available for another UE */
20269       return (TRUE);
20270    }
20271
20272    /* Update Tb info for each scheduled TB */
20273    iTbs = rbAllocInfo->tbInfo[0].iTbs;
20274    noLyr = rbAllocInfo->tbInfo[0].noLyr;
20275    rbAllocInfo->tbInfo[0].bytesAlloc =
20276       rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
20277
20278    if (rbAllocInfo->tbInfo[1].schdlngForTb)
20279    {
20280       iTbs = rbAllocInfo->tbInfo[1].iTbs;
20281       noLyr = rbAllocInfo->tbInfo[1].noLyr;
20282       rbAllocInfo->tbInfo[1].bytesAlloc =
20283          rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
20284    }
20285
20286    /* Update rbAllocInfo with the allocation information */
20287    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20288    {
20289       rbAllocInfo->allocInfo.raType0.dlAllocBitMask =
20290          rbAllocInfo->resAllocInfo.raType0Mask;
20291       rbAllocInfo->allocInfo.raType0.numDlAlloc = numAllocRbgs;
20292    }
20293 #ifdef RGSCH_SPS_UNUSED
20294    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
20295    {
20296       rbAllocInfo->allocInfo.raType1.dlAllocBitMask =
20297          rbAllocInfo->resAllocInfo.raType1Mask[rbAllocInfo->allocInfo.raType1.rbgSubset];
20298       rbAllocInfo->allocInfo.raType1.numDlAlloc = numAllocRbs;
20299       rbAllocInfo->allocInfo.raType1.shift = 0;
20300    }
20301 #endif
20302    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20303    {
20304       rbAllocInfo->allocInfo.raType2.isLocal = TRUE;
20305       rbAllocInfo->allocInfo.raType2.rbStart = rbStart;
20306       rbAllocInfo->allocInfo.raType2.numRb = numAllocRbs;
20307    }
20308
20309    rbAllocInfo->rbsAlloc = numAllocRbs;
20310    rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
20311
20312    /* Update allocation masks for RA types 0, 1 and 2 in DL SF */
20313
20314    /* Update type 0 allocation mask */
20315    dlSfAlloc->raType0Mask |= rbAllocInfo->resAllocInfo.raType0Mask;
20316 #ifdef RGSCH_SPS_UNUSED
20317    /* Update type 1 allocation masks */
20318    for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
20319    {
20320       dlSfAlloc->raType1Mask[idx] |= rbAllocInfo->resAllocInfo.raType1Mask[idx];
20321       dlSfAlloc->raType1UsedRbs[idx] +=
20322          rbAllocInfo->resAllocInfo.raType1UsedRbs[idx];
20323    }
20324 #endif
20325    /* Update type 2 allocation masks */
20326    for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
20327    {
20328       dlSfAlloc->raType2Mask[idx] |= rbAllocInfo->resAllocInfo.raType2Mask[idx];
20329    }
20330
20331    dlSf->spsAllocdBw += numAllocRbs;
20332    return (TRUE);
20333 }
20334
20335 /***********************************************************
20336  *
20337  *     Func : rgSCHCmnDlGetBestFitHole
20338  *
20339  *
20340  *     Desc : Converts the best fit hole into allocation and returns the
20341  *     allocation information.
20342  *
20343  *
20344  *     Ret  : Void
20345  *
20346  *
20347  *     Notes:
20348  *
20349  *     File :
20350  *
20351  **********************************************************/
20352 static Void rgSCHCmnDlGetBestFitHole
20353 (
20354 uint32_t  *allocMask,
20355 uint8_t   numMaskRbs,
20356 uint32_t  *crntAllocMask,
20357 uint8_t   rbsReq,
20358 uint8_t   *allocStart,
20359 uint8_t   *allocNumRbs,
20360 Bool      isPartialAlloc
20361 )
20362 {
20363    uint8_t maskSz = (numMaskRbs + 31)/32;
20364    uint8_t maxMaskPos = (numMaskRbs % 32);
20365    uint8_t maskIdx, maskPos;
20366    uint8_t numAvailRbs = 0;
20367    uint8_t bestAvailNumRbs = 0;
20368    S8 bestStartPos = -1;
20369    S8 startPos = -1;
20370    uint32_t tmpMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
20371    uint32_t bestMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
20372
20373    *allocNumRbs = numAvailRbs;
20374    *allocStart = 0;
20375
20376    for (maskIdx = 0; maskIdx < maskSz; ++maskIdx)
20377    {
20378       maxMaskPos = 31;
20379       if (maskIdx == (maskSz - 1))
20380       {
20381          if (numMaskRbs % 32)
20382          {
20383             maxMaskPos = numMaskRbs % 32;
20384          }
20385       }
20386       for (maskPos = 0; maskPos < maxMaskPos; ++maskPos)
20387       {
20388          if (!(allocMask[maskIdx] & (1 << (31 - maskPos))))
20389          {
20390             tmpMask[maskIdx] |= (1 << (31 - maskPos));
20391             if (startPos == -1)
20392             {
20393                startPos = maskIdx * 32 + maskPos;
20394             }
20395             ++numAvailRbs;
20396             if (numAvailRbs == rbsReq)
20397             {
20398                *allocStart = (uint8_t)startPos;
20399                *allocNumRbs = rbsReq;
20400                break;
20401             }
20402          }
20403          else
20404          {
20405             if (numAvailRbs > bestAvailNumRbs)
20406             {
20407                bestAvailNumRbs = numAvailRbs;
20408                bestStartPos = startPos;
20409                memcpy(bestMask, tmpMask, 4 * sizeof(uint32_t));
20410             }
20411             numAvailRbs = 0;
20412             startPos = -1;
20413             memset(tmpMask, 0, 4 * sizeof(uint32_t));
20414          }
20415       }
20416       if (*allocNumRbs == rbsReq)
20417       {
20418          break;
20419       }
20420    }
20421
20422    if (*allocNumRbs == rbsReq)
20423    {
20424       /* Convert the hole into allocation */
20425       memcpy(crntAllocMask, tmpMask, 4 * sizeof(uint32_t));
20426       return;
20427    }
20428    else
20429    {
20430       if (bestAvailNumRbs && isPartialAlloc)
20431       {
20432          /* Partial allocation could have been done */
20433          *allocStart = (uint8_t)bestStartPos;
20434          *allocNumRbs = bestAvailNumRbs;
20435          /* Convert the hole into allocation */
20436          memcpy(crntAllocMask, bestMask, 4 * sizeof(uint32_t));
20437       }
20438    }
20439
20440    return;
20441 }
20442 #endif /* LTEMAC_SPS */
20443
20444 /***************************************************************************
20445  *
20446  * NON-DLFS Allocation functions
20447  *
20448  * *************************************************************************/
20449 #ifndef LTE_TDD
20450 #ifdef DEBUGP
20451 /**
20452  * @brief Function to find out code rate
20453  *
20454  * @details
20455  *
20456  *     Function : rgSCHCmnFindCodeRate
20457  *
20458  *     Processing Steps:
20459  *
20460  *  @param[in]      RgSchCellCb     *cell
20461  *  @param[in]      RgSchDlSf       *dlSf
20462  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20463  *  @return  void
20464  **/
20465 #ifdef UNUSED_FUNC
20466 static Void rgSCHCmnFindCodeRate
20467 (
20468 RgSchCellCb    *cell,
20469 RgSchDlSf      *dlSf,
20470 RgSchDlRbAlloc *allocInfo,
20471 uint8_t        idx
20472 )
20473 {
20474     return;
20475
20476 }
20477 #endif
20478
20479 /* Adjust the Imcs and bytes allocated also with respect to the adjusted
20480    RBs - Here we will find out the Imcs by identifying first Highest
20481    number of bits compared to the original bytes allocated.  */
20482 /**
20483  * @brief Adjust IMCS according to tbSize and ITBS
20484  *
20485  * @details
20486  *
20487  *     Function : rgSCHCmnNonDlfsPbchTbImcsAdj
20488  *
20489  *     Processing Steps:
20490  *      - Adjust Imcs according to tbSize and ITBS.
20491  *
20492  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20493  *  @param[in]      uint8_t              *idx
20494  *  @return  void
20495  **/
20496 static Void rgSCHCmnNonDlfsPbchTbImcsAdj
20497 (
20498 RgSchCellCb     *cell,
20499 RgSchDlRbAlloc  *allocInfo,
20500 uint8_t         idx,
20501 uint8_t         rbsReq
20502 )
20503 {
20504    uint8_t     noLyrs = 0;
20505    uint8_t     tbs = 0;
20506    uint32_t    origBytesReq;
20507    uint8_t     noRbgs = 0;
20508    uint8_t     noRbs = 0;
20509    RgSchDlSf   *dlSf = allocInfo->dlSf;
20510
20511    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
20512    noLyrs = allocInfo->tbInfo[idx].noLyr;
20513
20514    if((allocInfo->raType == RG_SCH_CMN_RA_TYPE0))
20515    {
20516       noRbgs = RGSCH_CEIL((allocInfo->rbsReq + dlSf->lstRbgDfct), cell->rbgSize);
20517       noRbs = (noRbgs * cell->rbgSize) - dlSf->lstRbgDfct;
20518    }
20519    else
20520    {
20521        noRbs = allocInfo->rbsReq;
20522    }
20523
20524    /* This line will help in case if tbs is zero and reduction in MCS is not possible */
20525    if (allocInfo->rbsReq == 0 )
20526    {
20527       return;
20528    }
20529    origBytesReq = rgTbSzTbl[noLyrs - 1][tbs][rbsReq - 1]/8;
20530
20531    /* Find out the ITbs & Imcs by identifying first Highest
20532       number of bits compared to the original bytes allocated.*/
20533    if(tbs > 0)
20534    {
20535       if(((rgTbSzTbl[noLyrs - 1][0][noRbs - 1])/8) < origBytesReq)
20536       {
20537           RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyrs - 1], tbs);
20538           while(((rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1])/8) > origBytesReq)
20539           {
20540               tbs--;
20541           }
20542       }
20543       else
20544       {
20545           tbs = 0;
20546       }
20547       allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1]/8;
20548       allocInfo->tbInfo[idx].iTbs = tbs;
20549       RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
20550    }
20551
20552    return;
20553 }
20554 /* Added funcion to adjust TBSize*/
20555 /**
20556  * @brief Function to adjust the tbsize in case of subframe 0 & 5 when
20557  * we were not able to do RB alloc adjustment by adding extra required Rbs
20558  *
20559  * @details
20560  *
20561  *     Function : rgSCHCmnNonDlfsPbchTbSizeAdj
20562  *
20563  *     Processing Steps:
20564  *
20565  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20566  *  @param[in]      uint8_t            numOvrlapgPbchRb
20567  *  @param[in]      uint8_t            idx
20568  *  @param[in]      uint8_t            pbchSsRsSym
20569  *  @return  void
20570  **/
20571 static Void rgSCHCmnNonDlfsPbchTbSizeAdj
20572 (
20573 RgSchDlRbAlloc  *allocInfo,
20574 uint8_t         numOvrlapgPbchRb,
20575 uint8_t         pbchSsRsSym,
20576 uint8_t         idx,
20577 uint32_t        bytesReq
20578 )
20579 {
20580    uint32_t     reducedTbs = 0;
20581    uint8_t      noLyrs = 0;
20582    uint8_t      tbs = 0;
20583    
20584    noLyrs = allocInfo->tbInfo[idx].noLyr;
20585
20586    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
20587
20588    reducedTbs = bytesReq - (((uint32_t)numOvrlapgPbchRb * (uint32_t)pbchSsRsSym * 6)/8);
20589
20590    /* find out the ITbs & Imcs by identifying first Highest
20591     number of bits compared with reduced bits considering the bits that are
20592     reserved for PBCH/PSS/SSS */
20593    if(((rgTbSzTbl[noLyrs - 1][0][allocInfo->rbsReq - 1])/8) < reducedTbs)
20594    {
20595        while(((rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1])/8) > reducedTbs)
20596        {
20597            tbs--;
20598        }
20599    }
20600    else
20601    {
20602        tbs = 0;
20603    }
20604    allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1]/8;
20605    allocInfo->tbInfo[idx].iTbs = tbs;
20606    RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
20607
20608    return;
20609 }
20610
20611 /* Added this function to find num of ovrlapping PBCH rb*/
20612 /**
20613  * @brief Function to find out how many additional rbs are available
20614  *    in the entire bw which can be allocated to a UE
20615  * @details
20616  *
20617  *     Function : rgSCHCmnFindNumAddtlRbsAvl
20618  *
20619  *     Processing Steps:
20620  *      - Calculates number of additinal rbs available
20621  *
20622  *  @param[in]      RgSchCellCb     *cell
20623  *  @param[in]      RgSchDlSf       *dlSf
20624  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20625  *  @param[out]      uint8_t            addtlRbsAvl
20626  *  @return  void
20627  **/
20628 static uint8_t rgSCHCmnFindNumAddtlRbsAvl(RgSchCellCb *cell,RgSchDlSf *dlSf,RgSchDlRbAlloc *allocInfo)
20629 {
20630     uint8_t addtlRbsAvl = 0;
20631     if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
20632     {
20633          addtlRbsAvl = (((dlSf->type0End - dlSf->type2End + 1)*\
20634                         cell->rbgSize) - dlSf->lstRbgDfct) - allocInfo->rbsReq;
20635     }
20636     else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
20637     {
20638        addtlRbsAvl = (dlSf->bw - dlSf->bwAlloced) - allocInfo->rbsReq;
20639     }
20640
20641     return (addtlRbsAvl);
20642
20643 }
20644 /* Added this function to find num of ovrlapping PBCH rb*/
20645 /**
20646  * @brief Function to find out how many of the requested RBs are
20647  *        falling in the center 6 RBs of the downlink bandwidth.
20648  * @details
20649  *
20650  *     Function : rgSCHCmnFindNumPbchOvrlapRbs
20651  *
20652  *     Processing Steps:
20653  *      - Calculates number of overlapping rbs
20654  *
20655  *  @param[in]      RgSchCellCb     *cell
20656  *  @param[in]      RgSchDlSf       *dlSf
20657  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20658  *  @param[out]      uint8_t*            numOvrlapgPbchRb
20659  *  @return  void
20660  **/
20661 static Void rgSCHCmnFindNumPbchOvrlapRbs
20662 (
20663 RgSchCellCb    *cell,
20664 RgSchDlSf      *dlSf,
20665 RgSchDlRbAlloc *allocInfo,
20666 uint8_t        *numOvrlapgPbchRb
20667 )
20668 {
20669     *numOvrlapgPbchRb = 0;
20670    /*Find if we have already crossed the start boundary for PBCH 6 RBs,
20671     * if yes then lets find the number of RBs which are getting overlapped
20672     * with this allocation.*/
20673    if(dlSf->bwAlloced <= (cell->pbchRbStart))
20674    {
20675       /*We have not crossed the start boundary of PBCH RBs. Now we need
20676        * to know that if take this allocation then how much PBCH RBs
20677        * are overlapping with this allocation.*/
20678       /* Find out the overlapping RBs in the centre 6 RBs */
20679        if((dlSf->bwAlloced + allocInfo->rbsReq) > cell->pbchRbStart)
20680        {
20681            *numOvrlapgPbchRb = (dlSf->bwAlloced + allocInfo->rbsReq) - (cell->pbchRbStart);
20682            if(*numOvrlapgPbchRb > 6)
20683                 *numOvrlapgPbchRb = 6;
20684        }
20685    }
20686    else if ((dlSf->bwAlloced > (cell->pbchRbStart)) &&
20687          (dlSf->bwAlloced < (cell->pbchRbEnd)))
20688    {
20689       /*We have already crossed the start boundary of PBCH RBs.We need to
20690        * find that if we take this allocation then how much of the RBs for
20691        * this allocation will overlap with PBCH RBs.*/
20692       /* Find out the overlapping RBs in the centre 6 RBs */
20693       if(dlSf->bwAlloced + allocInfo->rbsReq < (cell->pbchRbEnd))
20694       {
20695          /*If we take this allocation then also we are not crossing the
20696           * end boundary of PBCH 6 RBs.*/
20697          *numOvrlapgPbchRb = allocInfo->rbsReq;
20698       }
20699       else
20700       {
20701          /*If we take this allocation then we are crossing the
20702           * end boundary of PBCH 6 RBs.*/
20703          *numOvrlapgPbchRb = (cell->pbchRbEnd) - dlSf->bwAlloced;
20704       }
20705    }
20706     return;
20707
20708 }
20709 /**
20710  * @brief Performs RB allocation adjustment if the requested RBs are
20711  *        falling in the center 6 RBs of the downlink bandwidth.
20712  * @details
20713  *
20714  *     Function : rgSCHCmnNonDlfsPbchRbAllocAdj
20715  *
20716  *     Processing Steps:
20717  *      - Allocate consecutively available RBs.
20718  *
20719  *  @param[in]      RgSchCellCb     *cell
20720  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
20721  *  @param[in]      uint8_t               pbchSsRsSym
20722  *  @return  void
20723  **/
20724 static Void rgSCHCmnNonDlfsPbchRbAllocAdj
20725 (
20726 RgSchCellCb      *cell,
20727 RgSchDlRbAlloc   *allocInfo,
20728 uint8_t          pbchSsRsSym,
20729 Bool             isBcchPcch
20730 )
20731 {
20732    RgSchDlSf  *dlSf = allocInfo->dlSf;
20733    uint8_t    numOvrlapgPbchRb = 0;
20734    uint8_t    numOvrlapgAdtlPbchRb = 0;
20735    uint8_t    totSym;
20736    uint8_t    addtlRbsReq = 0;
20737    uint8_t    moreAddtlRbsReq = 0;
20738    uint8_t    addtlRbsAdd = 0;
20739    uint8_t    moreAddtlRbsAdd = 0;
20740    uint8_t    tbs;
20741    uint8_t    origRbsReq = 0;
20742    uint32_t   bytesReq;
20743    uint8_t    noLyr;
20744    uint8_t    divResult;
20745
20746
20747
20748
20749    origRbsReq = allocInfo->rbsReq;
20750    rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20751
20752   totSym =  (cell->isCpDlExtend) ? RGSCH_TOT_NUM_SYM_EXTCP : RGSCH_TOT_NUM_SYM_NORCP;
20753
20754    /* Additional RBs are allocated by considering the loss due to
20755       the reserved symbols for CFICH, PBCH, PSS, SSS and cell specific RS */
20756
20757    divResult = (numOvrlapgPbchRb * pbchSsRsSym)/totSym;
20758    if((numOvrlapgPbchRb * pbchSsRsSym) % totSym)
20759    {
20760       divResult++;
20761    }
20762    addtlRbsReq = divResult;
20763
20764    RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, addtlRbsReq, addtlRbsAdd)
20765
20766    /*Now RBs requires is original requested RBs + these additional RBs to make
20767     * up for PSS/SSS/BCCH.*/
20768    allocInfo->rbsReq = allocInfo->rbsReq + addtlRbsAdd;
20769
20770    /*Check if with these additional RBs we have taken up, these are also falling
20771     * under PBCH RBs range, if yes then we would need to account for
20772     * PSS/BSS/BCCH for these additional RBs too.*/
20773    if(addtlRbsAdd && ((dlSf->bwAlloced + allocInfo->rbsReq - addtlRbsAdd) < (cell->pbchRbEnd)))
20774    {
20775       if((dlSf->bwAlloced + allocInfo->rbsReq) <= (cell->pbchRbEnd))
20776       {
20777       /*With additional RBs taken into account, we are not crossing the
20778        * PBCH RB end boundary.Thus here we need to account just for
20779        * overlapping PBCH RBs for these additonal RBs.*/
20780           divResult = (addtlRbsAdd * pbchSsRsSym)/totSym;
20781           if((addtlRbsAdd * pbchSsRsSym) % totSym)
20782           {
20783             divResult++;
20784           }
20785
20786           moreAddtlRbsReq = divResult;
20787
20788           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
20789
20790           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
20791       }
20792       else
20793       {
20794
20795          /*Here we have crossed the PBCH RB end boundary, thus we need to take
20796           * into account the overlapping RBs for additional RBs which will be
20797           * subset of addtlRbs.*/
20798           numOvrlapgAdtlPbchRb = (cell->pbchRbEnd) - ((dlSf->bwAlloced + allocInfo->rbsReq) -  addtlRbsAdd);
20799
20800           divResult = (numOvrlapgAdtlPbchRb * pbchSsRsSym)/totSym;
20801           if((numOvrlapgAdtlPbchRb * pbchSsRsSym) % totSym)
20802           {
20803              divResult++;
20804           }
20805
20806           moreAddtlRbsReq =  divResult;
20807
20808           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
20809
20810           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
20811       }
20812    }
20813    if (isBcchPcch == TRUE)
20814    {
20815       return;
20816    }
20817
20818    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
20819    if(tbs == 6)
20820    {
20821       /* This case might be for Imcs value 6 and NPrb = 1 case  - Not
20822          Adjusting either RBs or Imcs or Bytes Allocated */
20823       allocInfo->rbsReq = allocInfo->rbsReq - addtlRbsAdd - moreAddtlRbsAdd;
20824    }
20825    else if(tbs && ((0 == addtlRbsAdd) && (moreAddtlRbsAdd == 0)))
20826    {
20827        /*In case of a situation where we the entire bandwidth is already occupied
20828         * and we dont have room to add additional Rbs then in order to decrease the
20829         * code rate we reduce the tbsize such that we reduce the present calculated
20830         * tbsize by number of bytes that would be occupied by PBCH/PSS/SSS in overlapping
20831         * rbs and find the nearest tbsize which would be less than this deduced value*/
20832
20833       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20834
20835       noLyr = allocInfo->tbInfo[0].noLyr;
20836       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyr - 1], tbs);
20837       bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
20838
20839       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,bytesReq);
20840
20841       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20842       {
20843           noLyr = allocInfo->tbInfo[1].noLyr;
20844           bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
20845           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,bytesReq);
20846       }
20847
20848    }
20849    else if(tbs && ((addtlRbsAdd != addtlRbsReq) ||
20850           (addtlRbsAdd && (moreAddtlRbsReq != moreAddtlRbsAdd))))
20851    {
20852        /*In case of a situation where we were not able to add required number of
20853         * additional RBs then we adjust the Imcs based on original RBs requested.
20854         * Doing this would comensate for the few extra Rbs we have added but inorder
20855         * to comensate for number of RBS we couldnt add we again do the TBSize adjustment*/
20856
20857       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
20858
20859       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20860       {
20861           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
20862       }
20863
20864       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
20865       numOvrlapgPbchRb = numOvrlapgPbchRb - (addtlRbsAdd + moreAddtlRbsAdd);
20866
20867       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,allocInfo->tbInfo[0].bytesReq);
20868
20869       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20870       {
20871           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,allocInfo->tbInfo[1].bytesReq);
20872       }
20873
20874    }
20875    else
20876    {
20877        /*We hit this code when we were able to add the required additional RBS
20878         * hence we should adjust the IMcs based on orignals RBs requested*/
20879
20880       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
20881
20882       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
20883       {
20884           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
20885       }
20886    }
20887
20888    return;
20889 } /* end of rgSCHCmnNonDlfsPbchRbAllocAdj */
20890 #endif
20891 #endif
20892 /**
20893  * @brief Performs RB allocation for frequency non-selective cell.
20894  *
20895  * @details
20896  *
20897  *     Function : rgSCHCmnNonDlfsCmnRbAlloc
20898  *
20899  *     Processing Steps:
20900  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
20901  *
20902  *  @param[in]      RgSchCellCb     *cell
20903  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
20904  *  @return  S16
20905  *      -# ROK
20906  *      -# RFAILED
20907  **/
20908 static S16 rgSCHCmnNonDlfsCmnRbAlloc(RgSchCellCb  *cell,RgSchDlRbAlloc  *allocInfo)
20909 {
20910 #ifndef LTE_TDD
20911 #ifdef LTEMAC_SPS
20912 #endif
20913    uint8_t pbchSsRsSym = 0;
20914    uint8_t pbchFrame = 0;
20915    uint8_t  tbs = 0;
20916    RgSchCmnDlCell   *cellDl    = RG_SCH_CMN_GET_DL_CELL(cell); 
20917 #endif
20918    RgSchDlSf     *dlSf   = allocInfo->dlSf;
20919 #ifdef LTEMAC_SPS
20920    uint8_t                  rbStart = 0;
20921    uint8_t                  spsRbsAlloc = 0;
20922    RgSchDlSfAllocInfo  *dlSfAlloc = &allocInfo->dlSf->dlSfAllocInfo;
20923 #endif
20924
20925    allocInfo->tbInfo[0].noLyr = 1;
20926
20927 #ifdef LTEMAC_SPS
20928    /* Note: Initialize the masks to 0, this might not be needed since alloInfo
20929     * is initialized to 0 at the beginning of allcoation */
20930    allocInfo->resAllocInfo.raType0Mask = 0;
20931    memset(allocInfo->resAllocInfo.raType1Mask, 0,
20932          RG_SCH_NUM_RATYPE1_32BIT_MASK * sizeof (uint32_t));
20933    memset(allocInfo->resAllocInfo.raType2Mask, 0,
20934          RG_SCH_NUM_RATYPE2_32BIT_MASK * sizeof (uint32_t));
20935
20936    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
20937          (dlSf->bwAlloced == dlSf->bw))
20938 #else
20939    if(dlSf->bwAlloced == dlSf->bw)
20940 #endif
20941    {
20942       return RFAILED;
20943    }
20944 #ifndef LTE_TDD
20945    if (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))
20946    {
20947 #ifdef LTEMAC_SPS
20948       if ((allocInfo->tbInfo[0].imcs < 29) && (dlSf->bwAlloced < dlSf->bw))
20949 #else
20950       if(allocInfo->tbInfo[0].imcs < 29)
20951 #endif
20952       {
20953          /* set the remaining RBs for the requested UE */
20954          allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
20955          RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
20956          allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[0][tbs][allocInfo->rbsReq - 1]/8;
20957       }
20958       else
20959       {
20960 #ifdef LTEMAC_SPS
20961          /* Attempt RA Type 2 allocation in SPS Bandwidth */
20962          if (dlSf->spsAllocdBw < cell->spsBwRbgInfo.numRbs) 
20963          {
20964             spsRbsAlloc =
20965                rgSCHCmnDlRaType2Alloc(dlSfAlloc,
20966                      allocInfo->rbsReq, &cell->spsBwRbgInfo, &rbStart,
20967                      &allocInfo->resAllocInfo, FALSE);
20968             /* rbsAlloc assignment moved from line 16671 to here to avoid
20969              * compilation error. Recheck */
20970             dlSf->spsAllocdBw += spsRbsAlloc;
20971          }
20972          if (!spsRbsAlloc)
20973 #endif /* LTEMAC_SPS */
20974          {
20975             return RFAILED;
20976          }
20977       }
20978    }
20979 #endif
20980
20981    /* Update allocation information */
20982    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
20983    if (allocInfo->pdcch == NULLP)
20984    {
20985       return RFAILED;
20986    }
20987    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
20988    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
20989    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
20990    allocInfo->allocInfo.raType2.isLocal = TRUE;
20991 #ifdef LTEMAC_SPS
20992    if (spsRbsAlloc) 
20993    {
20994       allocInfo->allocInfo.raType2.rbStart = rbStart;
20995       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
20996       allocInfo->rbsAlloc = allocInfo->rbsReq;
20997    }
20998 #endif
20999
21000 #ifdef LTEMAC_SPS
21001    if (!spsRbsAlloc)
21002    {
21003 #endif
21004 #ifndef LTE_TDD
21005       if(dlSf->sfNum)
21006       {
21007          if(!(dlSf->sfNum == 5))
21008          {
21009             /* case for subframes 1 to 9 except 5 */
21010 #ifdef LTEMAC_SPS
21011             allocInfo->allocInfo.raType2.rbStart = rbStart;
21012 #else
21013             /*Fix for ccpu00123918*/
21014             allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21015 #endif
21016          }
21017          else
21018          {
21019             pbchFrame = 1; /* case for subframe 5 */
21020             /* In subframe 5, symbols are reserved for PSS and SSS and CFICH
21021                and Cell Specific Reference Signals */
21022             pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PSS_SSS_SYM) *
21023                   RGSCH_NUM_SC_IN_RB + cell->numCellRSPerSf);
21024          }
21025       }
21026       else
21027       {
21028          pbchFrame = 1;
21029          /* In subframe 0, symbols are reserved for PSS, SSS, PBCH, CFICH and
21030             and Cell Specific Reference signals */
21031          pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PBCH_SYM +
21032                   RGSCH_NUM_PSS_SSS_SYM) * RGSCH_NUM_SC_IN_RB +
21033                cell->numCellRSPerSf);
21034       } /* end of outer else */
21035
21036       if((pbchFrame) &&
21037             (((dlSf->bwAlloced + allocInfo->rbsReq) - cell->pbchRbStart) > 0)&&
21038             (dlSf->bwAlloced < cell->pbchRbEnd))
21039       {
21040          if(allocInfo->tbInfo[0].imcs < 29)
21041          {
21042             rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo, pbchSsRsSym, TRUE);
21043          }
21044       }
21045 #endif
21046 #ifdef LTEMAC_SPS
21047    }
21048 #endif
21049
21050 #ifdef LTEMAC_SPS
21051    if (!spsRbsAlloc)
21052    {  
21053 #endif
21054       /*Fix for ccpu00123918*/
21055       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21056       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
21057       allocInfo->rbsAlloc = allocInfo->rbsReq;
21058
21059       /* LTE_ADV_FLAG_REMOVED_START */
21060 #ifndef LTE_TDD
21061       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
21062       {
21063          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
21064                allocInfo->allocInfo.raType2.rbStart, \
21065                allocInfo->allocInfo.raType2.numRb);
21066       }
21067       else
21068 #endif
21069       {
21070          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
21071                allocInfo->allocInfo.raType2.rbStart, \
21072                allocInfo->allocInfo.raType2.numRb);
21073       }
21074
21075 #ifdef LTEMAC_SPS
21076    }
21077 #endif
21078    /* LTE_ADV_FLAG_REMOVED_END */
21079    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21080
21081
21082 #ifdef LTEMAC_SPS
21083    if (spsRbsAlloc)
21084    {
21085       uint8_t    idx;
21086       /* Update type 0, 1 and 2 masks */
21087       dlSfAlloc->raType0Mask    |= allocInfo->resAllocInfo.raType0Mask;
21088 #ifdef RGSCH_SPS_UNUSED
21089       for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
21090       {
21091          dlSfAlloc->raType1Mask[idx] |=
21092             allocInfo->resAllocInfo.raType1Mask[idx];
21093          dlSfAlloc->raType1UsedRbs[idx] +=
21094             allocInfo->resAllocInfo.raType1UsedRbs[idx];
21095       }
21096 #endif
21097       for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
21098       {
21099          dlSfAlloc->raType2Mask[idx] |=
21100             allocInfo->resAllocInfo.raType2Mask[idx];
21101       }
21102    }
21103 #endif
21104
21105    return ROK;
21106 }
21107
21108
21109 /**
21110  * @brief Performs RB allocation for frequency non-selective cell.
21111  *
21112  * @details
21113  *
21114  *     Function : rgSCHCmnNonDlfsCmnRbAllocRar
21115  *
21116  *     Processing Steps:
21117  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
21118  *
21119  *  @param[in]      RgSchCellCb     *cell
21120  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
21121  *  @return  S16
21122  *      -# ROK
21123  *      -# RFAILED
21124  **/
21125 static S16 rgSCHCmnNonDlfsCmnRbAllocRar(RgSchCellCb *cell,RgSchDlRbAlloc *allocInfo)
21126 {
21127    RgSchDlSf     *dlSf   = allocInfo->dlSf;
21128
21129    if(dlSf->bwAlloced == dlSf->bw)
21130    {
21131       return RFAILED;
21132    }
21133
21134    allocInfo->tbInfo[0].noLyr = 1;
21135 #ifndef RG_5GTF
21136    /* Update allocation information */
21137    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
21138    if (allocInfo->pdcch == NULLP)
21139    {
21140       return RFAILED;
21141    }
21142    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
21143    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
21144    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
21145    allocInfo->allocInfo.raType2.isLocal = TRUE;
21146
21147    /*Fix for ccpu00123918*/
21148    allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
21149    allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
21150    allocInfo->rbsAlloc = allocInfo->rbsReq;
21151
21152    /* LTE_ADV_FLAG_REMOVED_END */
21153    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21154
21155 #else
21156    allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, NULLP, dlSf, 13, TFU_DCI_FORMAT_B1, FALSE);
21157    if (allocInfo->pdcch == NULLP)
21158    {
21159       return RFAILED;
21160    }
21161    RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
21162    if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
21163    {
21164       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
21165       return RFAILED;
21166    }
21167
21168    allocInfo->tbInfo[0].cmnGrnt.vrbgStart = beamInfo->vrbgStart;
21169    allocInfo->tbInfo[0].cmnGrnt.numVrbg = allocInfo->vrbgReq;
21170
21171    /* Update allocation information */
21172    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
21173
21174    allocInfo->tbInfo[0].cmnGrnt.xPDSCHRange = 1;  
21175    allocInfo->tbInfo[0].cmnGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
21176          allocInfo->tbInfo[0].cmnGrnt.vrbgStart, allocInfo->tbInfo[0].cmnGrnt.numVrbg);
21177
21178    allocInfo->tbInfo[0].cmnGrnt.rbStrt = (allocInfo->tbInfo[0].cmnGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
21179    allocInfo->tbInfo[0].cmnGrnt.numRb = (allocInfo->tbInfo[0].cmnGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
21180
21181    beamInfo->vrbgStart += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
21182    beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
21183    allocInfo->tbInfo[0].cmnGrnt.rv = 0;
21184    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
21185
21186 #endif
21187    DU_LOG("\nINFO  -->  SCH : [%s],allocInfo->tbInfo[0].bytesAlloc:%u,vrbgReq:%u\n",
21188          __func__,allocInfo->tbInfo[0].bytesAlloc,allocInfo->vrbgReq);
21189
21190    return ROK;
21191 }
21192
21193
21194 /* LTE_ADV_FLAG_REMOVED_START */
21195 #ifndef LTE_TDD
21196 /**
21197  * @brief To check if DL BW available for non-DLFS allocation.
21198  *
21199  * @details
21200  *
21201  *     Function : rgSCHCmnNonDlfsBwAvlbl
21202  *
21203  *     Processing Steps:
21204  *      - Determine availability based on RA Type.
21205  *
21206  *  @param[in]  RgSchCellCb     *cell
21207  *  @param[in]  RgSchDlSf       *dlSf
21208  *  @param[in]  RgSchDlRbAlloc  *allocInfo
21209  *
21210  *  @return Bool
21211  *      -# TRUE
21212  *      -# FALSE
21213  **/
21214 #ifdef UNUSED_FUNC
21215 static Bool rgSCHCmnNonDlfsSFRBwAvlbl
21216 (
21217 RgSchCellCb      *cell,
21218 RgSchSFRPoolInfo **sfrpoolInfo,
21219 RgSchDlSf        *dlSf,
21220 RgSchDlRbAlloc   *allocInfo,
21221 Bool             isUeCellEdge
21222 )
21223 {
21224    CmLListCp   *l;
21225    CmLListCp   *l1;
21226    CmLList     *n;
21227    CmLList     *n1;
21228    RgSchSFRPoolInfo  *sfrPool;
21229    RgSchSFRPoolInfo  *sfrCEPool;
21230
21231    uint8_t tbs;
21232    uint8_t noLyrs;
21233    RgSchSFRPoolInfo *poolWithMaxAvlblBw = NULLP;
21234    uint32_t bwAvlbl = 0;
21235    uint32_t addtnlPRBs = 0;
21236
21237    if (dlSf->bw <= dlSf->bwAlloced)
21238    {
21239       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for subframe (%d) CRNTI:%d", dlSf->sfNum,allocInfo->rnti);
21240       return FALSE;
21241    }
21242
21243    if (dlSf->sfrTotalPoolInfo.ccBwFull == TRUE)
21244    {
21245       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for CC Pool CRNTI:%d",allocInfo->rnti);
21246       return FALSE;
21247    }
21248
21249    if ((dlSf->sfrTotalPoolInfo.ceBwFull == TRUE) && (isUeCellEdge))
21250    {
21251       DU_LOG("\nERROR  -->  SCH : BW is fully allocated for CE Pool CRNTI:%d",allocInfo->rnti);
21252       return FALSE;
21253    }  
21254
21255    /* We first check if the ue scheduled is a cell edge or cell centre and accordingly check the avaialble
21256       memory in their pool. If the cell centre UE doesnt have Bw available in its pool, then it will check
21257       Bw availability in cell edge pool but the other way around is NOT possible.   */
21258    if(isUeCellEdge)
21259    {   
21260       l = &dlSf->sfrTotalPoolInfo.cePool;
21261    }
21262    else
21263    {
21264       l = &dlSf->sfrTotalPoolInfo.ccPool; 
21265    }     
21266
21267    n = cmLListFirst(l);
21268
21269    while(n)       
21270    {
21271       if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
21272       {
21273          sfrPool = (RgSchSFRPoolInfo*)(n->node);
21274
21275          /* MS_FIX for ccpu00123919 : Number of RBs in case of RETX should be same as that of initial transmission. */
21276          if(allocInfo->tbInfo[0].tbCb->txCntr)
21277          {
21278             /* If RB assignment is being done for RETX. Then if reqRbs are   a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
21279              * not a multiple of rbgSize then check if lsgRbgDfct exists */
21280             if (allocInfo->rbsReq % cell->rbgSize == 0)
21281             {
21282                if ((sfrPool->type2End == dlSf->type2End) && dlSf->lstRbgDfct)
21283                {
21284                   /* In this scenario we are wasting the last RBG for this dlSf */
21285                   sfrPool->type0End--;
21286                   sfrPool->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21287
21288                   dlSf->lstRbgDfct = 0;
21289
21290                   /*ABHINAV To check if these variables need to be taken care of*/
21291                   dlSf->type0End--;
21292                   dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21293                }
21294             }
21295             else
21296             {
21297                if (dlSf->lstRbgDfct)
21298                {
21299                   /* Check if type0 allocation can cater to this RETX requirement */
21300                   if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
21301                   {
21302                      return (FALSE);
21303                   }
21304                   else
21305                   {
21306                      if (sfrPool->type2End != dlSf->type2End)   /*Search again for some pool which has the END RBG of the BandWidth*/
21307                      {
21308                         continue;                                       
21309                      }  
21310                   }
21311                }
21312                else
21313                {
21314                   /* cannot allocate same number of required RBs */
21315                   return (FALSE);                    
21316                }
21317             }
21318          }
21319
21320          /*rg002.301 ccpu00120391 MOD condition is modified approprialtely to find if rbsReq is less than available RBS*/
21321          if(allocInfo->rbsReq <= (((sfrPool->type0End - sfrPool->type2End + 1)*\
21322                      cell->rbgSize) - dlSf->lstRbgDfct))
21323          {
21324             *sfrpoolInfo = sfrPool;
21325             return (TRUE);
21326          }
21327          else
21328          {
21329             if (sfrPool->bw <= sfrPool->bwAlloced + cell->rbgSize)
21330             {
21331                n = cmLListNext(l);
21332                /* If the ue is cell centre then it will simply check the memory available in next pool.
21333                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
21334
21335                if((!isUeCellEdge) && (!n->node))
21336                {
21337                   l = &dlSf->sfrTotalPoolInfo.cePool;
21338                   n = cmLListFirst(l);
21339                }
21340
21341                continue; 
21342             }    
21343
21344             /* MS_FIX: Number of RBs in case of RETX should be same as that of initial transmission */
21345             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21346             {
21347                /*rg002.301 ccpu00120391 MOD setting the remaining RBs  for the requested UE*/
21348                allocInfo->rbsReq = (((sfrPool->type0End - sfrPool->type2End + 1)*\
21349                         cell->rbgSize) - dlSf->lstRbgDfct);
21350                RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21351                noLyrs = allocInfo->tbInfo[0].noLyr;
21352                allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21353                *sfrpoolInfo = sfrPool;
21354                return (TRUE);
21355             }
21356             else
21357             {
21358                n = cmLListNext(l);
21359
21360                /* If the ue is cell centre then it will simply check the memory available in next pool.
21361                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
21362                if((!isUeCellEdge) && (!n->node))
21363                {
21364                   l = &dlSf->sfrTotalPoolInfo.cePool;
21365                   n = cmLListFirst(l);
21366                }
21367
21368                continue;
21369             }
21370
21371          //   return (FALSE);
21372          }
21373       }
21374       else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
21375       {
21376          sfrPool = (RgSchSFRPoolInfo*)(n->node);
21377          /* This is a Case where a UE was CC and had more RBs allocated than present in CE pool.
21378             In case this UE whn become CE with retx going on, then BW is not sufficient for Retx */
21379          if ((isUeCellEdge) &&
21380             (allocInfo->tbInfo[0].tbCb->txCntr != 0))
21381          {
21382             if(allocInfo->rbsReq > (sfrPool->bw - sfrPool->bwAlloced))
21383             {
21384                /* Adjust CE BW such that Retx alloc is successful */
21385                /* Check if merging CE with adjacent CC pool will be sufficient to process Retx */
21386
21387                /* If no Type 0 allocations are made from this pool */
21388                if (sfrPool->type0End == (((sfrPool->poolendRB + 1) / cell->rbgSize) - 1))
21389                {
21390                   if (sfrPool->adjCCPool &&
21391                         (sfrPool->adjCCPool->type2Start == sfrPool->poolendRB + 1) &&
21392                         (allocInfo->rbsReq <= ((sfrPool->bw - sfrPool->bwAlloced) + 
21393                                                ((sfrPool->adjCCPool->bw - sfrPool->adjCCPool->bwAlloced)))))
21394                   {
21395                      addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
21396
21397                      /* Adjusting CE Pool Info */
21398                      sfrPool->bw += addtnlPRBs;
21399                      sfrPool->type0End = ((sfrPool->poolendRB + addtnlPRBs + 1) /
21400                            cell->rbgSize) - 1;
21401
21402                      /* Adjusting CC Pool Info */
21403                      sfrPool->adjCCPool->type2Start += addtnlPRBs;
21404                      sfrPool->adjCCPool->type2End = RGSCH_CEIL(sfrPool->adjCCPool->type2Start, 
21405                            cell->rbgSize);
21406                      sfrPool->adjCCPool->bw -= addtnlPRBs;
21407                      *sfrpoolInfo = sfrPool;
21408                      return (TRUE);
21409                   }
21410                }
21411             }
21412          }
21413
21414          /* Check if CC pool is one of the following:
21415           * 1. |CE| + |CC "CCPool2Exists" = TRUE|
21416           * 2. |CC "CCPool2Exists" = FALSE| + |CE| + |CC "CCPool2Exists" = TRUE|
21417           */ 
21418          if(TRUE == sfrPool->CCPool2Exists)
21419          {
21420             l1 = &dlSf->sfrTotalPoolInfo.cePool;
21421             n1 = cmLListFirst(l1); 
21422             sfrCEPool = (RgSchSFRPoolInfo*)(n1->node);
21423             if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced))
21424             {
21425                *sfrpoolInfo = sfrCEPool;
21426                return (TRUE);
21427             }
21428             else if(allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))  
21429             {
21430                *sfrpoolInfo = sfrPool;
21431                return (TRUE);
21432             }
21433             /* Check if CE and CC boundary has unallocated prbs */
21434             else if ((sfrPool->poolstartRB == sfrPool->type2Start) &&
21435                   (sfrCEPool->type0End  == ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1))
21436             {
21437                if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced) + 
21438                      (sfrPool->bw - sfrPool->bwAlloced))
21439                {
21440                   /* Checking if BW can be allocated partly from CE pool and partly
21441                    * from CC pool
21442                    */
21443                   addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
21444                   /* Updating CE and CC  type2 parametrs based on the RBs allocated
21445                    * from these pools*/
21446                   sfrPool->type2Start -= addtnlPRBs;
21447                   sfrPool->type2End = RGSCH_CEIL(sfrPool->type2Start, cell->rbgSize);
21448                   sfrPool->bw += addtnlPRBs;
21449                   if (addtnlPRBs == (sfrCEPool->bw - sfrCEPool->bwAlloced))
21450                   {
21451                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
21452                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
21453                   }
21454                   else
21455                   {
21456                      sfrCEPool->bw -= addtnlPRBs;
21457                      sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1 - addtnlPRBs) / cell->rbgSize) - 1;
21458                   }
21459                   *sfrpoolInfo = sfrPool;
21460                   return (TRUE);
21461                }
21462                else if ( bwAvlbl < 
21463                      ((sfrCEPool->bw - sfrCEPool->bwAlloced) +
21464                       (sfrPool->bw - sfrPool->bwAlloced)))
21465                {
21466                   /* All the Prbs from CE BW shall be allocated */
21467                   if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21468                   {
21469                      sfrPool->type2Start   = sfrCEPool->type2Start;
21470                      sfrPool->bw          += sfrCEPool->bw - sfrCEPool->bwAlloced;
21471                      sfrCEPool->type2Start = sfrCEPool->poolendRB + 1;
21472                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
21473                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
21474
21475                      /* set the remaining RBs for the requested UE */
21476                      allocInfo->rbsReq = (sfrPool->bw - sfrPool->bwAlloced);
21477                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21478                      noLyrs = allocInfo->tbInfo[0].noLyr;
21479                      allocInfo->tbInfo[0].bytesReq = 
21480                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21481                      *sfrpoolInfo = sfrPool;               
21482                      return (TRUE);
21483                   }
21484                   else
21485                   {
21486                      return (FALSE);
21487                   }
21488                }
21489             }
21490          } 
21491
21492          /* Checking if no. of RBs required can be allocated from
21493           * SFR pool. 
21494           * 1. If available return the SFR pool.
21495           * 2. Else update the RBs required parameter based on the 
21496           *    BW available in the pool 
21497           * 3. Return FALSE if no B/W is available. 
21498           */
21499          if (allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))
21500          {
21501             *sfrpoolInfo = sfrPool;
21502             return (TRUE);
21503          }
21504          else
21505          {
21506             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
21507             {
21508                if (bwAvlbl < sfrPool->bw - sfrPool->bwAlloced)
21509                {
21510                   if (isUeCellEdge)
21511                   {
21512                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
21513                   }
21514                   bwAvlbl = sfrPool->bw - sfrPool->bwAlloced;
21515                   poolWithMaxAvlblBw = sfrPool;
21516                }
21517                n = cmLListNext(l);
21518
21519                if ((isUeCellEdge == FALSE) && (n == NULLP))
21520                {
21521                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
21522                   {
21523                      l = &dlSf->sfrTotalPoolInfo.cePool;
21524                      n = cmLListFirst(l);                          
21525                   }
21526                }
21527
21528                if (n == NULLP)
21529                {
21530                   if (bwAvlbl == 0)
21531                   {                                                             
21532                      if (isUeCellEdge)
21533                      {
21534                         dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
21535                      }
21536                      else
21537                      {
21538                         dlSf->sfrTotalPoolInfo.ccBwFull = TRUE;  
21539                      }
21540                      return (FALSE);
21541                   }
21542                   else
21543                   {
21544                      /* set the remaining RBs for the requested UE */
21545                      allocInfo->rbsReq = poolWithMaxAvlblBw->bw - 
21546                         poolWithMaxAvlblBw->bwAlloced;
21547                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21548                      noLyrs = allocInfo->tbInfo[0].noLyr;
21549                      allocInfo->tbInfo[0].bytesReq = 
21550                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21551                      *sfrpoolInfo = poolWithMaxAvlblBw;            
21552                      return (TRUE);
21553                   }
21554                }                          
21555             }
21556             else
21557             {                   
21558                n = cmLListNext(l);
21559
21560                if ((isUeCellEdge == FALSE) && (n == NULLP))
21561                {
21562                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
21563                   {
21564                      l = &dlSf->sfrTotalPoolInfo.cePool;
21565                      n = cmLListFirst(l);                          
21566                   }
21567                }
21568
21569                if (n == NULLP)
21570                {
21571                   return (FALSE);
21572                }
21573             }
21574
21575          }
21576       }   
21577    } 
21578    return (FALSE);
21579 }
21580 #endif
21581 #endif /* end of ifndef LTE_TDD*/
21582 /* LTE_ADV_FLAG_REMOVED_END */
21583
21584 /**
21585  * @brief To check if DL BW available for non-DLFS allocation.
21586  *
21587  * @details
21588  *
21589  *     Function : rgSCHCmnNonDlfsUeRbAlloc
21590  *
21591  *     Processing Steps:
21592  *      - Determine availability based on RA Type.
21593  *
21594  *  @param[in]  RgSchCellCb     *cell
21595  *  @param[in]  RgSchDlSf       *dlSf
21596  *  @param[in]  RgSchDlRbAlloc  *allocInfo
21597  *
21598  *  @return Bool
21599  *      -# TRUE
21600  *      -# FALSE
21601  **/
21602 #ifdef UNUSED_FUNC
21603 static Bool rgSCHCmnNonDlfsBwAvlbl
21604 (
21605 RgSchCellCb     *cell,
21606 RgSchDlSf       *dlSf,
21607 RgSchDlRbAlloc  *allocInfo
21608 )
21609 {
21610    uint8_t tbs;
21611    uint8_t noLyrs;
21612    uint8_t ignoredDfctRbg = FALSE;
21613
21614    if (dlSf->bw <= dlSf->bwAlloced)
21615    {
21616       DU_LOG("\nERROR  -->  SCH : (%d:%d)FAILED CRNTI:%d",
21617          dlSf->bw, dlSf->bwAlloced,allocInfo->rnti);
21618       return (FALSE);
21619    }
21620    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
21621    {
21622        /* Fix for ccpu00123919 : Number of RBs in case of RETX should be same as 
21623         * that of initial transmission. */
21624        if(allocInfo->tbInfo[0].tbCb->txCntr)
21625        {
21626           /* If RB assignment is being done for RETX. Then if reqRbs are 
21627            * a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
21628            * not a multiple of rbgSize then check if lsgRbgDfct exists */
21629           if (allocInfo->rbsReq % cell->rbgSize == 0)
21630           {
21631              if (dlSf->lstRbgDfct)
21632              {
21633                 /* In this scenario we are wasting the last RBG for this dlSf */
21634                 
21635                 dlSf->type0End--;
21636                 dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
21637                 /* Fix: MUE_PERTTI_DL */
21638                 dlSf->lstRbgDfct = 0;
21639                 ignoredDfctRbg = TRUE;
21640                 
21641              }
21642           }
21643           else
21644           {
21645              if (dlSf->lstRbgDfct)
21646              {
21647                 /* Check if type0 allocation can cater to this RETX requirement */
21648                 if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
21649                 {
21650                    return (FALSE);
21651                 }
21652              }
21653              else
21654              {
21655                 /* cannot allocate same number of required RBs */
21656                 return (FALSE);              
21657              }
21658           }
21659        }
21660
21661        /* Condition is modified approprialtely to find
21662         * if rbsReq is less than available RBS*/
21663       if(allocInfo->rbsReq <= (((dlSf->type0End - dlSf->type2End + 1)*\
21664                cell->rbgSize) - dlSf->lstRbgDfct))
21665       {
21666          return (TRUE);
21667       }
21668       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
21669        * allocation in TDD when requested RBs are more than available RBs*/
21670       else
21671       {
21672           /* MS_WORKAROUND for ccpu00122022 */
21673          if (dlSf->bw < dlSf->bwAlloced + cell->rbgSize)
21674          {
21675             /* ccpu00132358- Re-assigning the values which were updated above 
21676              * if it is RETX and Last  RBG available*/
21677             if(ignoredDfctRbg == TRUE)
21678             {
21679                dlSf->type0End++;
21680                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
21681                dlSf->lstRbgDfct = 1;
21682             }
21683
21684
21685             return (FALSE);
21686          }
21687          /* Fix: Number of RBs in case of RETX should be same as 
21688           * that of initial transmission. */
21689          if(allocInfo->tbInfo[0].tbCb->txCntr == 0 
21690 #ifdef LTE_ADV
21691             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
21692 #endif
21693             )
21694          {
21695             /* Setting the remaining RBs for the requested UE*/
21696             allocInfo->rbsReq = (((dlSf->type0End - dlSf->type2End + 1)*\
21697                         cell->rbgSize) - dlSf->lstRbgDfct);
21698             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21699             noLyrs = allocInfo->tbInfo[0].noLyr;
21700             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21701             /* DwPts Scheduling Changes Start */
21702 #if LTE_TDD
21703             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
21704             {   
21705                allocInfo->tbInfo[0].bytesReq = 
21706                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
21707             }
21708 #endif            
21709             /* DwPts Scheduling Changes End */
21710          }
21711          else
21712          {
21713                     /* ccpu00132358- Re-assigning the values which were updated above 
21714              * if it is RETX and Last  RBG available*/
21715             if(ignoredDfctRbg == TRUE)
21716             {
21717                dlSf->type0End++;
21718                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
21719                dlSf->lstRbgDfct = 1;
21720             }
21721
21722             DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",
21723                   allocInfo->rnti);
21724             DU_LOG("\nERROR  -->  SCH : RB Alloc failed for LAA TB type 0\n");
21725             return (FALSE);
21726          }
21727          return (TRUE);
21728       }
21729    }
21730    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
21731    {
21732       if (allocInfo->rbsReq <= (dlSf->bw - dlSf->bwAlloced))
21733       {
21734          return (TRUE);
21735       }
21736       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
21737        * allocation in TDD when requested RBs are more than available RBs*/
21738       else
21739       {
21740          /* Fix: Number of RBs in case of RETX should be same as 
21741           * that of initial transmission. */
21742          if((allocInfo->tbInfo[0].tbCb->txCntr == 0) 
21743 #ifdef LTE_ADV
21744             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
21745 #endif
21746             )
21747          {
21748             /* set the remaining RBs for the requested UE */
21749             allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
21750             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
21751             noLyrs = allocInfo->tbInfo[0].noLyr;
21752             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
21753             /* DwPts Scheduling Changes Start */
21754 #ifdef LTE_TDD
21755             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
21756             {   
21757                allocInfo->tbInfo[0].bytesReq = 
21758                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
21759             }
21760 #endif            
21761             /* DwPts Scheduling Changes End */
21762          }
21763          else
21764          {
21765             DU_LOG("\nERROR  -->  SCH : RB Alloc failed for LAA TB type 2\n");
21766             DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",allocInfo->rnti);
21767             return (FALSE);
21768          }
21769          /* Fix: Number of RBs in case of RETX should be same as 
21770           * that of initial transmission. */
21771          return (TRUE);
21772       }
21773    }
21774    DU_LOG("\nERROR  -->  SCH : FAILED for CRNTI:%d",allocInfo->rnti);
21775    return (FALSE);
21776 }
21777 #endif
21778 /* LTE_ADV_FLAG_REMOVED_START */
21779 #ifndef LTE_TDD
21780 /**
21781  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21782  *
21783  * @details
21784  *
21785  *     Function : rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
21786  *
21787  *     Processing Steps:
21788  *
21789  *  @param[in]  RgSchCellCb     *cell
21790  *  @param[in]  RgSchDlSf       *dlSf
21791  *  @param[in]  uint8_t              rbStrt
21792  *  @param[in]  uint8_t              numRb
21793  *
21794  *  @return Void
21795  **/
21796 Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
21797 (
21798 RgSchCellCb  *cell,
21799 RgSchDlSf    *dlSf,
21800 uint8_t      rbStrt,
21801 uint8_t      numRb
21802 )
21803
21804    CmLListCp   *l;
21805    CmLList     *n;
21806    RgSchSFRPoolInfo  *sfrPool;
21807    
21808    l = &dlSf->sfrTotalPoolInfo.ccPool;
21809      
21810    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21811    dlSf->bwAlloced += numRb;
21812    dlSf->type2Start += numRb;
21813    n = cmLListFirst(l);
21814         
21815    while(n->node)
21816    {
21817         sfrPool = (RgSchSFRPoolInfo*)(n->node);
21818         n = cmLListNext(l);
21819          
21820          /* 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   */
21821         if((sfrPool->poolendRB >= dlSf->type2Start) && (sfrPool->type2Start < dlSf->type2Start))
21822         {
21823                 sfrPool->type2End   =  dlSf->type2End;
21824                 sfrPool->bwAlloced  =  dlSf->type2Start - sfrPool->poolstartRB; 
21825                 sfrPool->type2Start =  dlSf->type2Start;
21826         }          
21827         else 
21828         { 
21829                 /* If the pool contains all RBs allocated in this allocation*/
21830                 if(dlSf->type2Start > sfrPool->poolendRB)
21831                 {                
21832                         sfrPool->type2End   =  sfrPool->type0End + 1;
21833                         sfrPool->bwAlloced  =  sfrPool->bw; 
21834                         sfrPool->type2Start =  sfrPool->poolendRB + 1;             
21835                 }  
21836         }
21837       if (!n)
21838       { 
21839          if (l != &dlSf->sfrTotalPoolInfo.cePool)
21840          {
21841             l = &dlSf->sfrTotalPoolInfo.cePool;   
21842             n = cmLListFirst(l);
21843          }
21844          else
21845             return;
21846       }
21847    }
21848    return;
21849 }
21850
21851 /**
21852  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21853  *
21854  * @details
21855  *
21856  *     Function : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
21857  *
21858  *     Processing Steps:
21859  *
21860  *  @param[in]  RgSchCellCb     *cell
21861  *  @param[in]  RgSchDlSf       *dlSf
21862  *  @param[in]  uint8_t              rbStrt
21863  *  @param[in]  uint8_t              numRb
21864  *
21865  *  @return Void
21866  **/
21867 #ifdef UNUSED_FUNC
21868 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
21869 (
21870 RgSchCellCb  *cell,
21871 RgSchUeCb    *ue,
21872 RgSchDlSf    *dlSf,
21873 uint8_t      rbStrt,
21874 uint8_t      numRb
21875 )
21876 {
21877    CmLListCp   *l;
21878    CmLList     *n;
21879    RgSchSFRPoolInfo  *sfrCCPool1 = NULL;
21880    RgSchSFRPoolInfo  *sfrCCPool2 = NULL;
21881    S16 ret = RFAILED;
21882
21883    /* Move the type2End pivot forward */
21884    
21885    
21886    l = &dlSf->sfrTotalPoolInfo.ccPool;
21887    n = cmLListFirst(l);
21888    while(n)
21889    {
21890       sfrCCPool1 = (RgSchSFRPoolInfo*)(n->node);
21891       /* KWork fix */
21892       if (sfrCCPool1 ==  NULLP)
21893             {
21894                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
21895                         "sfrCCPool1 is NULL for CRNTI:%d",ue->ueId);
21896                return RFAILED;
21897             }
21898       n = cmLListNext(l);
21899       if(n)
21900       {
21901           sfrCCPool2 = (RgSchSFRPoolInfo*)(n->node);
21902           n = cmLListNext(l);
21903       }
21904       if((sfrCCPool1) && (sfrCCPool2))
21905       { 
21906           /* Based on RNTP info, the CC user is assigned high power per subframe basis */
21907           if(((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
21908               (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) || 
21909              ((dlSf->type2Start >= sfrCCPool2->pwrHiCCRange.startRb) &&
21910               (dlSf->type2Start + numRb < sfrCCPool2->pwrHiCCRange.endRb)))
21911           {
21912                ue->lteAdvUeCb.isCCUePHigh = TRUE;
21913
21914                /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
21915                ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
21916                if (ret != ROK)
21917                {
21918                     DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
21919                       "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
21920                     return RFAILED;
21921                }
21922            }
21923       }
21924       else
21925       {
21926          if((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
21927                (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb))
21928          {
21929             ue->lteAdvUeCb.isCCUePHigh = TRUE;
21930
21931             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
21932             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
21933             if (ret != ROK)
21934             {
21935                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" 
21936                         "rgSCHCmnBuildRntpInfo() function returned RFAILED CRNTI:%d",ue->ueId);
21937                return RFAILED;
21938             }
21939          }
21940       }
21941    }
21942    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21943 #ifndef LTEMAC_SPS
21944    dlSf->bwAlloced += numRb;
21945    /*MS_FIX for ccpu00123918*/
21946    dlSf->type2Start += numRb;
21947 #endif
21948    return ROK;
21949
21950 }
21951 #endif
21952 #endif /* end of ifndef LTE_TDD*/
21953 /* LTE_ADV_FLAG_REMOVED_END */
21954 /**
21955  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
21956  *
21957  * @details
21958  *
21959  *     Function : rgSCHCmnNonDlfsUpdTyp2Alloc
21960  *
21961  *     Processing Steps:
21962  *
21963  *  @param[in]  RgSchCellCb     *cell
21964  *  @param[in]  RgSchDlSf       *dlSf
21965  *  @param[in]  uint8_t              rbStrt
21966  *  @param[in]  uint8_t              numRb
21967  *
21968  *  @return Void
21969  **/
21970 static Void rgSCHCmnNonDlfsUpdTyp2Alloc
21971 (
21972 RgSchCellCb *cell,
21973 RgSchDlSf   *dlSf,
21974 uint8_t     rbStrt,
21975 uint8_t     numRb
21976 )
21977 {
21978    /* Move the type2End pivot forward */
21979    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
21980 //#ifndef LTEMAC_SPS
21981    dlSf->bwAlloced += numRb;
21982    /*Fix for ccpu00123918*/
21983    dlSf->type2Start += numRb;
21984 //#endif
21985    return;
21986 }
21987
21988 /**
21989  * @brief To do DL allocation using TYPE0 RA.
21990  *
21991  * @details
21992  *
21993  *     Function : rgSCHCmnNonDlfsType0Alloc
21994  *
21995  *     Processing Steps:
21996  *      - Perform TYPE0 allocation using the RBGs between
21997  *        type0End and type2End.
21998  *      - Build the allocation mask as per RBG positioning.
21999  *      - Update the allocation parameters.
22000  *
22001  *  @param[in]  RgSchCellCb     *cell
22002  *  @param[in]  RgSchDlSf       *dlSf
22003  *  @param[in]  RgSchDlRbAlloc  *allocInfo
22004  *
22005  *  @return Void
22006  **/
22007 #ifdef UNUSED_FUNC
22008 static Void rgSCHCmnNonDlfsType0Alloc
22009 (
22010 RgSchCellCb     *cell,
22011 RgSchDlSf       *dlSf,
22012 RgSchDlRbAlloc  *allocInfo,
22013 RgSchUeCb       *ue
22014 )
22015 {
22016    uint32_t dlAllocMsk = 0;
22017    uint8_t  rbgFiller = dlSf->lstRbgDfct;
22018    uint8_t  noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
22019    //uint8_t  noRbgs = (allocInfo->rbsReq + rbgFiller)/ cell->rbgSize;
22020    uint8_t  noRbs;
22021    uint8_t  noLyr;
22022    uint8_t  iTbs;
22023    uint32_t          tb1BytesAlloc = 0;
22024    uint32_t          tb2BytesAlloc = 0;
22025    RgSchCmnDlUe *dlUe         = RG_SCH_CMN_GET_DL_UE(ue,cell);
22026
22027    //if(noRbgs == 0) noRbgs = 1; /* Not required as ceilling is used above*/
22028
22029    /* Fix for ccpu00123919*/
22030    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22031    if (dlSf->bwAlloced + noRbs > dlSf->bw)
22032    {
22033       if (--noRbgs == 0)
22034       {
22035          return;
22036       }
22037       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22038    }
22039
22040    /* Fix for ccpu00138701: Ceilling is using to derive num of RBGs, Therefore, 
22041    *  after this operation,checking Max TB size and Max RBs are not crossed
22042    * if it is crossed then decrement num of RBGs. */
22043    //if((noRbs + rbgFiller) % cell->rbgSize)
22044    if((noRbs > allocInfo->rbsReq) &&
22045          (allocInfo->rbsReq + rbgFiller) % cell->rbgSize)
22046    {/* considering ue category limitation
22047      * due to ceiling */
22048
22049 #ifdef LTE_ADV
22050       if (rgSCHLaaIsLaaTB(allocInfo)== FALSE)
22051 #endif
22052       {
22053          if ((allocInfo->tbInfo[0].schdlngForTb) && (!allocInfo->tbInfo[0].tbCb->txCntr))
22054          {
22055             iTbs = allocInfo->tbInfo[0].iTbs;
22056             noLyr = allocInfo->tbInfo[0].noLyr;
22057             tb1BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22058          }
22059
22060          if ((allocInfo->tbInfo[1].schdlngForTb) && (!allocInfo->tbInfo[1].tbCb->txCntr))
22061          {
22062             iTbs = allocInfo->tbInfo[1].iTbs;
22063             noLyr = allocInfo->tbInfo[1].noLyr;
22064             tb2BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22065          }
22066       }
22067       
22068       /* Only Check for New Tx No need for Retx */
22069       if (tb1BytesAlloc || tb2BytesAlloc)
22070       {
22071          if (( ue->dl.aggTbBits >= dlUe->maxTbBits) ||
22072                (tb1BytesAlloc >= dlUe->maxTbSz/8) ||
22073                (tb2BytesAlloc >= dlUe->maxTbSz/8) ||
22074                (noRbs >= dlUe->maxRb))
22075          {
22076             if (--noRbgs == 0)
22077             {
22078                return;
22079             }
22080             noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22081          }
22082       }
22083    }
22084    /* type0End would have been initially (during subfrm Init) at the bit position
22085     * (cell->noOfRbgs - 1), 0 being the most significant.
22086     * Getting DlAllocMsk for noRbgs and at the appropriate position */
22087    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - dlSf->type0End));
22088    /* Move backwards the type0End pivot */
22089    dlSf->type0End -= noRbgs;
22090    /*Fix for ccpu00123919*/
22091    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
22092    /* Update the bwAlloced field accordingly */
22093 //#ifndef LTEMAC_SPS    /* ccpu00129474*/
22094    dlSf->bwAlloced += noRbs;
22095 //#endif
22096    /* Update Type0 Alloc Info */
22097    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
22098    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
22099    allocInfo->rbsAlloc = noRbs;
22100
22101    /* Update Tb info for each scheduled TB */
22102    iTbs = allocInfo->tbInfo[0].iTbs;
22103    noLyr = allocInfo->tbInfo[0].noLyr;
22104    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
22105     * RETX TB Size is same as Init TX TB Size */
22106    if (allocInfo->tbInfo[0].tbCb->txCntr)
22107    {
22108       allocInfo->tbInfo[0].bytesAlloc =
22109          allocInfo->tbInfo[0].bytesReq;
22110    }
22111    else
22112    {
22113       allocInfo->tbInfo[0].bytesAlloc =
22114          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22115       /* DwPts Scheduling Changes Start */
22116 #ifdef LTE_TDD
22117       if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
22118       {
22119          allocInfo->tbInfo[0].bytesAlloc =
22120             rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
22121       }
22122 #endif      
22123       /* DwPts Scheduling Changes End */
22124    }
22125
22126    if (allocInfo->tbInfo[1].schdlngForTb)
22127    {
22128       iTbs = allocInfo->tbInfo[1].iTbs;
22129       noLyr = allocInfo->tbInfo[1].noLyr;
22130       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
22131        * RETX TB Size is same as Init TX TB Size */
22132       if (allocInfo->tbInfo[1].tbCb->txCntr)
22133       {
22134          allocInfo->tbInfo[1].bytesAlloc =
22135             allocInfo->tbInfo[1].bytesReq;
22136       }
22137       else
22138       {
22139          allocInfo->tbInfo[1].bytesAlloc =
22140             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22141          /* DwPts Scheduling Changes Start */
22142 #ifdef LTE_TDD
22143          if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
22144          {
22145             allocInfo->tbInfo[1].bytesAlloc =
22146                rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
22147          }
22148 #endif      
22149          /* DwPts Scheduling Changes End */
22150       }
22151    }
22152
22153    /* The last RBG which can be smaller than the RBG size is consedered
22154     * only for the first time allocation of TYPE0 UE */
22155    dlSf->lstRbgDfct = 0;
22156    return;
22157 }
22158 #endif
22159 #ifndef LTE_TDD
22160
22161 /**
22162  * @brief To prepare RNTP value from the PRB allocation (P-High -> 1 and P-Low -> 0)
22163  *
22164  * @details
22165  *
22166  *     Function : rgSCHCmnBuildRntpInfo
22167  *
22168  *     Processing Steps:
22169  *
22170  *  @param[in]  uint8_t                 *rntpPtr
22171  *  @param[in]  uint8_t                 startRb
22172  *  @param[in]  uint8_t                 numRb
22173  *
22174  *  @return Void
22175  **/
22176 #ifdef UNUSED_FUNC
22177 static S16 rgSCHCmnBuildRntpInfo
22178 (
22179 RgSchCellCb  *cell,
22180 uint8_t      *rntpPtr,
22181 uint8_t      startRb,
22182 uint8_t      nmbRb,
22183 uint16_t     bw
22184 )
22185 {
22186    uint16_t rbPtrStartIdx;              /* Start Index of Octete Buffer to be filled */
22187    uint16_t rbPtrEndIdx;                /* End Index of Octete Buffer to be filled */
22188    uint16_t rbBitLoc;                   /* Bit Location to be set as 1 in the current Byte */
22189    uint16_t nmbRbPerByte;               /* PRB's to be set in the current Byte (in case of multiple Bytes) */
22190
22191
22192    rbPtrStartIdx = (startRb)/8;
22193    rbPtrEndIdx   = (startRb + nmbRb)/8;
22194
22195    if (rntpPtr == NULLP)
22196    {
22197       DU_LOG("\nERROR  -->  SCH : rgSCHCmnBuildRntpInfo():"
22198                "rntpPtr can't be NULLP (Memory Allocation Failed)");
22199       return RFAILED;
22200    }
22201
22202    while(rbPtrStartIdx <= rbPtrEndIdx)
22203    {
22204       rbBitLoc = (startRb)%8;
22205
22206       /* case 1: startRb and endRb lies in same Byte */
22207       if (rbPtrStartIdx == rbPtrEndIdx)
22208       {
22209          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
22210                                      | (((1<<nmbRb)-1)<<rbBitLoc);
22211       }
22212
22213       /* case 2: startRb and endRb lies in different Byte */
22214       if (rbPtrStartIdx != rbPtrEndIdx)
22215       {
22216          nmbRbPerByte = 8 - rbBitLoc;
22217          nmbRb        = nmbRb - nmbRbPerByte;
22218          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
22219                                      | (((1<<nmbRbPerByte)-1)<<rbBitLoc);
22220          startRb = startRb + nmbRbPerByte;
22221       }
22222
22223       rbPtrStartIdx++;
22224    }
22225
22226    /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** Adding Debug logs */
22227
22228    /* dsfr_pal_fixes ** 25-March-2013 ** SKS ** Adding Debug logs to print RNTP */
22229
22230    return ROK;
22231 }
22232
22233 /**
22234  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
22235  *
22236  * @details
22237  *
22238  *     Function : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
22239  *
22240  *     Processing Steps:
22241  *
22242  *  @param[in]  RgSchCellCb     *cell
22243  *  @param[in]  RgSchDlSf       *dlSf
22244  *  @param[in]  uint8_t              rbStrt
22245  *  @param[in]  uint8_t              numRb
22246  *
22247  *  @return Void
22248  **/
22249 static S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
22250 (
22251 RgSchCellCb        *cell,
22252 RgSchUeCb          *ue,
22253 RgSchDlSf          *dlSf,
22254 RgSchSFRPoolInfo   *sfrPool,
22255 uint8_t            rbStrt,
22256 uint8_t            numRb
22257 )
22258 {
22259 #ifndef LTEMAC_SPS
22260    S16 ret;
22261 #endif
22262
22263    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
22264    sfrPool->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
22265    
22266 #ifndef LTEMAC_SPS
22267    dlSf->type2Start += numRb;
22268    dlSf->bwAlloced += numRb;
22269    
22270    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
22271    {
22272       /* Based on RNTP info, the CC user is assigned high power per subframe basis */
22273       if(FALSE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge)
22274       {
22275          if((sfrPool->type2Start >= sfrPool->pwrHiCCRange.startRb) &&
22276                (sfrPool->type2Start + numRb < sfrPool->pwrHiCCRange.endRb))
22277          {
22278             ue->lteAdvUeCb.isCCUePHigh = TRUE;
22279
22280             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
22281             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
22282             if (ret != ROK)
22283             {
22284                DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
22285                         "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
22286                return RFAILED;
22287             }
22288          }
22289       }
22290       else
22291       {
22292          /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
22293          ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
22294          if (ret != ROK)
22295          {
22296             DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
22297                      "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
22298             return RFAILED;
22299          }
22300       }
22301    }
22302    sfrPool->type2Start += numRb;
22303    sfrPool->bwAlloced += numRb;
22304 #endif 
22305
22306    return ROK;
22307 }
22308
22309 /**
22310  * @brief To do DL allocation using TYPE0 RA.
22311  *
22312  * @details
22313  *
22314  *     Function : rgSCHCmnNonDlfsSFRPoolType0Alloc
22315  *
22316  *     Processing Steps:
22317  *      - Perform TYPE0 allocation using the RBGs between type0End and type2End.
22318  *      - Build the allocation mask as per RBG positioning.
22319  *      - Update the allocation parameters.
22320  *
22321  *  @param[in]  RgSchCellCb     *cell
22322  *  @param[in]  RgSchDlSf       *dlSf
22323  *  @param[in]  RgSchDlRbAlloc  *allocInfo
22324  *
22325  *  @return Void
22326  **/
22327 static Void rgSCHCmnNonDlfsSFRPoolType0Alloc
22328 (
22329 RgSchCellCb        *cell,
22330 RgSchDlSf          *dlSf,
22331 RgSchSFRPoolInfo   *poolInfo,
22332 RgSchDlRbAlloc     *allocInfo
22333 )
22334 {
22335    uint32_t dlAllocMsk = 0;
22336    uint8_t  rbgFiller = 0;
22337    uint8_t  noRbgs = 0;
22338    uint8_t  noRbs;
22339    uint8_t  noLyr;
22340    uint8_t  iTbs;
22341
22342
22343    if (poolInfo->poolstartRB + poolInfo->bw == dlSf->bw)
22344    {
22345                 if (poolInfo->type0End == dlSf->bw/4)
22346                 {
22347                         rbgFiller = dlSf->lstRbgDfct;
22348                         /* The last RBG which can be smaller than the RBG size is consedered
22349                         * only for the first time allocation of TYPE0 UE */
22350                         dlSf->lstRbgDfct = 0;
22351                 }
22352    }
22353
22354    noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
22355
22356    /* Abhinav to-do start */
22357    /* MS_FIX for ccpu00123919*/
22358    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22359    if (dlSf->bwAlloced + noRbs > dlSf->bw)
22360    {
22361       if (--noRbgs == 0)
22362       {
22363          return;
22364       }
22365       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
22366    }
22367    /* Abhinav to-do end */
22368
22369
22370    
22371    /* type0End would have been initially (during subfrm Init) at the bit position
22372     * (cell->noOfRbgs - 1), 0 being the most significant.
22373     * Getting DlAllocMsk for noRbgs and at the appropriate position */
22374    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - poolInfo->type0End));
22375    /* Move backwards the type0End pivot */
22376    poolInfo->type0End -= noRbgs;
22377    /*MS_FIX for ccpu00123919*/
22378    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
22379    /* Update the bwAlloced field accordingly */
22380    poolInfo->bwAlloced += noRbs + dlSf->lstRbgDfct;
22381    dlSf->bwAlloced += noRbs + dlSf->lstRbgDfct;
22382    
22383    /* Update Type0 Alloc Info */
22384    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
22385    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
22386    allocInfo->rbsAlloc = noRbs;
22387
22388    /* Update Tb info for each scheduled TB */
22389    iTbs = allocInfo->tbInfo[0].iTbs;
22390    noLyr = allocInfo->tbInfo[0].noLyr;
22391    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
22392     * RETX TB Size is same as Init TX TB Size */
22393    if (allocInfo->tbInfo[0].tbCb->txCntr)
22394    {
22395       allocInfo->tbInfo[0].bytesAlloc =
22396          allocInfo->tbInfo[0].bytesReq;
22397    }
22398    else
22399    {
22400       allocInfo->tbInfo[0].bytesAlloc =
22401          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22402    }
22403
22404    if (allocInfo->tbInfo[1].schdlngForTb)
22405    {
22406       iTbs = allocInfo->tbInfo[1].iTbs;
22407       noLyr = allocInfo->tbInfo[1].noLyr;
22408       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
22409        * RETX TB Size is same as Init TX TB Size */
22410       if (allocInfo->tbInfo[1].tbCb->txCntr)
22411       {
22412          allocInfo->tbInfo[1].bytesAlloc =
22413             allocInfo->tbInfo[1].bytesReq;
22414       }
22415       else
22416       {
22417          allocInfo->tbInfo[1].bytesAlloc =
22418             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
22419       }
22420    }
22421
22422    /* The last RBG which can be smaller than the RBG size is consedered
22423     * only for the first time allocation of TYPE0 UE */
22424    dlSf->lstRbgDfct = 0;
22425    return;
22426 }
22427 #endif
22428 /**
22429  * @brief Computes RNTP Info for a subframe.
22430  *
22431  * @details
22432  *
22433  *     Function :  rgSCHCmnNonDlfsDsfrRntpComp 
22434  *
22435  *     Processing Steps:
22436  *      - Computes RNTP info from individual pools.
22437  *
22438  *  @param[in]  RgSchDlSf       *dlSf
22439  *
22440  *  @return  void
22441  
22442  **/
22443 static void rgSCHCmnNonDlfsDsfrRntpComp(RgSchCellCb *cell,RgSchDlSf *dlSf)
22444 {
22445    static uint16_t samples = 0;
22446    uint16_t i;
22447    uint16_t bwBytes = (dlSf->bw-1)/8;
22448    RgrLoadInfIndInfo *rgrLoadInf;
22449    uint16_t len;
22450    uint16_t ret     = ROK;
22451
22452
22453    len = (dlSf->bw % 8 == 0) ? dlSf->bw/8 : dlSf->bw/8 + 1;
22454
22455    /* RNTP info is ORed every TTI and the sample is stored in cell control block */ 
22456    for(i = 0; i <= bwBytes; i++)
22457    {
22458      cell->rntpAggrInfo.val[i] |= dlSf->rntpInfo.val[i];
22459    }
22460    samples = samples + 1;
22461    /* After every 1000 ms, the RNTP info will be sent to application to be further sent to all neighbouring eNB
22462          informing them about the load indication for cell edge users */
22463    if(RG_SCH_MAX_RNTP_SAMPLES == samples)
22464    {
22465       /* ccpu00134492 */
22466       ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf,
22467                sizeof(RgrLoadInfIndInfo));
22468       if (ret != ROK)
22469       {
22470          DU_LOG("\nERROR  -->  SCH : Could not "
22471             "allocate memory for sending LoadInfo");
22472          return;  
22473       }
22474      
22475       rgrLoadInf->u.rntpInfo.pres = cell->rntpAggrInfo.pres;
22476       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
22477       rgrLoadInf->u.rntpInfo.len  = len;
22478
22479       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
22480       rgrLoadInf->u.rntpInfo.val = cell->rntpAggrInfo.val; 
22481       rgrLoadInf->cellId = cell->cellId;
22482
22483       /* dsfr_pal_fixes ** 22-March-2013 ** SKS */
22484       rgrLoadInf->bw = dlSf->bw;
22485       rgrLoadInf->type = RGR_SFR;
22486
22487       ret = rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf);
22488       if(ret == RFAILED)
22489       {
22490          DU_LOG("\nERROR  -->  SCH : rgSCHCmnNonDlfsDsfrRntpComp():"
22491                   "rgSCHUtlRgrLoadInfInd() returned RFAILED");
22492       }
22493
22494       memset(cell->rntpAggrInfo.val,0,len);
22495       samples = 0;
22496    }
22497  } 
22498 /* LTE_ADV_FLAG_REMOVED_END */
22499
22500 /* LTE_ADV_FLAG_REMOVED_START */
22501 /**
22502  * @brief Performs RB allocation per UE from a pool.
22503  *
22504  * @details
22505  *
22506  *     Function : rgSCHCmnSFRNonDlfsUeRbAlloc
22507  *
22508  *     Processing Steps:
22509  *      - Allocate consecutively available RBs.
22510  *
22511  *  @param[in]  RgSchCellCb     *cell
22512  *  @param[in]  RgSchUeCb       *ue
22513  *  @param[in]  RgSchDlSf       *dlSf
22514  *  @param[out] uint8_t              *isDlBwAvail
22515  *
22516  *  @return  S16
22517  *      -# ROK
22518  *      -# RFAILED
22519  **/
22520 #ifdef UNUSED_FUNC
22521 static S16 rgSCHCmnSFRNonDlfsUeRbAlloc
22522 (
22523 RgSchCellCb        *cell,
22524 RgSchUeCb          *ue,
22525 RgSchDlSf          *dlSf,
22526 uint8_t           *isDlBwAvail
22527 )
22528 {
22529    RgSchDlRbAlloc  *allocInfo;
22530    RgSchCmnDlUe    *dlUe;
22531    Bool isUECellEdge;
22532    RgSchSFRPoolInfo *sfrpoolInfo = NULLP;
22533
22534
22535    isUECellEdge = RG_SCH_CMN_IS_UE_CELL_EDGE(ue);
22536
22537    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
22538    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
22539    *isDlBwAvail = TRUE;
22540
22541    /*Find which pool is available for this UE*/
22542    if (rgSCHCmnNonDlfsSFRBwAvlbl(cell,  &sfrpoolInfo, dlSf, allocInfo, isUECellEdge) != TRUE)
22543    {
22544       /* SFR_FIX - If this is CE UE there may be BW available in CC Pool
22545          So CC UEs will be scheduled */
22546       if (isUECellEdge)
22547       {
22548          *isDlBwAvail = TRUE;
22549       }
22550       else
22551       {
22552          *isDlBwAvail = FALSE;
22553       }
22554       return RFAILED;
22555    }
22556
22557    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX || dlUe->proc->tbInfo[1].isAckNackDtx)
22558    {
22559       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
22560    }
22561    else
22562    {
22563       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
22564    }
22565    
22566    if (!(allocInfo->pdcch))
22567    {
22568       /* Returning ROK since PDCCH might be available for another UE and further allocations could be done */
22569       return RFAILED;
22570    }
22571    
22572 #ifdef LTEMAC_SPS
22573    allocInfo->rnti = ue->ueId;
22574 #endif
22575
22576    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
22577    {
22578       allocInfo->allocInfo.raType2.isLocal = TRUE;
22579       /* rg004.201 patch - ccpu00109921 fix end */
22580       /* MS_FIX for ccpu00123918*/
22581       allocInfo->allocInfo.raType2.rbStart = (uint8_t)sfrpoolInfo->type2Start;
22582       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22583       /* rg007.201 - Changes for MIMO feature addition */
22584       /* rg008.201 - Removed dependency on MIMO compile-time flag */
22585       rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrpoolInfo, \
22586             allocInfo->allocInfo.raType2.rbStart, \
22587             allocInfo->allocInfo.raType2.numRb);
22588       allocInfo->rbsAlloc = allocInfo->rbsReq;
22589       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22590    }
22591    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
22592    {
22593       rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, sfrpoolInfo, allocInfo);
22594    }
22595 #ifndef LTE_TDD
22596 #ifdef DEBUGP
22597    rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,0);
22598    if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
22599    {
22600       rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,1);
22601    }
22602 #endif
22603 #endif
22604
22605 #if defined(LTEMAC_SPS)
22606    /* Update the sub-frame with new allocation */
22607    dlSf->bwAlloced += allocInfo->rbsReq;
22608 #endif
22609
22610    return ROK;
22611 }
22612 #endif
22613 /* LTE_ADV_FLAG_REMOVED_END */
22614 #endif /* LTE_TDD */
22615
22616 /**
22617  * @brief Performs RB allocation per UE for frequency non-selective cell.
22618  *
22619  * @details
22620  *
22621  *     Function : rgSCHCmnNonDlfsUeRbAlloc
22622  *
22623  *     Processing Steps:
22624  *      - Allocate consecutively available RBs.
22625  *
22626  *  @param[in]  RgSchCellCb     *cell
22627  *  @param[in]  RgSchUeCb       *ue
22628  *  @param[in]  RgSchDlSf       *dlSf
22629  *  @param[out] uint8_t              *isDlBwAvail
22630  *
22631  *  @return  S16
22632  *      -# ROK
22633  *      -# RFAILED
22634  **/
22635 static S16 rgSCHCmnNonDlfsUeRbAlloc
22636 (
22637 RgSchCellCb  *cell,
22638 RgSchUeCb    *ue,
22639 RgSchDlSf    *dlSf,
22640 uint8_t      *isDlBwAvail
22641 )
22642 {
22643    RgSchDlRbAlloc  *allocInfo;
22644    RgSchCmnDlUe    *dlUe;
22645 #ifdef LAA_DBG
22646    uint32_t            dbgRbsReq = 0;
22647 #endif
22648
22649 #ifdef RG_5GTF
22650    RgSch5gtfUeCb  *ue5gtfCb = &(ue->ue5gtfCb);
22651         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[ue5gtfCb->BeamId]);
22652 #endif
22653    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
22654    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
22655    *isDlBwAvail = TRUE;
22656
22657         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
22658         {
22659            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
22660          ue->ueId);
22661            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
22662                 return RFAILED;
22663         }
22664
22665    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX 
22666        || dlUe->proc->tbInfo[1].isAckNackDtx)
22667    {
22668       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
22669    }
22670    else
22671    {
22672       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
22673    }
22674    if (!(allocInfo->pdcch))
22675    {
22676       /* Returning ROK since PDCCH might be available for another UE and
22677        * further allocations could be done */
22678         DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : PDCCH allocation failed :ue (%u)",
22679          ue->ueId);
22680         DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR PDCCH allocation failed\n");
22681       return RFAILED;
22682    }
22683 #ifdef RG_5GTF
22684         //maxPrb = RGSCH_MIN((allocInfo->vrbgReq * MAX_5GTF_VRBG_SIZE), ue5gtfCb->maxPrb);
22685    //maxPrb = RGSCH_MIN(maxPrb, 
22686                 //((beamInfo->totVrbgAvail - beamInfo->vrbgStart)* MAX_5GTF_VRBG_SIZE)));
22687         //TODO_SID Need to check for vrbg available after scheduling for same beam.
22688         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
22689         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
22690         //TODO_SID: Setting for max TP
22691         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
22692         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
22693          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
22694         allocInfo->tbInfo[0].tbCb->dlGrnt.SCID = 0;
22695         allocInfo->tbInfo[0].tbCb->dlGrnt.dciFormat = allocInfo->dciFormat;
22696    //Filling temporarily
22697    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
22698    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
22699
22700         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
22701         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
22702         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22703 #endif
22704
22705    return ROK;
22706 }
22707
22708 #ifdef RGR_V1
22709 /**
22710  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
22711  *
22712  * @details
22713  *
22714  *     Function : rgSCHCmnNonDlfsCcchSduAlloc
22715  *
22716  *     Processing Steps:
22717  *     - For each element in the list, Call rgSCHCmnNonDlfsCcchSduRbAlloc().
22718  *        - If allocation is successful, add the ueCb to scheduled list of CCCH
22719  *        SDU.
22720  *        - else, add UeCb to non-scheduled list.
22721  *
22722  *  @param[in]      RgSchCellCb         *cell
22723  *  @param[in, out] RgSchCmnCcchSduRbAlloc *allocInfo
22724  *  @param[in]      uint8_t                  isRetx
22725  *
22726  *  @return  Void
22727  **/
22728 static Void rgSCHCmnNonDlfsCcchSduAlloc
22729 (
22730 RgSchCellCb         *cell,
22731 RgSchCmnCcchSduRbAlloc *allocInfo,
22732 uint8_t                  isRetx
22733 )
22734 {
22735    S16             ret;
22736    CmLListCp       *ccchSduLst        = NULLP;
22737    CmLListCp       *schdCcchSduLst    = NULLP;
22738    CmLListCp       *nonSchdCcchSduLst = NULLP;
22739    CmLList         *schdLnkNode    = NULLP;
22740    CmLList         *toBeSchdLnk    = NULLP;
22741    RgSchDlSf       *dlSf           = allocInfo->ccchSduDlSf;
22742    RgSchUeCb       *ueCb           = NULLP;
22743    RgSchDlHqProcCb *hqP            = NULLP;
22744
22745    if (isRetx)
22746    {
22747       /* Initialize re-transmitting lists */
22748       ccchSduLst = &(allocInfo->ccchSduRetxLst);
22749       schdCcchSduLst = &(allocInfo->schdCcchSduRetxLst);
22750       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduRetxLst);
22751    }
22752    else
22753    {
22754       /* Initialize transmitting lists */
22755       ccchSduLst = &(allocInfo->ccchSduTxLst);
22756       schdCcchSduLst = &(allocInfo->schdCcchSduTxLst);
22757       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduTxLst);
22758    }
22759
22760    /* Perform allocaations  for the list */
22761    toBeSchdLnk = cmLListFirst(ccchSduLst);
22762    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
22763    {
22764       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
22765       ueCb = hqP->hqE->ue;
22766       schdLnkNode = &hqP->schdLstLnk;
22767       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
22768       ret = rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf);
22769       if (ret != ROK)
22770       {
22771          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
22772           * list and return */
22773          do
22774          {
22775             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
22776             ueCb = hqP->hqE->ue;
22777             schdLnkNode = &hqP->schdLstLnk;
22778             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
22779             cmLListAdd2Tail(nonSchdCcchSduLst, schdLnkNode);
22780             toBeSchdLnk = toBeSchdLnk->next;
22781          } while(toBeSchdLnk);
22782          return;
22783       }
22784
22785       /* Allocation successful: Add UE to the scheduled list */
22786       cmLListAdd2Tail(schdCcchSduLst, schdLnkNode);
22787    }
22788
22789
22790    return;
22791 }
22792
22793 /**
22794  * @brief Performs RB allocation for CcchSdu for frequency non-selective cell.
22795  *
22796  * @details
22797  *
22798  *     Function : rgSCHCmnNonDlfsCcchSduRbAlloc
22799  *
22800  *     Processing Steps:
22801  *     - Fetch PDCCH
22802  *     - Allocate consecutively available RBs
22803  *
22804  *  @param[in] RgSchCellCb     *cell
22805  *  @param[in] RgSchUeCb       *ueCb
22806  *  @param[in] RgSchDlSf       *dlSf
22807  *  @return  S16
22808  *      -# ROK
22809  *      -# RFAILED
22810  **/
22811 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc
22812 (
22813 RgSchCellCb        *cell,
22814 RgSchUeCb          *ueCb,
22815 RgSchDlSf          *dlSf
22816 )
22817 {
22818    RgSchDlRbAlloc  *allocInfo;
22819    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
22820
22821
22822
22823    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb,cell);
22824
22825    /* [ccpu00138802]-MOD-If Bw is less than required, return fail
22826       It will be allocated in next TTI */
22827 #ifdef LTEMAC_SPS
22828    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
22829          (dlSf->bwAlloced == dlSf->bw))
22830 #else
22831    if((dlSf->bwAlloced == dlSf->bw) ||
22832       (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
22833 #endif
22834    {
22835       return RFAILED;
22836    }
22837    /* Retrieve PDCCH */
22838    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
22839    if (ueDl->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
22840    {
22841       /*      allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, dlSf, y, ueDl->cqi,
22842        *      TFU_DCI_FORMAT_1A, TRUE);*/
22843       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, TRUE);
22844    }
22845    else
22846    {
22847       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE);
22848    }
22849    if (!(allocInfo->pdcch))
22850    {
22851       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
22852       return RFAILED;
22853    }
22854
22855    /* Update allocation information */
22856    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
22857    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
22858    allocInfo->allocInfo.raType2.isLocal = TRUE;
22859
22860       /*Fix for ccpu00123918*/
22861       /* Push this harq process back to the free queue */
22862       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
22863       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22864       allocInfo->rbsAlloc = allocInfo->rbsReq;
22865       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22866       /* Update the sub-frame with new allocation */
22867       /* ccpu00129469 */
22868       /* LTE_ADV_FLAG_REMOVED_START */
22869 #ifndef LTE_TDD
22870       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
22871       {
22872          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf,
22873                allocInfo->allocInfo.raType2.rbStart,
22874                allocInfo->allocInfo.raType2.numRb);
22875       }
22876       else
22877 #endif /* end of ifndef LTE_TDD*/
22878       {
22879          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, 
22880                allocInfo->allocInfo.raType2.rbStart, 
22881                allocInfo->allocInfo.raType2.numRb);
22882       }
22883
22884    /* LTE_ADV_FLAG_REMOVED_END */
22885    /* ccpu00131941 - bwAlloced is updated from SPS bandwidth */  
22886
22887
22888    return ROK;
22889 }
22890 #endif
22891
22892 /**
22893  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
22894  *
22895  * @details
22896  *
22897  *     Function : rgSCHCmnNonDlfsMsg4RbAlloc
22898  *
22899  *     Processing Steps:
22900  *     - Fetch PDCCH
22901  *     - Allocate consecutively available RBs
22902  *
22903  *  @param[in] RgSchCellCb     *cell
22904  *  @param[in] RgSchRaCb       *raCb
22905  *  @param[in] RgSchDlSf       *dlSf
22906  *  @return  S16
22907  *      -# ROK
22908  *      -# RFAILED
22909  **/
22910 static S16 rgSCHCmnNonDlfsMsg4RbAlloc
22911 (
22912 RgSchCellCb        *cell,
22913 RgSchRaCb          *raCb,
22914 RgSchDlSf          *dlSf
22915 )
22916 {
22917    RgSchDlRbAlloc  *allocInfo;
22918
22919
22920    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(raCb);
22921
22922 #ifdef RG_5GTF
22923         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
22924         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
22925         {
22926            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
22927          raCb->ue->ueId);
22928            DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR vrbg allocated > 25\n");
22929                 return RFAILED;
22930         }
22931 #endif
22932 #ifdef LTEMAC_SPS
22933    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
22934          (dlSf->bwAlloced == dlSf->bw))
22935 #else
22936    if((dlSf->bwAlloced == dlSf->bw) ||
22937             (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
22938 #endif
22939    {
22940
22941       return RFAILED;
22942    }
22943
22944    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
22945    if (raCb->dlHqE->msg4Proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
22946    {
22947       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, TRUE);
22948    }
22949    else
22950    {
22951       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, FALSE);
22952    }
22953    if (!(allocInfo->pdcch))
22954    {
22955       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
22956       return RFAILED;
22957    }
22958    
22959 #ifndef RG_5GTF
22960  /* SR_RACH_STATS : MSG4 TX Failed */
22961    allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
22962
22963    /* Update allocation information */
22964    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
22965    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
22966    allocInfo->allocInfo.raType2.isLocal = TRUE;
22967
22968
22969         /*Fix for ccpu00123918*/
22970         allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
22971         allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
22972         /* LTE_ADV_FLAG_REMOVED_START */
22973 #ifndef LTE_TDD
22974         if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
22975         {
22976           rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
22977                 allocInfo->allocInfo.raType2.rbStart, \
22978                 allocInfo->allocInfo.raType2.numRb);
22979         }
22980         else
22981 #endif /* end of ifndef LTE_TDD */
22982         {
22983           rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
22984                 allocInfo->allocInfo.raType2.rbStart, \
22985                 allocInfo->allocInfo.raType2.numRb);
22986         }
22987         /* LTE_ADV_FLAG_REMOVED_END */
22988
22989    allocInfo->rbsAlloc = allocInfo->rbsReq;
22990    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
22991
22992 #else
22993
22994   allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
22995
22996         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
22997         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
22998
22999    /* Update allocation information */
23000    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
23001
23002         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
23003         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
23004          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
23005
23006    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
23007    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
23008
23009
23010         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
23011         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
23012         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
23013
23014 #endif
23015
23016    return ROK;
23017 }
23018
23019 /**
23020  * @brief Performs RB allocation for Msg4 lists of frequency non-selective cell.
23021  *
23022  * @details
23023  *
23024  *     Function : rgSCHCmnNonDlfsMsg4Alloc
23025  *
23026  *     Processing Steps:
23027  *     - For each element in the list, Call rgSCHCmnNonDlfsMsg4RbAlloc().
23028  *        - If allocation is successful, add the raCb to scheduled list of MSG4.
23029  *        - else, add RaCb to non-scheduled list.
23030  *
23031  *  @param[in]      RgSchCellCb         *cell
23032  *  @param[in, out] RgSchCmnMsg4RbAlloc *allocInfo
23033  *  @param[in]      uint8_t                  isRetx
23034  *
23035  *  @return  Void
23036  **/
23037 static Void rgSCHCmnNonDlfsMsg4Alloc
23038 (
23039 RgSchCellCb         *cell,
23040 RgSchCmnMsg4RbAlloc *allocInfo,
23041 uint8_t             isRetx
23042 )
23043 {
23044    S16             ret;
23045    CmLListCp       *msg4Lst        = NULLP;
23046    CmLListCp       *schdMsg4Lst    = NULLP;
23047    CmLListCp       *nonSchdMsg4Lst = NULLP;
23048    CmLList         *schdLnkNode    = NULLP;
23049    CmLList         *toBeSchdLnk    = NULLP;
23050    RgSchDlSf       *dlSf           = allocInfo->msg4DlSf;
23051    RgSchRaCb       *raCb           = NULLP;
23052    RgSchDlHqProcCb *hqP            = NULLP;
23053
23054    if (isRetx)
23055    {
23056       /* Initialize re-transmitting lists */
23057       msg4Lst = &(allocInfo->msg4RetxLst);
23058       schdMsg4Lst = &(allocInfo->schdMsg4RetxLst);
23059       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4RetxLst);
23060    }
23061    else
23062    {
23063       /* Initialize transmitting lists */
23064       msg4Lst = &(allocInfo->msg4TxLst);
23065       schdMsg4Lst = &(allocInfo->schdMsg4TxLst);
23066       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4TxLst);
23067    }
23068
23069    /* Perform allocaations  for the list */
23070    toBeSchdLnk = cmLListFirst(msg4Lst);
23071    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
23072    {
23073       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23074       raCb = hqP->hqE->raCb;
23075       schdLnkNode = &hqP->schdLstLnk;
23076       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23077       ret = rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf);
23078       if (ret != ROK)
23079       {
23080          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
23081           * list and return */
23082          do
23083          {
23084             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23085             raCb = hqP->hqE->raCb;
23086             schdLnkNode = &hqP->schdLstLnk;
23087             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23088             cmLListAdd2Tail(nonSchdMsg4Lst, schdLnkNode);
23089             toBeSchdLnk = toBeSchdLnk->next;
23090          } while(toBeSchdLnk);
23091          return;
23092       }
23093
23094       /* Allocation successful: Add UE to the scheduled list */
23095       cmLListAdd2Tail(schdMsg4Lst, schdLnkNode);
23096       if (isRetx)
23097       {
23098       }
23099    }
23100
23101
23102    return;
23103 }
23104
23105 /**
23106  * @brief Performs RB allocation for the list of UEs of a frequency
23107  * non-selective cell.
23108  *
23109  * @details
23110  *
23111  *     Function : rgSCHCmnNonDlfsDedRbAlloc
23112  *
23113  *     Processing Steps:
23114  *     - For each element in the list, Call rgSCHCmnNonDlfsUeRbAlloc().
23115  *        - If allocation is successful, add the ueCb to scheduled list of UEs.
23116  *        - else, add ueCb to non-scheduled list of UEs.
23117  *
23118  *  @param[in]      RgSchCellCb        *cell
23119  *  @param[in, out] RgSchCmnUeRbAlloc  *allocInfo
23120  *  @param[in]      CmLListCp          *ueLst,
23121  *  @param[in, out] CmLListCp          *schdHqPLst,
23122  *  @param[in, out] CmLListCp          *nonSchdHqPLst
23123  *
23124  *  @return  Void
23125  **/
23126 Void rgSCHCmnNonDlfsDedRbAlloc
23127 (
23128 RgSchCellCb        *cell,
23129 RgSchCmnUeRbAlloc  *allocInfo,
23130 CmLListCp          *ueLst,
23131 CmLListCp          *schdHqPLst,
23132 CmLListCp          *nonSchdHqPLst
23133 )
23134 {
23135    S16             ret;
23136    CmLList         *schdLnkNode  = NULLP;
23137    CmLList         *toBeSchdLnk  = NULLP;
23138    RgSchDlSf       *dlSf         = allocInfo->dedDlSf;
23139    RgSchUeCb       *ue           = NULLP;
23140    RgSchDlHqProcCb *hqP          = NULLP;
23141    uint8_t         isDlBwAvail;
23142
23143
23144    /* Perform allocaations  for the list */
23145    toBeSchdLnk = cmLListFirst(ueLst);
23146    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
23147    {
23148       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23149       ue = hqP->hqE->ue;
23150       schdLnkNode = &hqP->schdLstLnk;
23151       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23152
23153       ret = rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, &isDlBwAvail);
23154       if (!isDlBwAvail)
23155       {
23156          /* Allocation failed: Add remaining UEs to non-scheduled
23157           * list and return */
23158          do
23159          {
23160             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
23161             ue = hqP->hqE->ue;
23162             schdLnkNode = &hqP->schdLstLnk;
23163             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
23164             cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
23165             toBeSchdLnk = toBeSchdLnk->next;
23166          } while(toBeSchdLnk);
23167          break; 
23168       }
23169
23170       if (ret == ROK)
23171       {
23172 #if defined (TENB_STATS) && defined (RG_5GTF)
23173          cell->tenbStats->sch.dl5gtfRbAllocPass++;
23174 #endif
23175          /* Allocation successful: Add UE to the scheduled list */
23176          cmLListAdd2Tail(schdHqPLst, schdLnkNode);
23177       }
23178       else
23179       {
23180 #if defined (TENB_STATS) && defined (RG_5GTF)
23181          cell->tenbStats->sch.dl5gtfRbAllocFail++;
23182 #endif
23183          /* Allocation failed : Add UE to the non-scheduled list */
23184          DU_LOG("\nERROR  -->  SCH : 5GTF_ERROR Dl rb alloc failed adding nonSchdHqPLst\n");
23185          cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
23186       }
23187    }
23188
23189    return;
23190 }
23191
23192 /**
23193  * @brief Handles RB allocation for frequency non-selective cell.
23194  *
23195  * @details
23196  *
23197  *     Function : rgSCHCmnNonDlfsRbAlloc
23198  *
23199  *     Invoking Module Processing:
23200  *      - SCH shall invoke this if downlink frequency selective is disabled for
23201  *        the cell for RB allocation.
23202  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
23203  *        estimate and subframe for each allocation to be made to SCH.
23204  *
23205  *     Processing Steps:
23206  *     - Allocate sequentially for common channels.
23207  *     - For transmitting and re-transmitting UE list.
23208  *      - For each UE:
23209  *       - Perform wide-band allocations for UE in increasing order of
23210  *         frequency.
23211  *       - Determine Imcs for the allocation.
23212  *       - Determine RA type.
23213  *       - Determine DCI format.
23214  *
23215  *  @param[in]  RgSchCellCb        *cell
23216  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
23217  *  @return  Void
23218  **/
23219
23220 Void rgSCHCmnNonDlfsRbAlloc
23221 (
23222 RgSchCellCb           *cell,
23223 RgSchCmnDlRbAllocInfo *allocInfo
23224 )
23225 {
23226    uint8_t        raRspCnt = 0;
23227    RgSchDlRbAlloc *reqAllocInfo;
23228
23229    /* Allocate for MSG4 retransmissions */
23230    if (allocInfo->msg4Alloc.msg4RetxLst.count)
23231    {
23232       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc RetxLst\n");
23233       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), TRUE);
23234    }
23235
23236    /* Allocate for MSG4 transmissions */
23237    /* Assuming all the nodes in the list need allocations: rbsReq is valid */
23238    if (allocInfo->msg4Alloc.msg4TxLst.count)
23239    {
23240       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc txLst\n");
23241       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), FALSE);
23242    }
23243 #ifdef RGR_V1
23244    /* Allocate for CCCH SDU (received after guard timer expiry)
23245     * retransmissions */
23246    if (allocInfo->ccchSduAlloc.ccchSduRetxLst.count)
23247    {
23248       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
23249       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), TRUE);
23250    }
23251
23252    /* Allocate for CCCD SDU transmissions */
23253    /* Allocate for CCCH SDU (received after guard timer expiry) transmissions */
23254    if (allocInfo->ccchSduAlloc.ccchSduTxLst.count)
23255    {
23256       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
23257       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), FALSE);
23258    }
23259 #endif
23260
23261    /* Allocate for Random access response */
23262    for (raRspCnt = 0; raRspCnt < RG_SCH_CMN_MAX_CMN_PDCCH; ++raRspCnt)
23263    {
23264       /* Assuming that the requests will be filled in sequentially */
23265       reqAllocInfo = &(allocInfo->raRspAlloc[raRspCnt]);
23266       if (!reqAllocInfo->rbsReq)
23267       {
23268          break;
23269       }
23270       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR calling RAR rgSCHCmnNonDlfsCmnRbAlloc\n");
23271    //   if ((rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo)) != ROK)
23272       if ((rgSCHCmnNonDlfsCmnRbAllocRar(cell, reqAllocInfo)) != ROK)
23273       {
23274          break;
23275       }
23276    }
23277
23278    /* Allocate for RETX+TX UEs */
23279    if(allocInfo->dedAlloc.txRetxHqPLst.count)
23280    {
23281       DU_LOG("\nDEBUG  -->  SCH : 5GTF_ERROR TX RETX rgSCHCmnNonDlfsDedRbAlloc\n");
23282       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23283             &(allocInfo->dedAlloc.txRetxHqPLst),
23284             &(allocInfo->dedAlloc.schdTxRetxHqPLst),
23285             &(allocInfo->dedAlloc.nonSchdTxRetxHqPLst));
23286    }
23287
23288    if((allocInfo->dedAlloc.retxHqPLst.count))
23289    {
23290       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23291             &(allocInfo->dedAlloc.retxHqPLst),
23292             &(allocInfo->dedAlloc.schdRetxHqPLst),
23293             &(allocInfo->dedAlloc.nonSchdRetxHqPLst));
23294    }
23295
23296    /* Allocate for transmitting UEs */
23297    if((allocInfo->dedAlloc.txHqPLst.count))
23298    {
23299       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
23300             &(allocInfo->dedAlloc.txHqPLst),
23301             &(allocInfo->dedAlloc.schdTxHqPLst),
23302             &(allocInfo->dedAlloc.nonSchdTxHqPLst));
23303    }
23304    {
23305       RgSchCmnCell  *cmnCell = RG_SCH_CMN_GET_CELL(cell);
23306       if ((allocInfo->dedAlloc.txRetxHqPLst.count + 
23307                allocInfo->dedAlloc.retxHqPLst.count + 
23308                allocInfo->dedAlloc.txHqPLst.count) > 
23309             cmnCell->dl.maxUePerDlSf)
23310       {
23311 #ifndef ALIGN_64BIT
23312          DU_LOG("\nERROR  -->  SCH : UEs selected by"
23313                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %ld retx %ld tx %ld\n",
23314                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
23315                   allocInfo->dedAlloc.retxHqPLst.count,
23316                   allocInfo->dedAlloc.txHqPLst.count);
23317 #else
23318          DU_LOG("\nERROR  -->  SCH : UEs selected by"
23319                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %d retx %d tx %d\n",
23320                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
23321                   allocInfo->dedAlloc.retxHqPLst.count,
23322                   allocInfo->dedAlloc.txHqPLst.count);
23323 #endif
23324       }
23325    }
23326 #ifndef LTE_TDD
23327    /* LTE_ADV_FLAG_REMOVED_START */
23328    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
23329    {    
23330       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR RETX rgSCHCmnNonDlfsDsfrRntpComp\n");
23331       rgSCHCmnNonDlfsDsfrRntpComp(cell, allocInfo->dedAlloc.dedDlSf); 
23332    }  
23333    /* LTE_ADV_FLAG_REMOVED_END */
23334 #endif /* LTE_TDD */
23335    return;
23336 }
23337
23338 /***********************************************************
23339  *
23340  *     Func : rgSCHCmnCalcRiv
23341  *
23342  *     Desc : This function calculates RIV.
23343  *
23344  *     Ret  : None.
23345  *
23346  *     Notes: None.
23347  *
23348  *     File : rg_sch_utl.c
23349  *
23350  **********************************************************/
23351 #ifdef LTEMAC_SPS
23352 uint32_t rgSCHCmnCalcRiv
23353 (
23354 uint8_t    bw,
23355 uint8_t    rbStart,
23356 uint8_t    numRb
23357 )
23358 #else
23359 uint32_t rgSCHCmnCalcRiv
23360 (
23361 uint8_t    bw,
23362 uint8_t    rbStart,
23363 uint8_t    numRb
23364 )
23365 #endif
23366 {
23367    uint8_t  numRbMinus1 = numRb - 1;
23368    uint32_t riv;
23369
23370
23371    if (numRbMinus1 <= bw/2)
23372    {
23373       riv = bw * numRbMinus1 + rbStart;
23374    }
23375    else
23376    {
23377       riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
23378    }
23379    return (riv);
23380 } /* rgSCHCmnCalcRiv */
23381
23382 #ifdef LTE_TDD
23383 /**
23384  * @brief This function allocates and copies the RACH response scheduling
23385  *        related information into cell control block.
23386  *
23387  * @details
23388  *
23389  *     Function: rgSCHCmnDlCpyRachInfo
23390  *     Purpose:  This function allocates and copies the RACH response
23391  *               scheduling related information into cell control block
23392  *               for each DL subframe.
23393  *
23394  *
23395  *     Invoked by: Scheduler
23396  *
23397  *  @param[in]  RgSchCellCb*           cell
23398  *  @param[in]  RgSchTddRachRspLst     rachRspLst[][RGSCH_NUM_SUB_FRAMES]
23399  *  @param[in]  uint8_t                     raArrSz
23400  *  @return     S16
23401  *
23402  **/
23403 static S16 rgSCHCmnDlCpyRachInfo
23404 (
23405 RgSchCellCb         *cell,
23406 RgSchTddRachRspLst  rachRspLst[][RGSCH_NUM_SUB_FRAMES],
23407 uint8_t             raArrSz
23408 )
23409 {
23410    uint8_t   ulDlCfgIdx = cell->ulDlCfgIdx;
23411    uint8_t   sfNum;
23412    S16       sfnIdx;
23413    uint16_t  subfrmIdx;
23414    uint8_t   numRfs;
23415    uint8_t   numSubfrms;
23416    uint8_t   sfcount;
23417    S16       ret;
23418
23419
23420    /* Allocate RACH response information for each DL
23421     * subframe in a radio frame */
23422    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cell->rachRspLst,
23423          rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1] *
23424          sizeof(RgSchTddRachRspLst));
23425    if (ret != ROK)
23426    {
23427       return (ret);
23428    }
23429
23430    for(sfnIdx=raArrSz-1; sfnIdx>=0; sfnIdx--)
23431    {
23432       for(subfrmIdx=0; subfrmIdx < RGSCH_NUM_SUB_FRAMES; subfrmIdx++)
23433       {
23434          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
23435          if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
23436          {
23437             break;
23438          }
23439
23440          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx],subfrmIdx);
23441          numSubfrms =
23442             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
23443
23444          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddNumDlSubfrmTbl[ulDlCfgIdx],subfrmIdx);
23445          sfNum = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][subfrmIdx]-1;
23446          numRfs = cell->rachRspLst[sfNum].numRadiofrms;
23447          /* For each DL subframe in which RACH response can
23448           * be sent is updated */
23449          if(numSubfrms > 0)
23450          {
23451             cell->rachRspLst[sfNum].rachRsp[numRfs].sfnOffset =
23452                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset;
23453             for(sfcount=0; sfcount < numSubfrms; sfcount++)
23454             {
23455                cell->rachRspLst[sfNum].rachRsp[numRfs].\
23456                   subframe[sfcount] =
23457                   rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].\
23458                   subframe[sfcount];
23459             }
23460             cell->rachRspLst[sfNum].rachRsp[numRfs].numSubfrms =
23461                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
23462             cell->rachRspLst[sfNum].numRadiofrms++;
23463          }
23464
23465          /* Copy the subframes to be deleted at ths subframe */
23466          numSubfrms =
23467             rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
23468          if(numSubfrms > 0)
23469          {
23470             cell->rachRspLst[sfNum].delInfo.sfnOffset =
23471                rachRspLst[sfnIdx][subfrmIdx].delInfo.sfnOffset;
23472             for(sfcount=0; sfcount < numSubfrms; sfcount++)
23473             {
23474                cell->rachRspLst[sfNum].delInfo.subframe[sfcount] =
23475                   rachRspLst[sfnIdx][subfrmIdx].delInfo.subframe[sfcount];
23476             }
23477             cell->rachRspLst[sfNum].delInfo.numSubfrms =
23478                rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
23479          }
23480       }
23481    }
23482    return ROK;
23483 }
23484 #endif
23485 /**
23486  * @brief This function determines the iTbs based on the new CFI, 
23487  *        CQI and BLER based delta iTbs 
23488  *
23489  * @details
23490  *
23491  *     Function: rgSchCmnFetchItbs
23492  *     Purpose:  Fetch the new iTbs when CFI changes.
23493  *
23494  *  @param[in]  RgSchCellCb           *cell
23495  *  @param[in]  RgSchCmnDlUe          *ueDl
23496  *  @param[in]  uint8_t                    cqi
23497  *
23498  *  @return S32 iTbs
23499  *
23500  **/
23501 #ifdef LTE_TDD
23502 static S32 rgSchCmnFetchItbs 
23503 (
23504 RgSchCellCb   *cell,
23505 RgSchCmnDlUe  *ueDl,
23506 RgSchDlSf     *subFrm,
23507 uint8_t       cqi,
23508 uint8_t       cfi,
23509 uint8_t       cwIdx,
23510 uint8_t       noLyr
23511 )
23512 #else
23513 static S32 rgSchCmnFetchItbs 
23514 (
23515 RgSchCellCb   *cell,
23516 RgSchCmnDlUe  *ueDl,
23517 uint8_t       cqi,
23518 uint8_t       cfi,
23519 uint8_t       cwIdx,
23520 uint8_t       noLyr
23521 )
23522 #endif
23523 {
23524
23525    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
23526    S32 iTbs = 0;
23527
23528
23529 #ifdef LTE_TDD      
23530    /* Special Handling for Spl Sf when CFI is 3 as 
23531     * CFI in Spl Sf will be max 2 */
23532    if(subFrm->sfType == RG_SCH_SPL_SF_DATA) 
23533    {
23534       if((cellDl->currCfi == 3) || 
23535             ((cell->bwCfg.dlTotalBw <= 10) && (cellDl->currCfi == 1)))
23536       {    
23537          /* Use CFI 2 in this case */
23538          iTbs = (ueDl->laCb[cwIdx].deltaiTbs + 
23539                ((*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][2]))[cqi])* 100)/100;
23540
23541          RG_SCH_CHK_ITBS_RANGE(iTbs, RGSCH_NUM_ITBS - 1);
23542       }
23543       else
23544       {
23545          iTbs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1];
23546       }
23547       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
23548    }   
23549    else /* CFI Changed. Update with new iTbs Reset the BLER*/
23550 #endif         
23551    {
23552       S32 tmpiTbs  = (*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][cfi]))[cqi];
23553       
23554       iTbs = (ueDl->laCb[cwIdx].deltaiTbs + tmpiTbs*100)/100;
23555
23556       RG_SCH_CHK_ITBS_RANGE(iTbs, tmpiTbs);     
23557
23558       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
23559
23560       ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1] = iTbs;
23561
23562       ueDl->lastCfi = cfi;
23563       ueDl->laCb[cwIdx].deltaiTbs = 0;
23564    }
23565
23566    return (iTbs);
23567
23568 \f
23569 /**
23570  * @brief This function determines the RBs and Bytes required for BO
23571  *        transmission for UEs configured with TM 1/2/6/7.
23572  *
23573  * @details
23574  *
23575  *     Function: rgSCHCmnDlAllocTxRb1Tb1Cw
23576  *     Purpose:  Allocate TB1 on CW1.
23577  *
23578  *               Reference Parameter effBo is filled with alloced bytes.
23579  *               Returns RFAILED if BO not satisfied at all.
23580  *
23581  *     Invoked by: rgSCHCmnDlAllocTxRbTM1/2/6/7
23582  *
23583  *  @param[in]  RgSchCellCb           *cell
23584  *  @param[in]  RgSchDlSf             *subFrm
23585  *  @param[in]  RgSchUeCb             *ue
23586  *  @param[in]  uint32_t                   bo
23587  *  @param[out] uint32_t                   *effBo
23588  *  @param[in]  RgSchDlHqProcCb       *proc
23589  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23590  *  @return  Void
23591  *
23592  **/
23593 static Void rgSCHCmnDlAllocTxRb1Tb1Cw
23594 (
23595 RgSchCellCb           *cell,
23596 RgSchDlSf             *subFrm,
23597 RgSchUeCb             *ue,
23598 uint32_t              bo,
23599 uint32_t              *effBo,
23600 RgSchDlHqProcCb       *proc,
23601 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23602 )
23603 {
23604    RgSchDlRbAlloc   *allocInfo;
23605    S16              ret;
23606    uint8_t          numRb;
23607
23608    ret = ROK;
23609    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
23610 #ifdef RG_5GTF
23611    if (ue->ue5gtfCb.rank == 2)
23612    {
23613       allocInfo->dciFormat = TFU_DCI_FORMAT_B2;
23614    }
23615    else
23616    {
23617       allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
23618    }
23619 #else
23620    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
23621          allocInfo->raType);
23622 #endif
23623    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
23624          bo, &numRb, effBo);
23625    if (ret == RFAILED)
23626    {
23627       /* If allocation couldn't be made then return */
23628       return;
23629    }
23630    /* Adding UE to RbAllocInfo TX Lst */
23631    rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
23632    /* Fill UE alloc Info */
23633    allocInfo->rbsReq = numRb;
23634    allocInfo->dlSf   = subFrm;
23635 #ifdef RG_5GTF
23636    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
23637 #endif
23638
23639    return;
23640 }
23641
23642 \f
23643 /**
23644  * @brief This function determines the RBs and Bytes required for BO
23645  *        retransmission for UEs configured with TM 1/2/6/7.
23646  *
23647  * @details
23648  *
23649  *     Function: rgSCHCmnDlAllocRetxRb1Tb1Cw
23650  *     Purpose:  Allocate TB1 on CW1.
23651  *
23652  *               Reference Parameter effBo is filled with alloced bytes.
23653  *               Returns RFAILED if BO not satisfied at all.
23654  *
23655  *     Invoked by: rgSCHCmnDlAllocRetxRbTM1/2/6/7
23656  *
23657  *  @param[in]  RgSchCellCb           *cell
23658  *  @param[in]  RgSchDlSf             *subFrm
23659  *  @param[in]  RgSchUeCb             *ue
23660  *  @param[in]  uint32_t                   bo
23661  *  @param[out] uint32_t                   *effBo
23662  *  @param[in]  RgSchDlHqProcCb       *proc
23663  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23664  *  @return  Void
23665  *
23666  **/
23667 static Void rgSCHCmnDlAllocRetxRb1Tb1Cw
23668 (
23669 RgSchCellCb                *cell,
23670 RgSchDlSf                  *subFrm,
23671 RgSchUeCb                  *ue,
23672 uint32_t                   bo,
23673 uint32_t                   *effBo,
23674 RgSchDlHqProcCb            *proc,
23675 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23676 )
23677 {
23678    RgSchDlRbAlloc   *allocInfo;
23679    S16              ret;
23680    uint8_t          numRb;
23681
23682    ret = ROK;
23683    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
23684
23685 #ifndef RG_5GTF
23686    /* 5GTF: RETX DCI format same as TX */
23687    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
23688       &allocInfo->raType);
23689 #endif
23690
23691    /* Get the Allocation in terms of RBs that are required for
23692     * this retx of TB1 */
23693    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
23694          1, &numRb, effBo);
23695    if (ret == RFAILED)
23696    {
23697       /* Allocation couldn't be made for Retx */
23698       /* Fix : syed If TxRetx allocation failed then add the UE along with the proc
23699        * to the nonSchdTxRetxUeLst and let spfc scheduler take care of it during
23700        * finalization. */        
23701       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
23702       return;
23703    }
23704    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
23705    /* Fill UE alloc Info */
23706    allocInfo->rbsReq = numRb;
23707    allocInfo->dlSf   = subFrm;
23708 #ifdef RG_5GTF
23709    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
23710 #endif
23711
23712    return;
23713 }
23714
23715 \f
23716 /**
23717  * @brief This function determines the RBs and Bytes required for BO
23718  *        transmission for UEs configured with TM 2.
23719  *
23720  * @details
23721  *
23722  *     Function: rgSCHCmnDlAllocTxRbTM1
23723  *     Purpose:
23724  *
23725  *               Reference Parameter effBo is filled with alloced bytes.
23726  *               Returns RFAILED if BO not satisfied at all.
23727  *
23728  *     Invoked by: rgSCHCmnDlAllocTxRb
23729  *
23730  *  @param[in]  RgSchCellCb           *cell
23731  *  @param[in]  RgSchDlSf             *subFrm
23732  *  @param[in]  RgSchUeCb             *ue
23733  *  @param[in]  uint32_t                   bo
23734  *  @param[out] uint32_t                   *effBo
23735  *  @param[in]  RgSchDlHqProcCb       *proc
23736  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23737  *  @return Void
23738  *
23739  **/
23740 static Void rgSCHCmnDlAllocTxRbTM1
23741 (
23742 RgSchCellCb            *cell,
23743 RgSchDlSf              *subFrm,
23744 RgSchUeCb              *ue,
23745 uint32_t               bo,
23746 uint32_t               *effBo,
23747 RgSchDlHqProcCb        *proc,
23748 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
23749 )
23750 {
23751    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23752    return;
23753 }
23754
23755 \f
23756 /**
23757  * @brief This function determines the RBs and Bytes required for BO
23758  *        retransmission for UEs configured with TM 2.
23759  *
23760  * @details
23761  *
23762  *     Function: rgSCHCmnDlAllocRetxRbTM1
23763  *     Purpose:
23764  *
23765  *               Reference Parameter effBo is filled with alloced bytes.
23766  *               Returns RFAILED if BO not satisfied at all.
23767  *
23768  *     Invoked by: rgSCHCmnDlAllocRetxRb
23769  *
23770  *  @param[in]  RgSchCellCb           *cell
23771  *  @param[in]  RgSchDlSf             *subFrm
23772  *  @param[in]  RgSchUeCb             *ue
23773  *  @param[in]  uint32_t                   bo
23774  *  @param[out] uint32_t                   *effBo
23775  *  @param[in]  RgSchDlHqProcCb       *proc
23776  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23777  *  @return Void
23778  *
23779  **/
23780 static Void rgSCHCmnDlAllocRetxRbTM1
23781 (
23782 RgSchCellCb                *cell,
23783 RgSchDlSf                  *subFrm,
23784 RgSchUeCb                  *ue,
23785 uint32_t                   bo,
23786 uint32_t                   *effBo,
23787 RgSchDlHqProcCb            *proc,
23788 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23789 )
23790 {
23791    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23792    return;
23793 }
23794
23795 \f
23796 /**
23797  * @brief This function determines the RBs and Bytes required for BO
23798  *        transmission for UEs configured with TM 2.
23799  *
23800  * @details
23801  *
23802  *     Function: rgSCHCmnDlAllocTxRbTM2
23803  *     Purpose:
23804  *
23805  *               Reference Parameter effBo is filled with alloced bytes.
23806  *               Returns RFAILED if BO not satisfied at all.
23807  *
23808  *     Invoked by: rgSCHCmnDlAllocTxRb
23809  *
23810  *  @param[in]  RgSchCellCb           *cell
23811  *  @param[in]  RgSchDlSf             *subFrm
23812  *  @param[in]  RgSchUeCb             *ue
23813  *  @param[in]  uint32_t                   bo
23814  *  @param[out] uint32_t                   *effBo
23815  *  @param[in]  RgSchDlHqProcCb       *proc
23816  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23817  *  @return Void
23818  *
23819  **/
23820 static Void rgSCHCmnDlAllocTxRbTM2
23821 (
23822 RgSchCellCb                *cell,
23823 RgSchDlSf                  *subFrm,
23824 RgSchUeCb                  *ue,
23825 uint32_t                   bo,
23826 uint32_t                   *effBo,
23827 RgSchDlHqProcCb            *proc,
23828 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23829 )
23830 {
23831    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23832    return;
23833 }
23834
23835 \f
23836 /**
23837  * @brief This function determines the RBs and Bytes required for BO
23838  *        retransmission for UEs configured with TM 2.
23839  *
23840  * @details
23841  *
23842  *     Function: rgSCHCmnDlAllocRetxRbTM2
23843  *     Purpose:
23844  *
23845  *               Reference Parameter effBo is filled with alloced bytes.
23846  *               Returns RFAILED if BO not satisfied at all.
23847  *
23848  *     Invoked by: rgSCHCmnDlAllocRetxRb
23849  *
23850  *  @param[in]  RgSchCellCb           *cell
23851  *  @param[in]  RgSchDlSf             *subFrm
23852  *  @param[in]  RgSchUeCb             *ue
23853  *  @param[in]  uint32_t                   bo
23854  *  @param[out] uint32_t                   *effBo
23855  *  @param[in]  RgSchDlHqProcCb       *proc
23856  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23857  *  @return Void
23858  *
23859  **/
23860 static Void rgSCHCmnDlAllocRetxRbTM2
23861 (
23862 RgSchCellCb                *cell,
23863 RgSchDlSf                  *subFrm,
23864 RgSchUeCb                  *ue,
23865 uint32_t                   bo,
23866 uint32_t                   *effBo,
23867 RgSchDlHqProcCb            *proc,
23868 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23869 )
23870 {
23871    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
23872    return;
23873 }
23874
23875 \f
23876 /**
23877  * @brief This function determines the RBs and Bytes required for BO
23878  *        transmission for UEs configured with TM 3.
23879  *
23880  * @details
23881  *
23882  *     Function: rgSCHCmnDlAllocTxRbTM3
23883  *     Purpose:
23884  *
23885  *               Reference Parameter effBo is filled with alloced bytes.
23886  *               Returns RFAILED if BO not satisfied at all.
23887  *
23888  *     Invoked by: rgSCHCmnDlAllocTxRb
23889  *
23890  *  @param[in]  RgSchCellCb           *cell
23891  *  @param[in]  RgSchDlSf             *subFrm
23892  *  @param[in]  RgSchUeCb             *ue
23893  *  @param[in]  uint32_t                   bo
23894  *  @param[out] uint32_t                   *effBo
23895  *  @param[in]  RgSchDlHqProcCb       *proc
23896  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23897  *  @return Void
23898  *
23899  **/
23900 static Void rgSCHCmnDlAllocTxRbTM3
23901 (
23902 RgSchCellCb                *cell,
23903 RgSchDlSf                  *subFrm,
23904 RgSchUeCb                  *ue,
23905 uint32_t                   bo,
23906 uint32_t                   *effBo,
23907 RgSchDlHqProcCb            *proc,
23908 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23909 )
23910 {
23911
23912
23913    /* Both TBs free for TX allocation */
23914    rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo,\
23915          proc, cellWdAllocInfo);
23916
23917    return;
23918 }
23919
23920 \f
23921 /**
23922  * @brief This function determines the RBs and Bytes required for BO
23923  *        retransmission for UEs configured with TM 3.
23924  *
23925  * @details
23926  *
23927  *     Function: rgSCHCmnDlAllocRetxRbTM3
23928  *     Purpose:
23929  *
23930  *               Reference Parameter effBo is filled with alloced bytes.
23931  *               Returns RFAILED if BO not satisfied at all.
23932  *
23933  *     Invoked by: rgSCHCmnDlAllocRetxRb
23934  *
23935  *  @param[in]  RgSchCellCb           *cell
23936  *  @param[in]  RgSchDlSf             *subFrm
23937  *  @param[in]  RgSchUeCb             *ue
23938  *  @param[in]  uint32_t                   bo
23939  *  @param[out] uint32_t                   *effBo
23940  *  @param[in]  RgSchDlHqProcCb       *proc
23941  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
23942  *  @return Void
23943  *
23944  **/
23945 static Void rgSCHCmnDlAllocRetxRbTM3
23946 (
23947 RgSchCellCb                *cell,
23948 RgSchDlSf                  *subFrm,
23949 RgSchUeCb                  *ue,
23950 uint32_t                   bo,
23951 uint32_t                   *effBo,
23952 RgSchDlHqProcCb            *proc,
23953 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
23954 )
23955 {
23956
23957
23958    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
23959          (proc->tbInfo[1].state == HQ_TB_NACKED))
23960    {
23961 #ifdef LAA_DBG_LOG
23962       DU_LOG("\nDEBUG  -->  SCH : RETX RB TM3 nack for both hqp %d cell %d \n", proc->procId, proc->hqE->cell->cellId);
23963 #endif
23964       /* Both TBs require RETX allocation */
23965       rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo,\
23966             proc, cellWdAllocInfo);
23967    }
23968    else
23969    {
23970       /* One of the TBs need RETX allocation. Other TB may/maynot
23971        * be available for new TX allocation. */
23972       rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo,\
23973             proc, cellWdAllocInfo);
23974    }
23975
23976    return;
23977 }
23978
23979 \f
23980 /**
23981  * @brief This function performs the DCI format selection in case of
23982  *        Transmit Diversity scheme where there can be more
23983  *        than 1 option for DCI format selection.
23984  *
23985  * @details
23986  *
23987  *     Function: rgSCHCmnSlctPdcchFrmt
23988  *     Purpose:  1. If DLFS is enabled, then choose TM specific
23989  *                  DCI format for Transmit diversity. All the
23990  *                  TM Specific DCI Formats support Type0 and/or
23991  *                  Type1 resource allocation scheme. DLFS
23992  *                  supports only Type-0&1 Resource allocation.
23993  *               2. If DLFS is not enabled, select a DCI format
23994  *                  which is of smaller size. Since Non-DLFS
23995  *                  scheduler supports all Resource allocation
23996  *                  schemes, selection is based on efficiency.
23997  *
23998  *     Invoked by: DL UE Allocation by Common Scheduler.
23999  *
24000  *  @param[in]  RgSchCellCb      *cell
24001  *  @param[in]  RgSchUeCb        *ue
24002  *  @param[out] uint8_t               *raType
24003  *  @return  TfuDciFormat
24004  *
24005  **/
24006 TfuDciFormat rgSCHCmnSlctPdcchFrmt
24007 (
24008 RgSchCellCb   *cell,
24009 RgSchUeCb     *ue,
24010 uint8_t       *raType
24011 )
24012 {
24013    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
24014
24015
24016    /* ccpu00140894- Selective DCI Format and RA type should be selected only 
24017     * after TX Mode transition is completed*/
24018    if ((cellSch->dl.isDlFreqSel) && (ue->txModeTransCmplt))
24019    {
24020       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciRAType;
24021       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciFrmt);
24022    }
24023    else
24024    {
24025       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciRAType;
24026       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciFrmt);
24027    }
24028 }
24029
24030 \f
24031 /**
24032  * @brief This function handles Retx allocation in case of TM3 UEs
24033  *        where both the TBs were NACKED previously.
24034  *
24035  * @details
24036  *
24037  *     Function: rgSCHCmnDlTM3RetxRetx
24038  *     Purpose:  If forceTD flag enabled
24039  *                  TD for TB1 on CW1.
24040  *               Else
24041  *                  DCI Frmt 2A and RA Type 0
24042  *                  RI layered SM of both TBs on 2 CWs
24043  *               Add UE to cell Alloc Info.
24044  *               Fill UE alloc Info.
24045  *
24046  *
24047  *               Successful allocation is indicated by non-zero effBo value.
24048  *
24049  *     Invoked by: rgSCHCmnDlAllocRbTM3
24050  *
24051  *  @param[in]  RgSchCellCb           *cell
24052  *  @param[in]  RgSchDlSf             *subFrm
24053  *  @param[in]  RgSchUeCb             *ue
24054  *  @param[in]  uint32_t                   bo
24055  *  @param[out] uint32_t                   *effBo
24056  *  @param[in]  RgSchDlHqProcCb       *proc
24057  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24058  *  @return  Void
24059  *
24060  **/
24061 static Void rgSCHCmnDlTM3RetxRetx
24062 (
24063 RgSchCellCb                *cell,
24064 RgSchDlSf                  *subFrm,
24065 RgSchUeCb                  *ue,
24066 uint32_t                   bo,
24067 uint32_t                   *effBo,
24068 RgSchDlHqProcCb            *proc,
24069 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
24070 )
24071 {
24072    S16           ret;
24073    RgSchDlRbAlloc *allocInfo;
24074    uint8_t       numRb;
24075    Bool          swpFlg;
24076    uint8_t       precInfo;
24077    uint8_t       noTxLyrs;
24078    uint8_t       precInfoAntIdx;
24079
24080
24081    ret = ROK;
24082    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24083    swpFlg = FALSE;
24084 /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
24085    {
24086       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
24087       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
24088
24089       ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
24090             effBo);
24091       if (ret == RFAILED)
24092       {
24093          /* Allocation couldn't be made for Retx */
24094          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24095          return;
24096       }
24097       /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
24098       noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
24099 #ifdef FOUR_TX_ANTENNA
24100       /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 should
24101        * have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
24102       if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
24103       {
24104          swpFlg = TRUE;
24105          proc->cwSwpEnabled = TRUE;
24106       }
24107 #endif
24108       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24109       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
24110    }
24111
24112 #ifdef LTEMAC_SPS
24113    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24114 #endif
24115    {
24116       /* Adding UE to allocInfo RETX Lst */
24117       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24118    }
24119    /* Fill UE alloc Info scratch pad */
24120    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24121          precInfo, noTxLyrs, subFrm);
24122
24123    return;
24124 }
24125
24126 \f
24127 /**
24128  * @brief This function handles Retx allocation in case of TM4 UEs
24129  *        where both the TBs were NACKED previously.
24130  *
24131  * @details
24132  *
24133  *     Function: rgSCHCmnDlTM4RetxRetx
24134  *     Purpose:  If forceTD flag enabled
24135  *                  TD for TB1 on CW1.
24136  *               Else
24137  *                  DCI Frmt 2 and RA Type 0
24138  *                  If RI == 1
24139  *                     1 layer SM of TB1 on CW1.
24140  *                  Else
24141  *                     RI layered SM of both TBs on 2 CWs
24142  *               Add UE to cell Alloc Info.
24143  *               Fill UE alloc Info.
24144  *
24145  *
24146  *               Successful allocation is indicated by non-zero effBo value.
24147  *
24148  *     Invoked by: rgSCHCmnDlAllocRbTM4
24149  *
24150  *  @param[in]  RgSchCellCb           *cell
24151  *  @param[in]  RgSchDlSf             *subFrm
24152  *  @param[in]  RgSchUeCb             *ue
24153  *  @param[in]  uint32_t                   bo
24154  *  @param[out] uint32_t                   *effBo
24155  *  @param[in]  RgSchDlHqProcCb       *proc
24156  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24157  *  @return  Void
24158  *
24159  **/
24160 static Void rgSCHCmnDlTM4RetxRetx
24161 (
24162 RgSchCellCb           *cell,
24163 RgSchDlSf             *subFrm,
24164 RgSchUeCb             *ue,
24165 uint32_t              bo,
24166 uint32_t              *effBo,
24167 RgSchDlHqProcCb       *proc,
24168 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24169 )
24170 {
24171    S16            ret;
24172    RgSchDlRbAlloc *allocInfo;
24173    uint8_t        numRb;
24174    Bool           swpFlg = FALSE;
24175    uint8_t        precInfo;
24176 #ifdef FOUR_TX_ANTENNA
24177    uint8_t        precInfoAntIdx;
24178 #endif
24179    uint8_t        noTxLyrs;
24180
24181
24182    ret = ROK;
24183    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24184                        
24185    /* Irrespective of RI Schedule both CWs */
24186    allocInfo->dciFormat = TFU_DCI_FORMAT_2;
24187    allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
24188
24189    ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
24190          effBo);
24191    if (ret == RFAILED)
24192    {
24193       /* Allocation couldn't be made for Retx */
24194       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24195       return;
24196    }
24197    noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
24198    precInfo = 0; 
24199 #ifdef FOUR_TX_ANTENNA
24200    /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1
24201     * should have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
24202    if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
24203    {
24204       swpFlg = TRUE;
24205       proc->cwSwpEnabled = TRUE;
24206 }
24207 precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24208 precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
24209 #endif
24210
24211 #ifdef LTEMAC_SPS
24212    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24213 #endif
24214    {
24215       /* Adding UE to allocInfo RETX Lst */
24216       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24217    }
24218    /* Fill UE alloc Info scratch pad */
24219    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24220          precInfo, noTxLyrs, subFrm);
24221
24222    return;
24223 }
24224
24225
24226 \f
24227 /**
24228  * @brief This function determines Transmission attributes
24229  *        incase of Spatial multiplexing for TX and RETX TBs.
24230  *
24231  * @details
24232  *
24233  *     Function: rgSCHCmnDlSMGetAttrForTxRetx
24234  *     Purpose:  1. Reached here for a TM3/4 UE's HqP whose one of the TBs is
24235  *                  NACKED and the other TB is either NACKED or WAITING.
24236  *               2. Select the NACKED TB for RETX allocation.
24237  *               3. Allocation preference for RETX TB by mapping it to a better
24238  *                  CW (better in terms of efficiency).
24239  *               4. Determine the state of the other TB.
24240  *                  Determine if swapFlag were to be set.
24241  *                  Swap flag would be set if Retx TB is cross
24242  *                  mapped to a CW.
24243  *               5. If UE has new data available for TX and if the other TB's state
24244  *                  is ACKED then set furtherScope as TRUE.
24245  *
24246  *     Invoked by: rgSCHCmnDlTM3[4]TxRetx
24247  *
24248  *  @param[in]  RgSchUeCb        *ue
24249  *  @param[in]  RgSchDlHqProcCb  *proc
24250  *  @param[out] RgSchDlHqTbCb    **retxTb
24251  *  @param[out] RgSchDlHqTbCb    **txTb
24252  *  @param[out] Bool             *frthrScp
24253  *  @param[out] Bool             *swpFlg
24254  *  @return  Void
24255  *
24256  **/
24257 static Void rgSCHCmnDlSMGetAttrForTxRetx
24258 (
24259 RgSchUeCb                  *ue,
24260 RgSchDlHqProcCb            *proc,
24261 RgSchDlHqTbCb              **retxTb,
24262 RgSchDlHqTbCb              **txTb,
24263 Bool                       *frthrScp,
24264 Bool                       *swpFlg
24265 )
24266 {
24267    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,proc->hqE->cell);
24268    RgSchDlRbAlloc  *allocInfo;
24269
24270
24271    if (proc->tbInfo[0].state == HQ_TB_NACKED)
24272    {
24273       *retxTb = &proc->tbInfo[0];
24274       *txTb = &proc->tbInfo[1];
24275       /* TENB_BRDCM_TM4- Currently disabling swapflag for TM3/TM4, since 
24276        * HqFeedback processing does not consider a swapped hq feedback */
24277       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 1))
24278       {
24279          *swpFlg = TRUE;
24280          proc->cwSwpEnabled = TRUE;
24281       }
24282       if (proc->tbInfo[1].state == HQ_TB_ACKED)
24283       {
24284          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
24285          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
24286       }
24287    }
24288    else
24289    {
24290       *retxTb = &proc->tbInfo[1];
24291       *txTb = &proc->tbInfo[0];
24292       /* TENB_BRDCM_TM4 - Currently disabling swapflag for TM3/TM4, since 
24293        * HqFeedback processing does not consider a swapped hq feedback */
24294       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 0))
24295       {
24296          *swpFlg = TRUE;
24297          proc->cwSwpEnabled = TRUE;
24298       }
24299       if (proc->tbInfo[0].state == HQ_TB_ACKED)
24300       {
24301          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
24302          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
24303       }
24304    }
24305    return;
24306 }
24307
24308 \f
24309 /**
24310  * @brief Determine Precoding information for TM3 2 TX Antenna.
24311  *
24312  * @details
24313  *
24314  *     Function: rgSCHCmnDlTM3PrecInf2
24315  *     Purpose:
24316  *
24317  *     Invoked by: rgSCHCmnDlGetAttrForTM3
24318  *
24319  *  @param[in]  RgSchUeCb        *ue
24320  *  @param[in]  uint8_t               numTxLyrs
24321  *  @param[in]  Bool             bothCwEnbld
24322  *  @return  uint8_t
24323  *
24324  **/
24325 static uint8_t rgSCHCmnDlTM3PrecInf2
24326 (
24327 RgSchCellCb *cell,
24328 RgSchUeCb   *ue,
24329 uint8_t     numTxLyrs,
24330 Bool        bothCwEnbld
24331 )
24332 {
24333
24334    return (0);
24335 }
24336
24337 \f
24338 /**
24339  * @brief Determine Precoding information for TM4 2 TX Antenna.
24340  *
24341  * @details
24342  *
24343  *     Function: rgSCHCmnDlTM4PrecInf2
24344  *     Purpose:  To determine a logic of deriving precoding index
24345  *               information from 36.212 table 5.3.3.1.5-4
24346  *
24347  *     Invoked by: rgSCHCmnDlGetAttrForTM4
24348  *
24349  *  @param[in]  RgSchUeCb        *ue
24350  *  @param[in]  uint8_t               numTxLyrs
24351  *  @param[in]  Bool             bothCwEnbld
24352  *  @return  uint8_t
24353  *
24354  **/
24355 static uint8_t rgSCHCmnDlTM4PrecInf2
24356 (
24357 RgSchCellCb  *cell,
24358 RgSchUeCb    *ue,
24359 uint8_t      numTxLyrs,
24360 Bool         bothCwEnbld
24361 )
24362 {
24363    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24364    uint8_t            precIdx;
24365
24366
24367    if (ueDl->mimoInfo.ri == numTxLyrs)
24368    {
24369       if (ueDl->mimoInfo.ri == 2)
24370       {
24371          /* PrecInfo corresponding to 2 CW
24372            Transmission */
24373          if (ue->mimoInfo.puschFdbkVld)
24374          {
24375             precIdx = 2;
24376          }
24377          else 
24378          {
24379             precIdx = ueDl->mimoInfo.pmi - 1;
24380          }
24381       }
24382       else
24383       {
24384          /* PrecInfo corresponding to 1 CW
24385           * Transmission */
24386          if (ue->mimoInfo.puschFdbkVld)
24387          {
24388             precIdx =  5;
24389          }
24390          else
24391          {
24392             precIdx =  ueDl->mimoInfo.pmi + 1;
24393          }
24394       }
24395    }
24396    else if (ueDl->mimoInfo.ri > numTxLyrs)
24397    {
24398       /* In case of choosing among the columns of a
24399        * precoding matrix, choose the column corresponding
24400        * to the MAX-CQI */
24401       if (ue->mimoInfo.puschFdbkVld)
24402       {
24403          precIdx = 5;
24404       }
24405       else
24406       {
24407          precIdx = (ueDl->mimoInfo.pmi- 1)* 2  + 1;
24408       }
24409    }
24410    else /* if RI < numTxLyrs */
24411    {
24412       precIdx = (ueDl->mimoInfo.pmi < 2)? 0:1;
24413    }
24414    return (precIdx);
24415 }
24416
24417 \f
24418 /**
24419  * @brief Determine Precoding information for TM3 4 TX Antenna.
24420  *
24421  * @details
24422  *
24423  *     Function: rgSCHCmnDlTM3PrecInf4
24424  *     Purpose:  To determine a logic of deriving precoding index
24425  *               information from 36.212 table 5.3.3.1.5A-2
24426  *
24427  *     Invoked by: rgSCHCmnDlGetAttrForTM3
24428  *
24429  *  @param[in]  RgSchUeCb        *ue
24430  *  @param[in]  uint8_t               numTxLyrs
24431  *  @param[in]  Bool             bothCwEnbld
24432  *  @return  uint8_t
24433  *
24434  **/
24435 static uint8_t rgSCHCmnDlTM3PrecInf4
24436 (
24437 RgSchCellCb *cell,
24438 RgSchUeCb   *ue,
24439 uint8_t     numTxLyrs,
24440 Bool        bothCwEnbld
24441 )
24442 {
24443    uint8_t  precIdx;
24444
24445
24446    if (bothCwEnbld)
24447    {
24448       precIdx = numTxLyrs - 2;
24449    }
24450    else /* one 1 CW transmission */
24451    {
24452       precIdx = 1;
24453    }
24454    return (precIdx);
24455 }
24456
24457 \f
24458 /**
24459  * @brief Determine Precoding information for TM4 4 TX Antenna.
24460  *
24461  * @details
24462  *
24463  *     Function: rgSCHCmnDlTM4PrecInf4
24464  *     Purpose:  To determine a logic of deriving precoding index
24465  *               information from 36.212 table 5.3.3.1.5-5
24466  *
24467  *     Invoked by: rgSCHCmnDlGetAttrForTM4
24468  *
24469  *  @param[in]  RgSchUeCb        *ue
24470  *  @param[in]  uint8_t               numTxLyrs
24471  *  @param[in]  Bool             bothCwEnbld
24472  *  @return  uint8_t
24473  *
24474  **/
24475 static uint8_t rgSCHCmnDlTM4PrecInf4
24476 (
24477 RgSchCellCb  *cell,
24478 RgSchUeCb    *ue,
24479 uint8_t      numTxLyrs,
24480 Bool         bothCwEnbld
24481 )
24482 {
24483    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24484    uint8_t       precInfoBaseIdx, precIdx;
24485
24486
24487    precInfoBaseIdx  = (ue->mimoInfo.puschFdbkVld)? (16):
24488       (ueDl->mimoInfo.pmi);
24489    if (bothCwEnbld)
24490    {
24491       precIdx = precInfoBaseIdx + (numTxLyrs-2)*17;
24492    }
24493    else /* one 1 CW transmission */
24494    {
24495       precInfoBaseIdx += 1;
24496       precIdx = precInfoBaseIdx + (numTxLyrs-1)*17;
24497    }
24498    return (precIdx);
24499 }
24500
24501 \f
24502 /**
24503  * @brief This function determines Transmission attributes
24504  *        incase of TM3 scheduling.
24505  *
24506  * @details
24507  *
24508  *     Function: rgSCHCmnDlGetAttrForTM3
24509  *     Purpose:  Determine retx TB and tx TB based on TB states.
24510  *               If forceTD enabled
24511  *                  perform only retx TB allocation.
24512  *                  If retxTB == TB2 then DCI Frmt = 2A, RA Type = 0.
24513  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
24514  *               If RI == 1
24515  *                  perform retxTB allocation on CW1.
24516  *               Else if RI > 1
24517  *                  Determine further Scope and Swap Flag attributes
24518  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
24519  *                  If no further scope for new TX allocation
24520  *                     Allocate only retx TB using 2 layers if
24521  *                     this TB was previously transmitted using 2 layers AND
24522  *                     number of Tx antenna ports == 4.
24523  *                     otherwise do single layer precoding.
24524  *
24525  *     Invoked by: rgSCHCmnDlTM3TxRetx
24526  *
24527  *  @param[in]  RgSchUeCb        *ue
24528  *  @param[in]  RgSchDlHqProcCb  *proc
24529  *  @param[out] uint8_t               *numTxLyrs
24530  *  @param[out] Bool             *isTraDiv
24531  *  @param[out] uint8_t               *prcdngInf
24532  *  @param[out] uint8_t               *raType
24533  *  @return  Void
24534  *
24535  **/
24536 static Void rgSCHCmnDlGetAttrForTM3
24537 (
24538 RgSchCellCb      *cell,
24539 RgSchUeCb        *ue,
24540 RgSchDlHqProcCb  *proc,
24541 uint8_t          *numTxLyrs,
24542 TfuDciFormat     *dciFrmt,
24543 uint8_t          *prcdngInf,
24544 RgSchDlHqTbCb    **retxTb,
24545 RgSchDlHqTbCb    **txTb,
24546 Bool             *frthrScp,
24547 Bool             *swpFlg,
24548 uint8_t          *raType
24549 )
24550 {
24551    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24552    uint8_t       precInfoAntIdx;
24553
24554
24555    /* Avoiding Tx-Retx for LAA cell as firstSchedTime is associated with 
24556       HQP */
24557    /* Integration_fix: SPS Proc shall always have only one Cw */
24558 #ifdef LTEMAC_SPS
24559    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
24560          (ueDl->mimoInfo.forceTD)) 
24561 #ifdef LTE_ADV
24562      ||(TRUE == rgSCHLaaSCellEnabled(cell))
24563 #endif
24564       )
24565 #else
24566    if ((ueDl->mimoInfo.forceTD) 
24567 #ifdef LTE_ADV
24568        || (TRUE == rgSCHLaaSCellEnabled(cell))
24569 #endif
24570       )
24571 #endif
24572    {
24573       /* Transmit Diversity. Format based on dlfsEnabled
24574        * No further scope */
24575       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24576       {
24577          *retxTb = &proc->tbInfo[0];
24578          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24579       }
24580       else
24581       {
24582          *retxTb = &proc->tbInfo[1];
24583          *dciFrmt = TFU_DCI_FORMAT_2A;
24584          *raType = RG_SCH_CMN_RA_TYPE0;
24585       }
24586       *numTxLyrs = 1;
24587       *frthrScp = FALSE;
24588       *prcdngInf = 0;
24589       return;
24590    }
24591
24592    /* Determine the 2 TB transmission attributes */
24593    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
24594          frthrScp, swpFlg);
24595    if (*frthrScp)
24596    {
24597       /* Prefer allocation of RETX TB over 2 layers rather than combining
24598        * it with a new TX. */
24599       if ((ueDl->mimoInfo.ri == 2)
24600             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
24601       {
24602          /* Allocate TB on CW1, using 2 Lyrs,
24603           * Format 2, precoding accordingly */
24604          *numTxLyrs = 2;
24605          *frthrScp = FALSE;
24606       }
24607       else
24608       {
24609          *numTxLyrs=  ((*retxTb)->numLyrs + ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)].noLyr);
24610
24611          if((*retxTb)->tbIdx == 0 && ((*retxTb)->numLyrs == 2 ) && *numTxLyrs ==3)
24612          {
24613             *swpFlg = TRUE;
24614             proc->cwSwpEnabled = TRUE;
24615          }
24616          else if((*retxTb)->tbIdx == 1 && ((*retxTb)->numLyrs == 1) && *numTxLyrs ==3)
24617          {
24618             *swpFlg = TRUE;
24619             proc->cwSwpEnabled = TRUE;
24620          }
24621       }
24622
24623       precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
24624       *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])\
24625                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
24626       *dciFrmt = TFU_DCI_FORMAT_2A;
24627       *raType = RG_SCH_CMN_RA_TYPE0;
24628    }
24629    else /* frthrScp == FALSE */
24630    {
24631       if (cell->numTxAntPorts == 2)
24632       {
24633          /*  Transmit Diversity  */
24634          *numTxLyrs = 1;
24635          if ((*retxTb)->tbIdx == 0)
24636          {
24637             *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24638          }
24639          else
24640          {
24641             /* If retxTB is TB2 then use format 2A */
24642             *dciFrmt = TFU_DCI_FORMAT_2A;
24643             *raType = RG_SCH_CMN_RA_TYPE0;
24644          }
24645          *prcdngInf = 0;
24646          return;
24647       }
24648       else /* NumAntPorts == 4 */
24649       {
24650          if ((*retxTb)->numLyrs == 2)
24651          {
24652             /* Allocate TB on CW1, using 2 Lyrs,
24653              * Format 2A, precoding accordingly */
24654             *numTxLyrs = 2;
24655             *dciFrmt = TFU_DCI_FORMAT_2A;
24656             *raType = RG_SCH_CMN_RA_TYPE0;
24657             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24658             *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, *numTxLyrs, *frthrScp);
24659             return;
24660          }
24661          else
24662          {
24663             /*  Transmit Diversity  */
24664             *numTxLyrs = 1;
24665             if ((*retxTb)->tbIdx == 0)
24666             {
24667                *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24668             }
24669             else
24670             {
24671                /* If retxTB is TB2 then use format 2A */
24672                *dciFrmt = TFU_DCI_FORMAT_2A;
24673                *raType = RG_SCH_CMN_RA_TYPE0;
24674             }
24675             *prcdngInf = 0;
24676             return;
24677          }
24678       }
24679    }
24680
24681    return;
24682 }
24683
24684
24685 \f
24686 /**
24687  * @brief This function determines Transmission attributes
24688  *        incase of TM4 scheduling.
24689  *
24690  * @details
24691  *
24692  *     Function: rgSCHCmnDlGetAttrForTM4
24693  *     Purpose:  Determine retx TB and tx TB based on TB states.
24694  *               If forceTD enabled
24695  *                  perform only retx TB allocation.
24696  *                  If retxTB == TB2 then DCI Frmt = 2, RA Type = 0.
24697  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
24698  *               If RI == 1
24699  *                  perform retxTB allocation on CW1.
24700  *               Else if RI > 1
24701  *                  Determine further Scope and Swap Flag attributes
24702  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
24703  *                  If no further scope for new TX allocation
24704  *                     Allocate only retx TB using 2 layers if
24705  *                     this TB was previously transmitted using 2 layers AND
24706  *                     number of Tx antenna ports == 4.
24707  *                     otherwise do single layer precoding.
24708  *
24709  *     Invoked by: rgSCHCmnDlTM4TxRetx
24710  *
24711  *  @param[in]  RgSchUeCb        *ue
24712  *  @param[in]  RgSchDlHqProcCb  *proc
24713  *  @param[out] uint8_t               *numTxLyrs
24714  *  @param[out] Bool             *isTraDiv
24715  *  @param[out] uint8_t               *prcdngInf
24716  *  @param[out] uint8_t               *raType
24717  *  @return  Void
24718  *
24719  **/
24720 static Void rgSCHCmnDlGetAttrForTM4
24721 (
24722 RgSchCellCb      *cell,
24723 RgSchUeCb        *ue,
24724 RgSchDlHqProcCb  *proc,
24725 uint8_t          *numTxLyrs,
24726 TfuDciFormat     *dciFrmt,
24727 uint8_t          *prcdngInf,
24728 RgSchDlHqTbCb    **retxTb,
24729 RgSchDlHqTbCb    **txTb,
24730 Bool             *frthrScp,
24731 Bool             *swpFlg,
24732 uint8_t          *raType
24733 )
24734 {
24735    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
24736    uint8_t precInfoAntIdx;
24737
24738
24739    *frthrScp = FALSE;
24740    /* Integration_fix: SPS Proc shall always have only one Cw */
24741 #ifdef LTEMAC_SPS
24742    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
24743          (ueDl->mimoInfo.forceTD)) 
24744 #ifdef LTE_ADV
24745      ||(TRUE == rgSCHLaaSCellEnabled(cell))
24746 #endif
24747       )
24748 #else
24749    if ((ueDl->mimoInfo.forceTD) 
24750 #ifdef LTE_ADV
24751        || (TRUE == rgSCHLaaSCellEnabled(cell))
24752 #endif
24753       )
24754 #endif
24755    {
24756       /* Transmit Diversity. Format based on dlfsEnabled
24757        * No further scope */
24758       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24759       {
24760          *retxTb = &proc->tbInfo[0];
24761          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
24762       }
24763       else
24764       {
24765          *retxTb = &proc->tbInfo[1];
24766          *dciFrmt = TFU_DCI_FORMAT_2;
24767          *raType = RG_SCH_CMN_RA_TYPE0;
24768       }
24769       *numTxLyrs = 1;
24770       *frthrScp = FALSE;
24771       *prcdngInf = 0;
24772       return;
24773    }
24774
24775    if (ueDl->mimoInfo.ri == 1)
24776    {
24777       /* single layer precoding. Format 2.
24778        * No further scope */
24779       if (proc->tbInfo[0].state == HQ_TB_NACKED)
24780       {
24781          *retxTb = &proc->tbInfo[0];
24782       }
24783       else
24784       {
24785          *retxTb = &proc->tbInfo[1];
24786       }
24787       *numTxLyrs = 1;
24788       *dciFrmt = TFU_DCI_FORMAT_2;
24789       *raType = RG_SCH_CMN_RA_TYPE0;
24790       *frthrScp = FALSE;
24791       *prcdngInf = 0; /*When RI= 1*/
24792       return;
24793    }
24794
24795    /* Determine the 2 TB transmission attributes */
24796    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
24797          frthrScp, swpFlg);
24798    *dciFrmt = TFU_DCI_FORMAT_2;
24799    *raType = RG_SCH_CMN_RA_TYPE0;
24800    if (*frthrScp)
24801    {
24802       /* Prefer allocation of RETX TB over 2 layers rather than combining
24803        * it with a new TX. */
24804       if ((ueDl->mimoInfo.ri == 2)
24805             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
24806       {
24807          /* Allocate TB on CW1, using 2 Lyrs,
24808           * Format 2, precoding accordingly */
24809          *numTxLyrs = 2;
24810          *frthrScp = FALSE;
24811       }
24812       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24813       *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])
24814                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
24815    }
24816    else /* frthrScp == FALSE */
24817    {
24818       if (cell->numTxAntPorts == 2)
24819       {
24820          /* single layer precoding. Format 2. */
24821          *numTxLyrs = 1;
24822          *prcdngInf = (getPrecInfoFunc[1][cell->numTxAntPorts/2 - 1])\
24823                       (cell, ue, *numTxLyrs, *frthrScp);
24824          return;
24825       }
24826       else /* NumAntPorts == 4 */
24827       {
24828          if ((*retxTb)->numLyrs == 2)
24829          {
24830             /* Allocate TB on CW1, using 2 Lyrs,
24831              * Format 2, precoding accordingly */
24832             *numTxLyrs = 2;
24833             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24834             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
24835                          (cell, ue, *numTxLyrs, *frthrScp);
24836             return;
24837          }
24838          else
24839          {
24840             /* Allocate TB with 1 lyr precoding,
24841              * Format 2, precoding info accordingly */
24842             *numTxLyrs = 1;
24843             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
24844             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
24845                          (cell, ue, *numTxLyrs, *frthrScp);
24846             return;
24847          }
24848       }
24849    }
24850
24851    return;
24852 }
24853
24854 \f
24855 /**
24856  * @brief This function handles Retx allocation in case of TM3 UEs
24857  *        where previously one of the TBs was NACKED and the other
24858  *        TB is either ACKED/WAITING.
24859  *
24860  * @details
24861  *
24862  *     Function: rgSCHCmnDlTM3TxRetx
24863  *     Purpose:  Determine the TX attributes for TM3 TxRetx Allocation.
24864  *               If futher Scope for New Tx Allocation on other TB
24865  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
24866  *                  Add UE to cell wide RetxTx List.
24867  *               Else
24868  *                  Perform only RETX alloc'n on CW1.
24869  *                  Add UE to cell wide Retx List.
24870  *
24871  *               effBo is set to a non-zero value if allocation is
24872  *               successful.
24873  *
24874  *     Invoked by: rgSCHCmnDlAllocRbTM3
24875  *
24876  *  @param[in]  RgSchCellCb           *cell
24877  *  @param[in]  RgSchDlSf             *subFrm
24878  *  @param[in]  RgSchUeCb             *ue
24879  *  @param[in]  uint32_t                   bo
24880  *  @param[out] uint32_t                   *effBo
24881  *  @param[in]  RgSchDlHqProcCb       *proc
24882  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24883  *  @return  Void
24884  *
24885  **/
24886 static Void rgSCHCmnDlTM3TxRetx
24887 (
24888 RgSchCellCb           *cell,
24889 RgSchDlSf             *subFrm,
24890 RgSchUeCb             *ue,
24891 uint32_t              bo,
24892 uint32_t              *effBo,
24893 RgSchDlHqProcCb       *proc,
24894 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24895 )
24896 {
24897    S16              ret;
24898    RgSchDlRbAlloc   *allocInfo;
24899    uint8_t          numRb;
24900    RgSchDlHqTbCb    *retxTb, *txTb;
24901    Bool             frthrScp;
24902    Bool             swpFlg;
24903    uint8_t          prcdngInf;
24904    uint8_t          numTxLyrs;
24905
24906    frthrScp = FALSE;
24907
24908    ret = ROK;
24909    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
24910    swpFlg = FALSE;
24911
24912    /* Determine the transmission attributes */
24913    rgSCHCmnDlGetAttrForTM3(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
24914          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
24915          &allocInfo->raType);
24916
24917    if (frthrScp)
24918    {
24919 #ifdef LAA_DBG_LOG
24920       DU_LOG("\nDEBUG  -->  SCH : TX RETX called from proc %d cell %d \n",proc->procId, cell->cellId);
24921 #endif
24922       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
24923             &numRb, effBo);
24924       if (ret == RFAILED)
24925       {
24926          /* Allocation couldn't be made for Retx */
24927          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24928          return;
24929       }
24930       /* Adding UE to RbAllocInfo RETX-TX Lst */
24931       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
24932    }
24933    else
24934    {
24935       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
24936             numTxLyrs, &numRb, effBo);
24937       if (ret == RFAILED)
24938       {
24939          /* Allocation couldn't be made for Retx */
24940          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
24941          return;
24942       }
24943 #ifdef LTEMAC_SPS
24944       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
24945 #endif
24946       {
24947          /* Adding UE to allocInfo RETX Lst */
24948          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
24949       }
24950    }
24951    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
24952          prcdngInf, numTxLyrs, subFrm);
24953
24954    return;
24955 }
24956
24957 \f
24958 /**
24959  * @brief This function handles Retx allocation in case of TM4 UEs
24960  *        where previously one of the TBs was NACKED and the other
24961  *        TB is either ACKED/WAITING.
24962  *
24963  * @details
24964  *
24965  *     Function: rgSCHCmnDlTM4TxRetx
24966  *     Purpose:  Determine the TX attributes for TM4 TxRetx Allocation.
24967  *               If futher Scope for New Tx Allocation on other TB
24968  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
24969  *                  Add UE to cell wide RetxTx List.
24970  *               Else
24971  *                  Perform only RETX alloc'n on CW1.
24972  *                  Add UE to cell wide Retx List.
24973  *
24974  *               effBo is set to a non-zero value if allocation is
24975  *               successful.
24976  *
24977  *     Invoked by: rgSCHCmnDlAllocRbTM4
24978  *
24979  *  @param[in]  RgSchCellCb           *cell
24980  *  @param[in]  RgSchDlSf             *subFrm
24981  *  @param[in]  RgSchUeCb             *ue
24982  *  @param[in]  uint32_t                   bo
24983  *  @param[out] uint32_t                   *effBo
24984  *  @param[in]  RgSchDlHqProcCb       *proc
24985  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
24986  *  @return  Void
24987  *
24988  **/
24989 static Void rgSCHCmnDlTM4TxRetx
24990 (
24991 RgSchCellCb                *cell,
24992 RgSchDlSf                  *subFrm,
24993 RgSchUeCb                  *ue,
24994 uint32_t                   bo,
24995 uint32_t                   *effBo,
24996 RgSchDlHqProcCb            *proc,
24997 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
24998 )
24999 {
25000    S16              ret;
25001    RgSchDlRbAlloc   *allocInfo;
25002    uint8_t          numRb;
25003    RgSchDlHqTbCb    *retxTb, *txTb;
25004    Bool             frthrScp;
25005    Bool             swpFlg;
25006    uint8_t          prcdngInf;
25007    uint8_t          numTxLyrs;
25008
25009
25010    ret = ROK;
25011    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25012    swpFlg = FALSE;
25013
25014    /* Determine the transmission attributes */
25015    rgSCHCmnDlGetAttrForTM4(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
25016          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
25017          &allocInfo->raType);
25018
25019    if (frthrScp)
25020    {
25021       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
25022             &numRb, effBo);
25023       if (ret == RFAILED)
25024       {
25025          /* Fix : syed If TxRetx allocation failed then add the UE along 
25026           * with the proc to the nonSchdTxRetxUeLst and let spfc scheduler
25027           *  take care of it during finalization. */       
25028          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25029          return;
25030       }
25031       /* Adding UE to RbAllocInfo RETX-TX Lst */
25032       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
25033    }
25034    else
25035    {
25036       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
25037             numTxLyrs, &numRb, effBo);
25038       if (ret == RFAILED)
25039       {
25040          /* Allocation couldn't be made for Retx */
25041          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25042          return;
25043       }
25044 #ifdef LTEMAC_SPS
25045       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25046 #endif
25047       {
25048          /* Adding UE to allocInfo RETX Lst */
25049          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
25050       }
25051    }
25052    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
25053          prcdngInf, numTxLyrs, subFrm)
25054
25055       return;
25056 }
25057
25058 \f
25059 /**
25060  * @brief This function handles Retx allocation in case of TM4 UEs
25061  *        where previously both the TBs were ACKED and ACKED
25062  *        respectively.
25063  *
25064  * @details
25065  *
25066  *     Function: rgSCHCmnDlTM3TxTx
25067  *     Purpose:  Reached here for a TM3 UE's HqP's fresh allocation
25068  *                  where both the TBs are free for TX scheduling.
25069  *               If forceTD flag is set
25070  *                  perform TD on CW1 with TB1.
25071  *                  precInfo = 0
25072  *               else
25073  *                  DCI Format = 2A.
25074  *                  RA Type = Type0.
25075  *                  RI layered precoding 2 TB on 2 CW.
25076  *                  Set precoding info.
25077  *               Add UE to cellAllocInfo.
25078  *               Fill ueAllocInfo.
25079  *
25080  *              effBo is set to a non-zero value if allocation is
25081  *              successful.
25082  *
25083  *     Invoked by: rgSCHCmnDlAllocRbTM3
25084  *
25085  *  @param[in]  RgSchCellCb           *cell
25086  *  @param[in]  RgSchDlSf             *subFrm
25087  *  @param[in]  RgSchUeCb             *ue
25088  *  @param[in]  uint32_t                   bo
25089  *  @param[out] uint32_t                   *effBo
25090  *  @param[in]  RgSchDlHqProcCb       *proc
25091  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25092  *  @return  Void
25093  *
25094  **/
25095 static Void rgSCHCmnDlTM3TxTx
25096 (
25097 RgSchCellCb           *cell,
25098 RgSchDlSf             *subFrm,
25099 RgSchUeCb             *ue,
25100 uint32_t              bo,
25101 uint32_t              *effBo,
25102 RgSchDlHqProcCb       *proc,
25103 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25104 )
25105 {
25106    RgSchCmnDlUe     *ueDl;
25107    RgSchDlRbAlloc   *allocInfo;
25108    uint8_t          numRb;
25109    uint8_t          noTxLyrs;
25110    uint8_t          precInfo;
25111    S16              ret;
25112    uint8_t          precInfoAntIdx;
25113
25114
25115    ret = ROK;
25116    ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
25117    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25118
25119    /* Integration_fix: SPS Proc shall always have only one Cw */
25120 #ifdef LTEMAC_SPS
25121 #ifdef FOUR_TX_ANTENNA
25122       if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25123                      (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
25124 #else
25125    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25126          (ueDl->mimoInfo.forceTD))
25127 #endif
25128 #else
25129    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
25130 #endif
25131    {
25132       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
25133             &allocInfo->raType);
25134       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25135             bo, &numRb, effBo);
25136       if (ret == RFAILED)
25137       {
25138          /* If allocation couldn't be made then return */
25139          return;
25140       }
25141       noTxLyrs = 1;
25142       precInfo = 0; /* TD */
25143    }
25144    else /* Precoding */
25145    {
25146       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
25147       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
25148
25149       /* Spatial Multiplexing using 2 CWs */
25150       ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
25151       if (ret == RFAILED)
25152       {
25153          /* If allocation couldn't be made then return */
25154          return;
25155       }
25156       noTxLyrs = ueDl->mimoInfo.ri;
25157       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
25158       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, getPrecInfoFunc[0], precInfoAntIdx);
25159       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
25160    }
25161
25162 #ifdef LTEMAC_SPS
25163    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25164 #endif
25165    {
25166       /* Adding UE to RbAllocInfo TX Lst */
25167       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25168    }
25169    /* Fill UE allocInfo scrath pad */
25170    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
25171          precInfo, noTxLyrs, subFrm);
25172
25173    return;
25174 }
25175
25176 \f
25177 /**
25178  * @brief This function handles Retx allocation in case of TM4 UEs
25179  *        where previously both the TBs were ACKED and ACKED
25180  *        respectively.
25181  *
25182  * @details
25183  *
25184  *     Function: rgSCHCmnDlTM4TxTx
25185  *     Purpose:  Reached here for a TM4 UE's HqP's fresh allocation
25186  *                  where both the TBs are free for TX scheduling.
25187  *               If forceTD flag is set
25188  *                  perform TD on CW1 with TB1.
25189  *                  precInfo = 0
25190  *               else
25191  *                  DCI Format = 2.
25192  *                  RA Type = Type0.
25193  *                  If Rank == 1
25194  *                     Single layer precoding of TB1 on CW1.
25195  *                     Set precoding info.
25196  *                  else
25197  *                     RI layered precoding 2 TB on 2 CW.
25198  *                     Set precoding info.
25199  *               Add UE to cellAllocInfo.
25200  *               Fill ueAllocInfo.
25201  *
25202  *              effBo is set to a non-zero value if allocation is
25203  *              successful.
25204  *
25205  *     Invoked by: rgSCHCmnDlAllocRbTM4
25206  *
25207  *  @param[in]  RgSchCellCb           *cell
25208  *  @param[in]  RgSchDlSf             *subFrm
25209  *  @param[in]  RgSchUeCb             *ue
25210  *  @param[in]  uint32_t                   bo
25211  *  @param[out] uint32_t                   *effBo
25212  *  @param[in]  RgSchDlHqProcCb       *proc
25213  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25214  *  @return  Void
25215  *
25216  **/
25217 static Void rgSCHCmnDlTM4TxTx
25218 (
25219 RgSchCellCb           *cell,
25220 RgSchDlSf             *subFrm,
25221 RgSchUeCb             *ue,
25222 uint32_t              bo,
25223 uint32_t              *effBo,
25224 RgSchDlHqProcCb       *proc,
25225 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25226 )
25227 {
25228    RgSchCmnDlUe     *ueDl;
25229    RgSchDlRbAlloc   *allocInfo;
25230    uint8_t          numRb;
25231    uint8_t          precInfo;
25232    uint8_t          noTxLyrs;
25233    uint8_t          precInfoAntIdx;
25234    S16              ret;
25235
25236
25237    ret       = ROK;
25238    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25239    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25240
25241    /* Integration_fix: SPS Proc shall always have only one Cw */
25242 #ifdef LTEMAC_SPS
25243 #ifdef FOUR_TX_ANTENNA
25244    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25245                   (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
25246 #else
25247    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
25248          (ueDl->mimoInfo.forceTD))
25249 #endif
25250 #else
25251    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
25252 #endif
25253    {
25254       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
25255             &allocInfo->raType);
25256
25257       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25258             bo, &numRb, effBo);
25259       if (ret == RFAILED)
25260       {
25261          /* If allocation couldn't be made then return */
25262          return;
25263       }
25264       noTxLyrs = 1;
25265       precInfo = 0; /* TD */
25266    }
25267    else /* Precoding */
25268    {
25269       allocInfo->dciFormat = TFU_DCI_FORMAT_2;
25270       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
25271
25272       if (ueDl->mimoInfo.ri == 1)
25273       {
25274          /* Single Layer SM using FORMAT 2 */
25275          ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25276                bo, &numRb, effBo);
25277          if (ret == RFAILED)
25278          {
25279             /* If allocation couldn't be made then return */
25280             return;
25281          }
25282          noTxLyrs = 1;
25283          precInfo = 0; /* PrecInfo as 0 for RI=1*/
25284       }
25285       else
25286       {
25287          /* Spatial Multiplexing using 2 CWs */
25288          ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
25289          if (ret == RFAILED)
25290          {
25291             /* If allocation couldn't be made then return */
25292             return;
25293          }
25294          noTxLyrs = ueDl->mimoInfo.ri;
25295          precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
25296          precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
25297       }
25298    }
25299
25300    
25301 #ifdef LTEMAC_SPS
25302    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25303 #endif
25304    {
25305       /* Adding UE to RbAllocInfo TX Lst */
25306       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25307    }
25308
25309    /* Fill UE allocInfo scrath pad */
25310    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
25311          precInfo, noTxLyrs, subFrm);
25312
25313    return;
25314 }
25315
25316 \f
25317 /**
25318  * @brief This function determines the RBs and Bytes required for BO
25319  *        transmission for UEs configured with TM 4.
25320  *
25321  * @details
25322  *
25323  *     Function: rgSCHCmnDlAllocTxRbTM4
25324  *     Purpose:  Invokes the functionality particular to the
25325  *               current state of the TBs of the "proc".
25326  *
25327  *               Reference Parameter effBo is filled with alloced bytes.
25328  *               Returns RFAILED if BO not satisfied at all.
25329  *
25330  *     Invoked by: rgSCHCmnDlAllocTxRb
25331  *
25332  *  @param[in]  RgSchCellCb           *cell
25333  *  @param[in]  RgSchDlSf             *subFrm
25334  *  @param[in]  RgSchUeCb             *ue
25335  *  @param[in]  uint32_t                   bo
25336  *  @param[out] uint32_t                   *effBo
25337  *  @param[in]  RgSchDlHqProcCb       *proc
25338  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25339  *  @return  Void
25340  *
25341  **/
25342 static Void rgSCHCmnDlAllocTxRbTM4
25343 (
25344 RgSchCellCb            *cell,
25345 RgSchDlSf              *subFrm,
25346 RgSchUeCb              *ue,
25347 uint32_t               bo,
25348 uint32_t               *effBo,
25349 RgSchDlHqProcCb        *proc,
25350 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
25351 )
25352 {
25353
25354    /* Both TBs free for TX allocation */
25355    rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo,\
25356          proc, cellWdAllocInfo);
25357
25358    return;
25359 }
25360
25361 \f
25362 /**
25363  * @brief This function determines the RBs and Bytes required for BO
25364  *        retransmission for UEs configured with TM 4.
25365  *
25366  * @details
25367  *
25368  *     Function: rgSCHCmnDlAllocRetxRbTM4
25369  *     Purpose:  Invokes the functionality particular to the
25370  *               current state of the TBs of the "proc".
25371  *
25372  *               Reference Parameter effBo is filled with alloced bytes.
25373  *               Returns RFAILED if BO not satisfied at all.
25374  *
25375  *     Invoked by: rgSCHCmnDlAllocRetxRb
25376  *
25377  *  @param[in]  RgSchCellCb           *cell
25378  *  @param[in]  RgSchDlSf             *subFrm
25379  *  @param[in]  RgSchUeCb             *ue
25380  *  @param[in]  uint32_t                   bo
25381  *  @param[out] uint32_t                   *effBo
25382  *  @param[in]  RgSchDlHqProcCb       *proc
25383  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25384  *  @return  Void
25385  *
25386  **/
25387 static Void rgSCHCmnDlAllocRetxRbTM4
25388 (
25389 RgSchCellCb           *cell,
25390 RgSchDlSf             *subFrm,
25391 RgSchUeCb             *ue,
25392 uint32_t              bo,
25393 uint32_t              *effBo,
25394 RgSchDlHqProcCb       *proc,
25395 RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25396 )
25397 {
25398
25399    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
25400          (proc->tbInfo[1].state == HQ_TB_NACKED))
25401    {
25402       /* Both TBs require RETX allocation */
25403       rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo,\
25404             proc, cellWdAllocInfo);
25405    }
25406    else
25407    {
25408       /* One of the TBs need RETX allocation. Other TB may/maynot
25409        * be available for new TX allocation. */
25410       rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo,\
25411             proc, cellWdAllocInfo);
25412    }
25413
25414    return;
25415 }
25416
25417 #ifdef RG_UNUSED
25418 \f
25419 /**
25420  * @brief This function determines the RBs and Bytes required for BO
25421  *        transmission for UEs configured with TM 5.
25422  *
25423  * @details
25424  *
25425  *     Function: rgSCHCmnDlAllocTxRbTM5
25426  *     Purpose:
25427  *
25428  *               Reference Parameter effBo is filled with alloced bytes.
25429  *               Returns RFAILED if BO not satisfied at all.
25430  *
25431  *     Invoked by: rgSCHCmnDlAllocTxRb
25432  *
25433  *  @param[in]  RgSchCellCb           *cell
25434  *  @param[in]  RgSchDlSf             *subFrm
25435  *  @param[in]  RgSchUeCb             *ue
25436  *  @param[in]  uint32_t                   bo
25437  *  @param[out] uint32_t                   *effBo
25438  *  @param[in]  RgSchDlHqProcCb       *proc
25439  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25440  *  @return Void
25441  *
25442  **/
25443 static Void rgSCHCmnDlAllocTxRbTM5
25444 (
25445 RgSchCellCb                *cell,
25446 RgSchDlSf                  *subFrm,
25447 RgSchUeCb                  *ue,
25448 uint32_t                   bo,
25449 uint32_t                   *effBo,
25450 RgSchDlHqProcCb            *proc,
25451 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25452 )
25453 {
25454 #if (ERRCLASS & ERRCLS_DEBUG)
25455    DU_LOG("\nERROR  -->  SCH : Invalid TM 5 for CRNTI:%d",ue->ueId);
25456 #endif
25457    return;
25458 }
25459
25460 \f
25461 /**
25462  * @brief This function determines the RBs and Bytes required for BO
25463  *        retransmission for UEs configured with TM 5.
25464  *
25465  * @details
25466  *
25467  *     Function: rgSCHCmnDlAllocRetxRbTM5
25468  *     Purpose:
25469  *
25470  *               Reference Parameter effBo is filled with alloced bytes.
25471  *               Returns RFAILED if BO not satisfied at all.
25472  *
25473  *     Invoked by: rgSCHCmnDlAllocRetxRb
25474  *
25475  *  @param[in]  RgSchCellCb           *cell
25476  *  @param[in]  RgSchDlSf             *subFrm
25477  *  @param[in]  RgSchUeCb             *ue
25478  *  @param[in]  uint32_t                   bo
25479  *  @param[out] uint32_t                   *effBo
25480  *  @param[in]  RgSchDlHqProcCb       *proc
25481  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25482  *  @return Void
25483  *
25484  **/
25485 static Void rgSCHCmnDlAllocRetxRbTM5
25486 (
25487 RgSchCellCb            *cell,
25488 RgSchDlSf              *subFrm,
25489 RgSchUeCb              *ue,
25490 uint32_t               bo,
25491 uint32_t               *effBo,
25492 RgSchDlHqProcCb        *proc,
25493 RgSchCmnDlRbAllocInfo  *cellWdAllocInfo
25494 )
25495 {
25496 #if (ERRCLASS & ERRCLS_DEBUG)
25497    DU_LOG("\nERROR  -->  SCH : Invalid TM 5 for CRNTI:%d",ue->ueId);
25498 #endif
25499    return;
25500 }
25501 #endif
25502
25503 \f
25504 /**
25505  * @brief This function determines the RBs and Bytes required for BO
25506  *        transmission for UEs configured with TM 6.
25507  *
25508  * @details
25509  *
25510  *     Function: rgSCHCmnDlAllocTxRbTM6
25511  *     Purpose:
25512  *
25513  *               Reference Parameter effBo is filled with alloced bytes.
25514  *               Returns RFAILED if BO not satisfied at all.
25515  *
25516  *     Invoked by: rgSCHCmnDlAllocTxRb
25517  *
25518  *  @param[in]  RgSchCellCb           *cell
25519  *  @param[in]  RgSchDlSf             *subFrm
25520  *  @param[in]  RgSchUeCb             *ue
25521  *  @param[in]  uint32_t                   bo
25522  *  @param[out] uint32_t                   *effBo
25523  *  @param[in]  RgSchDlHqProcCb       *proc
25524  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25525  *  @return Void
25526  *
25527  **/
25528 static Void rgSCHCmnDlAllocTxRbTM6
25529 (
25530 RgSchCellCb                *cell,
25531 RgSchDlSf                  *subFrm,
25532 RgSchUeCb                  *ue,
25533 uint32_t                   bo,
25534 uint32_t                   *effBo,
25535 RgSchDlHqProcCb            *proc,
25536 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25537 )
25538 {
25539    RgSchDlRbAlloc *allocInfo;
25540    RgSchCmnDlUe   *ueDl;
25541    S16            ret;
25542    uint8_t        numRb;
25543
25544
25545    ret       = ROK;
25546    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25547    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25548
25549    if (ueDl->mimoInfo.forceTD)
25550    {
25551       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25552       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25553    }
25554    else
25555    {
25556       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
25557       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25558       /* Fill precoding information for FORMAT 1B */
25559       /* First 4 least significant bits to indicate PMI.
25560        * 4th most significant corresponds to pmi Confirmation.
25561        */
25562       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
25563       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
25564    }
25565    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
25566          bo, &numRb, effBo);
25567    if (ret == RFAILED)
25568    {
25569       /* If allocation couldn't be made then return */
25570       return;
25571    }
25572    
25573 #ifdef LTEMAC_SPS
25574    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
25575 #endif
25576    {
25577       /* Adding UE to RbAllocInfo TX Lst */
25578       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
25579    }
25580    /* Fill UE alloc Info */
25581    allocInfo->rbsReq = numRb;
25582    allocInfo->dlSf   = subFrm;
25583    return;
25584 }
25585
25586 \f
25587 /**
25588  * @brief This function determines the RBs and Bytes required for BO
25589  *        retransmission for UEs configured with TM 6.
25590  *
25591  * @details
25592  *
25593  *     Function: rgSCHCmnDlAllocRetxRbTM6
25594  *     Purpose:
25595  *
25596  *               Reference Parameter effBo is filled with alloced bytes.
25597  *               Returns RFAILED if BO not satisfied at all.
25598  *
25599  *     Invoked by: rgSCHCmnDlAllocRetxRb
25600  *
25601  *  @param[in]  RgSchCellCb           *cell
25602  *  @param[in]  RgSchDlSf             *subFrm
25603  *  @param[in]  RgSchUeCb             *ue
25604  *  @param[in]  uint32_t                   bo
25605  *  @param[out] uint32_t                   *effBo
25606  *  @param[in]  RgSchDlHqProcCb       *proc
25607  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25608  *  @return Void
25609  *
25610  **/
25611 static Void rgSCHCmnDlAllocRetxRbTM6
25612 (
25613 RgSchCellCb                *cell,
25614 RgSchDlSf                  *subFrm,
25615 RgSchUeCb                  *ue,
25616 uint32_t                   bo,
25617 uint32_t                   *effBo,
25618 RgSchDlHqProcCb            *proc,
25619 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25620 )
25621 {
25622    RgSchDlRbAlloc *allocInfo;
25623    RgSchCmnDlUe   *ueDl;
25624    S16            ret;
25625    uint8_t        numRb;
25626
25627
25628    ret       = ROK;
25629    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25630    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
25631
25632    if (ueDl->mimoInfo.forceTD)
25633    {
25634       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25635       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25636    }
25637    else
25638    {
25639       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
25640       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
25641       /* Fill precoding information for FORMAT 1B */
25642       /* First 4 least significant bits to indicate PMI.
25643        * 4th most significant corresponds to pmi Confirmation.
25644        */
25645       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
25646       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
25647    }
25648
25649    /* Get the Allocation in terms of RBs that are required for
25650     * this retx of TB1 */
25651    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
25652          1, &numRb, effBo);
25653    if (ret == RFAILED)
25654    {
25655       /* Allocation couldn't be made for Retx */
25656       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
25657       return;
25658    }
25659    /* Adding UE to allocInfo RETX Lst */
25660    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
25661    /* Fill UE alloc Info */
25662    allocInfo->rbsReq = numRb;
25663    allocInfo->dlSf   = subFrm;
25664    return;
25665 }
25666
25667 \f
25668 /**
25669  * @brief This function determines the RBs and Bytes required for BO
25670  *        transmission for UEs configured with TM 7.
25671  *
25672  * @details
25673  *
25674  *     Function: rgSCHCmnDlAllocTxRbTM7
25675  *     Purpose:
25676  *
25677  *               Reference Parameter effBo is filled with alloced bytes.
25678  *               Returns RFAILED if BO not satisfied at all.
25679  *
25680  *     Invoked by: rgSCHCmnDlAllocTxRb
25681  *
25682  *  @param[in]  RgSchCellCb           *cell
25683  *  @param[in]  RgSchDlSf             *subFrm
25684  *  @param[in]  RgSchUeCb             *ue
25685  *  @param[in]  uint32_t                   bo
25686  *  @param[out] uint32_t                   *effBo
25687  *  @param[in]  RgSchDlHqProcCb       *proc
25688  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25689  *  @return Void
25690  *
25691  **/
25692 static Void rgSCHCmnDlAllocTxRbTM7
25693 (
25694 RgSchCellCb                *cell,
25695 RgSchDlSf                  *subFrm,
25696 RgSchUeCb                  *ue,
25697 uint32_t                   bo,
25698 uint32_t                   *effBo,
25699 RgSchDlHqProcCb            *proc,
25700 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25701 )
25702 {
25703    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
25704    return;
25705 }
25706
25707 \f
25708 /**
25709  * @brief This function determines the RBs and Bytes required for BO
25710  *        retransmission for UEs configured with TM 7.
25711  *
25712  * @details
25713  *
25714  *     Function: rgSCHCmnDlAllocRetxRbTM7
25715  *     Purpose:
25716  *
25717  *               Reference Parameter effBo is filled with alloced bytes.
25718  *               Returns RFAILED if BO not satisfied at all.
25719  *
25720  *     Invoked by: rgSCHCmnDlAllocRetxRb
25721  *
25722  *  @param[in]  RgSchCellCb           *cell
25723  *  @param[in]  RgSchDlSf             *subFrm
25724  *  @param[in]  RgSchUeCb             *ue
25725  *  @param[in]  uint32_t                   bo
25726  *  @param[out] uint32_t                   *effBo
25727  *  @param[in]  RgSchDlHqProcCb       *proc
25728  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25729  *  @return Void
25730  *
25731  **/
25732 static Void rgSCHCmnDlAllocRetxRbTM7
25733 (
25734 RgSchCellCb                *cell,
25735 RgSchDlSf                  *subFrm,
25736 RgSchUeCb                  *ue,
25737 uint32_t                   bo,
25738 uint32_t                   *effBo,
25739 RgSchDlHqProcCb            *proc,
25740 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25741 )
25742 {
25743    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
25744    return;
25745 }
25746
25747 \f
25748 /**
25749  * @brief This function invokes the TM specific DL TX RB Allocation routine.
25750  *
25751  * @details
25752  *
25753  *     Function: rgSCHCmnDlAllocTxRb
25754  *     Purpose:  This function invokes the TM specific
25755  *               DL TX RB Allocation routine.
25756  *
25757  *     Invoked by: Specific Schedulers
25758  *
25759  *  @param[in]  RgSchCellCb           *cell
25760  *  @param[in]  RgSchDlSf             *subFrm
25761  *  @param[in]  RgSchUeCb             *ue
25762  *  @param[in]  uint32_t                   bo
25763  *  @param[out] uint32_t                   *effBo
25764  *  @param[in]  RgSchDlHqProcCb       *proc
25765  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25766  *  @return  S16
25767  *
25768  **/
25769 S16 rgSCHCmnDlAllocTxRb
25770 (
25771 RgSchCellCb                *cell,
25772 RgSchDlSf                  *subFrm,
25773 RgSchUeCb                  *ue,
25774 uint32_t                   bo,
25775 uint32_t                   *effBo,
25776 RgSchDlHqProcCb            *proc,
25777 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25778 )
25779 {
25780    uint32_t                newSchBits = 0;
25781    uint32_t                prevSchBits = 0;
25782    RgSchDlRbAlloc          *allocInfo;
25783
25784
25785    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
25786    {
25787       ue->dl.aggTbBits = 0;
25788    }
25789    *effBo = 0;
25790
25791    /* Calculate totals bits previously allocated */
25792    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25793    if (allocInfo->tbInfo[0].schdlngForTb)
25794    {
25795       prevSchBits += allocInfo->tbInfo[0].bytesReq;
25796    }
25797    if (allocInfo->tbInfo[1].schdlngForTb)
25798    {
25799       prevSchBits += allocInfo->tbInfo[1].bytesReq;
25800    }
25801
25802    /* Call TM specific RB allocation routine */
25803    (dlAllocTxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
25804          proc, cellWdAllocInfo);
25805
25806    if (*effBo)
25807    {
25808       /* Calculate totals bits newly allocated */
25809       if (allocInfo->tbInfo[0].schdlngForTb)
25810       {
25811          newSchBits += allocInfo->tbInfo[0].bytesReq;
25812       }
25813       if (allocInfo->tbInfo[1].schdlngForTb)
25814       {
25815          newSchBits += allocInfo->tbInfo[1].bytesReq;
25816       }
25817       if (newSchBits > prevSchBits)
25818       {
25819          ue->dl.aggTbBits += ((newSchBits - prevSchBits) * 8);
25820          RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
25821       }
25822    }
25823
25824    return ROK;
25825 }
25826
25827 /* DwPTS Scheduling Changes Start */
25828 #ifdef LTE_TDD
25829 /**
25830  * @brief Retransmit decision for TDD. Retx is avoided in below cases
25831  *        1) DL Sf       -> Spl Sf
25832  *        2) DL SF       -> DL SF 0 
25833  *
25834  * @details
25835  *
25836  *     Function: rgSCHCmnRetxAvoidTdd 
25837  *     Purpose: Avoid allocating RETX for cases 1, 2 
25838  * 
25839  *     Invoked by: rgSCHCmnRetxAvoidTdd 
25840  *
25841  *  @param[in]  RgSchDlSf             *curSf
25842  *  @param[in]  RgSchCellCb           *cell
25843  *  @param[in]  RgSchDlHqProcCb       *proc
25844  *  @return  Bool 
25845  *
25846  **/
25847 Bool rgSCHCmnRetxAvoidTdd 
25848 (
25849 RgSchDlSf                  *curSf,
25850 RgSchCellCb                *cell,
25851 RgSchDlHqProcCb            *proc
25852 )
25853 {
25854    RgSchTddSfType   txSfType = 0;
25855
25856
25857    /* Get the RBs of TB that will be retransmitted */
25858    if (proc->tbInfo[0].state == HQ_TB_NACKED)
25859    {
25860       txSfType = proc->tbInfo[0].sfType;
25861
25862 #ifdef XEON_SPECIFIC_CHANGES
25863 #ifndef XEON_TDD_SPCL
25864       /* Avoid re-transmission on Normal SF when the corresponding TB wss transmitted on SPCL SF */
25865       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
25866       {
25867          return (TRUE);
25868       }
25869 #endif
25870 #endif
25871    }
25872    if (proc->tbInfo[1].state == HQ_TB_NACKED) 
25873    {
25874       /* Select the TxSf with the highest num of possible REs 
25875        * In ascending order -> 1) SPL SF 2) DL_SF_0 3) DL_SF */
25876       txSfType = RGSCH_MAX(txSfType, proc->tbInfo[1].sfType);
25877
25878 #ifdef XEON_SPECIFIC_CHANGES
25879 #ifndef XEON_TDD_SPCL
25880       /* Avoid re-transmission on Normal SF when the corresponding TB wss tranmitted on SPCL SF */
25881       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
25882       {
25883          return (TRUE);
25884       }
25885 #endif
25886 #endif
25887    }
25888
25889    if (txSfType > curSf->sfType)
25890    {
25891       /* Avoid retx */
25892       return (TRUE);
25893    }
25894    
25895    /* Allow Retx */
25896    return (FALSE);
25897 }
25898
25899 #else
25900 /* DwPTS Scheduling Changes End */
25901 \f
25902 /**
25903  * @brief Avoid allocating RETX incase of collision
25904  * with reserved resources for BCH/PSS/SSS occassions.
25905  *
25906  * @details
25907  *
25908  *     Function: rgSCHCmnRetxAllocAvoid 
25909  *     Purpose: Avoid allocating RETX incase of collision
25910  * with reserved resources for BCH/PSS/SSS occassions 
25911  *
25912  *     Invoked by: rgSCHCmnDlAllocRetxRb 
25913  *
25914  *  @param[in]  RgSchDlSf             *subFrm
25915  *  @param[in]  RgSchUeCb             *ue
25916  *  @param[in]  RgSchDlHqProcCb       *proc
25917  *  @return  Bool 
25918  *
25919  **/
25920 Bool rgSCHCmnRetxAllocAvoid 
25921 (
25922 RgSchDlSf                  *subFrm,
25923 RgSchCellCb                *cell,
25924 RgSchDlHqProcCb            *proc
25925 )
25926 {
25927    uint8_t          reqRbs;
25928
25929
25930    if (proc->tbInfo[0].state == HQ_TB_NACKED)
25931    {
25932       reqRbs = proc->tbInfo[0].dlGrnt.numRb;    
25933    }
25934    else
25935    {
25936       reqRbs = proc->tbInfo[1].dlGrnt.numRb;    
25937    }
25938    /* Consider the dlGrnt.numRb of the Retransmitting proc->tbInfo
25939     * and current available RBs to determine if this RETX TB
25940     * will collide with the BCH/PSS/SSS occassion */
25941    if (subFrm->sfNum % 5 == 0)
25942    {
25943       if ((subFrm->bwAssigned < cell->pbchRbEnd) &&
25944           (((subFrm->bwAssigned + reqRbs) - cell->pbchRbStart) > 0))
25945       {
25946          return (TRUE);
25947       }
25948    }
25949    return (FALSE);
25950 }
25951
25952 #endif
25953
25954 \f
25955 /**
25956  * @brief This function invokes the TM specific DL RETX RB Allocation routine.
25957  *
25958  * @details
25959  *
25960  *     Function: rgSCHCmnDlAllocRetxRb
25961  *     Purpose:  This function invokes the TM specific
25962  *               DL RETX RB Allocation routine.
25963  *
25964  *     Invoked by: Specific Schedulers
25965  *
25966  *  @param[in]  RgSchCellCb           *cell
25967  *  @param[in]  RgSchDlSf             *subFrm
25968  *  @param[in]  RgSchUeCb             *ue
25969  *  @param[in]  uint32_t                   bo
25970  *  @param[out] uint32_t                   *effBo
25971  *  @param[in]  RgSchDlHqProcCb       *proc
25972  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
25973  *  @return  S16
25974  *
25975  **/
25976 S16 rgSCHCmnDlAllocRetxRb
25977 (
25978 RgSchCellCb                *cell,
25979 RgSchDlSf                  *subFrm,
25980 RgSchUeCb                  *ue,
25981 uint32_t                   bo,
25982 uint32_t                   *effBo,
25983 RgSchDlHqProcCb            *proc,
25984 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
25985 )
25986 {
25987    uint32_t                     newSchBits = 0;
25988    RgSchDlRbAlloc          *allocInfo;
25989
25990
25991    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
25992    {
25993       ue->dl.aggTbBits = 0;
25994    }
25995  
25996    *effBo = 0;
25997    /* Check for DL BW exhaustion */
25998    if (subFrm->bw <= subFrm->bwAssigned)
25999    {
26000       return RFAILED;
26001    }
26002    /* Call TM specific RB allocation routine */
26003    (dlAllocRetxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
26004          proc, cellWdAllocInfo);
26005
26006    if (*effBo)
26007    {
26008       allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26009       /* Calculate totals bits newly allocated */
26010       if (allocInfo->tbInfo[0].schdlngForTb)
26011       {
26012          newSchBits += allocInfo->tbInfo[0].bytesReq;
26013       }
26014       if (allocInfo->tbInfo[1].schdlngForTb)
26015       {
26016          newSchBits += allocInfo->tbInfo[1].bytesReq;
26017       }
26018       ue->dl.aggTbBits += (newSchBits * 8);
26019       RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
26020    }
26021    
26022    return ROK;
26023 }
26024
26025 \f
26026 /**
26027  * @brief This function determines the RBs and Bytes required for
26028  *        Transmission on 1 CW.
26029  *
26030  * @details
26031  *
26032  *     Function: rgSCHCmnDlAlloc1CwTxRb
26033  *     Purpose:  This function determines the RBs and Bytes required
26034  *               for Transmission of DL SVC BO on 1 CW.
26035  *               Also, takes care of SVC by SVC allocation by tracking
26036  *               previous SVCs allocations.
26037  *               Returns RFAILED if BO not satisfied at all.
26038  *
26039  *     Invoked by: DL UE Allocation
26040  *
26041  *  @param[in]  RgSchCellCb      *cell
26042  *  @param[in]  RgSchDlSf        *subFrm
26043  *  @param[in]  RgSchUeCb        *ue
26044  *  @param[in]  RgSchDlHqTbCb    *tbInfo
26045  *  @param[in]  uint32_t              bo
26046  *  @param[out] uint8_t               *numRb
26047  *  @param[out] uint32_t              *effBo
26048  *  @return  S16
26049  *
26050  **/
26051 static S16 rgSCHCmnDlAlloc1CwTxRb
26052 (
26053 RgSchCellCb       *cell,
26054 RgSchDlSf         *subFrm,
26055 RgSchUeCb         *ue,
26056 RgSchDlHqTbCb     *tbInfo,
26057 uint32_t          bo,
26058 uint8_t           *numRb,
26059 uint32_t          *effBo
26060 )
26061 {
26062    uint32_t        tbSz;
26063    uint8_t         imcs;
26064    uint8_t         iTbs;
26065    RgSchCmnDlUe    *ueDl;
26066    RgSchDlRbAlloc  *allocInfo;
26067    uint32_t        oldReq;
26068    uint32_t        reqBytes;
26069    /* Correcting wrap around issue.
26070     * This change has been done at mutliple places in this function.*/
26071    uint32_t        tempNumRb;
26072
26073    reqBytes  = bo;
26074    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26075    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26076    oldReq    = ueDl->outStndAlloc;
26077
26078 #ifdef RG_5GTF
26079    //TODO_SID: Currently setting max Tb size wrt to 5GTF TM3
26080    iTbs = ue->ue5gtfCb.mcs;
26081    ueDl->maxTbSz = MAX_5GTF_TB_SIZE * ue->ue5gtfCb.rank;
26082    ueDl->maxRb = MAX_5GTF_PRBS;
26083 #endif
26084    ueDl->outStndAlloc += bo;
26085    /* consider Cumulative amount of this BO and bytes so far allocated */
26086    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbSz/8);
26087    /* Get the number of REs needed for this bo. */
26088    //noRes = ((bo * 8 * 1024) / eff);
26089
26090    /* Get the number of RBs needed for this transmission */
26091    /* Number of RBs = No of REs / No of REs per RB       */
26092    //tempNumRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
26093    tempNumRb = MAX_5GTF_PRBS;
26094    tbSz = RGSCH_MIN(bo, (rgSch5gtfTbSzTbl[iTbs]/8) * ue->ue5gtfCb.rank);
26095
26096    /* DwPts Scheduling Changes End */
26097    *effBo = RGSCH_MIN(tbSz - oldReq, reqBytes);
26098
26099 #ifdef RG_5GTF
26100    //RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs);
26101    imcs = iTbs;
26102 #endif
26103
26104
26105    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbSz, \
26106          iTbs, imcs, tbInfo, ue->ue5gtfCb.rank);
26107    *numRb = (uint8_t) tempNumRb;
26108    
26109    /* Update the subframe Allocated BW field */
26110    subFrm->bwAssigned = subFrm->bwAssigned + tempNumRb - allocInfo->rbsReq;
26111    
26112    return ROK;
26113 }
26114
26115 \f
26116 /**
26117  * @brief This function is invoked in the event of any TB's allocation
26118  *  being underutilized by the specific scheduler. Here we reduce iMcs
26119  *  to increase redundancy and hence increase reception quality at UE.
26120  *
26121  * @details
26122  *
26123  *     Function: rgSCHCmnRdcImcsTxTb
26124  *     Purpose:  This function shall reduce the iMcs in accordance with
26125  *               the total consumed bytes by the UE at allocation
26126  *               finalization.
26127  *
26128  *     Invoked by: UE DL Allocation finalization routine
26129  *                 of specific scheduler.
26130  *
26131  *  @param[in]  RgSchDlRbAlloc   *allocInfo
26132  *  @param[in]  uint8_t               tbInfoIdx
26133  *  @param[in]  uint32_t              cnsmdBytes
26134  *  @return  Void
26135  *
26136  **/
26137 Void rgSCHCmnRdcImcsTxTb
26138 (
26139 RgSchDlRbAlloc   *allocInfo,
26140 uint8_t          tbInfoIdx,
26141 uint32_t         cnsmdBytes
26142 )
26143 {
26144    return;
26145    /*The below functionality is not needed.*/
26146    uint8_t                 noLyr;
26147    uint8_t                 iTbs;
26148    uint16_t                numRb;
26149
26150
26151    iTbs = allocInfo->tbInfo[tbInfoIdx].iTbs;
26152    noLyr = allocInfo->tbInfo[tbInfoIdx].noLyr;
26153    numRb = allocInfo->rbsAlloc;
26154    if ( numRb > 0)
26155    {
26156       if ((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) == cnsmdBytes)
26157       {
26158          return;
26159       }
26160    }
26161    /* Get iTbs as suitable for the consumed bytes */
26162    while((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) > cnsmdBytes)
26163    {
26164       if (iTbs == 0)
26165       {
26166          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].\
26167                tbCb->dlGrnt.iMcs);
26168          return;
26169       }
26170       iTbs--;
26171    }
26172    iTbs++;
26173    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].tbCb->dlGrnt.iMcs);
26174
26175    return;
26176 }
26177
26178 \f
26179 /**
26180  * @brief This function determines the RBs and Bytes required for
26181  *        Transmission on 2 CWs.
26182  *
26183  * @details
26184  *
26185  *     Function: rgSCHCmnDlAlloc2CwTxRb
26186  *     Purpose:  This function determines the RBs and Bytes required
26187  *               for Transmission of DL SVC BO on 2 CWs.
26188  *               Also, takes care of SVC by SVC allocation by tracking
26189  *               previous SVCs allocations.
26190  *               Returns RFAILED if BO not satisfied at all.
26191  *
26192  *     Invoked by: TM3 and TM4 DL UE Allocation
26193  *
26194  *  @param[in]  RgSchCellCb      *cell
26195  *  @param[in]  RgSchDlSf        *subFrm
26196  *  @param[in]  RgSchUeCb        *ue
26197  *  @param[in]  RgSchDlHqProcCb  *proc
26198  *  @param[in]  RgSchDlHqProcCb  bo
26199  *  @param[out] uint8_t               *numRb
26200  *  @param[out] uint32_t              *effBo
26201  *  @return  Void
26202  *
26203  **/
26204 static S16 rgSCHCmnDlAlloc2CwTxRb
26205 (
26206 RgSchCellCb      *cell,
26207 RgSchDlSf        *subFrm,
26208 RgSchUeCb        *ue,
26209 RgSchDlHqProcCb  *proc,
26210 uint32_t         bo,
26211 uint8_t          *numRbRef,
26212 uint32_t         *effBo
26213 )
26214 {
26215    uint32_t       noRes;
26216    uint32_t       eff1, eff2;
26217    uint32_t       tb1Sz, tb2Sz;
26218    uint8_t        imcs1, imcs2;
26219    uint8_t        noLyr1, noLyr2;
26220    uint8_t        iTbs1, iTbs2;
26221    RgSchCmnDlCell *cellDl;
26222    RgSchCmnDlUe   *ueDl;
26223    RgSchDlRbAlloc *allocInfo;
26224    uint32_t       oldReq;
26225    uint32_t       reqBytes;
26226    /* Fix: MUE_PERTTI_DL */
26227    uint32_t       numRb;
26228    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
26229    uint8_t        cfi = cellSch->dl.currCfi;
26230    S16            availBw; 
26231    uint32_t       availBits = 0;
26232 #ifdef LTE_ADV
26233    uint32_t       boTmp = bo;
26234 #endif
26235
26236
26237    reqBytes  = bo;
26238    cellDl    = RG_SCH_CMN_GET_DL_CELL(cell);
26239    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26240    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26241    oldReq    = ueDl->outStndAlloc;
26242
26243    
26244    if (ueDl->maxTbBits > ue->dl.aggTbBits)
26245    {
26246       availBits = ueDl->maxTbBits - ue->dl.aggTbBits;
26247    }
26248    /* check if we can further allocate to this UE */
26249    if ((ue->dl.aggTbBits >= ueDl->maxTbBits) ||
26250          (allocInfo->tbInfo[0].bytesReq >= ueDl->maxTbSz/8) ||
26251          (allocInfo->tbInfo[1].bytesReq >= ueDl->maxTbSz/8) ||
26252          (allocInfo->rbsReq >= ueDl->maxRb))
26253    {
26254       DU_LOG("\nDEBUG  -->  SCH : rgSCHCmnDlAllocRb(): UEs max allocation exceed");
26255       return RFAILED;
26256    }
26257
26258    noLyr1 = ueDl->mimoInfo.cwInfo[0].noLyr;
26259    noLyr2 = ueDl->mimoInfo.cwInfo[1].noLyr;
26260
26261    /* If there is no CFI change, continue to use the BLER based
26262     * iTBS value */
26263    if (ueDl->lastCfi == cfi)
26264    {   
26265       iTbs1  = ueDl->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
26266       iTbs2  = ueDl->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
26267    }
26268    else
26269    {  
26270       uint8_t cqi = ueDl->mimoInfo.cwInfo[0].cqi;
26271 #ifdef LTE_TDD      
26272       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 0, noLyr1);
26273 #else      
26274       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 0, noLyr1);
26275 #endif         
26276
26277       cqi = ueDl->mimoInfo.cwInfo[1].cqi;
26278 #ifdef LTE_TDD      
26279       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 1, noLyr2);
26280 #else      
26281       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 1, noLyr2);
26282 #endif         
26283    } 
26284
26285    /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure
26286     * issue for VoLTE call */
26287    //if ((proc->hasDcch)  || (TRUE == rgSCHLaaSCellEnabled(cell)))
26288    if (proc->hasDcch)
26289    {
26290       if (iTbs1 > 5)
26291       {
26292          iTbs1  = iTbs1 - 5;
26293       }
26294       else
26295       {
26296          iTbs1  = 0; 
26297       }
26298       if (iTbs2 > 5)
26299       {
26300          iTbs2  = iTbs2 - 5;
26301       }
26302       else
26303       {
26304          iTbs2  = 0; 
26305       }
26306    }
26307    else if(!cellSch->dl.isDlFreqSel)
26308    {
26309 #ifdef LTE_TDD
26310       /* for Tdd reduce iTbs only for SF0. SF5 contains only 
26311        * SSS and can be ignored */
26312       if (subFrm->sfNum == 0)
26313       {
26314          (iTbs1 > 1)? (iTbs1 -= 1) : (iTbs1 = 0);
26315          (iTbs2 > 1)? (iTbs2 -= 1) : (iTbs2 = 0);
26316       }
26317       /* For SF 3 and 8 CRC is getting failed in DL.
26318          Need to do proper fix after the replay from 
26319          BRCM PHY team*/
26320 #ifdef CA_PHY_BRDCM_61765      
26321       if ((subFrm->sfNum == 3) || (subFrm->sfNum == 8))
26322       {
26323          (iTbs1 > 2)? (iTbs1 -= 2) : (iTbs1 = 0);
26324          (iTbs2 > 2)? (iTbs2 -= 2) : (iTbs2 = 0);
26325       }
26326 #endif
26327 #else
26328 #endif
26329    }
26330
26331 #ifdef LTE_TDD
26332    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
26333    {
26334       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
26335    }
26336 #endif 
26337
26338    eff1 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
26339    eff2 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
26340
26341
26342    bo = RGSCH_MIN(bo,availBits/8);
26343    ueDl->outStndAlloc += bo;
26344    /* consider Cumulative amount of this BO and bytes so far allocated */
26345    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbBits/8);
26346    bo = RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff1)/(eff1+eff2)), 
26347                   ueDl->maxTbSz/8) +
26348         RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff2)/(eff1+eff2)), 
26349                   (ueDl->maxTbSz)/8) +
26350         1; /* Add 1 to adjust the truncation at weighted averaging */
26351    /* Get the number of REs needed for this bo. */
26352    noRes = ((bo * 8 * 1024) / (eff1 + eff2));
26353
26354    /* Get the number of RBs needed for this transmission */
26355    /* Number of RBs = No of REs / No of REs per RB       */
26356    numRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
26357    /* Cannot exceed the maximum number of RBs per UE */
26358    if (numRb > ueDl->maxRb)
26359    {
26360       numRb = ueDl->maxRb;
26361    }
26362    else
26363    {
26364 #ifdef LTE_ADV
26365       if(RFAILED == rgSCHLaaCmn2CwAdjustPrb(allocInfo,  boTmp, &numRb, ueDl, noLyr1, noLyr2, iTbs1, iTbs2))
26366 #endif
26367       {
26368          while ((numRb <= ueDl->maxRb) &&
26369                (rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1] <= ueDl->maxTbSz) &&
26370                (rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1] <= ueDl->maxTbSz) &&
26371                ((rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8 +
26372                  rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8) <= bo))
26373          {
26374             (numRb)++;
26375          }
26376       }
26377    }
26378    availBw = subFrm->bw - subFrm->bwAssigned;
26379    /* Cannot exceed the total number of RBs in the cell */
26380    if ((S16)(numRb - allocInfo->rbsReq) > availBw)
26381    {
26382       numRb = availBw + allocInfo->rbsReq;
26383    }
26384    tb1Sz = rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8;
26385    tb2Sz = rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8;
26386    /* DwPts Scheduling Changes Start */
26387 #ifdef LTE_TDD
26388    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
26389    { 
26390       /* Max Rb for Special Sf is approximated as 4/3 of maxRb */
26391       rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, (uint8_t*)&numRb,  ueDl->maxRb*4/3, 
26392                                 &iTbs1, &iTbs2, noLyr1, 
26393                                 noLyr2, &tb1Sz, &tb2Sz, cfi);   
26394       /* Check for available Bw */
26395       if ((S16)numRb - allocInfo->rbsReq > availBw)
26396       {
26397          numRb = availBw + allocInfo->rbsReq;
26398          tb1Sz = rgTbSzTbl[noLyr1-1][iTbs1][RGSCH_MAX(numRb*3/4,1)-1]/8;
26399          tb2Sz = rgTbSzTbl[noLyr2-1][iTbs2][RGSCH_MAX(numRb*3/4,1)-1]/8;
26400       }
26401    }
26402 #endif
26403    /* DwPts Scheduling Changes End */
26404    /* Update the subframe Allocated BW field */
26405    subFrm->bwAssigned = subFrm->bwAssigned + numRb - \
26406                         allocInfo->rbsReq;
26407
26408    *effBo = RGSCH_MIN((tb1Sz + tb2Sz) - oldReq, reqBytes);
26409
26410 #ifdef LTE_ADV
26411    if (ROK != rgSCHLaaCmn2TBPrbCheck(allocInfo, tb1Sz, tb2Sz, boTmp, effBo, iTbs1, iTbs2, numRb, proc))
26412    {
26413       return RFAILED;
26414    }
26415 #endif
26416
26417    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs1, imcs1);
26418    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs2, imcs2);
26419    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tb1Sz, \
26420          iTbs1, imcs1, &proc->tbInfo[0], noLyr1);
26421    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
26422          iTbs2, imcs2, &proc->tbInfo[1], noLyr2);
26423    *numRbRef = (uint8_t)numRb;
26424
26425
26426    return ROK;
26427 }
26428
26429 \f
26430 /**
26431  * @brief This function determines the RBs and Bytes required for
26432  *        Transmission & Retransmission on 2 CWs.
26433  *
26434  * @details
26435  *
26436  *     Function: rgSCHCmnDlAlloc2CwTxRetxRb
26437  *     Purpose:  This function determines the RBs and Bytes required
26438  *               for Transmission & Retransmission on 2 CWs. Allocate
26439  *               RETX TB on a better CW and restrict new TX TB by
26440  *               RETX allocation.
26441  *               Returns RFAILED if BO not satisfied at all.
26442  *
26443  *     Invoked by: TM3 and TM4 DL UE Allocation
26444  *
26445  *  @param[in]  RgSchCellCb      *cell
26446  *  @param[in]  RgSchDlSf        *subFrm
26447  *  @param[in]  RgSchUeCb        *ue
26448  *  @param[in]  RgSchDlHqTbCb    *reTxTb
26449  *  @param[in]  RgSchDlHqTbCb    *txTb
26450  *  @param[out] uint8_t               *numRb
26451  *  @param[out] uint32_t              *effBo
26452  *  @return  Void
26453  *
26454  **/
26455 static S16 rgSCHCmnDlAlloc2CwTxRetxRb
26456 (
26457 RgSchCellCb     *cell,
26458 RgSchDlSf       *subFrm,
26459 RgSchUeCb       *ue,
26460 RgSchDlHqTbCb   *reTxTb,
26461 RgSchDlHqTbCb   *txTb,
26462 uint8_t         *numRb,
26463 uint32_t                        *effBo
26464 )
26465 {
26466    RgSchCmnDlUe       *ueDl;
26467    RgSchDlRbAlloc     *allocInfo;
26468    uint8_t            imcs1, imcs2;
26469    uint8_t            noLyr2;
26470    uint16_t           tb2Sz;
26471    RgSchCmnDlUeCwInfo *otherCw;
26472    S16                 availBw;
26473    RgSchCmnDlCell     *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
26474    uint8_t            cfi = cellDl->currCfi; 
26475    uint8_t            iTbs;
26476
26477
26478    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
26479    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26480    otherCw   = &ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)];
26481
26482
26483    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26484     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26485     * MCS.  */
26486    availBw = subFrm->bw - subFrm->bwAssigned; 
26487    *numRb = reTxTb->dlGrnt.numRb;
26488
26489 #ifdef XEON_TDD_SPCL
26490    *numRb = (reTxTb->initTxNumRbs);
26491    if(reTxTb->sfType == RG_SCH_SPL_SF_DATA && subFrm->sfType != RG_SCH_SPL_SF_DATA)
26492    {
26493       *numRb = (reTxTb->initTxNumRbs*3/4);
26494
26495       if(*numRb <= 3)
26496       {
26497          DU_LOG("\nERROR  -->  SCH : Number of RBs [%d] are less than or equal to 3",*numRb);
26498          return RFAILED;
26499       }
26500    }
26501 #endif
26502
26503    if ((S16)*numRb > availBw)
26504    {
26505       return RFAILED;
26506    }
26507    /* Update the subframe Allocated BW field */
26508    subFrm->bwAssigned += *numRb;
26509    noLyr2 = otherCw->noLyr;
26510    RG_SCH_CMN_GET_MCS_FOR_RETX(reTxTb, imcs1);
26511
26512    /* If there is no CFI change, continue to use the BLER based
26513     * iTBS value */
26514    if (ueDl->lastCfi == cfi)
26515    {   
26516       iTbs = otherCw->iTbs[noLyr2-1];
26517    }
26518    else
26519    {  
26520 #ifdef LTE_TDD      
26521       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, otherCw->cqi, cfi, 
26522                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
26523 #else      
26524       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, otherCw->cqi, cfi, 
26525                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
26526 #endif 
26527    } 
26528    tb2Sz = rgTbSzTbl[noLyr2-1][iTbs][*numRb-1]/8;
26529    /* DwPts Scheduling Changes Start */
26530 #ifdef LTE_TDD
26531 #endif
26532    /* DwPts Scheduling Changes End */
26533    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs2);
26534    
26535    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], reTxTb->tbSz, \
26536                               0, imcs1, reTxTb, reTxTb->numLyrs);
26537    
26538    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
26539                               iTbs, imcs2, txTb, noLyr2);
26540    
26541    *effBo = reTxTb->tbSz + tb2Sz;
26542
26543    return ROK;
26544 }
26545
26546 \f
26547 /**
26548  * @brief This function determines the RBs and Bytes required for BO
26549  *        Retransmission on 2 CWs.
26550  *
26551  * @details
26552  *
26553  *     Function: rgSCHCmnDlAlloc2CwRetxRb
26554  *     Purpose:  This function determines the RBs and Bytes required
26555  *               for BO Retransmission on 2 CWs. Allocate larger TB
26556  *               on a better CW and check if the smaller TB can be
26557  *               accomodated on the other CW.
26558  *               Returns RFAILED if BO not satisfied at all.
26559  *
26560  *     Invoked by: Common Scheduler
26561  *
26562  *  @param[in]  RgSchCellCb      *cell
26563  *  @param[in]  RgSchDlSf        *subFrm
26564  *  @param[in]  RgSchUeCb        *ue
26565  *  @param[in]  RgSchDlHqProcCb  *proc
26566  *  @param[out] uint8_t               *numRb
26567  *  @param[out] Bool             *swpFlg
26568  *  @param[out] uint32_t              *effBo
26569  *  @return  Void
26570  *
26571  **/
26572 static S16 rgSCHCmnDlAlloc2CwRetxRb
26573 (
26574 RgSchCellCb      *cell,
26575 RgSchDlSf        *subFrm,
26576 RgSchUeCb        *ue,
26577 RgSchDlHqProcCb  *proc,
26578 uint8_t          *numRb,
26579 Bool             *swpFlg,
26580 uint32_t         *effBo
26581 )
26582 {
26583    RgSchDlRbAlloc  *allocInfo;
26584    uint8_t         imcs1;
26585    uint8_t         imcs2;
26586    RgSchDlHqTbCb   *lrgTbInfo, *othrTbInfo;
26587
26588
26589    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26590
26591
26592    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26593     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26594     * MCS.  */
26595    lrgTbInfo  = &proc->tbInfo[0];
26596    othrTbInfo = &proc->tbInfo[1];
26597    *numRb = lrgTbInfo->dlGrnt.numRb;
26598 #ifdef XEON_TDD_SPCL
26599    if((lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA || othrTbInfo->sfType == RG_SCH_SPL_SF_DATA))
26600    {
26601       if(lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA)
26602       {       
26603           *numRb = (lrgTbInfo->initTxNumRbs);
26604       }
26605       else
26606       {
26607           *numRb = (othrTbInfo->initTxNumRbs);
26608       }
26609
26610       if(subFrm->sfType != RG_SCH_SPL_SF_DATA)
26611       {
26612          *numRb = (*numRb)*3/4;
26613       }
26614        
26615       if(*numRb <= 3)
26616       {
26617          DU_LOG("\nERROR  -->  SCH :  Number of RBs [%d] are less than or equal to 3",*numRb);
26618          return RFAILED;
26619       }
26620    }
26621 #endif
26622    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
26623    {
26624       return RFAILED;
26625    }
26626    /* Update the subframe Allocated BW field */
26627    subFrm->bwAssigned += *numRb;
26628    RG_SCH_CMN_GET_MCS_FOR_RETX(lrgTbInfo, imcs1);
26629    RG_SCH_CMN_GET_MCS_FOR_RETX(othrTbInfo, imcs2);
26630    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], lrgTbInfo->tbSz, \
26631          0, imcs1, lrgTbInfo, lrgTbInfo->numLyrs);
26632    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], othrTbInfo->tbSz, \
26633          0, imcs2, othrTbInfo, othrTbInfo->numLyrs);
26634    *effBo = lrgTbInfo->tbSz + othrTbInfo->tbSz;
26635
26636
26637
26638    return ROK;
26639 }
26640
26641 \f
26642 /**
26643  * @brief This function determines the RBs and Bytes required for BO
26644  *        Retransmission on 1 CW.
26645  *
26646  * @details
26647  *
26648  *     Function: rgSCHCmnDlAlloc1CwRetxRb
26649  *     Purpose:  This function determines the RBs and Bytes required
26650  *               for BO Retransmission on 1 CW, the first CW.
26651  *               Returns RFAILED if BO not satisfied at all.
26652  *
26653  *     Invoked by: Common Scheduler
26654  *
26655  *  @param[in]  RgSchCellCb      *cell
26656  *  @param[in]  RgSchDlSf        *subFrm
26657  *  @param[in]  RgSchUeCb        *ue
26658  *  @param[in]  RgSchDlHqTbCb    *tbInfo
26659  *  @param[in]  uint8_t               noLyr
26660  *  @param[out] uint8_t               *numRb
26661  *  @param[out] uint32_t              *effBo
26662  *  @return  S16
26663  *
26664  **/
26665 static S16 rgSCHCmnDlAlloc1CwRetxRb
26666 (
26667 RgSchCellCb    *cell,
26668 RgSchDlSf      *subFrm,
26669 RgSchUeCb      *ue,
26670 RgSchDlHqTbCb  *tbInfo,
26671 uint8_t        noLyr,
26672 uint8_t        *numRb,
26673 uint32_t       *effBo
26674 )
26675 {
26676    RgSchDlRbAlloc  *allocInfo;
26677    uint8_t              imcs;
26678
26679
26680    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26681
26682
26683    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
26684     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
26685     * MCS.  */
26686    *numRb = tbInfo->dlGrnt.numRb;
26687    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
26688    {
26689       return RFAILED;
26690    }
26691    /* Update the subframe Allocated BW field */
26692    subFrm->bwAssigned += *numRb;
26693    imcs = tbInfo->dlGrnt.iMcs;
26694    allocInfo->dciFormat = tbInfo->dlGrnt.dciFormat; 
26695    /* Fix: For a RETX TB the iTbs is irrelevant, hence setting 0 */
26696    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbInfo->tbSz, \
26697          0, imcs, tbInfo, tbInfo->numLyrs);
26698    *effBo = tbInfo->tbSz;
26699
26700    return ROK;
26701 }
26702
26703 #ifdef LTEMAC_SPS
26704
26705 /**
26706  * @brief This function is called to handle Release PDCCH feedback for SPS UE
26707  *
26708  * @details
26709  *
26710  *     Function: rgSCHCmnDlRelPdcchFbk
26711  *     Purpose:  Invokes SPS module to handle release PDCCH feedback
26712  *
26713  *     Invoked by: DHM
26714  *
26715  *  @param[in]   RgSchCellCb     *cell
26716  *  @param[in]   RgSchUeCb       *ue
26717  *  @param[in]   Bool            isAck
26718  *  @return  Void
26719  *
26720  **/
26721 Void rgSCHCmnDlRelPdcchFbk
26722 (
26723 RgSchCellCb        *cell,
26724 RgSchUeCb          *ue,
26725 Bool               isAck
26726 )
26727 {
26728
26729    rgSCHCmnSpsDlRelPdcchFbk(cell, ue, isAck);
26730    return;
26731
26732 }
26733
26734
26735 /**
26736  * @brief This function is invoked to handle Ack processing for a HARQ proc.
26737  *
26738  * @details
26739  *
26740  *     Function: rgSCHCmnDlProcAck
26741  *     Purpose:  DTX processing for HARQ proc
26742  *
26743  *     Invoked by: DHM
26744  *
26745  *  @param[in]   RgSchCellCb     *cell
26746  *  @param[in]   RgSchDlHqProcCb *hqP
26747  *  @return  Void
26748  *
26749  **/
26750 Void rgSCHCmnDlProcAck
26751 (
26752 RgSchCellCb        *cell,
26753 RgSchDlHqProcCb    *hqP
26754 )
26755 {
26756
26757
26758    if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
26759    {
26760       /* Invoke SPS module if SPS service was scheduled for this HARQ proc */
26761       rgSCHCmnSpsDlProcAck(cell, hqP);
26762    }
26763    return;
26764 }
26765 #ifdef RGSCH_SPS_STATS
26766 uint32_t rgSchStatCrntiCeRcvCnt;
26767 #endif
26768 /**
26769  * @brief This function is invoked to handle CRNTI CE reception for an UE
26770  *
26771  * @details
26772  *
26773  *     Function: rgSCHCmnHdlCrntiCE
26774  *     Purpose:  Handle CRNTI CE reception
26775  *
26776  *     Invoked by: DHM
26777  *
26778  *  @param[in]   RgSchCellCb     *cell
26779  *  @param[in]   RgSchDlHqProcCb *hqP
26780  *  @return  Void
26781  *
26782  **/
26783 Void rgSCHCmnHdlCrntiCE
26784 (
26785 RgSchCellCb        *cell,
26786 RgSchUeCb          *ue
26787 )
26788 {
26789
26790 #ifdef RGSCH_SPS_STATS   
26791    rgSchStatCrntiCeRcvCnt++;
26792 #endif
26793
26794    /* When UL sync lost happened due to TA timer expiry UE is being moved to 
26795       PDCCH order inactivity list.But when CRNTI CE received in msg3 from UE
26796       we are not moving UE into active state due to that RRC Reconfiguration is
26797       not happening.
26798       So here we are moving UE to active list whenever we receive the CRNTI CE and
26799       UE is inactive */
26800    /* CR ccpu00144525 */      
26801    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
26802    {
26803        /* Activate this UE if it was inactive */
26804        RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
26805        RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
26806    }
26807
26808    /* Handling is same as reception of UE RESET for both DL and UL */
26809    if (ue->dl.dlSpsCfg.isDlSpsEnabled)
26810    {
26811       rgSCHCmnSpsDlUeReset(cell, ue);
26812    }
26813    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26814    {
26815       rgSCHCmnSpsUlUeReset(cell, ue);
26816    }
26817    
26818    return;
26819 }
26820
26821
26822 /**
26823  * @brief This function is called to handle relInd from MAC for a UE
26824  *
26825  * @details
26826  *
26827  *     Function: rgSCHCmnUlSpsRelInd
26828  *     Purpose:  Invokes SPS module to handle UL SPS release for a UE
26829  *
26830  *     Invoked by: SCH_UTL
26831  *
26832  *  @param[in]   RgSchCellCb        *cell
26833  *  @param[in]   RgSchUeCb          *ue
26834  *  @param[in]   Bool               isExplRel
26835  *  @return  Void
26836  *
26837  **/
26838 Void rgSCHCmnUlSpsRelInd
26839 (
26840 RgSchCellCb        *cell,
26841 RgSchUeCb          *ue,
26842 Bool               isExplRel
26843 )
26844 {
26845
26846    rgSCHCmnSpsUlProcRelInd(cell, ue, isExplRel);
26847    return;
26848
26849 } /* end of rgSCHCmnUlSpsRelInd */
26850
26851 /**
26852  * @brief This function is called to handle SPS Activate Ind from MAC for a UE
26853  *
26854  * @details
26855  *
26856  *     Function: rgSCHCmnUlSpsActInd
26857  *     Purpose:  Invokes SPS module to handle UL SPS activate for a UE
26858  *
26859  *     Invoked by: SCH_UTL
26860  *
26861  *  @param[in]   RgSchCellCb        *cell
26862  *  @param[in]   RgSchUeCb          *ue
26863  *  @return  Void
26864  *
26865  **/
26866 Void rgSCHCmnUlSpsActInd
26867 (
26868 RgSchCellCb     *cell,
26869 RgSchUeCb       *ue,
26870 uint16_t        spsSduSize
26871 )
26872 {
26873
26874
26875    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26876    {
26877       rgSCHCmnSpsUlProcActInd(cell, ue,spsSduSize);
26878    }
26879    return;
26880
26881 } /* end of rgSCHCmnUlSpsActInd */
26882
26883 /**
26884  * @brief This function is called to handle CRC in UL for UEs
26885  * undergoing SPS release
26886  *
26887  * @details
26888  *
26889  *     Function: rgSCHCmnUlCrcInd
26890  *     Purpose:  Invokes SPS module to handle CRC in UL for SPS UE
26891  *
26892  *     Invoked by: SCH_UTL
26893  *
26894  *  @param[in]   RgSchCellCb        *cell
26895  *  @param[in]   RgSchUeCb          *ue
26896  *  @param[in]   CmLteTimingInfo    crcTime
26897  *  @return  Void
26898  *
26899  **/
26900 Void rgSCHCmnUlCrcInd
26901 (
26902 RgSchCellCb        *cell,
26903 RgSchUeCb          *ue,
26904 CmLteTimingInfo    crcTime
26905 )
26906 {
26907
26908    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26909    {
26910       rgSCHCmnSpsUlProcCrcInd(cell, ue, crcTime);
26911    }
26912    return;
26913
26914 } /* end of rgSCHCmnUlCrcFailInd */
26915
26916 /**
26917  * @brief This function is called to handle CRC failure in UL
26918  *
26919  * @details
26920  *
26921  *     Function: rgSCHCmnUlCrcFailInd
26922  *     Purpose:  Invokes SPS module to handle CRC failure in UL for SPS UE
26923  *
26924  *     Invoked by: SCH_UTL
26925  *
26926  *  @param[in]   RgSchCellCb        *cell
26927  *  @param[in]   RgSchUeCb          *ue
26928  *  @param[in]   CmLteTimingInfo    crcTime
26929  *  @return  Void
26930  *
26931  **/
26932 Void rgSCHCmnUlCrcFailInd
26933 (
26934 RgSchCellCb        *cell,
26935 RgSchUeCb          *ue,
26936 CmLteTimingInfo    crcTime
26937 )
26938 {
26939
26940    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
26941    {
26942       rgSCHCmnSpsUlProcDtxInd(cell, ue, crcTime);
26943    }
26944    return;
26945
26946 } /* end of rgSCHCmnUlCrcFailInd */
26947
26948 #endif /* LTEMAC_SPS */
26949
26950 /**
26951  * @brief BCH,BCCH,PCCH Dowlink Scheduling Handler.
26952  *
26953  * @details
26954  *
26955  *     Function: rgSCHCmnDlBcchPcchAlloc
26956  *     Purpose:  This function calls common scheduler APIs to
26957  *     schedule for BCCH/PCCH.
26958  *     It then invokes Allocator for actual RB
26959  *     allocations. It processes on the actual resources allocated
26960  *     against requested to the allocator module.
26961  *
26962  *     Invoked by: Common Scheduler
26963  *
26964  *  @param[in]  RgSchCellCb *cell
26965  *  @return  Void
26966  **/
26967 static Void rgSCHCmnDlBcchPcchAlloc(RgSchCellCb  *cell)
26968 {
26969 #ifdef LTE_TDD
26970    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
26971 #else
26972 #ifdef LTEMAC_HDFDD
26973    uint8_t           nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
26974 #else
26975    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
26976 #endif
26977 #endif
26978    RgInfSfAlloc *nextsfAlloc = &(cell->sfAllocArr[nextSfIdx]);
26979    RgSchCmnCell           *cellSch   = RG_SCH_CMN_GET_CELL(cell);
26980    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo;  
26981    
26982
26983
26984    /*Reset the bitmask for BCCH/PCCH*/
26985    rgSCHUtlResetSfAlloc(nextsfAlloc,TRUE,FALSE);
26986 #ifndef DISABLE_MIB_SIB /* Not sending MIB and SIB to CL */
26987 #ifdef RGR_SI_SCH
26988    rgSCHChkNUpdSiCfg(cell);
26989    rgSCHSelectSi(cell);
26990 #endif
26991
26992    /*Perform the scheduling for BCCH,PCCH*/
26993    rgSCHCmnDlBcchPcch(cell, allocInfo, nextsfAlloc);
26994
26995    /* Call common allocator for RB Allocation */
26996    rgSCHBcchPcchDlRbAlloc(cell, allocInfo);
26997
26998    /* Finalize the Allocations for reqested Against alloced */
26999    rgSCHCmnDlBcchPcchFnlz(cell, allocInfo);
27000 #endif /* DISABLE_MIB_SIB */
27001    return;
27002 }
27003
27004 /**
27005  * @brief Handles RB allocation for BCCH/PCCH for downlink.
27006  *
27007  * @details
27008  *
27009  *     Function : rgSCHBcchPcchDlRbAlloc
27010  *
27011  *     Invoking Module Processing:
27012  *     - This function is invoked for DL RB allocation of BCCH/PCCH
27013  *
27014  *     Processing Steps:
27015  *     - If cell is frequency selecive,
27016  *       - Call rgSCHDlfsBcchPcchAllocRb().
27017  *     - else,
27018  *       - Do the processing
27019  *
27020  *  @param[in]  RgSchCellCb        *cell
27021  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
27022  *  @return  Void
27023  **/
27024
27025 static Void rgSCHBcchPcchDlRbAlloc
27026 (
27027 RgSchCellCb           *cell,
27028 RgSchCmnDlRbAllocInfo *allocInfo
27029 )
27030 {
27031    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
27032
27033
27034
27035    if (cellSch->dl.isDlFreqSel)
27036    {
27037       cellSch->apisDlfs->rgSCHDlfsBcchPcchAllocRb(cell, allocInfo);
27038    }
27039    else
27040    {
27041       rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo);
27042    }
27043
27044    return;
27045 }
27046
27047 /**
27048  * @brief Handles RB allocation for BCCH,PCCH for frequency
27049  *  non-selective cell.
27050  *
27051  * @details
27052  *
27053  *     Function : rgSCHCmnNonDlfsBcchPcchRbAlloc
27054  *
27055  *     Invoking Module Processing:
27056  *      - SCH shall invoke this if downlink frequency selective is disabled for
27057  *        the cell for RB allocation.
27058  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
27059  *        estimate and subframe for each allocation to be made to SCH.
27060  *
27061  *     Processing Steps:
27062  *     - Allocate sequentially for BCCH,PCCH common channels.
27063  *
27064  *  @param[in]  RgSchCellCb        *cell
27065  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
27066  *  @return  Void
27067  **/
27068
27069 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc
27070 (
27071 RgSchCellCb           *cell,
27072 RgSchCmnDlRbAllocInfo *allocInfo
27073 )
27074 {
27075    RgSchDlRbAlloc     *reqAllocInfo;
27076
27077
27078    /* 143473 */
27079    /* Allocate for PCCH */
27080    reqAllocInfo = &(allocInfo->pcchAlloc);
27081    if (reqAllocInfo->rbsReq)
27082    {
27083       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
27084    }
27085    /* Allocate for BCCH on DLSCH */
27086    reqAllocInfo = &(allocInfo->bcchAlloc);
27087    if (reqAllocInfo->rbsReq)
27088    {
27089       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
27090    }
27091    return;
27092 }
27093
27094
27095 #ifdef RGR_SI_SCH
27096 /**
27097  * @brief This function implements the handling to check and
27098  *        update the SI cfg at the start of the modificiation period.
27099  *
27100  * @details
27101  *
27102  *     Function: rgSCHChkNUpdSiCfg
27103  *     Purpose:  This function implements handling for update of SI Cfg
27104  *               at the start of modification period.
27105  *
27106  *     Invoked by: Scheduler
27107  *
27108  *  @param[in]  RgSchCellCb*     cell
27109  *  @return  S16
27110  *      -# ROK
27111  *      -# RFAILED
27112  **/
27113 static Void rgSCHChkNUpdSiCfg
27114 (
27115 RgSchCellCb             *cell
27116 )
27117 {
27118    CmLteTimingInfo   pdSchTmInfo;
27119
27120
27121
27122    pdSchTmInfo   = cell->crntTime;
27123 #ifdef LTEMAC_HDFDD
27124    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27125       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27126    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27127 #else
27128    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA);
27129 #endif
27130
27131
27132    /* Updating the SIB1 for Warning SI message immediately after it is received 
27133     * from application. No need to wait for next modification period.
27134     */
27135    if((pdSchTmInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
27136          && (RGSCH_SIB1_TX_SF_NUM == (pdSchTmInfo.slot % RGSCH_NUM_SUB_FRAMES)))
27137    {   
27138       /*Check whether SIB1 with PWS has been updated*/
27139       if(cell->siCb.siBitMask & RGSCH_SI_SIB1_PWS_UPD)
27140       {
27141          RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
27142                cell->siCb.newSiInfo.sib1Info.sib1);
27143          cell->siCb.crntSiInfo.sib1Info.mcs = 
27144             cell->siCb.newSiInfo.sib1Info.mcs;
27145          cell->siCb.crntSiInfo.sib1Info.nPrb = 
27146              cell->siCb.newSiInfo.sib1Info.nPrb;
27147          cell->siCb.crntSiInfo.sib1Info.msgLen = 
27148             cell->siCb.newSiInfo.sib1Info.msgLen;
27149          cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_PWS_UPD;
27150       }
27151    }
27152
27153    /*Check if this SFN and SF No marks the start of next modification
27154      period. If current SFN,SF No doesn't marks the start of next
27155      modification period, then return. */
27156    if(!((pdSchTmInfo.sfn % cell->siCfg.modPrd == 0)
27157             && (0 == pdSchTmInfo.slot)))
27158    /*if(!((((pdSchTmInfo.hSfn * 1024) + pdSchTmInfo.sfn) % cell->siCfg.modPrd == 0)
27159             && (0 == pdSchTmInfo.slot)))*/
27160    {
27161       return;
27162    }
27163
27164    /*Check whether MIB has been updated*/
27165    if(cell->siCb.siBitMask & RGSCH_SI_MIB_UPD)
27166    {
27167       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.mib,
27168             cell->siCb.newSiInfo.mib);
27169       cell->siCb.siBitMask &= ~RGSCH_SI_MIB_UPD;
27170    }
27171
27172    /*Check whether SIB1 has been updated*/
27173    if(cell->siCb.siBitMask & RGSCH_SI_SIB1_UPD)
27174    {
27175       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
27176             cell->siCb.newSiInfo.sib1Info.sib1);
27177       cell->siCb.crntSiInfo.sib1Info.mcs = cell->siCb.newSiInfo.sib1Info.mcs;
27178       cell->siCb.crntSiInfo.sib1Info.nPrb = cell->siCb.newSiInfo.sib1Info.nPrb;
27179       cell->siCb.crntSiInfo.sib1Info.msgLen = 
27180          cell->siCb.newSiInfo.sib1Info.msgLen;
27181       cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_UPD;
27182    }
27183
27184    /*Check whether SIs have been updated*/
27185    if(cell->siCb.siBitMask & RGSCH_SI_SI_UPD)
27186    {
27187       uint8_t  idx;
27188
27189       /*Check if SI cfg have been modified And Check if numSi have
27190         been changed, if yes then we would need to update the
27191         pointers for all the SIs */
27192       if((cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) &&
27193             (cell->siCfg.numSi != cell->siCb.newSiCfg.numSi))
27194       {
27195          for(idx = 0;idx < cell->siCb.newSiCfg.numSi;idx++)
27196          {
27197             RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
27198                   cell->siCb.newSiInfo.siInfo[idx].si);
27199             cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
27200             cell->siCb.siArray[idx].isWarningSi = FALSE;
27201
27202             cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
27203             cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
27204             cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
27205          }
27206
27207          /*If numSi have been reduced then we need to free the
27208            pointers at the indexes in crntSiInfo which haven't
27209            been exercised. If numSi has increased then nothing
27210            additional is requires as above handling has taken
27211            care.*/
27212          if(cell->siCfg.numSi > cell->siCb.newSiCfg.numSi)
27213          {
27214             for(idx = cell->siCb.newSiCfg.numSi;
27215                   idx < cell->siCfg.numSi;idx++)
27216             {
27217                RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si);
27218                cell->siCb.siArray[idx].si = NULLP;
27219             }
27220          }
27221       }
27222       else
27223       {
27224          /*numSi has not been updated, we just need to update the
27225            pointers for the SIs which are set to NON NULLP */
27226          /*ccpu00118260 - Correct Update of SIB2 */
27227          for(idx = 0;idx < cell->siCfg.numSi;idx++)
27228          {
27229             if(NULLP != cell->siCb.newSiInfo.siInfo[idx].si)
27230             {
27231                RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
27232                      cell->siCb.newSiInfo.siInfo[idx].si);
27233
27234                cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
27235                cell->siCb.siArray[idx].isWarningSi = FALSE;
27236                cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
27237                cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
27238                cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
27239             }
27240          }
27241       }
27242       cell->siCb.siBitMask &= ~RGSCH_SI_SI_UPD;
27243    }
27244
27245    /*Check whether SI cfg have been updated*/
27246    if(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD)
27247    {
27248       cell->siCfg = cell->siCb.newSiCfg;
27249       cell->siCb.siBitMask &= ~RGSCH_SI_SICFG_UPD;
27250    }
27251
27252    return;
27253 }
27254
27255
27256 /**
27257  * @brief This function implements the selection of the SI
27258  *        that is to be scheduled.
27259  *
27260  * @details
27261  *
27262  *     Function: rgSCHSelectSi
27263  *     Purpose:  This function implements the selection of SI
27264  *               that is to be scheduled.
27265  *
27266  *     Invoked by: Scheduler
27267  *
27268  *  @param[in]  RgSchCellCb*     cell
27269  *  @return  S16
27270  *      -# ROK
27271  *      -# RFAILED
27272  **/
27273 static Void rgSCHSelectSi
27274 (
27275 RgSchCellCb             *cell
27276 )
27277 {
27278    CmLteTimingInfo crntTmInfo;
27279    uint8_t         siWinSize;
27280    uint16_t        x; 
27281    uint16_t        windowId; 
27282
27283
27284
27285    crntTmInfo  = cell->crntTime;
27286 #ifdef LTEMAC_HDFDD
27287    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27288       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27289    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27290 #else
27291    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA);
27292 #endif
27293
27294    siWinSize    = cell->siCfg.siWinSize;
27295
27296    /* Select SI only once at the starting of the new window */
27297    if(cell->siCb.inWindow)
27298    {
27299       if ((crntTmInfo.sfn % cell->siCfg.minPeriodicity) == 0 && 
27300           crntTmInfo.slot == 0)
27301       {
27302          /* Reinit inWindow at the beginning of every SI window */
27303          cell->siCb.inWindow = siWinSize - 1;
27304       }
27305       else
27306       {
27307          cell->siCb.inWindow--;
27308          return;
27309       }
27310    }
27311    else /* New window. Re-init the winSize counter with the window length */
27312    {
27313       if((cell->siCb.siArray[cell->siCb.siCtx.siId - 1].isWarningSi == TRUE)&&
27314             (cell->siCb.siCtx.retxCntRem != 0))   
27315       {
27316          rgSCHUtlFreeWarningSiPdu(cell);
27317          cell->siCb.siCtx.warningSiFlag  = FALSE;
27318       }
27319
27320       cell->siCb.inWindow = siWinSize - 1;
27321    }
27322
27323    x = rgSCHCmnGetSiSetId(crntTmInfo.sfn, crntTmInfo.slot, 
27324                                   cell->siCfg.minPeriodicity); 
27325
27326    /* Window Id within a SI set. This window Id directly maps to a
27327     * unique SI Id */
27328    windowId = (((crntTmInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + 
27329             crntTmInfo.slot) - (x * (cell->siCfg.minPeriodicity * 10))) 
27330                                                                / siWinSize;
27331
27332    if(windowId >= RGR_MAX_NUM_SI)
27333       return;
27334
27335    /* Update the siCtx if there is a valid SI and its periodicity
27336     * has occurred */
27337    if (NULLP != cell->siCb.siArray[windowId].si)
27338    {
27339       /* Warning SI Periodicity is same as SIB2 Periodicity */
27340       if(((cell->siCb.siArray[windowId].isWarningSi == FALSE) && 
27341                (x % (cell->siCfg.siPeriodicity[windowId]
27342                      /cell->siCfg.minPeriodicity) == 0)) || 
27343             ((cell->siCb.siArray[windowId].isWarningSi == TRUE) &&
27344              (x % (cell->siCfg.siPeriodicity[0]
27345                    /cell->siCfg.minPeriodicity) == 0)))
27346       {
27347          cell->siCb.siCtx.siId = windowId+1;
27348          cell->siCb.siCtx.retxCntRem = cell->siCfg.retxCnt;
27349          cell->siCb.siCtx.warningSiFlag = cell->siCb.siArray[windowId].
27350                                                            isWarningSi;
27351          cell->siCb.siCtx.timeToTx.sfn = crntTmInfo.sfn;
27352          cell->siCb.siCtx.timeToTx.slot = crntTmInfo.slot;
27353
27354          RG_SCH_ADD_TO_CRNT_TIME(cell->siCb.siCtx.timeToTx,
27355                cell->siCb.siCtx.maxTimeToTx, (siWinSize - 1))
27356       }
27357    }
27358    else
27359    {/* Update the siCtx with invalid si Id */
27360       cell->siCb.siCtx.siId = 0;
27361    }
27362
27363    return;
27364 }
27365
27366
27367 /**
27368  * @brief This function implements scheduler DL allocation for
27369  *        SI.
27370  *
27371  * @details
27372  *
27373  *     Function: rgSCHDlSiSched
27374  *     Purpose:  This function implements scheduler for DL allocation
27375  *               for SI.
27376  *
27377  *     Invoked by: Scheduler
27378  *
27379  *  @param[in]  RgSchCellCb*     cell
27380  *  @return  S16
27381  *      -# ROK
27382  *      -# RFAILED
27383  **/
27384 static Void rgSCHDlSiSched
27385 (
27386 RgSchCellCb             *cell,
27387 RgSchCmnDlRbAllocInfo   *allocInfo,
27388 RgInfSfAlloc            *subfrmAlloc
27389 )
27390 {
27391    CmLteTimingInfo   crntTimInfo;
27392    RgSchDlSf         *sf;
27393    uint8_t           nPrb = 0;
27394    uint8_t           mcs  = 0;
27395    MsgLen            msgLen = 0;
27396    uint32_t          rb=0;
27397    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
27398    /* DwPTS Scheduling Changes Start */
27399 #ifdef LTE_TDD   
27400    uint16_t          lostRe;  
27401    uint8_t           cfi = cellDl->currCfi;      
27402 #endif
27403    /* DwPTS Scheduling Changes End */
27404
27405
27406
27407    crntTimInfo   = cell->crntTime;
27408 #ifdef LTEMAC_HDFDD
27409    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
27410       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
27411    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
27412 #else
27413    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA);
27414 #endif
27415
27416    /* Compute the subframe for which allocation is being made.
27417       Essentially, we need pointer to the dl frame for this subframe */
27418    sf = rgSCHUtlSubFrmGet(cell, crntTimInfo);
27419
27420    /*Check if scheduling of MIB is required */
27421 #ifdef EMTC_ENABLE
27422    /* since we are adding the MIB repetition logic for EMTC UEs, checking if
27423     * emtcEnabled or not,  If enabled MIB would be repeted at as part of EMTC
27424     * feature, otherwise scheduling at (n,0) */
27425    if(0 == cell->emtcEnable)
27426    {
27427 #endif
27428    if((crntTimInfo.sfn % RGSCH_MIB_PERIODICITY == 0)
27429          && (RGSCH_MIB_TX_SF_NUM == crntTimInfo.slot))
27430    {
27431       MsgLen  mibLen = 0;
27432       uint8_t      sfnOctet, mibOct2 = 0;
27433       uint8_t      mibOct1 = 0;
27434       /*If MIB has not been yet setup by Application, return*/
27435       if(NULLP == cell->siCb.crntSiInfo.mib)
27436          return;
27437
27438       SFndLenMsg(cell->siCb.crntSiInfo.mib, &mibLen);
27439       sf->bch.tbSize = mibLen;
27440       /*Fill the interface information */
27441       rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, NULLD, NULLD);
27442
27443       /*Set the bits of MIB to reflect SFN */
27444       /*First get the Most signficant 8 bits of SFN */
27445       sfnOctet = (uint8_t)(crntTimInfo.sfn >> 2);
27446       /*Get the first two octets of MIB, and then update them
27447         using the SFN octet value obtained above.*/
27448       if(ROK != SExamMsg((Data *)(&mibOct1),
27449                cell->siCb.crntSiInfo.mib, 0))
27450          return;
27451
27452       if(ROK != SExamMsg((Data *)(&mibOct2),
27453                cell->siCb.crntSiInfo.mib, 1))
27454          return;
27455
27456       /* ccpu00114572- Fix for improper way of MIB Octet setting for SFN */
27457       mibOct1 = (mibOct1 & 0xFC) | (sfnOctet >> 6);
27458       mibOct2 = (mibOct2 & 0x03) | (sfnOctet << 2);
27459       /* ccpu00114572- Fix ends*/
27460
27461       /*Now, replace the two octets in MIB */
27462       if(ROK != SRepMsg((Data)(mibOct1),
27463                cell->siCb.crntSiInfo.mib, 0))
27464          return;
27465
27466       if(ROK != SRepMsg((Data)(mibOct2),
27467                cell->siCb.crntSiInfo.mib, 1))
27468          return;
27469
27470       /*Copy the MIB msg buff into interface buffer */
27471       SCpyMsgMsg(cell->siCb.crntSiInfo.mib,
27472             rgSchCb[cell->instIdx].rgSchInit.region,
27473             rgSchCb[cell->instIdx].rgSchInit.pool,
27474             &subfrmAlloc->cmnLcInfo.bchInfo.pdu);
27475       /* Added Dl TB count for MIB message transmission
27476        * This counter is incremented 4 times to consider 
27477        * the retransmission at the PHY level on PBCH channel*/
27478 #ifdef LTE_L2_MEAS
27479       cell->dlUlTbCnt.tbTransDlTotalCnt += RG_SCH_MIB_CNT;
27480 #endif      
27481    }
27482 #ifdef EMTC_ENABLE
27483    }
27484 #endif
27485
27486    allocInfo->bcchAlloc.schdFirst = FALSE;
27487    /*Check if scheduling of SIB1 is required.
27488      Check of (crntTimInfo.sfn % RGSCH_SIB1_PERIODICITY == 0)
27489      is not required here since the below check takes care
27490      of SFNs applicable for this one too.*/
27491    if((crntTimInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
27492          && (RGSCH_SIB1_TX_SF_NUM == crntTimInfo.slot))
27493    {
27494       /*If SIB1 has not been yet setup by Application, return*/
27495       if(NULLP == (cell->siCb.crntSiInfo.sib1Info.sib1))
27496       {
27497          return;
27498       }
27499
27500       allocInfo->bcchAlloc.schdFirst = TRUE;
27501       mcs =  cell->siCb.crntSiInfo.sib1Info.mcs;
27502       nPrb =  cell->siCb.crntSiInfo.sib1Info.nPrb;
27503       msgLen =  cell->siCb.crntSiInfo.sib1Info.msgLen;
27504    }
27505    else
27506    {
27507       /*Check if scheduling of SI can be performed.*/
27508       Bool    invalid = FALSE;
27509
27510       if(cell->siCb.siCtx.siId == 0)
27511          return;
27512
27513       /*Check if the Si-Window for the current Si-Context is completed*/
27514       invalid = rgSCHCmnChkPastWin(crntTimInfo, cell->siCb.siCtx.maxTimeToTx);
27515       if(invalid)
27516       {
27517          /* LTE_ADV_FLAG_REMOVED_START */
27518          if(cell->siCb.siCtx.retxCntRem)
27519          { 
27520              DU_LOG("\nERROR  -->  SCH : rgSCHDlSiSched(): SI not scheduled and window expired");
27521          }
27522          /* LTE_ADV_FLAG_REMOVED_END */
27523          if(cell->siCb.siCtx.warningSiFlag == TRUE)
27524          {
27525             rgSCHUtlFreeWarningSiPdu(cell);
27526             cell->siCb.siCtx.warningSiFlag  = FALSE;
27527          }
27528          return;
27529       }
27530
27531       /*Check the timinginfo of the current SI-Context to see if its
27532         transmission can be scheduled. */
27533       if(FALSE == (rgSCHCmnChkInWin(crntTimInfo,
27534                   cell->siCb.siCtx.timeToTx,
27535                   cell->siCb.siCtx.maxTimeToTx)))
27536       {
27537          return;
27538
27539       }
27540       /*Check if retransmission count has become 0*/
27541       if(0 == cell->siCb.siCtx.retxCntRem)
27542       {
27543          return;
27544       }
27545
27546       /* LTE_ADV_FLAG_REMOVED_START */
27547       /* Check if ABS is enabled/configured  */
27548       if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
27549       {
27550          /* The pattern type is RGR_ABS_MUTE, then eNB need to blank the subframe */
27551          if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
27552          {
27553             /* Determine next scheduling subframe is ABS or not */
27554             if(RG_SCH_ABS_ENABLED_ABS_SF == (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern
27555                   [((crntTimInfo.sfn*RGSCH_NUM_SUB_FRAMES) + crntTimInfo.slot) % RGR_ABS_PATTERN_LEN]))
27556             {
27557                /* Skip the SI scheduling to next tti */
27558                return;
27559             }
27560          }
27561       }
27562       /* LTE_ADV_FLAG_REMOVED_END */
27563
27564       /*Schedule the transmission of the current SI-Context */
27565       /*Find out the messg length for the SI message */
27566       /* warningSiFlag is to differentiate between Warning SI
27567        * and Other SI */
27568         if((rgSCHUtlGetMcsAndNPrb(cell, &nPrb, &mcs, &msgLen)) != ROK)
27569         {
27570            return; 
27571         }
27572
27573       cell->siCb.siCtx.i = RGSCH_CALC_SF_DIFF(crntTimInfo,
27574             cell->siCb.siCtx.timeToTx);
27575    } 
27576
27577
27578    /*Get the number of rb required */
27579    /*rgSCHCmnClcRbAllocForFxdTb(cell, msgLen, cellDl->ccchCqi, &rb);*/
27580    if(cellDl->bitsPerRb==0)
27581    {
27582       while ((rgTbSzTbl[0][0][rb]) < (uint32_t) (msgLen*8))
27583       {
27584          rb++;
27585       }
27586       rb = rb+1;
27587    }
27588    else
27589    {
27590       rb = RGSCH_CEIL((msgLen*8), cellDl->bitsPerRb);
27591    }
27592    /* DwPTS Scheduling Changes Start */   
27593 #ifdef LTE_TDD
27594    if (sf->sfType == RG_SCH_SPL_SF_DATA) 
27595    {
27596       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
27597
27598       /* Calculate the less RE's because of DwPTS */
27599        lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
27600
27601        /* Increase number of RBs in Spl SF to compensate for lost REs */
27602        rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
27603    }
27604 #endif
27605    /* DwPTS Scheduling Changes End */   
27606    /*ccpu00115595- end*/
27607    /* Additional check to see if required RBs
27608     * exceeds the available */
27609    if (rb > sf->bw - sf->bwAssigned)
27610    {
27611       DU_LOG("\nERROR  -->  SCH : rgSCHDlSiSched(): "
27612          "BW allocation failed CRNTI:%d",RGSCH_SI_RNTI);
27613       return;
27614    }
27615
27616    /* Update the subframe Allocated BW field */
27617    sf->bwAssigned = sf->bwAssigned + rb;
27618
27619    /*Fill the parameters in allocInfo */
27620    allocInfo->bcchAlloc.rnti = RGSCH_SI_RNTI;
27621    allocInfo->bcchAlloc.dlSf = sf;
27622    allocInfo->bcchAlloc.rbsReq = rb;
27623    /*ccpu00116710- MCS is not getting assigned */
27624    allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
27625
27626    /* ccpu00117510 - ADD - Assignment of nPrb and other information */
27627    allocInfo->bcchAlloc.nPrb = nPrb;
27628    allocInfo->bcchAlloc.tbInfo[0].bytesReq = msgLen;
27629    allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
27630    return;
27631 }
27632 #endif /*RGR_SI_SCH*/
27633
27634 \f
27635 /* ccpu00117452 - MOD - Changed macro name from
27636    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
27637 #ifdef RGR_CQI_REPT
27638 /**
27639  * @brief This function Updates the DL CQI for the UE.
27640  *
27641  * @details
27642  *
27643  *     Function: rgSCHCmnUeDlPwrCtColltCqiRept
27644  *     Purpose:  Manages PUSH N CQI reporting
27645  *         Step 1: Store the CQI in collation array
27646  *         Step 2: Increament the tracking count
27647  *         Step 3: Check is it time to to send the report
27648  *         Step 4: if yes, Send StaInd to RRM
27649  *         Step 4.1: Fill StaInd for sending collated N CQI rpeorts
27650  *         Step 4.2: Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM
27651  *         Step 4.2.1: If sending was not sucessful, return RFAILED
27652  *         Step 4.2.2: If sending was sucessful, return ROK
27653  *         Step 5: If no, return
27654  *     Invoked by: rgSCHCmnDlCqiInd
27655  *
27656  *  @param[in]  RgSchCellCb        *cell
27657  *  @param[in]  RgSchUeCb          *ue
27658  *  @param[in]  RgrUeCqiRept        *ueCqiRpt
27659  *  @return  Void
27660  *
27661  **/
27662 static S16 rgSCHCmnUeDlPwrCtColltCqiRept
27663 (
27664 RgSchCellCb        *cell,
27665 RgSchUeCb          *ue,
27666 RgrUeCqiRept        *ueCqiRpt
27667 )
27668 {
27669    uint8_t    *cqiCount = NULLP;
27670    S16   retVal;
27671    RgrStaIndInfo *staInfo = NULLP;
27672
27673
27674    /* Step 1: Store the CQI in collation array */
27675    /* Step 2: Increament the tracking count */
27676    cqiCount = &(ue->schCqiInfo.cqiCount);
27677    ue->schCqiInfo.cqiRept[(*cqiCount)++] =
27678                   *ueCqiRpt;
27679
27680
27681    /* Step 3: Check is it time to to send the report */
27682    if(RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(ue))
27683    {
27684    /* Step 4: if yes, Send StaInd to RRM */
27685       retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo,
27686                sizeof(RgrStaIndInfo));
27687       if (retVal != ROK)
27688       {
27689          DU_LOG("\nERROR  -->  SCH : Could not "
27690             "allocate memory for sending StaInd CRNTI:%d",ue->ueId);
27691          return (retVal);
27692       }
27693
27694    /* Step 4.1: Fill StaInd for sending collated N CQI rpeorts */
27695 #ifdef CA_DBG
27696       {
27697          uint32_t gCqiReptToAppCount;
27698          gCqiReptToAppCount++;
27699       
27700       }
27701
27702 #endif
27703       retVal = rgSCHUtlFillSndStaInd(cell, ue, staInfo,
27704             ue->cqiReptCfgInfo.numColltdCqiRept);
27705       return (retVal);
27706
27707    }
27708
27709    return ROK;
27710 } /* End of rgSCHCmnUeDlPwrCtColltCqiRept */
27711
27712 #endif /* End of RGR_CQI_REPT */
27713
27714 /**
27715  * @brief This function checks for the retransmisson
27716  *        for a DTX scenario.
27717  * @details
27718  *
27719  *     Function:
27720  *     Purpose:
27721  *     Invoked by:
27722  *
27723  *  @param[in]  RgSchCellCb        *cell
27724  *  @param[in]  RgSchUeCb          *ue
27725  *  @param[in]
27726  *  @return  Void
27727  *
27728  **/
27729 Void rgSCHCmnChkRetxAllowDtx
27730 (
27731 RgSchCellCb        *cell,
27732 RgSchUeCb          *ueCb,
27733 RgSchDlHqProcCb    *proc,
27734 Bool               *reTxAllwd
27735 )
27736 {
27737
27738
27739    *reTxAllwd = TRUE;
27740    /* Fix */
27741    if ((proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX))
27742    {
27743        *reTxAllwd = FALSE;
27744    }
27745
27746    return;
27747 }
27748
27749 /**
27750  * @brief API for calculating the SI Set Id 
27751  *
27752  * @details
27753  *
27754  *     Function: rgSCHCmnGetSiSetId
27755  *
27756  *     This API is used for calculating the SI Set Id, as shown below
27757  *     
27758  *          siSetId = 0        siSetId = 1
27759  *     |******************|******************|---------------->
27760  *   (0,0)              (8,0)              (16,0)          (SFN, SF)
27761  *    
27762  *
27763  *  @param[in]  uint16_t     sfn                   
27764  *  @param[in]  uint8_t      sf
27765  *  @return     uint16_t     siSetId
27766  **/
27767 uint16_t rgSCHCmnGetSiSetId
27768 (
27769 uint16_t    sfn,
27770 uint8_t     sf,
27771 uint16_t    minPeriodicity
27772 )
27773 {
27774    /* 80 is the minimum SI periodicity in sf. Also
27775     * all other SI periodicities are multiples of 80 */
27776     return  (((sfn * RGSCH_NUM_SUB_FRAMES_5G) + sf) / (minPeriodicity * 10));
27777 }
27778 #ifdef LTE_TDD
27779 /**
27780  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
27781  *
27782  * @details
27783  *
27784  *     Function: rgSCHCmnCalcDwPtsTbSz
27785  *
27786  *  @param[in]     RgSchCellCb    *cell                   
27787  *  @param[in]     uint32_t             bo
27788  *  @param[in/out] uint8_t             *rb
27789  *  @param[in/out] uint8_t             *iTbs
27790  *  @param[in]     uint8_t              lyr
27791  *  @param[in]     uint8_t              cfi
27792  *  @return        uint32_t             tbSz
27793  **/
27794 static uint32_t rgSCHCmnCalcDwPtsTbSz
27795 (
27796 RgSchCellCb *cell,
27797 uint32_t    bo,
27798 uint8_t     *rb,
27799 uint8_t     *iTbs,
27800 uint8_t     lyr,
27801 uint8_t     cfi
27802 )
27803 {
27804     uint32_t       tbSz;
27805     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
27806     uint32_t       numRE      = *rb * cellDl->noResPerRb[cfi];
27807     uint32_t       numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
27808
27809
27810     /* DwPts Rb cannot exceed the cell Bw */
27811     numDwPtsRb = RGSCH_MIN(numDwPtsRb, cellDl->maxDlBwPerUe);
27812     
27813     /* Adjust the iTbs for optimum usage of the DwPts region. 
27814      * Using the same iTbs adjustment will not work for all 
27815      * special subframe configurations and iTbs levels. Hence use the 
27816      * static iTbs Delta table for adjusting the iTbs  */
27817     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs);
27818     
27819     if (bo)
27820     {
27821        while(rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1] < bo*8 &&
27822              numDwPtsRb < cellDl->maxDlBwPerUe) 
27823        {
27824           (numDwPtsRb)++;
27825        }
27826
27827        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
27828     }
27829     else
27830     {
27831        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
27832     }
27833     *rb = numDwPtsRb;
27834
27835     return (tbSz/8);
27836 }
27837
27838 /**
27839  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
27840  *
27841  * @details
27842  *
27843  *     Function: rgSCHCmnCalcDwPtsTbSz2Cw
27844  *
27845  *  @param[in]      RgSchCellCb    *cell                   
27846  *  @param[in]      uint32_t             bo
27847  *  @param[in/out]  uint8_t             *rb
27848  *  @param[in]      uint8_t              maxRb
27849  *  @param[in/out]  uint8_t             *iTbs1
27850  *  @param[in/out]  uint8_t             *iTbs2
27851  *  @param[in]      uint8_t              lyr1
27852  *  @param[in]      uint8_t              lyr2
27853  *  @return[in/out] uint32_t            *tb1Sz
27854  *  @return[in/out] uint32_t            *tb2Sz
27855  *  @param[in]      uint8_t              cfi 
27856  **/
27857 static Void rgSCHCmnCalcDwPtsTbSz2Cw
27858 (
27859 RgSchCellCb  *cell,
27860 uint32_t     bo,
27861 uint8_t      *rb,
27862 uint8_t      maxRb,
27863 uint8_t      *iTbs1,
27864 uint8_t      *iTbs2,
27865 uint8_t      lyr1,
27866 uint8_t      lyr2,
27867 uint32_t     *tb1Sz, 
27868 uint32_t     *tb2Sz,
27869 uint8_t      cfi
27870 )
27871 {
27872     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
27873     uint32_t       numRE      = *rb * cellDl->noResPerRb[cfi];
27874     uint32_t       numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
27875
27876
27877     /* DwPts Rb cannot exceed the cell Bw */
27878     numDwPtsRb = RGSCH_MIN(numDwPtsRb, maxRb);
27879     
27880     /* Adjust the iTbs for optimum usage of the DwPts region. 
27881      * Using the same iTbs adjustment will not work for all 
27882      * special subframe configurations and iTbs levels. Hence use the 
27883      * static iTbs Delta table for adjusting the iTbs  */
27884     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs1);
27885     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs2);
27886     
27887     while((rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1] +
27888            rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1])< bo*8 &&
27889           numDwPtsRb < maxRb) 
27890     {
27891        (numDwPtsRb)++;
27892     }
27893
27894     *tb1Sz = rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
27895     *tb2Sz = rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
27896
27897     *rb = numDwPtsRb;
27898
27899     return;    
27900 }
27901
27902 #endif
27903
27904 /**
27905  * @brief Updates the GBR LCGs when datInd is received from MAC
27906  * 
27907  * @details
27908  *
27909  *     Function: rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
27910  *     Purpose:  This function updates the GBR LCGs 
27911  *               when datInd is received from MAC.
27912  *
27913  *     Invoked by: TOM
27914  *
27915  *  @param[in]  RgSchCellCb      *cell
27916  *  @param[in]  RgSchUeCb        *ue
27917  *  @param[in]  RgInfUeDatInd    *datInd
27918  *  @return Void
27919  **/
27920 Void rgSCHCmnUpdUeDataIndLcg 
27921 (
27922 RgSchCellCb    *cell,
27923 RgSchUeCb      *ue,
27924 RgInfUeDatInd  *datInd
27925 )
27926 {
27927    uint32_t idx = 0;
27928    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
27929
27930
27931    for (idx = 0; (idx < RGINF_MAX_LCG_PER_UE - 1); idx++)
27932    {
27933       if (datInd->lcgInfo[idx].bytesRcvd != 0)
27934       {
27935          uint8_t  lcgId     = datInd->lcgInfo[idx].lcgId;
27936          uint32_t bytesRcvd = datInd->lcgInfo[idx].bytesRcvd;
27937
27938          if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
27939          {
27940             RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
27941             if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
27942             {
27943                if(bytesRcvd > cmnLcg->effGbr)
27944                {
27945                   bytesRcvd -= cmnLcg->effGbr;
27946                   cmnLcg->effDeltaMbr = (cmnLcg->effDeltaMbr > bytesRcvd) ? \
27947                                         (cmnLcg->effDeltaMbr - bytesRcvd) : (0);
27948                   cmnLcg->effGbr = 0;
27949                }
27950                else
27951                {
27952                   cmnLcg->effGbr -= bytesRcvd;
27953                }
27954                /* To keep BS updated with the amount of data received for the GBR */
27955                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27956                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27957                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr+cmnLcg->effDeltaMbr);
27958             }
27959             else if(lcgId != 0)
27960             {
27961                ue->ul.effAmbr = (ue->ul.effAmbr > datInd->lcgInfo[idx].bytesRcvd) ? \
27962                                (ue->ul.effAmbr - datInd->lcgInfo[idx].bytesRcvd) : (0);
27963                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27964                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27965                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
27966                ue->ul.nonGbrLcgBs = (ue->ul.nonGbrLcgBs > datInd->lcgInfo[idx].bytesRcvd) ? \
27967                                    (ue->ul.nonGbrLcgBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27968             }
27969             ue->ul.nonLcg0Bs = (ue->ul.nonLcg0Bs > datInd->lcgInfo[idx].bytesRcvd) ? \
27970                               (ue->ul.nonLcg0Bs - datInd->lcgInfo[idx].bytesRcvd) : (0);
27971          }
27972       }
27973       else
27974       {
27975          break;
27976       }
27977    }
27978 #ifdef EMTC_ENABLE
27979    if(TRUE == ue->isEmtcUe)
27980    {
27981       if (cellSch->apisEmtcUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
27982       {
27983          DU_LOG("\nERROR  -->  SCH :  rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure");
27984       }
27985
27986    }
27987    else
27988 #endif
27989    {
27990       if (cellSch->apisUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
27991       {
27992          DU_LOG("\nERROR  -->  SCH : rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure");
27993       }
27994    }
27995 }
27996
27997
27998 /** @brief This function initializes DL allocation lists and prepares
27999  *         for scheduling  
28000  *
28001  * @details
28002  *
28003  *     Function: rgSCHCmnInitRbAlloc
28004  *
28005  * @param  [in] RgSchCellCb    *cell
28006  *
28007  * Returns: Void
28008  *
28009  */
28010 static Void  rgSCHCmnInitRbAlloc 
28011 (
28012 RgSchCellCb        *cell
28013 )
28014 {
28015    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
28016    CmLteTimingInfo        frm;
28017    RgSchDlSf              *dlSf;
28018    uint8_t                idx;
28019    
28020
28021 /* Initializing RgSchCmnUlRbAllocInfo structure.*/
28022    rgSCHCmnInitDlRbAllocInfo(&cellSch->allocInfo);
28023
28024    frm = cellSch->dl.time;
28025
28026    dlSf = rgSCHUtlSubFrmGet(cell, frm);
28027 #ifdef RG_5GTF
28028    dlSf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
28029    dlSf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
28030         for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
28031    {
28032       dlSf->sfBeamInfo[idx].totVrbgAllocated = 0;
28033       dlSf->sfBeamInfo[idx].totVrbgRequired = 0;
28034       dlSf->sfBeamInfo[idx].vrbgStart = 0;
28035    }
28036 #endif
28037    dlSf->remUeCnt = cellSch->dl.maxUePerDlSf;
28038    /* Updating the Subframe information in RBAllocInfo */
28039    cellSch->allocInfo.dedAlloc.dedDlSf   = dlSf;
28040    cellSch->allocInfo.msg4Alloc.msg4DlSf = dlSf;
28041
28042    /* LTE_ADV_FLAG_REMOVED_START */
28043    /* Determine next scheduling subframe is ABS or not */
28044    if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
28045    {
28046       cell->lteAdvCb.absPatternDlIdx = 
28047          ((frm.sfn*RGSCH_NUM_SUB_FRAMES_5G) + frm.slot) % RGR_ABS_PATTERN_LEN;
28048       cell->lteAdvCb.absDlSfInfo = (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern[
28049             cell->lteAdvCb.absPatternDlIdx]);
28050
28051    }
28052    else
28053    {
28054       cell->lteAdvCb.absDlSfInfo = RG_SCH_ABS_DISABLED;
28055    }
28056    /* LTE_ADV_FLAG_REMOVED_END */
28057
28058 #ifdef RGR_V1
28059    cellSch->allocInfo.ccchSduAlloc.ccchSduDlSf = dlSf;
28060 #endif
28061 #ifdef LTEMAC_SPS
28062    /* Update subframe-wide allocation information with SPS allocation */
28063    rgSCHCmnSpsDlUpdDlSfAllocWithSps(cell, frm, dlSf);
28064 #endif
28065    return;
28066 }
28067
28068
28069
28070 #ifdef DL_LA
28071 /**
28072  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
28073  * actual iTbs
28074  * 
28075  * @details
28076  *
28077  *     Function: rgSCHCmnSendTxModeInd(cell, ueUl, newTxMode)
28078  *     Purpose:  This function sends the TX mode Change 
28079  *               indication to RRM
28080  *     change
28081  *
28082  *     Invoked by: CMN
28083  *
28084  *  @param[in]  RgSchCellCb      *cell
28085  *  @param[in]  RgSchUeCb        *ue
28086  *  @param[in]  uint8_t               newTxMode
28087  *  @return Void
28088  **/
28089 static Void rgSCHCmnSendTxModeInd 
28090 (
28091 RgSchCellCb    *cell,
28092 RgSchUeCb      *ue,
28093 uint8_t        newTxMode
28094 )
28095
28096    RgmTransModeInd   *txModeChgInd;
28097    RgSchCmnDlUe      *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
28098
28099
28100    if(!(ueDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG))
28101    {
28102       /* Mem Alloc */
28103       if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
28104                cell->rgmSap->sapCfg.sapPst.pool, (Data**)&txModeChgInd,
28105                sizeof(RgmTransModeInd)) != ROK)
28106       {
28107          return;
28108       }
28109       RG_SCH_FILL_RGM_TRANSMODE_IND(ue->ueId, cell->cellId, newTxMode, txModeChgInd);
28110       RgUiRgmChangeTransModeInd(&(cell->rgmSap->sapCfg.sapPst),
28111             cell->rgmSap->sapCfg.suId, txModeChgInd);
28112    }
28113
28114    ue->mimoInfo.txModUpChgFactor = 0;
28115    ue->mimoInfo.txModDownChgFactor = 0;
28116    ueDl->laCb[0].deltaiTbs = 0;
28117
28118    return;
28119 }
28120
28121 /**
28122  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
28123  * actual iTbs
28124  * 
28125  * @details
28126  *
28127  *     Function: rgSchCheckAndTriggerModeChange(cell, ueUl, iTbsNew)
28128  *     Purpose:  This function update and check for threashold for TM mode
28129  *     change
28130  *
28131  *     Invoked by: CMN
28132  *
28133  *  @param[in]  RgSchCellCb      *cell
28134  *  @param[in]  RgSchUeCb        *ue
28135  *  @param[in]  uint8_t               iTbs
28136  *  @return Void
28137  **/
28138 Void rgSchCheckAndTriggerModeChange
28139 (
28140 RgSchCellCb    *cell,
28141 RgSchUeCb      *ue,
28142 uint8_t        reportediTbs,
28143 uint8_t        previTbs,
28144 uint8_t        maxiTbs
28145 )
28146 {
28147    RgrTxMode          txMode;       /*!< UE's Transmission Mode */
28148    RgrTxMode          modTxMode;       /*!< UE's Transmission Mode */
28149
28150
28151    txMode = ue->mimoInfo.txMode;
28152
28153    /* Check for Step down */
28154    /* Step down only when TM4 is configured. */
28155    if(RGR_UE_TM_4 == txMode)
28156    {
28157       if((previTbs <= reportediTbs) && ((reportediTbs - previTbs) >= RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR))
28158       {
28159          ue->mimoInfo.txModDownChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
28160       }
28161       else
28162       {
28163          ue->mimoInfo.txModDownChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
28164       }
28165
28166       ue->mimoInfo.txModDownChgFactor =  
28167          RGSCH_MAX(ue->mimoInfo.txModDownChgFactor, -(RG_SCH_MODE_CHNG_STEPDOWN_THRSHD));
28168
28169       if(ue->mimoInfo.txModDownChgFactor >= RG_SCH_MODE_CHNG_STEPDOWN_THRSHD)
28170       {
28171          /* Trigger Mode step down */
28172          modTxMode = RGR_UE_TM_3;
28173          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
28174       }
28175    }
28176
28177    /* Check for Setup up */
28178    /* Step Up only when TM3 is configured, Max possible Mode is TM4*/
28179    if(RGR_UE_TM_3 == txMode)
28180    {
28181       if((previTbs > reportediTbs) || (maxiTbs == previTbs))
28182       {
28183          ue->mimoInfo.txModUpChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
28184       }
28185       else
28186       {
28187          ue->mimoInfo.txModUpChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
28188       }
28189
28190       ue->mimoInfo.txModUpChgFactor = 
28191          RGSCH_MAX(ue->mimoInfo.txModUpChgFactor, -(RG_SCH_MODE_CHNG_STEPUP_THRSHD));
28192
28193       /* Check if TM step up need to be triggered */
28194       if(ue->mimoInfo.txModUpChgFactor >= RG_SCH_MODE_CHNG_STEPUP_THRSHD)
28195       {
28196          /* Trigger mode chnage */
28197          modTxMode =  RGR_UE_TM_4;
28198          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
28199       }
28200    }
28201
28202    return;
28203 }
28204 #endif
28205
28206 /**
28207 * @brief Updates the GBR LCGs when datInd is received from MAC
28208  * 
28209  * @details
28210  *
28211  *     Function: rgSCHCmnIsDlCsgPrio (cell)
28212  *     Purpose:  This function returns if csg UEs are
28213  *               having priority at current time
28214  *
28215  *     Invoked by: Scheduler
28216  *
28217  *  @param[in]  RgSchCellCb      *cell
28218  *  @param[in]  RgSchUeCb        *ue
28219  *  @param[in]  RgInfUeDatInd    *datInd
28220  *  @return Void
28221  **/
28222 Bool rgSCHCmnIsDlCsgPrio(RgSchCellCb    *cell)
28223 {
28224   
28225    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
28226  
28227    /* Calculating the percentage resource allocated */
28228    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
28229    {
28230       return (FALSE);
28231    }
28232    else
28233    {
28234       if(((cmnDlCell->ncsgPrbCnt * 100) / cmnDlCell->totPrbCnt) < cell->minDlResNonCsg)
28235       {
28236          return (FALSE);
28237       }
28238       else
28239       {
28240          return (TRUE);
28241       }
28242    }
28243 }
28244
28245 /**
28246 * @brief Updates the GBR LCGs when datInd is received from MAC
28247  * 
28248  * @details
28249  *
28250  *     Function: rgSCHCmnIsUlCsgPrio (cell)
28251  *     Purpose:  This function returns if csg UEs are
28252  *               having priority at current time
28253  *
28254  *     Invoked by: Scheduler
28255  *
28256  *  @param[in]  RgSchCellCb      *cell
28257  *  @param[in]  RgSchUeCb        *ue
28258  *  @param[in]  RgInfUeDatInd    *datInd
28259  *  @return Void
28260  **/
28261 Bool rgSCHCmnIsUlCsgPrio(RgSchCellCb    *cell)
28262 {
28263    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
28264  
28265
28266    /* Calculating the percentage resource allocated */
28267    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
28268    {
28269       return (FALSE);
28270    }
28271    else
28272    {
28273       if (((cmnUlCell->ncsgPrbCnt * 100) /cmnUlCell->totPrbCnt) < cell->minUlResNonCsg)
28274       {
28275          return (FALSE);
28276       }
28277       else
28278       {
28279          return (TRUE);
28280       }
28281    }
28282 }
28283
28284 /** @brief DL scheduler for SPS, and all other downlink data
28285  *
28286  * @details
28287  *
28288  *      Function: rgSchCmnPreDlSch
28289  *
28290  *  @param  [in] Inst               schInst;
28291  *   Returns: Void
28292  *
28293  */
28294 Void rgSchCmnPreDlSch
28295 (
28296 RgSchCellCb   **cell,
28297 uint8_t       nCell,
28298 RgSchCellCb   **cellLst
28299 )
28300 {
28301    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell[0]);
28302    RgSchDlSf     *sf;
28303    uint8_t       idx;
28304
28305
28306    if(nCell > CM_LTE_MAX_CELLS)
28307    {
28308       return;
28309    }
28310
28311    if (cell[0]->isDlDataAllwd && (cell[0]->stopDlSch == FALSE))
28312    {
28313       /* Specific DL scheduler to perform UE scheduling */
28314       cellSch->apisDl->rgSCHDlPreSched(cell[0]);
28315
28316       /* Rearranging the cell entries based on their remueCnt in SF.
28317        * cells will be processed in the order of number of ue scheduled
28318        * in that cell */
28319       for (idx = 0; idx < nCell; idx++)
28320       {
28321          uint8_t    j;
28322          cellSch = RG_SCH_CMN_GET_CELL(cell[idx]);
28323          sf = cellSch->allocInfo.dedAlloc.dedDlSf;
28324
28325          if(idx == 0)
28326          {
28327             cellLst[idx] = cell[idx];
28328             continue;
28329          }
28330
28331          for(j = 0; j < idx; j++)
28332          {
28333             RgSchCmnCell *cmnCell = RG_SCH_CMN_GET_CELL(cellLst[j]);
28334             RgSchDlSf    *subfrm = cmnCell->allocInfo.dedAlloc.dedDlSf;
28335
28336             if(sf->remUeCnt < subfrm->remUeCnt)
28337             {
28338                uint8_t  k;
28339                for(k = idx; k > j; k--)
28340                {
28341                   cellLst[k] = cellLst[k-1];
28342                }
28343                break;
28344             }
28345          }
28346          cellLst[j] = cell[idx];
28347       }
28348    }
28349    else
28350    {
28351       for (idx = 0; idx < nCell; idx++)
28352       {
28353          cellLst[idx] = cell[idx];
28354       }
28355    }
28356    return;
28357 }
28358
28359 /** @brief DL scheduler for SPS, and all other downlink data
28360  *  @details
28361  *
28362  *       Function: rgSchCmnPstDlSch
28363  *
28364  *        @param  [in] Inst               schInst;
28365  *        Returns: Void
28366  *
28367  */
28368 Void rgSchCmnPstDlSch(RgSchCellCb  *cell)
28369 {
28370    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
28371
28372
28373    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
28374    {
28375       cellSch->apisDl->rgSCHDlPstSched(cell->instIdx);
28376    }
28377 }
28378
28379 uint8_t rgSCHCmnCalcPcqiBitSz(RgSchUeCb *ueCb, uint8_t   numTxAnt)
28380 {
28381    uint8_t confRepMode;
28382    uint8_t pcqiSz;
28383    uint8_t ri;
28384    RgSchUePCqiCb *cqiCb = ueCb->nPCqiCb;
28385
28386
28387    confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
28388    if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && 
28389          (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
28390    {
28391       ri =1;
28392    }
28393    else
28394    {
28395       ri = cqiCb->perRiVal;
28396    }
28397    switch(confRepMode)
28398    {
28399       case RGR_PRD_CQI_MOD10:
28400          {
28401             pcqiSz = 4;
28402          }
28403          break;
28404
28405       case RGR_PRD_CQI_MOD11:
28406          {
28407             if(numTxAnt == 2)
28408             {
28409                if (ri ==1)
28410                {
28411                   pcqiSz = 6;
28412                }
28413                else
28414                {
28415                   pcqiSz = 8;
28416                }
28417             }
28418             else if(numTxAnt == 4)
28419             {
28420                if (ri ==1)
28421                {
28422                   pcqiSz = 8;
28423                }
28424                else
28425                {
28426                   pcqiSz = 11;
28427                }
28428             }
28429             else
28430             {
28431                /* This is number of antenna case 1.
28432                 * This is not applicable for Mode 1-1. 
28433                 * So setting it to invalid value */
28434                pcqiSz = 0;
28435             }
28436          }
28437          break;
28438
28439       case RGR_PRD_CQI_MOD20:
28440          {
28441             if(cqiCb->isWb)
28442             {
28443                pcqiSz = 4;
28444             }
28445             else
28446             {
28447                pcqiSz = 4 + cqiCb->label;
28448             }
28449          }
28450          break;
28451
28452       case RGR_PRD_CQI_MOD21:
28453          {
28454             if(cqiCb->isWb)
28455             {
28456                if(numTxAnt == 2)
28457                {
28458                   if (ri ==1)
28459                   {
28460                      pcqiSz = 6;
28461                   }
28462                   else
28463                   {
28464                      pcqiSz = 8;
28465                   }
28466                }
28467                else if(numTxAnt == 4)
28468                {
28469                   if (ri ==1)
28470                   {
28471                      pcqiSz = 8;
28472                   }
28473                   else
28474                   {
28475                      pcqiSz = 11;
28476                   }
28477                }
28478                else
28479                {
28480                   /* This might be number of antenna case 1.
28481                    * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
28482                    * So setting invalid value.*/
28483                   pcqiSz = 0;
28484                }
28485             }
28486             else
28487             {
28488                if (ri ==1)
28489                {
28490                   pcqiSz = 4 + cqiCb->label;
28491                }
28492                else
28493                {
28494                   pcqiSz = 7 + cqiCb->label;
28495                }
28496             }
28497          }
28498          break;
28499       default:
28500           pcqiSz = 0;
28501           break;
28502    }
28503    
28504    return (pcqiSz);
28505 }
28506
28507 /** @brief DL scheduler for SPS, and all other downlink data
28508  *
28509  * @details
28510  *
28511  *     Function: rgSCHCmnDlSch
28512  *
28513  * @param  [in] RgSchCellCb    *cell
28514  *
28515  * Returns: Void
28516  *
28517  */
28518 Void rgSCHCmnDlSch(RgSchCellCb *cell)
28519 {
28520    RgSchDlSf *dlSf;
28521    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
28522 #ifdef RG_5GTF
28523    RgSchDynTddCb  *rgSchDynTddInfo = &(rgSchCb[cell->instIdx].rgSchDynTdd);
28524    uint16_t dlCntrlSfIdx;
28525 #endif
28526
28527
28528    dlSf = rgSCHUtlSubFrmGet(cell, cellSch->dl.time);
28529 #ifdef RG_5GTF
28530         if (rgSchDynTddInfo->isDynTddEnbld)
28531    {
28532       RG_SCH_DYN_TDD_GET_SFIDX(dlCntrlSfIdx, rgSchDynTddInfo->crntDTddSfIdx, 
28533                                             RG_SCH_CMN_DL_DELTA);
28534                 if(RG_SCH_DYNTDD_DLC_ULD == rgSchDynTddInfo->sfInfo[dlCntrlSfIdx].sfType)
28535                 {
28536                    if(1 == cell->cellId)
28537          {
28538                       ul5gtfsidDlAlreadyMarkUl++;
28539             /*
28540                     DU_LOG("\nINFO   -->  SCH : ul5gtfsidDlAlreadyMarkUl: %d, [sfn:sf] [%04d:%02d]\n", 
28541                     ul5gtfsidDlAlreadyMarkUl, cellSch->dl.time.sfn, 
28542                     cellSch->dl.time.slot);
28543             */
28544          }
28545                    return;
28546                 }
28547    }
28548 #endif
28549
28550    /* Specific DL scheduler to perform UE scheduling */
28551    cellSch->apisDl->rgSCHDlNewSched(cell, &cellSch->allocInfo);      
28552    /* LTE_ADV_FLAG_REMOVED_END */
28553
28554    /* call common allocator for RB Allocation */
28555    rgSCHCmnDlRbAlloc(cell, &cellSch->allocInfo);
28556
28557    /* Finalize the Allocations for reqested Against alloced */
28558    rgSCHCmnDlAllocFnlz(cell);
28559
28560    /* Perform Pdcch allocations for PDCCH Order Q.
28561     * As of now, giving this the least preference.
28562     * This func call could be moved above other allocations
28563     * as per need */
28564    rgSCHCmnGenPdcchOrder(cell, dlSf);
28565
28566    /* Do group power control for PUCCH */
28567    rgSCHCmnGrpPwrCntrlPucch(cell, dlSf);
28568
28569    return;
28570 }
28571
28572 /**********************************************************************
28573
28574   End of file
28575 **********************************************************************/