remove/replaced PRIVATE and EXTERN keywords
[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 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=187;
37 static int RLOG_MODULE_ID=4096;
38
39 /* header include files -- defines (.h) */
40 #include "common_def.h"
41 #include "lrg.h"
42 #include "rgr.h"
43 #include "tfu.h"
44 #include "rgm.h"
45 #include "rg_env.h"
46 #include "rg_sch_err.h"
47 #include "rg_sch_inf.h"
48 #include "rg_sch.h"
49 #include "rg_sch_cmn.h"
50 #include "rl_interface.h"
51 #include "rl_common.h"
52
53 /* header/extern include files (.x) */
54 #include "tfu.x"           /* TFU types */
55 #include "lrg.x"           /* layer management typedefs for MAC */
56 #include "rgr.x"           /* layer management typedefs for MAC */
57 #include "rgm.x"           /* layer management typedefs for MAC */
58 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
59 #include "rg_sch.x"        /* typedefs for Scheduler */
60 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
61 #ifdef MAC_SCH_STATS
62 #include "lrg.x"            /* Stats Structures */
63 #endif /* MAC_SCH_STATS */
64 #ifdef __cplusplus
65 extern "C" {
66 #endif /* __cplusplus */
67
68 #ifdef EMTC_ENABLE
69 uint32_t emtcStatsUlTomSrInd;
70 uint32_t emtcStatsUlBsrTmrTxp;
71 #endif
72
73 #define RG_ITBS_DIFF(_x, _y) ((_x) > (_y) ? (_x) - (_y) : (_y) - (_x))
74 Void rgSCHSc1UlInit ARGS((RgUlSchdApis *apis));
75 #ifdef RG_PHASE2_SCHED
76 Void rgSCHRrUlInit ARGS((RgUlSchdApis *apis));
77 #ifdef EMTC_ENABLE
78 Void rgSCHEmtcHqInfoFree ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP));
79 Void rgSCHEmtcRrUlInit ARGS((RgUlSchdApis *apis));
80 Void rgSCHEmtcCmnDlInit ARGS((Void));
81 Void rgSCHEmtcCmnUlInit ARGS((Void));
82 Void rgSCHEmtcCmnUeNbReset ARGS((RgSchUeCb *ueCb));
83 RgSchCmnCqiToTbs *rgSchEmtcCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
84 #endif
85 Void rgSCHMaxciUlInit ARGS((RgUlSchdApis *apis));
86 Void rgSCHPfsUlInit ARGS((RgUlSchdApis *apis));
87 #endif
88 Void rgSCHSc1DlInit ARGS((RgDlSchdApis *apis));
89 #ifdef RG_PHASE2_SCHED
90 Void rgSCHRrDlInit ARGS((RgDlSchdApis *apis));
91 #ifdef EMTC_ENABLE
92 Void rgSCHEmtcRrDlInit ARGS((RgDlEmtcSchdApis *apis));
93 #endif
94 Void rgSCHMaxciDlInit ARGS((RgDlSchdApis *apis));
95 Void rgSCHPfsDlInit ARGS((RgDlSchdApis *apis));
96 #ifdef TFU_UPGRADE
97 Void rgSCHDlfsInit ARGS((RgDlfsSchdApis *apis));
98 #endif
99 #endif
100 #ifdef EMTC_ENABLE
101 Void rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl ARGS((RgSchCellCb *cell));
102 Void rgSCHCmnGetEmtcDciFrmtSizes ARGS((RgSchCellCb *cell));
103 Void rgSCHEmtcRrUlProcRmvFrmRetx ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *proc));
104 S16 rgSCHCmnPrecompEmtcMsg3Vars
105 ARGS((
106 RgSchCmnUlCell *cellUl,
107 uint8_t           ccchCqi,
108 uint16_t          msgSzA,
109 uint8_t           sbSize,
110 Bool         isEcp
111 ));
112 Void rgSCHEmtcCmnUeCcchSduDel
113 (
114 RgSchCellCb  *cell,
115 RgSchUeCb    *ueCb
116 );
117 Void rgSCHEmtcRmvFrmTaLst
118 (
119 RgSchCmnDlCell  *cellDl,
120 RgSchUeCb       *ue
121 );
122 Void rgSCHEmtcInitTaLst
123 (
124 RgSchCmnDlCell  *cellDl
125 );
126 Void rgSCHEmtcAddToTaLst
127 (
128 RgSchCmnDlCell  *cellDl,
129 RgSchUeCb       *ue
130 );
131
132 #endif
133
134 #ifdef RGR_SI_SCH
135 static Void rgSCHDlSiSched ARGS((RgSchCellCb  *cell,
136                       RgSchCmnDlRbAllocInfo *allocInfo,
137                       RgInfSfAlloc  *subfrmAlloc));
138 static Void rgSCHChkNUpdSiCfg ARGS((RgSchCellCb  *cell));
139 static Void rgSCHSelectSi ARGS((RgSchCellCb *cell));
140 #endif /*RGR_SI_SCH*/
141 /* LTE_ADV_FLAG_REMOVED_START */
142 #ifdef UNUSED_FUNC
143 #ifndef LTE_TDD
144 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
145 (
146 RgSchCellCb        *cell,
147 RgSchUeCb          *ue,
148 RgSchDlSf          *dlSf,
149 uint8_t                 rbStrt,
150 uint8_t                 numRb
151 );
152 static S16 rgSCHCmnBuildRntpInfo (
153 RgSchCellCb        *cell,
154 uint8_t                 *rntpPtr,
155 uint8_t                  startRb,
156 uint8_t                  nmbRb,
157 uint16_t                 bw
158 );
159 #endif
160 static Void rgSCHCmnNonDlfsType0Alloc
161 (
162 RgSchCellCb        *cell,
163 RgSchDlSf          *dlSf,
164 RgSchDlRbAlloc     *allocInfo,
165 RgSchUeCb          *ue
166 );
167 static uint8_t rgSchCmnUlRvIdxToIMcsTbl[4] = {32, 30, 31, 29};
168 static Void rgSCHCmnUlNonadapRetx ARGS((
169 RgSchCmnUlCell  *cellUl,
170 RgSchUlAlloc    *alloc,
171 uint8_t               idx
172 ));
173 static Void rgSCHCmnUlSfRlsRetxProcs ARGS((
174 RgSchCellCb *cell,
175 RgSchUlSf   *sf
176 ));
177
178 #ifdef TFU_UPGRADE
179 static S16 rgSCHCmnUlMdfyGrntForCqi ARGS((
180 RgSchCellCb  *cell,
181 RgSchUeCb    *ue,
182 uint32_t          maxRb,
183 uint32_t          *numSb,
184 uint8_t           *iTbs,
185 uint32_t          hqSz,
186 uint32_t          stepDownItbs,
187 uint32_t          effTgt
188 ));
189 #endif
190 static Void rgSCHCmnFillHqPPdcchDciFrmt1 ARGS((
191 RgSchCellCb                *cell,
192 RgSchDlRbAlloc             *rbAllocInfo,
193 RgSchDlHqProcCb            *hqP,
194 RgSchPdcch                 *pdcch,
195 uint8_t                         tpc
196 ));
197 static Void rgSCHCmnFillHqPPdcchDciFrmt1A ARGS((
198 RgSchCellCb                *cell,
199 RgSchDlRbAlloc             *rbAllocInfo,
200 RgSchDlHqProcCb            *hqP,
201 RgSchPdcch                 *pdcch,
202 uint8_t                         tpc
203 ));
204 static Void rgSCHCmnFillHqPPdcchDciFrmt1B ARGS((
205 RgSchCellCb                *cell,
206 RgSchDlRbAlloc             *rbAllocInfo,
207 RgSchDlHqProcCb            *hqP,
208 RgSchPdcch                 *pdcch,
209 uint8_t                         tpc
210 ));
211 static Void rgSCHCmnFillHqPPdcchDciFrmt2 ARGS((
212 RgSchCellCb                *cell,
213 RgSchDlRbAlloc             *rbAllocInfo,
214 RgSchDlHqProcCb            *hqP,
215 RgSchPdcch                 *pdcch,
216 uint8_t                         tpc
217 ));
218 static Void rgSCHCmnFillHqPPdcchDciFrmt2A ARGS((
219 RgSchCellCb                *cell,
220 RgSchDlRbAlloc             *rbAllocInfo,
221 RgSchDlHqProcCb            *hqP,
222 RgSchPdcch                 *pdcch,
223 uint8_t                         tpc
224 ));
225
226 #endif
227
228 Void rgSCHCmnDlSpsSch
229 (
230  RgSchCellCb        *cell
231 );
232 /* LTE_ADV_FLAG_REMOVED_END */
233
234 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc ARGS((
235 RgSchCellCb           *cell,
236 RgSchCmnDlRbAllocInfo *allocInfo
237 ));
238 static Void rgSCHBcchPcchDlRbAlloc ARGS((
239 RgSchCellCb           *cell,
240 RgSchCmnDlRbAllocInfo *allocInfo
241 ));
242 static Void rgSCHCmnDlBcchPcchAlloc ARGS((
243 RgSchCellCb  *cell
244 ));
245 #ifdef RGR_CQI_REPT
246 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
247  RgSchCellCb        *cell,
248  RgSchUeCb          *ue,
249  TfuDlCqiPucch      *pucchCqi,
250  RgrUeCqiRept       *ueCqiRept,
251  Bool               *isCqiAvail,
252  Bool               *is2ndCwCqiAvail
253  ));
254 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
255  RgSchCellCb        *cell,
256  RgSchUeCb          *ue,
257  TfuDlCqiPusch      *puschCqi,
258  RgrUeCqiRept       *ueCqiRept,
259  Bool               *isCqiAvail,
260  Bool               *is2ndCwCqiAvail
261  ));
262 #else
263 static Void rgSCHCmnDlCqiOnPucchInd ARGS ((
264  RgSchCellCb        *cell,
265  RgSchUeCb          *ue,
266  TfuDlCqiPucch      *pucchCqi
267  ));
268 static Void rgSCHCmnDlCqiOnPuschInd ARGS ((
269  RgSchCellCb        *cell,
270  RgSchUeCb          *ue,
271  TfuDlCqiPusch      *puschCqi
272  ));
273 #endif
274 /* ccpu00117452 - MOD - Changed macro name from
275    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
276 #ifdef RGR_CQI_REPT
277 static S16 rgSCHCmnUeDlPwrCtColltCqiRept ARGS((
278    RgSchCellCb        *cell,
279    RgSchUeCb          *ue,
280    RgrUeCqiRept        *ueCqiRept));
281 #endif /* End of RGR_CQI_REPT */
282 /* Fix: syed align multiple UEs to refresh at same time */
283 static Void rgSCHCmnGetRefreshPer ARGS((
284    RgSchCellCb  *cell,
285    RgSchUeCb    *ue,
286    uint32_t          *waitPer));
287 static S16 rgSCHCmnApplyUeRefresh ARGS((
288 RgSchCellCb     *cell,
289 RgSchUeCb       *ue));
290 #ifdef DL_LA
291 Void rgSCHCmnDlSetUeAllocLmtLa ARGS
292 ((
293 RgSchCellCb   *cell,
294 RgSchUeCb     *ue
295 ));
296 static Void rgSCHCheckAndSetTxScheme ARGS
297 ((
298 RgSchCellCb   *cell,
299 RgSchUeCb     *ue
300 ));
301 #endif
302
303 #ifdef LTE_TDD
304 static uint32_t rgSCHCmnCalcDwPtsTbSz ARGS
305 ((
306 RgSchCellCb    *cell,
307 uint32_t             bo,
308 uint8_t             *rb,
309 uint8_t             *iTbs,
310 uint8_t              lyr,
311 uint8_t              cfi
312 ));
313
314 static Void rgSCHCmnCalcDwPtsTbSz2Cw ARGS
315 ((
316 RgSchCellCb    *cell,
317 uint32_t             bo,
318 uint8_t             *rb,
319 uint8_t              maxRb,
320 uint8_t             *iTbs1,
321 uint8_t             *iTbs2,
322 uint8_t              lyr1,
323 uint8_t              lyr2,
324 uint32_t            *tb1Sz, 
325 uint32_t            *tb2Sz, 
326 uint8_t              cfi
327 ));
328
329 #endif
330 static Void  rgSCHCmnInitRbAlloc ARGS 
331 ((
332 RgSchCellCb        *cell
333 ));
334 #ifdef __cplusplus
335 }
336 #endif /* __cplusplus */
337
338
339 /* local defines */
340  RgSchdApis          rgSchCmnApis;
341 static RgUlSchdApis        rgSchUlSchdTbl[RGSCH_NUM_SCHEDULERS];
342 static RgDlSchdApis        rgSchDlSchdTbl[RGSCH_NUM_SCHEDULERS];
343 #ifdef EMTC_ENABLE
344 static RgUlSchdApis        rgSchEmtcUlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
345 static RgDlEmtcSchdApis        rgSchEmtcDlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS];
346 #endif
347 #ifdef RG_PHASE2_SCHED
348 static RgDlfsSchdApis      rgSchDlfsSchdTbl[RGSCH_NUM_DLFS_SCHEDULERS];
349 #endif
350 RgUlSchdInits       rgSchUlSchdInits = RGSCH_ULSCHED_INITS;
351 RgDlSchdInits       rgSchDlSchdInits = RGSCH_DLSCHED_INITS;
352 #ifdef EMTC_ENABLE
353 static RgEmtcUlSchdInits       rgSchEmtcUlSchdInits = RGSCH_EMTC_ULSCHED_INITS;
354 static RgEmtcDlSchdInits       rgSchEmtcDlSchdInits = RGSCH_EMTC_DLSCHED_INITS;
355 #endif
356 #if (defined (RG_PHASE2_SCHED) && defined (TFU_UPGRADE))
357 static RgDlfsSchdInits     rgSchDlfsSchdInits = RGSCH_DLFSSCHED_INITS;
358 #endif
359
360 typedef Void (*RgSchCmnDlAllocRbFunc) ARGS((RgSchCellCb *cell, RgSchDlSf *subFrm,
361 RgSchUeCb *ue, uint32_t bo, uint32_t *effBo, RgSchDlHqProcCb *proc,
362 RgSchCmnDlRbAllocInfo *cellWdAllocInfo));
363 typedef uint8_t (*RgSchCmnDlGetPrecInfFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, 
364       uint8_t numLyrs, Bool bothCwEnbld));
365 static Void rgSCHCmnDlAllocTxRbTM1 ARGS((
366 RgSchCellCb                *cell,
367 RgSchDlSf                  *subFrm,
368 RgSchUeCb                  *ue,
369 uint32_t                        bo,
370 uint32_t                        *effBo,
371 RgSchDlHqProcCb            *proc,
372 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
373 ));
374 static Void rgSCHCmnDlAllocTxRbTM2 ARGS((
375 RgSchCellCb                *cell,
376 RgSchDlSf                  *subFrm,
377 RgSchUeCb                  *ue,
378 uint32_t                        bo,
379 uint32_t                        *effBo,
380 RgSchDlHqProcCb            *proc,
381 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
382 ));
383 static Void rgSCHCmnDlAllocTxRbTM3 ARGS((
384 RgSchCellCb                *cell,
385 RgSchDlSf                  *subFrm,
386 RgSchUeCb                  *ue,
387 uint32_t                        bo,
388 uint32_t                        *effBo,
389 RgSchDlHqProcCb            *proc,
390 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
391 ));
392 static Void rgSCHCmnDlAllocTxRbTM4 ARGS((
393 RgSchCellCb                *cell,
394 RgSchDlSf                  *subFrm,
395 RgSchUeCb                  *ue,
396 uint32_t                        bo,
397 uint32_t                        *effBo,
398 RgSchDlHqProcCb            *proc,
399 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
400 ));
401 #ifdef RG_UNUSED
402 static Void rgSCHCmnDlAllocTxRbTM5 ARGS((
403 RgSchCellCb                *cell,
404 RgSchDlSf                  *subFrm,
405 RgSchUeCb                  *ue,
406 uint32_t                        bo,
407 uint32_t                        *effBo,
408 RgSchDlHqProcCb            *proc,
409 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
410 ));
411 #endif
412 static Void rgSCHCmnDlAllocTxRbTM6 ARGS((
413 RgSchCellCb                *cell,
414 RgSchDlSf                  *subFrm,
415 RgSchUeCb                  *ue,
416 uint32_t                        bo,
417 uint32_t                        *effBo,
418 RgSchDlHqProcCb            *proc,
419 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
420 ));
421 static Void rgSCHCmnDlAllocTxRbTM7 ARGS((
422 RgSchCellCb                *cell,
423 RgSchDlSf                  *subFrm,
424 RgSchUeCb                  *ue,
425 uint32_t                        bo,
426 uint32_t                        *effBo,
427 RgSchDlHqProcCb            *proc,
428 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
429 ));
430 static Void rgSCHCmnDlAllocRetxRbTM1 ARGS((
431 RgSchCellCb                *cell,
432 RgSchDlSf                  *subFrm,
433 RgSchUeCb                  *ue,
434 uint32_t                        bo,
435 uint32_t                        *effBo,
436 RgSchDlHqProcCb            *proc,
437 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
438 ));
439 static Void rgSCHCmnDlAllocRetxRbTM2 ARGS((
440 RgSchCellCb                *cell,
441 RgSchDlSf                  *subFrm,
442 RgSchUeCb                  *ue,
443 uint32_t                        bo,
444 uint32_t                        *effBo,
445 RgSchDlHqProcCb            *proc,
446 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
447 ));
448 static Void rgSCHCmnDlAllocRetxRbTM3 ARGS((
449 RgSchCellCb                *cell,
450 RgSchDlSf                  *subFrm,
451 RgSchUeCb                  *ue,
452 uint32_t                        bo,
453 uint32_t                        *effBo,
454 RgSchDlHqProcCb            *proc,
455 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
456 ));
457 static Void rgSCHCmnDlAllocRetxRbTM4 ARGS((
458 RgSchCellCb                *cell,
459 RgSchDlSf                  *subFrm,
460 RgSchUeCb                  *ue,
461 uint32_t                        bo,
462 uint32_t                        *effBo,
463 RgSchDlHqProcCb            *proc,
464 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
465 ));
466 #ifdef RG_UNUSED
467 static Void rgSCHCmnDlAllocRetxRbTM5 ARGS((
468 RgSchCellCb                *cell,
469 RgSchDlSf                  *subFrm,
470 RgSchUeCb                  *ue,
471 uint32_t                        bo,
472 uint32_t                        *effBo,
473 RgSchDlHqProcCb            *proc,
474 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
475 ));
476 #endif
477 static Void rgSCHCmnDlAllocRetxRbTM6 ARGS((
478 RgSchCellCb                *cell,
479 RgSchDlSf                  *subFrm,
480 RgSchUeCb                  *ue,
481 uint32_t                        bo,
482 uint32_t                        *effBo,
483 RgSchDlHqProcCb            *proc,
484 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
485 ));
486 static Void rgSCHCmnDlAllocRetxRbTM7 ARGS((
487 RgSchCellCb                *cell,
488 RgSchDlSf                  *subFrm,
489 RgSchUeCb                  *ue,
490 uint32_t                        bo,
491 uint32_t                        *effBo,
492 RgSchDlHqProcCb            *proc,
493 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
494 ));
495
496 #ifdef LTE_ADV 
497 static uint8_t rgSchGetN1ResCount ARGS ((
498  RgSchUeCb *ue,
499  uint16_t       servCellId 
500 ));
501 Bool rgSchCmnChkDataOnlyOnPcell 
502 (
503  RgSchUeCb         *ue,
504  RgSchDlSf         *dlSf
505 );
506 #endif /*LTE_ADV */
507 uint8_t rgSCHCmnCalcPcqiBitSz
508 (
509  RgSchUeCb    *ueCb, 
510  uint8_t           numTxAnt
511 );
512
513 #ifndef LTE_ADV
514 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
515 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[7] = {rgSCHCmnDlAllocTxRbTM1,
516 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
517 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7};
518
519 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
520 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[7] = {rgSCHCmnDlAllocRetxRbTM1,
521 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
522 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7};
523 #else
524 /* Functions specific to each transmission mode for DL Tx RB Allocation*/
525 RgSchCmnDlAllocRbFunc  dlAllocTxRbFunc[9] = {rgSCHCmnDlAllocTxRbTM1,
526 rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4,
527 NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7, NULLP, NULLP};
528
529 /* Functions specific to each transmission mode for DL Retx RB Allocation*/
530 RgSchCmnDlAllocRbFunc  dlAllocRetxRbFunc[9] = {rgSCHCmnDlAllocRetxRbTM1,
531 rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4,
532 NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7, NULLP, NULLP};
533
534 #endif
535
536
537 static uint8_t rgSCHCmnDlTM3PrecInf2 ARGS((
538 RgSchCellCb                *cell,
539 RgSchUeCb                  *ue,
540 uint8_t                         numTxLyrs,
541 Bool                       bothCwEnbld
542 ));
543 static uint8_t rgSCHCmnDlTM3PrecInf4 ARGS((
544 RgSchCellCb                *cell,
545 RgSchUeCb                  *ue,
546 uint8_t                         numTxLyrs,
547 Bool                       bothCwEnbld
548 ));
549 static uint8_t rgSCHCmnDlTM4PrecInf2 ARGS((
550 RgSchCellCb                *cell,
551 RgSchUeCb                  *ue,
552 uint8_t                         numTxLyrs,
553 Bool                       bothCwEnbld
554 ));
555 static uint8_t rgSCHCmnDlTM4PrecInf4 ARGS((
556 RgSchCellCb                *cell,
557 RgSchUeCb                  *ue,
558 uint8_t                         numTxLyrs,
559 Bool                       bothCwEnbld
560 ));
561 /* Functions specific to each transmission mode for DL RB Allocation*/
562 RgSchCmnDlGetPrecInfFunc getPrecInfoFunc[2][2] = {
563 {rgSCHCmnDlTM3PrecInf2, rgSCHCmnDlTM3PrecInf4},
564 {rgSCHCmnDlTM4PrecInf2, rgSCHCmnDlTM4PrecInf4}
565 };
566
567 static S16 rgSCHCmnDlAlloc1CwRetxRb ARGS((
568 RgSchCellCb                *cell,
569 RgSchDlSf                  *subFrm,
570 RgSchUeCb                  *ue,
571 RgSchDlHqTbCb              *tbInfo,
572 uint8_t                         noLyr,
573 uint8_t                         *numRb,
574 uint32_t                        *effBo
575 ));
576 static S16 rgSCHCmnDlAlloc2CwRetxRb ARGS((
577 RgSchCellCb                *cell,
578 RgSchDlSf                  *subFrm,
579 RgSchUeCb                  *ue,
580 RgSchDlHqProcCb            *proc,
581 uint8_t                         *numRb,
582 Bool                       *swpFlg,
583 uint32_t                        *effBo
584 ));
585 static Void rgSCHCmnDlTM3TxTx ARGS((
586 RgSchCellCb                *cell,
587 RgSchDlSf                  *subFrm,
588 RgSchUeCb                  *ue,
589 uint32_t                        bo,
590 uint32_t                        *effBo,
591 RgSchDlHqProcCb            *proc,
592 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
593 ));
594 static Void rgSCHCmnDlTM3TxRetx ARGS((
595 RgSchCellCb                *cell,
596 RgSchDlSf                  *subFrm,
597 RgSchUeCb                  *ue,
598 uint32_t                        bo,
599 uint32_t                        *effBo,
600 RgSchDlHqProcCb            *proc,
601 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
602 ));
603 static Void rgSCHCmnDlTM3RetxRetx ARGS((
604 RgSchCellCb                *cell,
605 RgSchDlSf                  *subFrm,
606 RgSchUeCb                  *ue,
607 uint32_t                        bo,
608 uint32_t                        *effBo,
609 RgSchDlHqProcCb            *proc,
610 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
611 ));
612
613 static Void rgSCHCmnNonDlfsUpdTyp2Alloc ARGS((
614 RgSchCellCb        *cell,
615 RgSchDlSf          *dlSf,
616 uint8_t                 rbStrt,
617 uint8_t                 numRb
618 ));
619 /* LTE_ADV_FLAG_REMOVED_START */
620 #ifndef LTE_TDD
621 static Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc ARGS((
622 RgSchCellCb        *cell,
623 RgSchDlSf          *dlSf,
624 uint8_t                 rbStrt,
625 uint8_t                 numRb
626 ));
627 #endif
628 /* LTE_ADV_FLAG_REMOVED_END */
629 static Void rgSCHCmnDlRbInfoAddUeTx ARGS((
630 RgSchCellCb        *cell,
631 RgSchCmnDlRbAllocInfo *allocInfo,
632 RgSchUeCb             *ue,
633 RgSchDlHqProcCb       *proc
634 ));
635 static Void rgSCHCmnDlRbInfoAddUeRetx ARGS((
636 RgSchCellCb        *cell,
637 RgSchCmnDlRbAllocInfo *allocInfo,
638 RgSchUeCb             *ue,
639 RgSchDlHqProcCb       *hqP
640 ));
641 static Void rgSCHCmnDlAdd2NonSchdRetxLst ARGS((
642 RgSchCmnDlRbAllocInfo *allocInfo,
643 RgSchUeCb             *ue,
644 RgSchDlHqProcCb       *proc
645 ));
646 static S16 rgSCHCmnDlAlloc2CwTxRetxRb ARGS((
647 RgSchCellCb                *cell,
648 RgSchDlSf                  *subFrm,
649 RgSchUeCb                  *ue,
650 RgSchDlHqTbCb              *reTxTb,
651 RgSchDlHqTbCb              *txTb,
652 uint8_t                         *numRb,
653 uint32_t                        *effBo
654 ));
655 static S16 rgSCHCmnDlAlloc2CwTxRb ARGS((
656 RgSchCellCb                *cell,
657 RgSchDlSf                  *subFrm,
658 RgSchUeCb                  *ue,
659 RgSchDlHqProcCb            *proc,
660 uint32_t                        bo,
661 uint8_t                         *numRb,
662 uint32_t                        *effBo
663 ));
664 static S16 rgSCHCmnDlAlloc1CwTxRb ARGS((
665 RgSchCellCb                *cell,
666 RgSchDlSf                  *subFrm,
667 RgSchUeCb                  *ue,
668 RgSchDlHqTbCb              *tbInfo,
669 uint32_t                        bo,
670 uint8_t                         *numRb,
671 uint32_t                        *effBo
672 ));
673 #ifndef LTEMAC_SPS
674 static Void rgSCHCmnFillHqPTb ARGS((
675 RgSchCellCb                *cell,
676 RgSchDlRbAlloc             *rbAllocInfo,
677 uint8_t                         tbAllocIdx,
678 RgSchPdcch                 *pdcch
679 ));
680 #endif
681 #ifdef LTEMAC_SPS
682 static Void rgSCHCmnDlGetBestFitHole ARGS((
683 uint32_t         *allocMask,
684 uint8_t          numMaskRbs,
685 uint32_t         *crntAllocMask,
686 uint8_t          rbsReq,
687 uint8_t          *allocStart,
688 uint8_t          *allocNumRbs,
689 Bool        isPartialAlloc
690 ));
691 #ifdef RGSCH_SPS_UNUSED
692 static uint32_t rgSCHCmnGetRaType1Mask ARGS((
693 uint8_t                rbIdx,
694 uint8_t                rbgSize,
695 uint8_t                *type1Subset
696 ));
697 #endif
698 static uint32_t rgSCHCmnGetRaType0Mask ARGS((
699 uint8_t                rbIdx,
700 uint8_t                rbgSize
701 ));
702 static uint32_t rgSCHCmnGetRaType2Mask ARGS((
703 uint8_t                rbIdx,
704 uint8_t                *maskIdx
705 ));
706 #endif
707
708 Bool rgSCHCmnRetxAllocAvoid ARGS(( 
709 RgSchDlSf                  *subFrm,
710 RgSchCellCb                *cell,
711 RgSchDlHqProcCb            *proc
712 ));
713
714 uint16_t rgSCHCmnGetSiSetId ARGS((
715 uint16_t    sfn,
716 uint8_t     sf,
717 uint16_t    minPeriodicity
718 ));
719
720
721 #ifdef RG_5GTF
722 //TODO_SID: Currenly table is only for 100 Prbs. Need to modify wrt VRBG table 8.1.5.2.1-1 V5G_213
723 uint32_t rgSch5gtfTbSzTbl[MAX_5GTF_MCS] = 
724     {1864, 5256, 8776, 13176, 17576, 21976, 26376, 31656, 35176, 39576, 43976, 47496, 52776, 59376, 66392};
725 uint32_t g5gtfTtiCnt = 0;
726 uint32_t gUl5gtfSrRecv = 0;
727 uint32_t gUl5gtfBsrRecv = 0;
728 uint32_t gUl5gtfUeSchPick = 0;
729 uint32_t gUl5gtfPdcchSchd = 0;
730 uint32_t gUl5gtfAllocAllocated = 0;
731 uint32_t gUl5gtfUeRbAllocDone = 0;
732 uint32_t gUl5gtfUeRmvFnlzZeroBo = 0;
733 uint32_t gUl5gtfUeFnlzReAdd = 0;
734 uint32_t gUl5gtfPdcchSend = 0;
735 uint32_t gUl5gtfRbAllocFail = 0;
736 uint32_t ul5gtfsidUlMarkUl = 0;
737 uint32_t ul5gtfsidDlSchdPass = 0;
738 uint32_t ul5gtfsidDlAlreadyMarkUl = 0;
739 uint32_t ul5gtfTotSchdCnt = 0;
740 #endif
741
742 /* CQI Offset Index to Beta CQI Offset value mapping,
743  * stored as parts per 1000. Reserved is set to 0.
744  * Refer 36.213 sec 8.6.3 Tbl 8.6.3-3 */
745 uint32_t rgSchCmnBetaCqiOffstTbl[16] = {0, 0, 1125,
746    1250, 1375, 1625, 1750, 2000, 2250, 2500, 2875,
747    3125, 3500, 4000, 5000, 6250};
748 uint32_t rgSchCmnBetaHqOffstTbl[16] =  {2000, 2500, 3125, 
749    4000, 5000, 6250, 8000,10000, 12625, 15875, 20000, 
750    31000, 50000,80000,126000,0};
751 uint32_t rgSchCmnBetaRiOffstTbl[16] = {1250, 1625, 2000, 
752    2500, 3125, 4000, 5000, 6250, 8000, 10000,12625,
753    15875,20000,0,0,0};
754 S8 rgSchCmnDlCqiDiffOfst[8] = {0, 1, 2, 3, -4, -3, -2, -1};
755
756 /* Include CRS REs while calculating Efficiency */
757 const static uint8_t rgSchCmnAntIdx[5] = {0,0,1,0,2};
758 const static uint8_t rgSchCmnNumResForCrs[5] = {0,6,12,0,16};
759 uint32_t cfiSwitchCnt ;
760 uint32_t cfiIncr ;
761 uint32_t cfiDecr ;
762
763
764 #ifdef TFU_UPGRADE
765 S8 rgSchCmnApUeSelDiffCqi[4] = {1, 2, 3, 4};
766 S8 rgSchCmnApEnbConfDiffCqi[4] = {0, 1, 2, -1};
767 #endif
768
769 typedef struct rgSchCmnDlUeDciFrmtOptns
770 {
771   TfuDciFormat spfcDciFrmt;   /* TM(Transmission Mode) specific DCI format.
772                                * Search space : UE Specific by C-RNTI only. */
773   uint8_t           spfcDciRAType; /* Resource Alloctn(RA) type for spfcDciFrmt */
774   TfuDciFormat prfrdDciFrmt;  /* Preferred DCI format among the available
775                                * options for TD (Transmit Diversity) */
776   uint8_t           prfrdDciRAType; /* Resource Alloctn(RA) type for prfrdDciFrmt */
777 }RgSchCmnDlUeDciFrmtOptns;
778 #ifndef LTE_ADV
779
780 /* DCI Format options for each Transmission Mode */
781 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[7] = {
782    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
783    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
784    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
785    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
786    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
787    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
788    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
789 };
790
791 #else
792 /* DCI Format options for each Transmission Mode */
793 RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[9] = {
794    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
795    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
796    {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
797    {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
798    {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
799    {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2},
800    {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}
801 };
802 #endif
803
804
805 typedef struct rgSchCmnDlImcsTbl
806 {
807   uint8_t   modOdr; /* Modulation Order */
808   uint8_t   iTbs;   /* ITBS */
809 }RgSchCmnDlImcsTbl[29];
810
811 const struct rgSchCmnMult235Info
812 {
813    uint8_t   match;    /* Closest number satisfying 2^a.3^b.5^c, with a bias
814                   * towards the smaller number */
815    uint8_t   prvMatch; /* Closest number not greater than array index
816                   * satisfying 2^a.3^b.5^c */
817 } rgSchCmnMult235Tbl[110+1] = {
818    {0, 0},  /* dummy */
819    {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {6, 6}, {8, 8},
820    {9, 9}, {10, 10}, {10, 10}, {12, 12}, {12, 12}, {15, 12}, {15, 15},
821    {16, 16}, {16, 16}, {18, 18}, {18, 18}, {20, 20}, {20, 20}, {20, 20},
822    {24, 20}, {24, 24}, {25, 25}, {25, 25}, {27, 27}, {27, 27}, {30, 27},
823    {30, 30}, {30, 30}, {32, 32}, {32, 32}, {32, 32}, {36, 32}, {36, 36},
824    {36, 36}, {36, 36}, {40, 36}, {40, 40}, {40, 40}, {40, 40}, {45, 40},
825    {45, 40}, {45, 45}, {45, 45}, {48, 45}, {48, 48}, {48, 48}, {50, 50},
826    {50, 50}, {50, 50}, {54, 50}, {54, 54}, {54, 54}, {54, 54}, {54, 54},
827    {60, 54}, {60, 54}, {60, 60}, {60, 60}, {60, 60}, {64, 60}, {64, 64},
828    {64, 64}, {64, 64}, {64, 64}, {64, 64}, {72, 64}, {72, 64}, {72, 64},
829    {72, 72}, {72, 72}, {75, 72}, {75, 75}, {75, 75}, {75, 75}, {80, 75},
830    {80, 75}, {80, 80}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, {81, 81},
831    {90, 81}, {90, 81}, {90, 81}, {90, 81}, {90, 90}, {90, 90}, {90, 90},
832    {90, 90}, {96, 90}, {96, 90}, {96, 96}, {96, 96}, {96, 96}, {100, 96},
833    {100, 100}, {100, 100}, {100, 100}, {100, 100}, {100, 100}, {108, 100},
834    {108, 100}, {108, 100}, {108, 108}, {108, 108}, {108, 108}
835 };
836
837 /* R8 Upgrade */
838 /* BI table from 36.321 Table 7.2.1 */
839 const static S16 rgSchCmnBiTbl[RG_SCH_CMN_NUM_BI_VAL] = {
840       0, 10, 20, 30,40,60,80,120,160,240,320,480,960};
841 RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI] = {
842  {     0,                0              },
843  {RGSCH_CMN_QM_CQI_1,RGSCH_CMN_UL_EFF_CQI_1 },
844  {RGSCH_CMN_QM_CQI_2,RGSCH_CMN_UL_EFF_CQI_2 },
845  {RGSCH_CMN_QM_CQI_3,RGSCH_CMN_UL_EFF_CQI_3 },
846  {RGSCH_CMN_QM_CQI_4,RGSCH_CMN_UL_EFF_CQI_4 },
847  {RGSCH_CMN_QM_CQI_5,RGSCH_CMN_UL_EFF_CQI_5 },
848  {RGSCH_CMN_QM_CQI_6,RGSCH_CMN_UL_EFF_CQI_6 },
849  {RGSCH_CMN_QM_CQI_7,RGSCH_CMN_UL_EFF_CQI_7 },
850  {RGSCH_CMN_QM_CQI_8,RGSCH_CMN_UL_EFF_CQI_8 },
851  {RGSCH_CMN_QM_CQI_9,RGSCH_CMN_UL_EFF_CQI_9 },
852  {RGSCH_CMN_QM_CQI_10,RGSCH_CMN_UL_EFF_CQI_10 },
853  {RGSCH_CMN_QM_CQI_11,RGSCH_CMN_UL_EFF_CQI_11 },
854  {RGSCH_CMN_QM_CQI_12,RGSCH_CMN_UL_EFF_CQI_12 },
855  {RGSCH_CMN_QM_CQI_13,RGSCH_CMN_UL_EFF_CQI_13 },
856  {RGSCH_CMN_QM_CQI_14,RGSCH_CMN_UL_EFF_CQI_14 },
857  {RGSCH_CMN_QM_CQI_15,RGSCH_CMN_UL_EFF_CQI_15 },
858 };
859
860 #ifdef RG_UNUSED
861 /* This table maps a (delta_offset * 2 + 2) to a (beta * 8)
862  * where beta is 10^-(delta_offset/10) rounded off to nearest 1/8
863  */
864 static uint16_t rgSchCmnUlBeta8Tbl[29] = {
865    6, RG_SCH_CMN_UL_INVALID_BETA8, 8, 9, 10, 11, 13, 14, 16, 18, 20, 23,
866    25, 28, 32, RG_SCH_CMN_UL_INVALID_BETA8, 40, RG_SCH_CMN_UL_INVALID_BETA8,
867    50, RG_SCH_CMN_UL_INVALID_BETA8, 64, RG_SCH_CMN_UL_INVALID_BETA8, 80,
868    RG_SCH_CMN_UL_INVALID_BETA8, 101, RG_SCH_CMN_UL_INVALID_BETA8, 127,
869    RG_SCH_CMN_UL_INVALID_BETA8, 160
870 };
871 #endif
872
873 /* QCI to SVC priority mapping. Index specifies the Qci*/
874 static uint8_t rgSchCmnDlQciPrio[RG_SCH_CMN_MAX_QCI] = RG_SCH_CMN_QCI_TO_PRIO;
875
876 /* The configuration is efficiency measured per 1024 REs.  */
877 /* The first element stands for when CQI is not known      */
878 /* This table is used to translate CQI to its corrospoding */
879 /* allocation parameters. These are currently from 36.213  */
880 /* Just this talbe needs to be edited for modifying the    */
881 /* the resource allocation behaviour                       */
882
883 /* ADD CQI to MCS mapping correction
884  * single dimensional array is replaced by 2 dimensions for different CFI*/
885 static uint16_t rgSchCmnCqiPdschEff[4][16] = {RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1,
886     RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3};
887
888 static uint16_t rgSchCmn2LyrCqiPdschEff[4][16] = {RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1,
889     RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2, RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3};
890
891 /* This configuration determines the transalation of a UEs CQI to its    */
892 /* PDCCH coding efficiency. This may be edited based on the installation */
893 static uint8_t rgSchCmnDlRvTbl[4] = {0, 2, 3, 1}; /* RVIdx sequence is corrected*/
894
895 /* Indexed by [DciFrmt].
896  * Considering the following definition in determining the dciFrmt index.
897  * typedef enum
898 {
899    TFU_DCI_FORMAT_0,
900    TFU_DCI_FORMAT_1,
901    TFU_DCI_FORMAT_1A,
902    TFU_DCI_FORMAT_1B,
903    TFU_DCI_FORMAT_1C,
904    TFU_DCI_FORMAT_1D,
905    TFU_DCI_FORMAT_2,
906    TFU_DCI_FORMAT_2A,
907    TFU_DCI_FORMAT_3,
908    TFU_DCI_FORMAT_3A
909 } TfuDciFormat;
910 */
911 static uint16_t rgSchCmnDciFrmtSizes[10];
912
913 static uint16_t rgSchCmnCqiPdcchEff[16] = RG_SCH_CMN_CQI_TO_PDCCH_EFF;
914
915 #ifdef LTE_TDD
916
917 RgSchTddUlDlSubfrmTbl rgSchTddUlDlSubfrmTbl = {
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_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_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_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_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_SPL_SUBFRAME, RG_SCH_TDD_UL_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_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME},
922    {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},
923    {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},
924    {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME,  RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_UL_SUBFRAME,  RG_SCH_TDD_DL_SUBFRAME}
925 };
926
927 /* SPS_INTG_FIX */
928 #ifdef LTEMAC_SPS
929 uint8_t rgSchTddSpsDlMaxRetxTbl[RGSCH_MAX_TDD_UL_DL_CFG] = {
930    /* 0 */ 6,
931    /* 1 */ 7,
932    /* 2 */ 8,
933    /* 3 */ 11,
934    /* 4 */ 12,
935    /* 5 */ 13,
936    /* 6 */ 7};
937
938 #endif
939
940
941 /* Special Subframes in OFDM symbols */
942 /* ccpu00134197-MOD-Correct the number of symbols */
943 RgSchTddSplSubfrmInfoTbl rgSchTddSplSubfrmInfoTbl = {
944         {3,  1, 1, 3,   1, 1},
945         {9,  1, 1, 8,   1, 1},
946         {10, 1, 1, 9,   1, 1},
947         {11, 1, 1, 10,  1, 1},
948         {12, 1, 1, 3,   2, 2},
949         {3,  2, 2, 8,   2, 2},
950         {9,  2, 2, 9,   2, 2},
951         {10, 2, 2, 0,   0, 0},
952         {11, 2, 2, 0,   0, 0}
953 };
954
955 /* PHICH 'm' value Table */
956 RgSchTddPhichMValTbl rgSchTddPhichMValTbl = {
957         {2, 1, 0, 0, 0, 2, 1, 0, 0, 0},
958         {0, 1, 0, 0, 1, 0, 1, 0, 0, 1},
959         {0, 0, 0, 1, 0, 0, 0, 0, 1, 0},
960         {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
961         {0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
962         {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
963         {1, 1, 0, 0, 0, 1, 1, 0, 0, 1}
964 };
965
966 /* PHICH 'K' value Table */
967 RgSchTddKPhichTbl rgSchTddKPhichTbl = {
968         {0, 0, 4, 7, 6, 0, 0, 4, 7, 6},
969         {0, 0, 4, 6, 0, 0, 0, 4, 6, 0},
970         {0, 0, 6, 0, 0, 0, 0, 6, 0, 0},
971         {0, 0, 6, 6, 6, 0, 0, 0, 0, 0},
972         {0, 0, 6, 6, 0, 0, 0, 0, 0, 0},
973         {0, 0, 6, 0, 0, 0, 0, 0, 0, 0},
974         {0, 0, 4, 6, 6, 0, 0, 4, 7, 0}
975 };
976
977 /* Uplink association index 'K' value Table */
978 RgSchTddUlAscIdxKDashTbl rgSchTddUlAscIdxKDashTbl = {
979         {0, 0, 6, 4, 0, 0, 0, 6, 4, 0},
980         {0, 0, 4, 0, 0, 0, 0, 4, 0, 0},
981         {0, 0, 4, 4, 4, 0, 0, 0, 0, 0},
982         {0, 0, 4, 4, 0, 0, 0, 0, 0, 0},
983         {0, 0, 4, 0, 0, 0, 0, 0, 0, 0},
984         {0, 0, 7, 7, 5, 0, 0, 7, 7, 0}
985 };
986
987
988 /* PUSCH 'K' value Table */
989 RgSchTddPuschTxKTbl rgSchTddPuschTxKTbl = {
990         {4, 6, 0, 0, 0, 4, 6, 0, 0, 0},
991         {0, 6, 0, 0, 4, 0, 6, 0, 0, 4},
992         {0, 0, 0, 4, 0, 0, 0, 0, 4, 0},
993         {4, 0, 0, 0, 0, 0, 0, 0, 4, 4},
994         {0, 0, 0, 0, 0, 0, 0, 0, 4, 4},
995         {0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
996         {7, 7, 0, 0, 0, 7, 7, 0, 0, 5}
997 };
998
999 /* PDSCH to PUCCH Table for DL Harq Feed back. Based on the 
1000    Downlink association set index 'K' table */
1001 uint8_t rgSchTddPucchTxTbl[7][10] = {
1002         {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1003         {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1004         {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1005         {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1006         {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1007         {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1008         {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1009 };
1010
1011 /* Table to fetch the next DL sf idx for applying the 
1012    new CFI. The next Dl sf Idx at which the new CFI 
1013    is applied is always the starting Sf of the next ACK/NACK
1014    Fdbk bundle. 
1015    
1016    Ex: In Cfg-2, sf4 and sf9 are the only subframes at which 
1017        a new ACK/NACK bundle of DL subframes can start
1018        
1019    D  S  U  D  D  D  S  U  D  D  D  S  U  D  D  D  S  U  D  D    
1020                4              9
1021    
1022    dlSf Array for Cfg-2:
1023    sfNum:  0  1  3  4  5  6  8  9  0  1   3  4  5  6  8  9 
1024    sfIdx:  0  1  2  3  4  5  6  7  8  9  10 11 12 12 14 15 
1025     
1026    If CFI changes at sf0,  nearest DL SF bundle >= 4 TTI is sf4
1027    So at sf4 the new CFI can be applied. To arrive at sf4 from
1028    sf0, the sfIdx has to be increased by 3 */  
1029                  
1030 uint8_t rgSchTddPdcchSfIncTbl[7][10] = {
1031  /* A/N Bundl: 0,1,5,6*/   {2,  1,  0, 0, 0, 2, 1,  0,  0,  0},
1032  /* A/N Bundl: 0,4,5,9*/   {2,  2,  0, 0, 3, 2, 2,  0,  0,  3},
1033  /* A/N Bundl: 4,9*/       {3,  6,  0, 5, 4, 3, 6,  0,  5,  4},
1034  /* A/N Bundl: 1,7,9*/     {4,  3,  0, 0, 0, 4, 5,  4,  6,  5},
1035  /* A/N Bundl: 0,6*/       {4,  3,  0, 0, 6, 5, 4,  7,  6,  5},
1036  /* A/N Bundl: 9*/         {8,  7,  0, 6, 5, 4, 12, 11, 10, 9},
1037  /* A/N Bundl: 0,1,5,6,9*/ {2,  1,  0, 0, 0, 2, 2,  0,  0,  3}
1038 };
1039    
1040
1041 /* combine compilation fixes */
1042 #ifdef LTEMAC_SPS
1043 /* subframe offset values to be used when twoIntervalsConfig is enabled in UL
1044  * SPS for a UE */
1045 RgSchTddSfOffTbl rgSchTddSfOffTbl = {
1046         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1047         {0, 0, 1, -1,  0, 0, 0,  1, -1, 0},
1048         {0, 0, 5,  0,  0, 0, 0, -5,  0, 0},
1049         {0, 0, 1,  1, -2, 0, 0,  0,  0, 0},
1050         {0, 0, 1, -1,  0, 0, 0,  0,  0, 0},
1051         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0},
1052         {0, 0, 0,  0,  0, 0, 0,  0,  0, 0}
1053 };
1054
1055
1056 /* Table to determine when uplink SPS configured grants should
1057  * explicitly be reserved in a subframe. When enries are same
1058  * as that of Msg3SubfrmTbl, indicates competition with msg3.
1059  * As of now, this is same as Msg3SubfrmTbl (leaving out uldlcfg 2),
1060  * except that all 255s are now zeros. */
1061 RgSchTddSpsUlRsrvTbl rgSchTddSpsUlRsrvTbl = {
1062         {0,    0,  0,  6,  8,  0, 0,  0,  6,  8},
1063         {0,    0,  6,  9,  0,  0, 0,  6,  9,  0},
1064         {0,    0,  10,  0,  0,  0, 0,  10,  0,  0},
1065         {0,   0,  0,  0,  8,  0, 7,  7,  14,  0},
1066         {0,   0,  0,  9,  0,  0, 7,  15,  0, 0},
1067         {0,   0,  10,  0,  0,  0, 16,  0, 0, 0},
1068         {0,    0,  0,  0,  8,  0, 0,  0,  9,  0}
1069 };
1070
1071 /* Inverse DL Assoc Set index Table */
1072 RgSchTddInvDlAscSetIdxTbl rgSchTddInvDlAscSetIdxTbl = {
1073        {4,  6,  0, 0, 0, 4, 6, 0, 0,  0},
1074        {7,  6,  0, 0, 4, 7, 6, 0, 0,  4},
1075        {7,  6,  0, 4, 8, 7, 6, 0, 4,  8},
1076        {4,  11, 0, 0, 0, 7, 6, 6, 5,  5},
1077        {12, 11, 0, 0, 8, 7, 7, 6, 5,  4},
1078        {12, 11, 0, 9, 8, 7, 6, 5, 4, 13},
1079        {7,  7,  0, 0, 0, 7, 7, 0, 0,  5}
1080 };
1081
1082 #endif /* (LTEMAC_SPS ) */
1083
1084 /* Number of Uplink subframes Table */
1085 static uint8_t rgSchTddNumUlSf[] = {6, 4, 2, 3, 2, 1, 5};
1086
1087 /* Downlink HARQ processes Table */
1088 RgSchTddUlNumHarqProcTbl rgSchTddUlNumHarqProcTbl = { 7, 4, 2, 3, 2, 1, 6};
1089
1090 /* Uplink HARQ processes Table */
1091 RgSchTddDlNumHarqProcTbl rgSchTddDlNumHarqProcTbl = { 4, 7, 10, 9, 12, 15, 6};
1092
1093 /* Downlink association index set 'K' value Table */
1094 RgSchTddDlAscSetIdxKTbl rgSchTddDlAscSetIdxKTbl = {
1095         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1096
1097         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1098
1099         { {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}} },
1100
1101         { {0, {0}}, {0, {0}}, {3, {7, 6, 11}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1102
1103         { {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}} },
1104
1105         { {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}} },
1106
1107         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1108 };
1109
1110  /* ccpu132282-ADD-the table rgSchTddDlAscSetIdxKTbl is rearranged in 
1111   * decreasing order of Km, this is used to calculate the NCE used for 
1112   * calculating N1Pucch Resource for Harq*/
1113 RgSchTddDlAscSetIdxKTbl rgSchTddDlHqPucchResCalTbl = {
1114         { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} },
1115
1116         { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} },
1117
1118         { {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}} },
1119
1120         { {0, {0}}, {0, {0}}, {3, {11, 7, 6}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} },
1121
1122         { {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}} },
1123
1124         { {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}} },
1125
1126         { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} }
1127 };
1128
1129 /* Minimum number of Ack/Nack feeback information to be
1130    stored for each UL-DL configuration */
1131 RgSchTddANFdbkMapTbl rgSchTddANFdbkMapTbl = {4, 4, 2, 3, 2, 1, 5};
1132
1133 /* Uplink switch points and number of UL subframes Table */
1134 RgSchTddMaxUlSubfrmTbl rgSchTddMaxUlSubfrmTbl = {
1135      {2,3,3}, {2,2,2}, {2,1,1}, {1,3,0}, {1,2,0}, {1,1,0}, {2,3,2}
1136 };
1137
1138 /* Uplink switch points and number of DL subframes Table */
1139 RgSchTddMaxDlSubfrmTbl rgSchTddMaxDlSubfrmTbl = {
1140      {2,2,2}, {2,3,3}, {2,4,4}, {1,7,0}, {1,8,0}, {1,9,0}, {2,2,3}
1141 };
1142
1143 /* Number of UL subframes present before a particular subframe */
1144 RgSchTddNumUlSubfrmTbl rgSchTddNumUlSubfrmTbl = {
1145         {0, 0, 1, 2, 3, 3, 3, 4, 5, 6},
1146         {0, 0, 1, 2, 2, 2, 2, 3, 4, 4},
1147         {0, 0, 1, 1, 1, 1, 1, 2, 2, 2},
1148         {0, 0, 1, 2, 3, 3, 3, 3, 3, 3},
1149         {0, 0, 1, 2, 2, 2, 2, 2, 2, 2},
1150         {0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
1151         {0, 0, 1, 2, 3, 3, 3, 4, 5, 5}
1152 };
1153
1154 /* Number of DL subframes present till a particular subframe */
1155 RgSchTddNumDlSubfrmTbl rgSchTddNumDlSubfrmTbl = {
1156         {1, 2, 2, 2, 2, 3, 4, 4, 4, 4},
1157         {1, 2, 2, 2, 3, 4, 5, 5, 5, 6},
1158         {1, 2, 2, 3, 4, 5, 6, 6, 7, 8},
1159         {1, 2, 2, 2, 2, 3, 4, 5, 6, 7},
1160         {1, 2, 2, 2, 3, 4, 5, 6, 7, 8},
1161         {1, 2, 2, 3, 4, 5, 6, 7, 8, 9},
1162         {1, 2, 2, 2, 2, 3, 4, 4, 4, 5}
1163 };
1164
1165
1166 /* Nearest possible UL subframe Index from UL subframe
1167  * DL Index < UL Index */
1168 RgSchTddLowDlSubfrmIdxTbl rgSchTddLowDlSubfrmIdxTbl = {
1169         {0, 1, 1, 1, 1, 5, 6, 6, 6, 6},
1170         {0, 1, 1, 1, 4, 5, 6, 6, 6, 9},
1171         {0, 1, 1, 3, 4, 5, 6, 6, 8, 9},
1172         {0, 1, 1, 1, 1, 5, 6, 7, 8, 9},
1173         {0, 1, 1, 1, 4, 5, 6, 7, 8, 9},
1174         {0, 1, 1, 3, 4, 5, 6, 7, 8, 9},
1175         {0, 1, 1, 1, 1, 5, 6, 6, 6, 9}
1176 };
1177
1178 /* Nearest possible DL subframe Index from UL subframe
1179  * DL Index > UL Index
1180  * 10 represents Next SFN low DL Idx */
1181 RgSchTddHighDlSubfrmIdxTbl rgSchTddHighDlSubfrmIdxTbl = {
1182         {0, 1, 5, 5, 5, 5, 6, 10, 10, 10},
1183         {0, 1, 4, 4, 4, 5, 6,  9,  9,  9},
1184         {0, 1, 3, 3, 4, 5, 6,  8,  8,  9},
1185         {0, 1, 5, 5, 5, 5, 6,  7,  8,  9},
1186         {0, 1, 4, 4, 4, 5, 6,  7,  8,  9},
1187         {0, 1, 3, 3, 4, 5, 6,  7,  8,  9},
1188         {0, 1, 5, 5, 5, 5, 6,  9,  9,  9}
1189 };
1190
1191 /* RACH Message3 related information */
1192 RgSchTddMsg3SubfrmTbl rgSchTddMsg3SubfrmTbl = {
1193         {7,      6,  255,  255,  255,  7,   6,  255,  255,  255},
1194         {7,      6,  255,  255,    8,  7,   6,  255,  255,    8},
1195         {7,      6,  255,  9,      8,  7,   6,  255,    9,    8},
1196         {12,    11,  255,  255,  255,  7,   6,    6,    6,   13},
1197         {12,    11,  255,  255,    8,  7,   6,    6,   14,   13},
1198         {12,    11,  255,    9,    8,  7,   6,   15,   14,   13},
1199         {7,      6,  255,  255,  255,  7,   6,  255,  255,    8}
1200 };
1201
1202 /* ccpu00132341-DEL Removed rgSchTddRlsDlSubfrmTbl and used Kset table for 
1203  * releasing DL HARQs */
1204
1205 /* DwPTS Scheduling Changes Start */
1206 /* Provides the number of Cell Reference Signals in DwPTS
1207  * region per RB */
1208 static uint8_t  rgSchCmnDwptsCrs[2][3] = {/* [Spl Sf cfg][Ant Port] */
1209            {4, 8,  16}, /* Spl Sf cfg 1,2,3,6,7,8 */
1210            {6, 12, 20}, /* Spl Sf cfg 4 */
1211 };
1212
1213 static S8  rgSchCmnSplSfDeltaItbs[9] = RG_SCH_DWPTS_ITBS_ADJ;
1214 /* DwPTS Scheduling Changes End */
1215 #endif
1216
1217
1218 static uint32_t rgSchCmnBsrTbl[64] = {
1219    0, 10, 12, 14, 17, 19, 22, 26,
1220    31, 36, 42, 49, 57, 67, 78, 91,
1221    107, 125, 146, 171, 200, 234, 274, 321,
1222    376, 440, 515, 603, 706, 826, 967, 1132,
1223    1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
1224    4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
1225    16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
1226    58255, 68201, 79846, 93479, 109439, 128125, 150000, 220000
1227 };
1228
1229 static uint32_t rgSchCmnExtBsrTbl[64] = {
1230    0, 10, 13, 16, 19, 23, 29, 35,
1231    43, 53, 65, 80, 98, 120, 147, 181,
1232    223, 274, 337, 414, 509, 625, 769, 945,
1233    1162, 1429, 1757, 2161, 2657, 3267, 4017, 4940,
1234    6074, 7469, 9185, 11294, 13888, 17077, 20999, 25822,
1235    31752, 39045, 48012, 59039, 72598, 89272, 109774, 134986,
1236    165989, 204111, 250990, 308634, 379519, 466683, 573866, 705666,
1237    867737, 1067031, 1312097, 1613447, 1984009, 2439678, 3000000, 3100000
1238 };
1239
1240 uint8_t rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI];
1241
1242 RgSchTbSzTbl rgTbSzTbl = {
1243  {
1244    {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},
1245    {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},
1246    {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},
1247    {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},
1248    {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},
1249    {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},
1250    {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},
1251    {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},
1252    {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},
1253    {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},
1254    {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},
1255    {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},
1256    {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},
1257    {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},
1258    {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},
1259    {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},
1260    {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},
1261    {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},
1262    {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},
1263    {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},
1264    {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},
1265    {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},
1266    {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},
1267    {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},
1268    {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},
1269    {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},
1270    {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}
1271  },
1272  {
1273    {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},
1274    {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},
1275    {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},
1276    {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},
1277    {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},
1278    {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},
1279    {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},
1280    {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},
1281    {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},
1282    {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},
1283    {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},
1284    {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},
1285    {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},
1286    {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},
1287    {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},
1288    {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},
1289    {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},
1290    {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},
1291    {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},
1292    {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},
1293    {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},
1294    {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},
1295    {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},
1296    {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},
1297    {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},
1298    {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},
1299    {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}
1300  }
1301 };
1302 RgSchUlIMcsTbl rgUlIMcsTbl = {
1303    {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
1304    {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10},
1305    {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14},
1306    {4, 15}, {4, 16}, {4, 17}, {4, 18}, {4, 19},
1307    {6, 19}, {6, 20}, {6, 21}, {6, 22}, {6, 23},
1308    {6, 24}, {6, 25}, {6, 26}
1309 };
1310 RgSchUeCatTbl rgUeCatTbl = {
1311    /*Column1:Maximum number of bits of an UL-SCH 
1312              transport block transmitted within a TTI
1313              - maxUlBits
1314      Column2:Maximum number of bits of a DLSCH
1315              transport block received within a TTI 
1316              - maxDlBits
1317      Column3:Total number of soft channel bits 
1318              - maxSftChBits
1319      Column4:Support for 64QAM in UL 
1320              - ul64qamSup
1321      Column5:Maximum number of DL-SCH transport
1322              block bits received within a TTI
1323              - maxDlTbBits
1324      Column6:Maximum number of supported layers for 
1325              spatial multiplexing in DL 
1326              - maxTxLyrs*/
1327    {5160,  {10296,0},      250368,  FALSE, 10296,  1},
1328    {25456, {51024,0},      1237248, FALSE, 51024,  2},
1329    {51024, {75376,0},      1237248, FALSE, 102048, 2},
1330    {51024, {75376,0},      1827072, FALSE, 150752, 2},
1331    {75376, {149776,0},     3667200, TRUE,  299552, 4},
1332    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1333    {51024, {75376,149776}, 3654144, FALSE, 301504,  4},
1334    {149776,{299856,0},     35982720,TRUE,  2998560, 8}
1335 };
1336
1337 /* [ccpu00138532]-ADD-The below table stores the min HARQ RTT time
1338    in Downlink for TDD and FDD. Indices 0 to 6 map to tdd UL DL config 0-6. 
1339    Index 7 map to FDD */    
1340 uint8_t rgSchCmnHarqRtt[8] = {4,7,10,9,12,15,6,8};
1341 /* Number of CFI Switchover Index is equals to 7 TDD Indexes + 1 FDD index */
1342 uint8_t rgSchCfiSwitchOvrWinLen[] = {7, 4, 2, 3, 2, 1, 6, 8};
1343
1344 /* EffTbl is calculated for single layer and two layers.
1345   * CqiToTbs is calculated for single layer and two layers */
1346 RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1347 RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1348 /* New variable to store UL effiency values for normal and extended CP*/
1349 RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1];
1350 RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1351 RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1352 RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI];
1353 RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW];
1354 RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW];
1355 RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1356 RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW];
1357 /* Include CRS REs while calculating Efficiency */
1358 RgSchCmnTbSzEff *rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI];
1359 RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP];
1360 #ifdef LTE_TDD
1361 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3, 1};
1362 #else
1363 /* Added matrix 'rgRaPrmblToRaFrmTbl'for computation of RA sub-frames from RA preamble */
1364 RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3};
1365 #endif
1366
1367  RgUlSchdInits        rgSchUlSchdInits;
1368  RgDlSchdInits        rgSchDlSchdInits;
1369  RgDlfsSchdInits      rgSchDlfsSchdInits;
1370 #ifdef EMTC_ENABLE
1371  RgEmtcUlSchdInits        rgSchEmtcUlSchdInits;
1372  RgEmtcDlSchdInits        rgSchEmtcDlSchdInits;
1373 #endif
1374
1375 /* RACHO : start */
1376 static S16 rgSCHCmnUeIdleExdThrsld ARGS((
1377 RgSchCellCb     *cell,
1378 RgSchUeCb       *ue
1379 ));
1380 RgSchUeCb* rgSCHCmnGetHoUe ARGS((
1381 RgSchCellCb           *cell,
1382 uint16_t                   rapId
1383 ));
1384 static Void rgSCHCmnDelDedPreamble ARGS((
1385 RgSchCellCb           *cell,
1386 uint8_t                    preambleId
1387 ));
1388 RgSchUeCb* rgSCHCmnGetPoUe ARGS((
1389 RgSchCellCb           *cell,
1390 uint16_t                   rapId,
1391 CmLteTimingInfo       timingInfo
1392 ));
1393 static Void rgSCHCmnDelRachInfo ARGS((
1394 RgSchCellCb  *cell,
1395 RgSchUeCb    *ue
1396 ));
1397 static S16 rgSCHCmnUlRbAllocForPoHoUe ARGS((
1398 RgSchCellCb           *cell,
1399 RgSchUlSf             *sf,
1400 RgSchUeCb             *ue,
1401 uint8_t                    maxRb
1402 ));
1403 static Void rgSCHCmnHdlHoPo ARGS((
1404 RgSchCellCb           *cell,
1405 CmLListCp             *raRspLst,
1406 RgSchRaReqInfo        *raReq
1407 ));
1408 static Void rgSCHCmnAllocPoHoGrnt ARGS((
1409 RgSchCellCb           *cell,
1410 CmLListCp             *raRspLst,
1411 RgSchUeCb             *ue,
1412 RgSchRaReqInfo        *raReq
1413 ));
1414 static Void rgSCHCmnFillPdcchOdr2Sf ARGS((
1415 RgSchCellCb *cell,
1416 RgSchUeCb   *ue,
1417 RgSchPdcch  *pdcc,
1418 uint8_t          rapId,
1419 uint8_t          prachMskIdx
1420 ));
1421 static Void rgSCHCmnDlAdd2PdcchOdrQ ARGS((
1422 RgSchCellCb                *cell,
1423 RgSchUeCb                  *ue
1424 ));
1425 static Void rgSCHCmnDlRmvFrmPdcchOdrQ ARGS((
1426 RgSchCellCb                *cell,
1427 RgSchUeCb                  *ue
1428 ));
1429 static Void rgSCHCmnUpdNxtPrchMskIdx ARGS((
1430 RgSchCellCb  *cell
1431 ));
1432 static Void rgSCHCmnUpdRachParam ARGS((
1433 RgSchCellCb  *cell
1434 ));
1435 static S16 rgSCHCmnAllocPOParam ARGS((
1436 RgSchCellCb  *cell,
1437 RgSchDlSf    *dlSf,
1438 RgSchUeCb    *ue,
1439 RgSchPdcch   **pdcch,
1440 uint8_t           *rapId,
1441 uint8_t           *prachMskIdx
1442 ));
1443 static Void rgSCHCmnGenPdcchOrder ARGS((
1444 RgSchCellCb  *cell,
1445 RgSchDlSf    *dlSf
1446 ));
1447 static Void rgSCHCmnCfgRachDedPrm ARGS((
1448 RgSchCellCb   *cell
1449 ));
1450 /* RACHO : end */
1451
1452 static Void rgSCHCmnHdlUlInactUes ARGS((
1453 RgSchCellCb  *cell
1454 ));
1455 static Void rgSCHCmnHdlDlInactUes ARGS((
1456 RgSchCellCb  *cell
1457 ));
1458 static Void rgSCHCmnUlInit ARGS((Void
1459 ));
1460 static Void rgSCHCmnDlInit ARGS((Void
1461 ));
1462 static Void rgSCHCmnInitDlRbAllocInfo ARGS((
1463 RgSchCmnDlRbAllocInfo  *allocInfo
1464 ));
1465 static Void rgSCHCmnUpdUlCompEffBsr ARGS((
1466 RgSchUeCb *ue
1467 ));
1468 #if RG_UNUSED
1469 static Void rgSCHCmnUlSetAllUnSched  ARGS((
1470 RgSchCmnUlRbAllocInfo *allocInfo
1471 ));
1472 static Void rgSCHCmnUlUpdSf ARGS((
1473          RgSchCellCb           *cell,
1474          RgSchCmnUlRbAllocInfo *allocInfo,
1475          RgSchUlSf     *sf
1476          ));
1477 static Void rgSCHCmnUlHndlAllocRetx ARGS((
1478          RgSchCellCb           *cell,
1479          RgSchCmnUlRbAllocInfo *allocInfo,
1480          RgSchUlSf     *sf,
1481          RgSchUlAlloc  *alloc
1482          ));
1483 #endif
1484 static Void rgSCHCmnGrpPwrCntrlPucch ARGS((
1485 RgSchCellCb  *cell,
1486 RgSchDlSf    *dlSf
1487 ));
1488 static Void rgSCHCmnGrpPwrCntrlPusch ARGS((
1489 RgSchCellCb  *cell,
1490 RgSchUlSf    *ulSf
1491 ));
1492 static Void rgSCHCmnDelUeFrmRefreshQ ARGS((
1493 RgSchCellCb     *cell,
1494 RgSchUeCb       *ue
1495 ));
1496 static S16 rgSCHCmnTmrExpiry ARGS((
1497 PTR cb,               /* Pointer to timer control block */
1498 S16 tmrEvnt           /* Timer Event */
1499 ));
1500 static S16 rgSCHCmnTmrProc ARGS((
1501 RgSchCellCb *cell
1502 ));
1503 static Void rgSCHCmnAddUeToRefreshQ ARGS((
1504 RgSchCellCb     *cell,
1505 RgSchUeCb       *ue,
1506 uint32_t             wait
1507 ));
1508 static Void rgSCHCmnDlCcchRetx ARGS((
1509 RgSchCellCb             *cell,
1510 RgSchCmnDlRbAllocInfo   *allocInfo
1511 ));
1512 static Void rgSCHCmnUpdUeMimoInfo ARGS((
1513 RgrUeCfg     *ueCfg,
1514 RgSchCmnDlUe *ueDl,
1515 RgSchCellCb  *cell,
1516 RgSchCmnCell *cellSchd
1517 ));
1518 static Void rgSCHCmnUpdUeUlCqiInfo ARGS((
1519 RgSchCellCb   *cell,
1520 RgSchUeCb     *ue,
1521 RgSchCmnUlUe  *ueUl,
1522 RgSchCmnUe    *ueSchCmn,
1523 RgSchCmnCell  *cellSchd,
1524 Bool          isEcp 
1525 ));
1526 #ifdef RGR_V1
1527 static Void rgSCHCmnDlCcchSduRetx ARGS((
1528 RgSchCellCb             *cell,
1529 RgSchCmnDlRbAllocInfo   *allocInfo
1530 ));
1531 static Void rgSCHCmnDlCcchSduTx ARGS((
1532 RgSchCellCb             *cell,
1533 RgSchCmnDlRbAllocInfo   *allocInfo
1534 ));
1535 static S16 rgSCHCmnCcchSduAlloc ARGS((
1536 RgSchCellCb                *cell,
1537 RgSchUeCb                  *ueCb,
1538 RgSchCmnDlRbAllocInfo      *allocInfo
1539 ));
1540 static S16 rgSCHCmnCcchSduDedAlloc ARGS((
1541 RgSchCellCb                *cell,
1542 RgSchUeCb                  *ueCb
1543 ));
1544 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc ARGS((
1545 RgSchCellCb           *cell,
1546 RgSchUeCb             *ueCb,
1547 RgSchDlSf             *dlSf
1548 ));
1549 #endif
1550 static Void rgSCHCmnInitVars ARGS((
1551          RgSchCellCb *cell
1552          ));
1553
1554 /*ccpu00117180 - DEL - Moved rgSCHCmnUpdVars to .x as its access is now */
1555 static Void rgSCHCmnUlRbAllocForLst ARGS((
1556          RgSchCellCb           *cell,
1557          RgSchUlSf             *sf,
1558          uint32_t                   count,
1559          CmLListCp             *reqLst,
1560          CmLListCp             *schdLst,
1561          CmLListCp             *nonSchdLst,
1562          Bool                  isNewTx
1563          ));
1564 static S16 rgSCHCmnUlRbAllocForUe ARGS((
1565          RgSchCellCb           *cell,
1566          RgSchUlSf             *sf,
1567          RgSchUeCb             *ue,
1568          uint8_t                    maxRb,
1569          RgSchUlHole           *hole
1570          ));
1571 static Void rgSCHCmnMsg3GrntReq ARGS((
1572          RgSchCellCb     *cell,
1573          CmLteRnti       rnti,
1574          Bool            preamGrpA,
1575          RgSchUlHqProcCb *hqProc,
1576          RgSchUlAlloc    **ulAllocRef,
1577          uint8_t              *hqProcIdRef
1578          ));
1579 static Void rgSCHCmnDlCcchRarAlloc ARGS((
1580 RgSchCellCb             *cell
1581 ));
1582 static Void rgSCHCmnDlCcchTx ARGS((
1583 RgSchCellCb             *cell,
1584 RgSchCmnDlRbAllocInfo   *allocInfo
1585 ));
1586 static Void rgSCHCmnDlBcchPcch ARGS((
1587 RgSchCellCb             *cell,
1588 RgSchCmnDlRbAllocInfo   *allocInfo,
1589 RgInfSfAlloc            *subfrmAlloc
1590 ));
1591 Bool rgSCHCmnChkInWin ARGS((
1592 CmLteTimingInfo   frm,
1593 CmLteTimingInfo   start,
1594 CmLteTimingInfo   end
1595 ));
1596 Bool rgSCHCmnChkPastWin ARGS((
1597 CmLteTimingInfo   frm,
1598 CmLteTimingInfo   end
1599 ));
1600 static Void rgSCHCmnClcAlloc ARGS((
1601 RgSchCellCb             *cell,
1602 RgSchDlSf               *sf,
1603 RgSchClcDlLcCb          *lch,
1604 uint16_t                     rnti,
1605 RgSchCmnDlRbAllocInfo   *allocInfo
1606 ));
1607 #ifndef LTEMAC_SPS
1608 static Void rgSCHCmnClcRbAlloc ARGS((
1609 RgSchCellCb             *cell,
1610 uint32_t                     bo,
1611 uint8_t                      cqi,
1612 uint8_t                      *rb,
1613 uint32_t                     *tbs,
1614 uint8_t                      *mcs,
1615 RgSchDlSf               *sf 
1616 ));
1617 #endif
1618
1619 static S16 rgSCHCmnMsg4Alloc ARGS((
1620 RgSchCellCb                *cell,
1621 RgSchRaCb                  *raCb,
1622 RgSchCmnDlRbAllocInfo      *allocInfo
1623 ));
1624 static S16 rgSCHCmnMsg4DedAlloc ARGS((
1625 RgSchCellCb                *cell,
1626 RgSchRaCb                  *raCb
1627 ));
1628 static Void rgSCHCmnDlRaRsp ARGS((
1629 RgSchCellCb                *cell,
1630 RgSchCmnDlRbAllocInfo      *allocInfo
1631 ));
1632 static S16 rgSCHCmnRaRspAlloc ARGS((
1633 RgSchCellCb             *cell,
1634 RgSchDlSf               *subFrm,
1635 uint16_t                     rntiIdx,
1636 uint16_t                     rarnti,
1637 uint8_t                      noRaRnti,
1638 RgSchCmnDlRbAllocInfo   *allocInfo
1639 ));
1640 static Void rgSCHCmnUlUeDelAllocs ARGS((
1641 RgSchCellCb  *cell,
1642 RgSchUeCb   *ue
1643 ));
1644 static Void rgSCHCmnDlSetUeAllocLmt ARGS((
1645 RgSchCellCb   *cell,
1646 RgSchCmnDlUe  *ueDl,
1647 Bool          isEmtcUe
1648 ));
1649 static S16 rgSCHCmnDlRgrCellCfg ARGS((
1650 RgSchCellCb    *cell,
1651 RgrCellCfg     *cfg,
1652 RgSchErrInfo   *err
1653 ));
1654 static Void rgSCHCmnUlAdapRetx ARGS((
1655 RgSchUlAlloc    *alloc,
1656 RgSchUlHqProcCb *proc
1657 ));
1658 static Void rgSCHCmnUlUpdAllocRetx ARGS((
1659 RgSchCellCb    *cell,
1660 RgSchUlAlloc   *alloc
1661 ));
1662 static Void rgSCHCmnUlSfReTxAllocs ARGS((
1663 RgSchCellCb *cell,
1664 RgSchUlSf   *sf
1665 ));
1666 /* Fix: syed Adaptive Msg3 Retx crash. */
1667 #ifdef TFU_UPGRADE
1668 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1669 ((
1670 RgSchCellCb *cell,
1671 RgSchUeCb    *ue,
1672 RgrUeRecfg   *ueRecfg,
1673 uint8_t numTxPorts
1674 ));
1675 #else
1676 static Void rgSCHCmnDlHdlTxModeRecfg ARGS
1677 ((
1678 RgSchCellCb *cell,
1679 RgSchUeCb    *ue,
1680 RgrUeRecfg   *ueRecfg
1681 ));
1682 #endif
1683
1684
1685 /*
1686  * DL RB allocation specific functions
1687  */
1688
1689 static Void rgSCHCmnDlRbAlloc ARGS((
1690 RgSchCellCb           *cell,
1691 RgSchCmnDlRbAllocInfo *allocInfo
1692 ));
1693 static Void rgSCHCmnNonDlfsRbAlloc ARGS((
1694 RgSchCellCb           *cell,
1695 RgSchCmnDlRbAllocInfo *allocInfo
1696 ));
1697 static S16 rgSCHCmnNonDlfsCmnRbAlloc ARGS((
1698 RgSchCellCb           *cell,
1699 RgSchDlRbAlloc        *cmnAllocInfo));
1700
1701 #ifndef LTE_TDD
1702 static Void rgSCHCmnNonDlfsPbchRbAllocAdj ARGS((
1703 RgSchCellCb           *cell,
1704 RgSchDlRbAlloc        *cmnAllocInfo,
1705 uint8_t                    pbchSsRsSym,
1706 Bool                  isBcchPcch
1707 ));
1708 /* Added function to adjust TBSize*/
1709 static Void rgSCHCmnNonDlfsPbchTbSizeAdj ARGS((
1710 RgSchDlRbAlloc        *allocInfo,
1711 uint8_t                    numOvrlapgPbchRb,
1712 uint8_t                    pbchSsRsSym,
1713 uint8_t                    idx,
1714 uint32_t                   bytesReq
1715 ));
1716
1717 /* Added function to find num of overlapping PBCH rb*/
1718 static Void rgSCHCmnFindNumPbchOvrlapRbs ARGS((
1719 RgSchCellCb           *cell,
1720 RgSchDlSf             *dlSf,
1721 RgSchDlRbAlloc        *allocInfo,
1722 uint8_t                    *numOvrlapgPbchRb
1723 ));
1724
1725 static uint8_t rgSCHCmnFindNumAddtlRbsAvl ARGS((
1726 RgSchCellCb           *cell,
1727 RgSchDlSf             *dlSf,
1728 RgSchDlRbAlloc        *allocInfo
1729 ));
1730 #ifdef DEBUGP
1731 #ifdef UNUSED_FUNC
1732 static Void rgSCHCmnFindCodeRate ARGS((
1733 RgSchCellCb           *cell,
1734 RgSchDlSf             *dlSf,
1735 RgSchDlRbAlloc        *allocInfo,
1736 uint8_t                    idx
1737 ));
1738 #endif
1739 #endif
1740 #endif
1741 static Void rgSCHCmnNonDlfsMsg4Alloc ARGS((
1742 RgSchCellCb           *cell,
1743 RgSchCmnMsg4RbAlloc   *msg4AllocInfo,
1744 uint8_t                    isRetx
1745 ));
1746 static S16 rgSCHCmnNonDlfsMsg4RbAlloc ARGS((
1747 RgSchCellCb           *cell,
1748 RgSchRaCb             *raCb,
1749 RgSchDlSf             *dlSf
1750 ));
1751
1752 static S16 rgSCHCmnNonDlfsUeRbAlloc ARGS((
1753 RgSchCellCb           *cell,
1754 RgSchUeCb             *ue,
1755 RgSchDlSf             *dlSf,
1756 uint8_t                    *isDlBwAvail
1757 ));
1758 #ifndef LTEMAC_SPS
1759 static uint32_t rgSCHCmnCalcRiv ARGS(( uint8_t bw,
1760          uint8_t           rbStart,
1761          uint8_t           numRb));
1762 #endif
1763
1764 #ifdef LTE_TDD
1765 static Void rgSCHCmnUpdHqAndDai ARGS((
1766 RgSchDlHqProcCb   *hqP,
1767 RgSchDlSf         *subFrm,
1768 RgSchDlHqTbCb     *tbCb,
1769 uint8_t                tbAllocIdx
1770 ));
1771 static S16 rgSCHCmnUlCalcAvailBw ARGS((
1772 RgSchCellCb *cell,
1773 RgrCellCfg  *cellCfg,
1774 uint8_t          cfi,
1775 uint8_t          *rbStartRef,
1776 uint8_t          *bwAvailRef
1777 ));
1778 static S16 rgSCHCmnDlKdashUlAscInit ARGS((
1779 RgSchCellCb *cell
1780 ));
1781 static S16 rgSCHCmnDlANFdbkInit ARGS((
1782 RgSchCellCb *cell
1783 ));
1784 static S16 rgSCHCmnDlNpValInit ARGS((
1785 RgSchCellCb *cell
1786 ));
1787 static S16 rgSCHCmnDlCreateRachPrmLst ARGS((
1788 RgSchCellCb *cell
1789 ));
1790 static S16 rgSCHCmnDlCpyRachInfo ARGS((
1791 RgSchCellCb        *cell,
1792 RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES],
1793 uint8_t                 raArrSz
1794 ));
1795 static S16 rgSCHCmnDlRachInfoInit ARGS((
1796 RgSchCellCb *cell
1797 ));
1798 static S16 rgSCHCmnDlPhichOffsetInit ARGS((
1799 RgSchCellCb *cell
1800 ));
1801 #endif
1802 #ifdef TFU_UPGRADE
1803 static Void rgSCHCmnFindUlCqiUlTxAnt ARGS
1804 ((
1805  RgSchCellCb          *cell,
1806  RgSchUeCb            *ue,
1807  uint8_t                          wideCqi
1808  ));
1809  static RgSchCmnRank rgSCHCmnComputeRank ARGS
1810 ((
1811  RgrTxMode    txMode,
1812  uint32_t          *pmiBitMap,
1813  uint8_t           numTxPorts
1814  ));
1815
1816  static RgSchCmnRank rgSCHCmnComp2TxMode3 ARGS
1817 ((
1818  uint32_t *pmiBitMap
1819  ));
1820
1821   static RgSchCmnRank rgSCHCmnComp4TxMode3 ARGS
1822 ((
1823  uint32_t *pmiBitMap
1824  ));
1825
1826   static RgSchCmnRank rgSCHCmnComp2TxMode4 ARGS
1827 ((
1828  uint32_t *pmiBitMap
1829  ));
1830
1831   static RgSchCmnRank rgSCHCmnComp4TxMode4 ARGS
1832 ((
1833  uint32_t *pmiBitMap
1834  ));
1835
1836  static uint8_t rgSCHCmnCalcWcqiFrmSnr ARGS
1837 ((
1838  RgSchCellCb        *cell,
1839  TfuSrsRpt        *srsRpt
1840  ));
1841 #endif
1842
1843 /* comcodsepa : start */
1844 \f
1845 /**
1846  * @brief This function computes efficiency and stores in a table.
1847  *
1848  * @details
1849  *
1850  *     Function: rgSCHCmnCompEff
1851  *     Purpose:  this function computes the efficiency as number of
1852  *               bytes per 1024 symbols. The CFI table is also filled
1853  *               with the same information such that comparison is valid
1854  *
1855  *     Invoked by: Scheduler
1856  *
1857  *  @param[in]  uint8_t            noPdcchSym
1858  *  @param[in]  uint8_t            cpType
1859  *  @param[in]  uint8_t            txAntIdx
1860  *  @param[in]  RgSchCmnTbSzEff* effTbl
1861  *  @return  Void
1862  *
1863  **/
1864 #ifdef ANSI
1865 static Void rgSCHCmnCompEff
1866 (
1867 uint8_t                    noPdcchSym,
1868 uint8_t                    cpType,
1869 uint8_t                    txAntIdx,
1870 RgSchCmnTbSzEff            *effTbl
1871 )
1872 #else
1873 static Void rgSCHCmnCompEff(noPdcchSym, cpType, txAntIdx, effTbl)
1874 uint8_t                    noPdcchSym;
1875 uint8_t                    cpType;
1876 uint8_t                    txAntIdx;
1877 RgSchCmnTbSzEff            *effTbl;
1878 #endif
1879 {
1880    uint8_t               noResPerRb;
1881    uint8_t               noSymPerRb;
1882    uint8_t               resOfCrs; /* Effective REs occupied by CRS */
1883    uint8_t               i, j;
1884
1885
1886    switch (cpType)
1887    {
1888       case RG_SCH_CMN_NOR_CP:
1889          noSymPerRb = 14;
1890          break;
1891       case RG_SCH_CMN_EXT_CP:
1892          noSymPerRb = 12;
1893          break;
1894       default:
1895          /* Generate a log error. This case should never be executed */
1896          return;
1897    }
1898
1899    /* Depending on the Tx Antenna Index, deduct the
1900     * Resource elements for the CRS */
1901    switch (txAntIdx)
1902    {
1903       case 0:
1904          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
1905          break;
1906       case 1:
1907          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
1908          break;
1909       case 2:
1910          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
1911          break;
1912       default:
1913          /* Generate a log error. This case should never be executed */
1914          return;
1915    }
1916    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
1917    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1918    {
1919       (*effTbl)[i] = 0;
1920       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1921       {
1922          /* This line computes the coding efficiency per 1024 REs */
1923          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1924       }
1925       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1926    }
1927    return;
1928 }
1929 /**
1930  * @brief This function computes efficiency and stores in a table.
1931  *
1932  * @details
1933  *
1934  *     Function: rgSCHCmnCompUlEff
1935  *     Purpose:  this function computes the efficiency as number of
1936  *               bytes per 1024 symbols. The CFI table is also filled
1937  *               with the same information such that comparison is valid
1938  *
1939  *     Invoked by: Scheduler
1940  *
1941  *  @param[in]  uint8_t            noUlRsSym
1942  *  @param[in]  uint8_t            cpType
1943  *  @param[in]  uint8_t            txAntIdx
1944  *  @param[in]  RgSchCmnTbSzEff* effTbl
1945  *  @return  Void
1946  *
1947  **/
1948 #ifdef ANSI
1949 static Void rgSCHCmnCompUlEff
1950 (
1951 uint8_t                    noUlRsSym,
1952 uint8_t                    cpType,
1953 RgSchCmnTbSzEff           *effTbl
1954 )
1955 #else
1956 static Void rgSCHCmnCompUlEff(noUlRsSym, cpType, effTbl)
1957 uint8_t                    noUlRsSym;
1958 uint8_t                    cpType;
1959 RgSchCmnTbSzEff            *effTbl;
1960 #endif
1961 {
1962    uint8_t               noResPerRb;
1963    uint8_t               noSymPerRb;
1964    uint8_t               i, j;
1965
1966
1967    switch (cpType)
1968    {
1969       case RG_SCH_CMN_NOR_CP:
1970          noSymPerRb = 14;
1971          break;
1972       case RG_SCH_CMN_EXT_CP:
1973          noSymPerRb = 12;
1974          break;
1975       default:
1976          /* Generate a log error. This case should never be executed */
1977          return;
1978    }
1979
1980    noResPerRb = ((noSymPerRb - noUlRsSym) * RB_SCH_CMN_NUM_SCS_PER_RB);
1981    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
1982    {
1983       (*effTbl)[i] = 0;
1984       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
1985       {
1986          /* This line computes the coding efficiency per 1024 REs */
1987          (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1));
1988       }
1989       (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS;
1990    }
1991    return;
1992 }
1993
1994 /**
1995  * @brief This function computes efficiency for 2 layers and stores in a table.
1996  *
1997  * @details
1998  *
1999  *     Function: rgSCHCmn2LyrCompEff
2000  *     Purpose:  this function computes the efficiency as number of
2001  *               bytes per 1024 symbols. The CFI table is also filled
2002  *               with the same information such that comparison is valid
2003  *
2004  *     Invoked by: Scheduler
2005  *
2006  *  @param[in]  uint8_t            noPdcchSym
2007  *  @param[in]  uint8_t            cpType
2008  *  @param[in]  uint8_t            txAntIdx
2009  *  @param[in]  RgSchCmnTbSzEff* effTbl2Lyr
2010  *  @return  Void
2011  *
2012  **/
2013 #ifdef ANSI
2014 static Void rgSCHCmn2LyrCompEff
2015 (
2016 uint8_t                    noPdcchSym,
2017 uint8_t                    cpType,
2018 uint8_t                    txAntIdx,
2019 RgSchCmnTbSzEff       *effTbl2Lyr
2020 )
2021 #else
2022 static Void rgSCHCmn2LyrCompEff(noPdcchSym, cpType, txAntIdx, effTbl2Lyr)
2023 uint8_t                    noPdcchSym;
2024 uint8_t                    cpType;
2025 uint8_t                    txAntIdx;
2026 RgSchCmnTbSzEff       *effTbl2Lyr;
2027 #endif
2028 {
2029    uint8_t               noResPerRb;
2030    uint8_t               noSymPerRb;
2031    uint8_t               resOfCrs; /* Effective REs occupied by CRS */
2032    uint8_t               i, j;
2033
2034
2035    switch (cpType)
2036    {
2037       case RG_SCH_CMN_NOR_CP:
2038          noSymPerRb = 14;
2039          break;
2040       case RG_SCH_CMN_EXT_CP:
2041          noSymPerRb = 12;
2042          break;
2043       default:
2044          /* Generate a log error. This case should never be executed */
2045          return;
2046    }
2047
2048    /* Depending on the Tx Antenna Index, deduct the
2049     * Resource elements for the CRS */
2050    switch (txAntIdx)
2051    {
2052       case 0:
2053          resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT;
2054          break;
2055       case 1:
2056          resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT;
2057          break;
2058       case 2:
2059          resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT;
2060          break;
2061       default:
2062          /* Generate a log error. This case should never be executed */
2063          return;
2064    }
2065
2066    noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs;
2067    for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++)
2068    {
2069       (*effTbl2Lyr)[i] = 0;
2070       for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++)
2071       {
2072          /* This line computes the coding efficiency per 1024 REs */
2073          (*effTbl2Lyr)[i] += (rgTbSzTbl[1][i][j] * 1024) / (noResPerRb * (j+1));
2074       }
2075       (*effTbl2Lyr)[i] /= RG_SCH_CMN_NUM_RBS;
2076    }
2077    return;
2078 }
2079
2080 \f
2081 /**
2082  * @brief This function initializes the rgSchCmnDciFrmtSizes table.
2083  *
2084  * @details
2085  *
2086  *     Function: rgSCHCmnGetDciFrmtSizes
2087  *     Purpose:  This function determines the sizes of all
2088  *               the available DCI Formats. The order of
2089  *               bits addition for each format is inaccordance
2090  *               with the specs.
2091  *     Invoked by: rgSCHCmnRgrCellCfg
2092  *
2093  *  @return  Void
2094  *
2095  **/
2096 #ifdef ANSI
2097 static Void rgSCHCmnGetDciFrmtSizes
2098 (
2099 RgSchCellCb *cell
2100 )
2101 #else
2102 static Void rgSCHCmnGetDciFrmtSizes(cell)
2103 RgSchCellCb *cell;
2104 #endif
2105 {
2106
2107
2108    /* DCI Format 0 size determination */
2109    rgSchCmnDciFrmtSizes[0] = 1 +
2110                              1 +
2111                              rgSCHUtlLog32bitNbase2((cell->bwCfg.ulTotalBw * \
2112                              (cell->bwCfg.ulTotalBw + 1))/2) +
2113                              5 +
2114                              1 +
2115                              2 +
2116                              3 +
2117 #ifdef LTE_TDD
2118                              2 +
2119                              2 +
2120 #endif
2121                              1;
2122    /* DCI Format 1 size determination */
2123    rgSchCmnDciFrmtSizes[1] = 1 +
2124    RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2125                              5 +
2126 #ifndef LTE_TDD
2127                              3 +
2128 #else
2129                              4 + 2 + /* HqProc Id and DAI */
2130 #endif
2131                              1 +
2132                              2 +
2133                              2;
2134
2135    /* DCI Format 1A size determination */
2136    rgSchCmnDciFrmtSizes[2] = 1 + /* Flag for format0/format1a differentiation */
2137                1 + /* Localized/distributed VRB assignment flag */
2138                5 + /* For mcs */
2139 #ifndef LTE_TDD
2140                3 + /* Harq process Id */
2141 #else
2142                4 + /* Harq process Id */
2143                2 + /* UL Index or DAI */
2144 #endif
2145                1 + /* New Data Indicator */
2146                2 + /* For RV */
2147                2 + /* For tpc */
2148                1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2149                    (cell->bwCfg.dlTotalBw + 1))/2);
2150                /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
2151                   Since VRB is local */
2152
2153    /* DCI Format 1B size determination */
2154    rgSchCmnDciFrmtSizes[3] = 1 +
2155                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2156                              (cell->bwCfg.dlTotalBw + 1))/2) +
2157                              5 +
2158                              3 +
2159 #ifdef LTE_TDD
2160                              1 + /* HqP */
2161                              2 + /* Dai */
2162 #endif
2163                              1 +
2164                              2 +
2165                              2 +
2166                              ((cell->numTxAntPorts == 4)? 4:2) +
2167                              1;
2168
2169    /* DCI Format 1C size determination */
2170    /* Approximation: NDLVrbGap1 ~= Nprb for DL */
2171    rgSchCmnDciFrmtSizes[4] = (cell->bwCfg.dlTotalBw < 50)? 0:1 +
2172                              (cell->bwCfg.dlTotalBw < 50)?
2173                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/2 * \
2174                                 (cell->bwCfg.dlTotalBw/2 + 1))/2)) :
2175                              (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/4 * \
2176                                 (cell->bwCfg.dlTotalBw/4 + 1))/2)) +
2177                              5;
2178
2179    /* DCI Format 1D size determination */
2180    rgSchCmnDciFrmtSizes[5] = 1 +
2181                              rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
2182                              (cell->bwCfg.dlTotalBw + 1))/2) +
2183                              5 +
2184                              3 +
2185 #ifdef LTE_TDD
2186                              1 + 2 +
2187 #endif
2188                              1 +
2189                              2 +
2190                              2 +
2191                              ((cell->numTxAntPorts == 4)? 4:2) +
2192                              1;
2193
2194    /* DCI Format 2 size determination */
2195    rgSchCmnDciFrmtSizes[6] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2196                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2197                              2 +
2198 #ifdef LTE_TDD
2199                              2 + 1 +
2200 #endif
2201                              3 +
2202                              1 +
2203                              (5 + 1 + 2)*2 +
2204                              ((cell->numTxAntPorts == 4)? 6:3);
2205
2206    /* DCI Format 2A size determination */
2207    rgSchCmnDciFrmtSizes[7] = ((cell->bwCfg.dlTotalBw < 10)?0:1) +
2208                              RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) +
2209                              2 +
2210 #ifdef LTE_TDD
2211                              2 + 1 +
2212 #endif
2213                              3 +
2214                              1 +
2215                              (5 + 1 + 2)*2 +
2216                              ((cell->numTxAntPorts == 4)? 2:0);
2217
2218    /* DCI Format 3 size determination */
2219    rgSchCmnDciFrmtSizes[8] = rgSchCmnDciFrmtSizes[0];
2220
2221    /* DCI Format 3A size determination */
2222    rgSchCmnDciFrmtSizes[9] = rgSchCmnDciFrmtSizes[0];
2223
2224    return;
2225 }
2226
2227
2228 /**
2229  * @brief This function initializes the cmnCell->dciAggrLvl table.
2230  *
2231  * @details
2232  *
2233  *     Function: rgSCHCmnGetCqiDciFrmt2AggrLvl
2234  *     Purpose:  This function determines the Aggregation level
2235  *               for each CQI level against each DCI format.
2236  *     Invoked by: rgSCHCmnRgrCellCfg
2237  *
2238  *  @return  Void
2239  *
2240  **/
2241 #ifdef ANSI
2242 static Void rgSCHCmnGetCqiDciFrmt2AggrLvl
2243 (
2244 RgSchCellCb *cell
2245 )
2246 #else
2247 static Void rgSCHCmnGetCqiDciFrmt2AggrLvl(cell)
2248 RgSchCellCb *cell;
2249 #endif
2250 {
2251    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
2252    uint8_t            i;
2253    uint8_t            j;
2254
2255
2256    for (i = 0; i < RG_SCH_CMN_MAX_CQI; i++)
2257    {
2258       for (j = 0; j < 10; j++)
2259       {
2260          uint32_t pdcchBits; /* Actual number of phy bits needed for a given DCI Format
2261                * for a given CQI Level */
2262          pdcchBits = (rgSchCmnDciFrmtSizes[j] * 1024)/rgSchCmnCqiPdcchEff[i];
2263                         /* V5G_211 : 6.6 */
2264          if (pdcchBits < 192)
2265          {
2266              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL2;
2267              continue;
2268          }
2269          if (pdcchBits < 384)
2270          {
2271              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL4;
2272              continue;
2273          }
2274          if (pdcchBits < 768)
2275          {
2276              cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL8;
2277              continue;
2278          }
2279          cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL16;
2280       }
2281    }
2282    return;
2283 }
2284 \f
2285 /**
2286  * @brief This function initializes all the data for the scheduler.
2287  *
2288  * @details
2289  *
2290  *     Function: rgSCHCmnDlInit
2291  *     Purpose:  This function initializes the following information:
2292  *               1. Efficiency table
2293  *               2. CQI to table index - It is one row for upto 3 RBs
2294  *                  and another row for greater than 3 RBs
2295  *                  currently extended prefix is compiled out.
2296  *     Invoked by: MAC intialization code..may be ActvInit
2297  *
2298  *  @return  Void
2299  *
2300  **/
2301 #ifdef ANSI
2302 static Void rgSCHCmnDlInit
2303 (
2304 )
2305 #else
2306 static Void rgSCHCmnDlInit()
2307 #endif
2308 {
2309    uint8_t                   i;
2310    S16                  j;
2311    S16                  k;
2312    uint8_t                   idx;
2313    RgSchCmnTbSzEff      *effTbl;
2314    RgSchCmnCqiToTbs     *tbsTbl;
2315
2316
2317    /* 0 corresponds to Single layer case, 1 corresponds to 2 layers case*/
2318    /* Init Efficiency table for normal cyclic prefix */
2319    /*Initialize Efficiency table for Layer Index 0 */
2320    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2321    /*Initialize Efficiency table for each of the CFI indices. The
2322     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2323    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[0];
2324    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[0];
2325    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[0];
2326    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[0];
2327    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2328    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[0];
2329    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[0];
2330    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[0];
2331    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[0];
2332    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2333    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[0];
2334    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[0];
2335    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[0];
2336    rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[0];
2337
2338    /*Initialize CQI to TBS table for Layer Index 0 for Normal CP */
2339    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[0];
2340    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[0];
2341    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[0];
2342    rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[0];
2343
2344    /*Intialize Efficency table for Layer Index 1 */
2345    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2346    /*Initialize Efficiency table for each of the CFI indices. The
2347     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2348    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[1];
2349    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[1];
2350    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[1];
2351    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[1];
2352    /*Initialize Efficiency table for Tx Antenna Port Index 1 */
2353    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[1];
2354    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[1];
2355    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[1];
2356    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[1];
2357    /*Initialize Efficiency table for Tx Antenna Port Index 2 */
2358    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[1];
2359    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[1];
2360    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[1];
2361    rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[1];
2362
2363    /*Initialize CQI to TBS table for Layer Index 1 for Normal CP */
2364    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[1];
2365    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[1];
2366    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[1];
2367    rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[1];
2368
2369    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2370    {
2371       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2372       {
2373          /* EfficiencyTbl calculation incase of 2 layers for normal CP  */
2374          rgSCHCmnCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx,\
2375                rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]);
2376          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), RG_SCH_CMN_NOR_CP, idx, \
2377                rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]);
2378       }
2379    }
2380
2381    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2382    {
2383       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2384       {
2385          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i];
2386          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][i];
2387          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2388                (j >= 0) && (k > 0); --j)
2389          {
2390             /* ADD CQI to MCS mapping correction
2391             * single dimensional array is replaced by 2 dimensions for different CFI*/
2392             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2393             {
2394                (*tbsTbl)[k--] = (uint8_t)j;
2395             }
2396          }
2397          for (; k > 0; --k)
2398          {
2399             (*tbsTbl)[k] = 0;
2400          }
2401          /* effTbl,tbsTbl calculation incase of 2 layers for normal CP */
2402          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i];
2403          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][i];
2404          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2405                (j >= 0) && (k > 0); --j)
2406          {
2407             /* ADD CQI to MCS mapping correction
2408             * single dimensional array is replaced by 2 dimensions for different CFI*/
2409             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2410             {
2411                (*tbsTbl)[k--] = (uint8_t)j;
2412             }
2413          }
2414          for (; k > 0; --k)
2415          {
2416             (*tbsTbl)[k] = 0;
2417          }
2418       }
2419    }
2420
2421    /* Efficiency Table for Extended CP */
2422    /*Initialize Efficiency table for Layer Index 0 */
2423    /*Initialize Efficiency table for Tx Antenna Port Index 0 */
2424    /*Initialize Efficiency table for each of the CFI indices. The
2425     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2426    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[0];
2427    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[0];
2428    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[0];
2429    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[0];
2430    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2431    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[0];
2432    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[0];
2433    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[0];
2434    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[0];
2435    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2436    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[0];
2437    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[0];
2438    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[0];
2439    rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[0];
2440
2441    /*Initialize CQI to TBS table for Layer Index 0 for Extended CP */
2442    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[0];
2443    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[0];
2444    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[0];
2445    rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[0];
2446
2447    /*Initialize Efficiency table for Layer Index 1 */
2448    /*Initialize Efficiency table for each of the CFI indices. The
2449     * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/
2450    /*Initialize Efficency table for Tx Antenna Port Index 0 */
2451    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[1];
2452    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[1];
2453    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[1];
2454    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[1];
2455    /*Initialize Efficency table for Tx Antenna Port Index 1 */
2456    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[1];
2457    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[1];
2458    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[1];
2459    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[1];
2460    /*Initialize Efficency table for Tx Antenna Port Index 2 */
2461    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[1];
2462    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[1];
2463    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[1];
2464    rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[1];
2465
2466    /*Initialize CQI to TBS table for Layer Index 1 for Extended CP */
2467    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[1];
2468    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[1];
2469    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[1];
2470    rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[1];
2471    /* Activate this code when extended cp is supported */
2472    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2473    {
2474       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2475       {
2476          /* EfficiencyTbl calculation incase of 2 layers for extendedl CP  */
2477          rgSCHCmnCompEff( (uint8_t)(i + 1 ), (uint8_t)RG_SCH_CMN_EXT_CP, idx,\
2478                rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]);
2479          rgSCHCmn2LyrCompEff((uint8_t)(i + 1), (uint8_t) RG_SCH_CMN_EXT_CP,idx, \
2480                rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]);
2481       }
2482    }
2483
2484    for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++)
2485    {
2486       for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++)
2487       {
2488          effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i];
2489          tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][i];
2490          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2491                (j >= 0) && (k > 0); --j)
2492          {
2493             /* ADD CQI to MCS mapping correction
2494             * single dimensional array is replaced by 2 dimensions for different CFI*/
2495             if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k])
2496             {
2497                (*tbsTbl)[k--] = (uint8_t)j;
2498             }
2499          }
2500          for (; k > 0; --k)
2501          {
2502             (*tbsTbl)[k] = 0;
2503          }
2504          /* effTbl,tbsTbl calculation incase of 2 layers for extended CP */
2505          effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i];
2506          tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][i];
2507          for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1;
2508                (j >= 0) && (k > 0); --j)
2509          {
2510            /* ADD CQI to MCS mapping correction
2511             * single dimensional array is replaced by 2 dimensions for different CFI*/
2512             if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k])
2513             {
2514                (*tbsTbl)[k--] = (uint8_t)j;
2515             }
2516          }
2517          for (; k > 0; --k)
2518          {
2519             (*tbsTbl)[k] = 0;
2520          }
2521       }
2522    }
2523    return;
2524 }
2525 \f
2526 /**
2527  * @brief This function initializes all the data for the scheduler.
2528  *
2529  * @details
2530  *
2531  *     Function: rgSCHCmnUlInit
2532  *     Purpose:  This function initializes the following information:
2533  *               1. Efficiency table
2534  *               2. CQI to table index - It is one row for upto 3 RBs
2535  *                  and another row for greater than 3 RBs
2536  *                  currently extended prefix is compiled out.
2537  *     Invoked by: MAC intialization code..may be ActvInit
2538  *
2539  *  @return  Void
2540  *
2541  **/
2542 #ifdef ANSI
2543 static Void rgSCHCmnUlInit
2544 (
2545 )
2546 #else
2547 static Void rgSCHCmnUlInit()
2548 #endif
2549 {
2550    uint8_t              *mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_NOR_CP][0];
2551    RgSchCmnTbSzEff    *effTbl    = &rgSchCmnNorUlEff[0];
2552    const RgSchCmnUlCqiInfo *cqiTbl = &rgSchCmnUlCqiTbl[0];
2553    S16              i;
2554    S16              j;
2555
2556    /* Initaializing new variable added for UL eff */
2557    rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP] = &rgSchCmnNorUlEff[0];
2558    /* Reason behind using 3 as the number of symbols to rule out for
2559     * efficiency table computation would be that we are using 2 symbols for
2560     * DMRS(1 in each slot) and 1 symbol for SRS*/
2561    rgSCHCmnCompUlEff(RGSCH_UL_SYM_DMRS_SRS,RG_SCH_CMN_NOR_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP]);
2562
2563    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2564          i >= 0 && j > 0; --i)
2565    {
2566       if ((*effTbl)[i] <= cqiTbl[j].eff)
2567       {
2568          mapTbl[j--] = (uint8_t)i;
2569       }
2570    }
2571    for (; j > 0; --j)
2572    {
2573       mapTbl[j] = 0;
2574    }
2575    effTbl    = &rgSchCmnExtUlEff[0];
2576    mapTbl    = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_EXT_CP][0];
2577
2578    /* Initaializing new variable added for UL eff */
2579    rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP] = &rgSchCmnExtUlEff[0];
2580    /* Reason behind using 3 as the number of symbols to rule out for
2581     * efficiency table computation would be that we are using 2 symbols for
2582     * DMRS(1 in each slot) and 1 symbol for SRS*/
2583    rgSCHCmnCompUlEff(3,RG_SCH_CMN_EXT_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP]);
2584
2585    for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1;
2586          i >= 0 && j > 0; --i)
2587    {
2588       if ((*effTbl)[i] <= cqiTbl[j].eff)
2589       {
2590          mapTbl[j--] = (uint8_t)i;
2591       }
2592    }
2593    for (; j > 0; --j)
2594    {
2595       mapTbl[j] = 0;
2596    }
2597    rgSCHPwrInit();
2598    return;
2599 }
2600
2601 /**
2602  * @brief This function initializes all the data for the scheduler.
2603  *
2604  * @details
2605  *
2606  *     Function: rgSCHCmnInit
2607  *     Purpose:  This function initializes the following information:
2608  *               1. Efficiency table
2609  *               2. CQI to table index - It is one row for upto 3 RBs
2610  *                  and another row for greater than 3 RBs
2611  *                  currently extended prefix is compiled out.
2612  *     Invoked by: MAC intialization code..may be ActvInit
2613  *
2614  *  @return  Void
2615  *
2616  **/
2617 #ifdef ANSI
2618 Void rgSCHCmnInit
2619 (
2620 )
2621 #else
2622 Void rgSCHCmnInit()
2623 #endif
2624 {
2625    uint8_t   idx;
2626
2627    rgSCHCmnDlInit();
2628    rgSCHCmnUlInit();
2629 #ifdef EMTC_ENABLE
2630    rgSCHEmtcCmnDlInit();
2631    rgSCHEmtcCmnUlInit();
2632 #endif      
2633 #ifdef LTEMAC_SPS
2634    rgSCHCmnSpsInit();
2635 #endif
2636
2637    /* Init the function pointers */
2638    rgSchCmnApis.rgSCHRgrUeCfg         = rgSCHCmnRgrUeCfg;
2639    rgSchCmnApis.rgSCHRgrUeRecfg       = rgSCHCmnRgrUeRecfg;
2640    rgSchCmnApis.rgSCHFreeUe           = rgSCHCmnUeDel;
2641    rgSchCmnApis.rgSCHRgrCellCfg       = rgSCHCmnRgrCellCfg;
2642    rgSchCmnApis.rgSCHRgrCellRecfg     = rgSCHCmnRgrCellRecfg;
2643    rgSchCmnApis.rgSCHFreeCell         = rgSCHCmnCellDel;
2644    rgSchCmnApis.rgSCHRgrLchCfg        = rgSCHCmnRgrLchCfg;
2645    rgSchCmnApis.rgSCHRgrLcgCfg        = rgSCHCmnRgrLcgCfg;
2646    rgSchCmnApis.rgSCHRgrLchRecfg      = rgSCHCmnRgrLchRecfg;
2647    rgSchCmnApis.rgSCHRgrLcgRecfg      = rgSCHCmnRgrLcgRecfg;
2648    rgSchCmnApis.rgSCHFreeDlLc         = rgSCHCmnFreeDlLc;
2649    rgSchCmnApis.rgSCHFreeLcg          = rgSCHCmnLcgDel;
2650    rgSchCmnApis.rgSCHRgrLchDel        = rgSCHCmnRgrLchDel;
2651    rgSchCmnApis.rgSCHActvtUlUe        = rgSCHCmnActvtUlUe;
2652    rgSchCmnApis.rgSCHActvtDlUe        = rgSCHCmnActvtDlUe;
2653    rgSchCmnApis.rgSCHHdlUlTransInd    = rgSCHCmnHdlUlTransInd;
2654    rgSchCmnApis.rgSCHDlDedBoUpd       = rgSCHCmnDlDedBoUpd;
2655    rgSchCmnApis.rgSCHUlRecMsg3Alloc   = rgSCHCmnUlRecMsg3Alloc;
2656    rgSchCmnApis.rgSCHUlCqiInd         = rgSCHCmnUlCqiInd;
2657    rgSchCmnApis.rgSCHPucchDeltaPwrInd = rgSCHPwrPucchDeltaInd;
2658    rgSchCmnApis.rgSCHUlHqProcForUe    = rgSCHCmnUlHqProcForUe;
2659 #ifdef RG_UNUSED
2660    rgSchCmnApis.rgSCHUpdUlHqProc      = rgSCHCmnUpdUlHqProc;
2661 #endif
2662    rgSchCmnApis.rgSCHUpdBsrShort      = rgSCHCmnUpdBsrShort;
2663    rgSchCmnApis.rgSCHUpdBsrTrunc      = rgSCHCmnUpdBsrTrunc;
2664    rgSchCmnApis.rgSCHUpdBsrLong       = rgSCHCmnUpdBsrLong;
2665    rgSchCmnApis.rgSCHUpdPhr           = rgSCHCmnUpdPhr;
2666    rgSchCmnApis.rgSCHUpdExtPhr        = rgSCHCmnUpdExtPhr;
2667    rgSchCmnApis.rgSCHContResUlGrant   = rgSCHCmnContResUlGrant;
2668    rgSchCmnApis.rgSCHSrRcvd           = rgSCHCmnSrRcvd;
2669    rgSchCmnApis.rgSCHFirstRcptnReq    = rgSCHCmnFirstRcptnReq;
2670    rgSchCmnApis.rgSCHNextRcptnReq     = rgSCHCmnNextRcptnReq;
2671    rgSchCmnApis.rgSCHFirstHqFdbkAlloc = rgSCHCmnFirstHqFdbkAlloc;
2672    rgSchCmnApis.rgSCHNextHqFdbkAlloc  = rgSCHCmnNextHqFdbkAlloc;
2673    rgSchCmnApis.rgSCHDlProcAddToRetx  = rgSCHCmnDlProcAddToRetx;
2674    rgSchCmnApis.rgSCHDlCqiInd         = rgSCHCmnDlCqiInd;
2675 #ifdef EMTC_ENABLE
2676    rgSchCmnApis.rgSCHUlProcAddToRetx  = rgSCHCmnEmtcUlProcAddToRetx;
2677 #endif
2678 #ifdef TFU_UPGRADE
2679    rgSchCmnApis.rgSCHSrsInd           = rgSCHCmnSrsInd;
2680 #endif
2681    rgSchCmnApis.rgSCHDlTARpt          = rgSCHCmnDlTARpt;
2682    rgSchCmnApis.rgSCHDlRlsSubFrm      = rgSCHCmnDlRlsSubFrm;
2683    rgSchCmnApis.rgSCHUeReset          = rgSCHCmnUeReset;
2684 #ifdef LTEMAC_SPS
2685    rgSchCmnApis.rgSCHHdlCrntiCE         = rgSCHCmnHdlCrntiCE;
2686    rgSchCmnApis.rgSCHDlProcAck        = rgSCHCmnDlProcAck;
2687    rgSchCmnApis.rgSCHDlRelPdcchFbk    = rgSCHCmnDlRelPdcchFbk;
2688    rgSchCmnApis.rgSCHUlSpsRelInd      = rgSCHCmnUlSpsRelInd;
2689    rgSchCmnApis.rgSCHUlSpsActInd      = rgSCHCmnUlSpsActInd;
2690    rgSchCmnApis.rgSCHUlCrcFailInd     = rgSCHCmnUlCrcFailInd;
2691    rgSchCmnApis.rgSCHUlCrcInd     = rgSCHCmnUlCrcInd;
2692 #endif
2693    rgSchCmnApis.rgSCHDrxStrtInActvTmrInUl = rgSCHCmnDrxStrtInActvTmrInUl;
2694    rgSchCmnApis.rgSCHUpdUeDataIndLcg      = rgSCHCmnUpdUeDataIndLcg;
2695
2696    for (idx = 0; idx < RGSCH_NUM_SCHEDULERS; ++idx)
2697    {
2698       rgSchUlSchdInits[idx](&rgSchUlSchdTbl[idx]);
2699       rgSchDlSchdInits[idx](&rgSchDlSchdTbl[idx]);
2700    }
2701 #ifdef EMTC_ENABLE 
2702    for (idx = 0; idx < RGSCH_NUM_EMTC_SCHEDULERS; ++idx)
2703    {
2704       rgSchEmtcUlSchdInits[idx](&rgSchEmtcUlSchdTbl[idx]);
2705       rgSchEmtcDlSchdInits[idx](&rgSchEmtcDlSchdTbl[idx]);
2706    }
2707 #endif
2708 #if (defined (RG_PHASE2_SCHED) && defined(TFU_UPGRADE))
2709    for (idx = 0; idx < RGSCH_NUM_DLFS_SCHEDULERS; ++idx)
2710    {
2711       rgSchDlfsSchdInits[idx](&rgSchDlfsSchdTbl[idx]);
2712    }
2713 #endif
2714 #ifdef LTE_ADV
2715    rgSchCmnApis.rgSCHRgrSCellUeCfg         = rgSCHCmnRgrSCellUeCfg;
2716    rgSchCmnApis.rgSCHRgrSCellUeDel         = rgSCHCmnRgrSCellUeDel;
2717 #endif
2718    return;
2719 }
2720
2721 \f
2722 /**
2723  * @brief This function is a wrapper to call scheduler specific API.
2724  *
2725  * @details
2726  *
2727  *     Function: rgSCHCmnDlRlsSubFrm
2728  *     Purpose:  Releases scheduler Information from DL SubFrm.
2729  *
2730  *     Invoked by: DHM
2731  *
2732  *  @param[in]   RgSchCellCb     *cell
2733  *  @param[out]  CmLteTimingInfo frm
2734  *  @return  Void
2735  *
2736  **/
2737 #ifdef ANSI
2738 Void rgSCHCmnDlRlsSubFrm
2739 (
2740 RgSchCellCb        *cell,
2741 CmLteTimingInfo   frm
2742 )
2743 #else
2744 Void rgSCHCmnDlRlsSubFrm(cell, frm)
2745 RgSchCellCb        *cell;
2746 CmLteTimingInfo    frm;
2747 #endif
2748 {
2749    RgSchCmnCell        *cellSch = RG_SCH_CMN_GET_CELL(cell);
2750    RgSchDlSf           *sf;
2751
2752
2753    /* Get the pointer to the subframe */
2754    sf = rgSCHUtlSubFrmGet(cell, frm);
2755
2756    rgSCHUtlSubFrmPut(cell, sf);
2757    if (sf->dlfsSf)
2758    {
2759       /* Re-initialize DLFS specific information for the sub-frame */
2760       cellSch->apisDlfs->rgSCHDlfsReinitSf(cell, sf);
2761    }
2762    return;
2763 }
2764
2765
2766 \f
2767 /**
2768  * @brief This function is the starting function for DL allocation.
2769  *
2770  * @details
2771  *
2772  *     Function: rgSCHCmnDlCmnChAlloc
2773  *     Purpose:  Scheduling for downlink. It performs allocation in the order
2774  *               of priority wich BCCH/PCH first, CCCH, Random Access and TA.
2775  *
2776  *     Invoked by: Scheduler
2777  *
2778  *  @param[in]  RgSchCellCb*           cell
2779  *  @param[out] RgSchCmnDlRbAllocInfo* allocInfo
2780  *  @return  Void
2781  *
2782  **/
2783 #ifdef ANSI
2784 static Void rgSCHCmnDlCcchRarAlloc
2785 (
2786 RgSchCellCb             *cell
2787 )
2788 #else
2789 static Void rgSCHCmnDlCcchRarAlloc(cell)
2790 RgSchCellCb             *cell;
2791 #endif
2792 {
2793    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
2794
2795
2796    rgSCHCmnDlCcchRetx(cell, &cellSch->allocInfo);
2797    /* LTE_ADV_FLAG_REMOVED_START */
2798    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2799    {
2800       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2801       {
2802          /*eNodeB need to blank the subframe */
2803       }
2804       else
2805       {
2806          rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2807       }
2808    }
2809    else
2810    {
2811       rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo);
2812    }
2813    /* LTE_ADV_FLAG_REMOVED_END */
2814
2815 #ifdef RGR_V1
2816
2817    /*Added these function calls for processing CCCH SDU arriving
2818     * after guard timer expiry.Functions differ from above two functions
2819     * in using ueCb instead of raCb.*/
2820    rgSCHCmnDlCcchSduRetx(cell, &cellSch->allocInfo);
2821    /* LTE_ADV_FLAG_REMOVED_START */
2822    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2823    {
2824       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2825       {
2826          /*eNodeB need to blank the subframe */
2827       }
2828       else
2829       {
2830          rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2831       }
2832    }
2833    else
2834    {
2835       rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo);
2836    }
2837    /* LTE_ADV_FLAG_REMOVED_END */
2838 #endif
2839
2840 #ifdef LTE_TDD
2841    if(cellSch->ul.msg3SchdIdx != RGSCH_INVALID_INFO)
2842    {
2843       /* Do not schedule msg3 if there is a CFI change ongoing */
2844       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2845       {
2846          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2847       }
2848    }
2849 #else
2850    /* LTE_ADV_FLAG_REMOVED_START */
2851    if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo)
2852    {
2853       if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
2854       {
2855          /*eNodeB need to blank the subframe */
2856       }
2857       else
2858       {
2859          /* Do not schedule msg3 if there is a CFI change ongoing */
2860          if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2861          {
2862             rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2863          }
2864       }
2865    }
2866    else
2867    {
2868       /* Do not schedule msg3 if there is a CFI change ongoing */
2869       if (cellSch->dl.currCfi == cellSch->dl.newCfi)
2870       {
2871          rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo);
2872       }
2873    }
2874    /* LTE_ADV_FLAG_REMOVED_END */
2875 #endif
2876
2877    return;
2878 }
2879
2880 #ifdef RGR_V1
2881 /**
2882  * @brief Scheduling for CCCH SDU.
2883  *
2884  * @details
2885  *
2886  *     Function: rgSCHCmnCcchSduAlloc
2887  *     Purpose:  Scheduling for CCCH SDU
2888  *
2889  *     Invoked by: Scheduler
2890  *
2891  *  @param[in]  RgSchCellCb*          cell
2892  *  @param[in]  RgSchUeCb*            ueCb
2893  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2894  *  @return  S16
2895  *
2896  **/
2897 #ifdef ANSI
2898 static S16 rgSCHCmnCcchSduAlloc
2899 (
2900 RgSchCellCb                *cell,
2901 RgSchUeCb                  *ueCb,
2902 RgSchCmnDlRbAllocInfo      *allocInfo
2903 )
2904 #else
2905 static S16 rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)
2906 RgSchCellCb                *cell;
2907 RgSchUeCb                  *ueCb;
2908 RgSchCmnDlRbAllocInfo      *allocInfo;
2909 #endif
2910 {
2911    RgSchDlRbAlloc  *rbAllocInfo;
2912    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
2913    RgSchCmnDlUe       *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2914
2915
2916    /* Return if subframe BW exhausted */
2917    if (allocInfo->ccchSduAlloc.ccchSduDlSf->bw <=
2918        allocInfo->ccchSduAlloc.ccchSduDlSf->bwAssigned)
2919    {
2920       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2921          "bw<=bwAssigned for UEID:%d",ueCb->ueId);
2922       return RFAILED;
2923    }
2924
2925    if (rgSCHDhmGetCcchSduHqProc(ueCb, cellSch->dl.time, &(ueDl->proc)) != ROK)
2926    {
2927       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2928          "rgSCHDhmGetCcchSduHqProc failed UEID:%d",ueCb->ueId);
2929       return RFAILED;
2930    }
2931
2932    rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
2933    rbAllocInfo->dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2934
2935    if (rgSCHCmnCcchSduDedAlloc(cell, ueCb) != ROK)
2936    {
2937       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
2938       rgSCHDhmRlsHqpTb(ueDl->proc, 0, FALSE);
2939       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2940          "rgSCHCmnCcchSduDedAlloc failed UEID:%d",ueCb->ueId);
2941       return RFAILED;
2942    }
2943    cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduTxLst, &ueDl->proc->reqLnk);
2944    ueDl->proc->reqLnk.node = (PTR)ueDl->proc;
2945    allocInfo->ccchSduAlloc.ccchSduDlSf->schdCcchUe++;
2946
2947    return ROK;
2948 }
2949 /**
2950  * @brief This function scheduler for downlink CCCH messages.
2951  *
2952  * @details
2953  *
2954  *     Function: rgSCHCmnDlCcchSduTx
2955  *     Purpose:  Scheduling for downlink CCCH
2956  *
2957  *     Invoked by: Scheduler
2958  *
2959  *  @param[in]  RgSchCellCb           *cell
2960  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2961  *  @return  Void
2962  *
2963  **/
2964 #ifdef ANSI
2965 static Void rgSCHCmnDlCcchSduTx
2966 (
2967 RgSchCellCb             *cell,
2968 RgSchCmnDlRbAllocInfo   *allocInfo
2969 )
2970 #else
2971 static Void rgSCHCmnDlCcchSduTx(cell, allocInfo)
2972 RgSchCellCb             *cell;
2973 RgSchCmnDlRbAllocInfo   *allocInfo;
2974 #endif
2975 {
2976    CmLList           *node;
2977    RgSchUeCb         *ueCb;
2978    RgSchCmnDlUe      *ueCmnDl;
2979    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
2980
2981    RgSchDlSf         *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
2982    
2983
2984    node = cell->ccchSduUeLst.first;
2985    while(node)
2986    {
2987       if(cellSch->dl.maxCcchPerDlSf &&
2988             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
2989       {
2990          break;
2991       }
2992       else
2993       {
2994          ueCb = (RgSchUeCb *)(node->node);
2995          ueCmnDl  = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
2996          node = node->next;
2997          /* Fix : syed postpone scheduling for this
2998           * until msg4 is done */
2999          /* Fix : syed RLC can erroneously send CCCH SDU BO 
3000           * twice. Hence an extra guard to avoid if already 
3001           * scheduled for RETX */
3002          if ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
3003                (!ueCmnDl->proc))
3004          {
3005             if ((rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)) != ROK)
3006             {
3007                break;
3008             }
3009          }
3010          else
3011          {
3012             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"ERROR!! THIS SHOULD "
3013                      "NEVER HAPPEN for UEID:%d", ueCb->ueId);
3014             continue;
3015          }
3016       }
3017    }
3018    return;
3019 }
3020 #endif
3021 \f
3022 /**
3023  * @brief This function scheduler for downlink CCCH messages.
3024  *
3025  * @details
3026  *
3027  *     Function: rgSCHCmnDlCcchTx
3028  *     Purpose:  Scheduling for downlink CCCH
3029  *
3030  *     Invoked by: Scheduler
3031  *
3032  *  @param[in]  RgSchCellCb           *cell
3033  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3034  *  @return  Void
3035  *
3036  **/
3037 #ifdef ANSI
3038 static Void rgSCHCmnDlCcchTx
3039 (
3040 RgSchCellCb             *cell,
3041 RgSchCmnDlRbAllocInfo   *allocInfo
3042 )
3043 #else
3044 static Void rgSCHCmnDlCcchTx(cell, allocInfo)
3045 RgSchCellCb             *cell;
3046 RgSchCmnDlRbAllocInfo   *allocInfo;
3047 #endif
3048 {
3049    CmLList           *node;
3050    RgSchRaCb         *raCb;
3051    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3052    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3053    
3054
3055    node = cell->raInfo.toBeSchdLst.first;
3056    while(node)
3057    {
3058       if(cellSch->dl.maxCcchPerDlSf &&
3059             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3060       {
3061          break;
3062       }
3063       else
3064       {
3065
3066          raCb = (RgSchRaCb *)(node->node);
3067          node = node->next;
3068          /* Address allocation for this UE for MSG 4 */
3069          /* Allocation for Msg4 */
3070          if ((rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)) != ROK)
3071          {
3072             break;
3073          }
3074       }
3075    }
3076    return;
3077 }
3078
3079 #ifdef RGR_V1
3080 /**
3081  * @brief This function scheduler for downlink CCCH messages.
3082  *
3083  * @details
3084  *
3085  *     Function: rgSCHCmnDlCcchSduRetx
3086  *     Purpose:  Scheduling for downlink CCCH
3087  *
3088  *     Invoked by: Scheduler
3089  *
3090  *  @param[in]  RgSchCellCb           *cell
3091  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3092  *  @return  Void
3093  *
3094  **/
3095 #ifdef ANSI
3096 static Void rgSCHCmnDlCcchSduRetx
3097 (
3098 RgSchCellCb             *cell,
3099 RgSchCmnDlRbAllocInfo   *allocInfo
3100 )
3101 #else
3102 static Void rgSCHCmnDlCcchSduRetx(cell, allocInfo)
3103 RgSchCellCb             *cell;
3104 RgSchCmnDlRbAllocInfo   *allocInfo;
3105 #endif
3106 {
3107    RgSchDlRbAlloc  *rbAllocInfo;
3108    CmLList           *node;
3109    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3110    RgSchUeCb         *ueCb;
3111    RgSchDlHqProcCb   *hqP;
3112    uint8_t                retxBw = 0;
3113    RgSchCmnDlUe      *ueDl;
3114    RgSchDlSf         *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf;
3115    
3116
3117    node = cellSch->dl.ccchSduRetxLst.first;
3118    while(node)
3119    {
3120       if(cellSch->dl.maxCcchPerDlSf &&
3121             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3122       {
3123          break;
3124       }
3125       else
3126       {
3127
3128          hqP = (RgSchDlHqProcCb *)(node->node);
3129          node = node->next;
3130
3131          /* DwPts Scheduling Changes Start */      
3132 #ifdef LTE_TDD
3133          if (rgSCHCmnRetxAvoidTdd(allocInfo->ccchSduAlloc.ccchSduDlSf, 
3134                   cell, hqP) == TRUE)
3135          {
3136             continue;  
3137          }
3138 #endif
3139          /* DwPts Scheduling Changes End */     
3140
3141          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3142          {
3143             break;
3144          }
3145          ueCb = (RgSchUeCb*)(hqP->hqE->ue);
3146          ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
3147
3148          rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
3149          /* Fill RB Alloc Info */
3150          rbAllocInfo->dlSf = dlSf;
3151          rbAllocInfo->tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3152          rbAllocInfo->rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3153          /* Fix : syed iMcs setting did not correspond to RETX */
3154          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3155                rbAllocInfo->tbInfo[0].imcs);
3156          rbAllocInfo->rnti = ueCb->ueId;
3157          rbAllocInfo->tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3158          /* Fix : syed Copying info in entirety without depending on stale TX information */
3159          rbAllocInfo->tbInfo[0].tbCb = &hqP->tbInfo[0];
3160          rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
3161          /* Fix : syed Assigning proc to scratchpad */ 
3162          ueDl->proc = hqP;
3163
3164          retxBw += rbAllocInfo->rbsReq;
3165
3166          cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduRetxLst, \
3167                &hqP->reqLnk);
3168          hqP->reqLnk.node = (PTR)hqP;
3169          dlSf->schdCcchUe++;
3170       }
3171    }
3172    dlSf->bwAssigned += retxBw;
3173    return;
3174 }
3175 #endif
3176 \f
3177 /**
3178  * @brief This function scheduler for downlink CCCH messages.
3179  *
3180  * @details
3181  *
3182  *     Function: rgSCHCmnDlCcchRetx
3183  *     Purpose:  Scheduling for downlink CCCH
3184  *
3185  *     Invoked by: Scheduler
3186  *
3187  *  @param[in]  RgSchCellCb           *cell
3188  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3189  *  @return  Void
3190  *
3191  **/
3192 #ifdef ANSI
3193 static Void rgSCHCmnDlCcchRetx
3194 (
3195 RgSchCellCb             *cell,
3196 RgSchCmnDlRbAllocInfo   *allocInfo
3197 )
3198 #else
3199 static Void rgSCHCmnDlCcchRetx(cell, allocInfo)
3200 RgSchCellCb             *cell;
3201 RgSchCmnDlRbAllocInfo   *allocInfo;
3202 #endif
3203 {
3204    CmLList           *node;
3205    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
3206    RgSchRaCb         *raCb;
3207    RgSchDlHqProcCb   *hqP;
3208    uint8_t                retxBw = 0;
3209    RgSchDlSf         *dlSf = allocInfo->msg4Alloc.msg4DlSf;
3210         
3211
3212    node = cellSch->dl.msg4RetxLst.first;
3213    while(node)
3214    {
3215       if(cellSch->dl.maxCcchPerDlSf &&
3216             dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf)
3217       {
3218          break;
3219       }
3220       else
3221       {
3222          hqP = (RgSchDlHqProcCb *)(node->node);
3223
3224          node = node->next;
3225
3226          /* DwPts Scheduling Changes Start */     
3227 #ifdef LTE_TDD      
3228          if (rgSCHCmnRetxAvoidTdd(allocInfo->msg4Alloc.msg4DlSf, 
3229                   cell, hqP) == TRUE)
3230          {
3231             continue;  
3232          }
3233 #endif      
3234          /* DwPts Scheduling Changes End */      
3235
3236          if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned))
3237          {
3238             break;
3239          }
3240          raCb = (RgSchRaCb*)(hqP->hqE->raCb);
3241          /* Fill RB Alloc Info */
3242          raCb->rbAllocInfo.dlSf = dlSf;
3243          raCb->rbAllocInfo.tbInfo[0].bytesReq =  hqP->tbInfo[0].ccchSchdInfo.totBytes;
3244          raCb->rbAllocInfo.rbsReq = hqP->tbInfo[0].dlGrnt.numRb;
3245          /* Fix : syed iMcs setting did not correspond to RETX */
3246          RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), 
3247                raCb->rbAllocInfo.tbInfo[0].imcs);
3248          raCb->rbAllocInfo.rnti = raCb->tmpCrnti;
3249          raCb->rbAllocInfo.tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs;
3250          /* Fix; syed Copying info in entirety without depending on stale TX information */
3251          raCb->rbAllocInfo.tbInfo[0].tbCb = &hqP->tbInfo[0];
3252          raCb->rbAllocInfo.tbInfo[0].schdlngForTb = TRUE;
3253
3254          retxBw += raCb->rbAllocInfo.rbsReq;
3255
3256          cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4RetxLst, \
3257                &hqP->reqLnk);
3258          hqP->reqLnk.node = (PTR)hqP;
3259          dlSf->schdCcchUe++;
3260       }
3261    }
3262    dlSf->bwAssigned += retxBw;
3263    return;
3264 }
3265
3266 \f
3267 /**
3268  * @brief This function implements scheduler DL allocation for
3269  *        for broadcast (on PDSCH) and paging.
3270  *
3271  * @details
3272  *
3273  *     Function: rgSCHCmnDlBcchPcch
3274  *     Purpose:  This function implements scheduler for DL allocation
3275  *               for broadcast (on PDSCH) and paging.
3276  *
3277  *     Invoked by: Scheduler
3278  *
3279  *  @param[in]  RgSchCellCb*     cell
3280  *  @return  S16
3281  *      -# ROK
3282  *      -# RFAILED
3283  **/
3284 #ifdef ANSI
3285 static Void rgSCHCmnDlBcchPcch
3286 (
3287 RgSchCellCb             *cell,
3288 RgSchCmnDlRbAllocInfo   *allocInfo,
3289 RgInfSfAlloc            *subfrmAlloc
3290 )
3291 #else
3292 static Void rgSCHCmnDlBcchPcch(cell, allocInfo, subfrmAlloc)
3293 RgSchCellCb             *cell;
3294 RgSchCmnDlRbAllocInfo   *allocInfo;
3295 RgInfSfAlloc            *subfrmAlloc;
3296 #endif
3297 {
3298    CmLteTimingInfo   frm;
3299    RgSchDlSf         *sf;
3300    RgSchClcDlLcCb    *pcch;
3301    RgSchClcBoRpt     *bo;
3302 #ifndef RGR_SI_SCH
3303    Bool              valid;
3304    RgSchClcDlLcCb    *bcch, *bch;
3305 #endif/*RGR_SI_SCH*/
3306
3307
3308
3309    frm   = cell->crntTime;
3310 #ifdef LTEMAC_HDFDD
3311    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
3312       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
3313    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
3314 #else
3315   // RGSCH_SUBFRAME_INDEX(frm);
3316    //RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
3317 #endif
3318
3319    /* Compute the subframe for which allocation is being made        */
3320    /* essentially, we need pointer to the dl frame for this subframe */
3321    sf = rgSCHUtlSubFrmGet(cell, frm);
3322
3323
3324 #ifndef RGR_SI_SCH
3325    bch = rgSCHDbmGetBcchOnBch(cell);
3326 #if (ERRCLASS & ERRCLS_DEBUG)
3327    if (bch == NULLP)
3328    {
3329       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on BCH is not configured");
3330       return;
3331    }
3332 #endif
3333    if (bch->boLst.first != NULLP)
3334    {
3335       bo = (RgSchClcBoRpt *)(bch->boLst.first->node);
3336       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3337       {
3338          sf->bch.tbSize = bo->bo;
3339          cmLListDelFrm(&bch->boLst, bch->boLst.first);
3340          /* ccpu00117052 - MOD - Passing double pointer
3341             for proper NULLP assignment*/
3342          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(*bo));
3343          rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, bch->lcId,TRUE);
3344       }
3345    }
3346    else
3347    {
3348       if ((frm.sfn % 4 == 0) && (frm.subframe == 0))
3349       {
3350       }
3351    }
3352
3353    allocInfo->bcchAlloc.schdFirst = FALSE;
3354    bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
3355 #if (ERRCLASS & ERRCLS_DEBUG)
3356    if (bcch == NULLP)
3357    {
3358       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured");
3359       return;
3360    }
3361 #endif
3362    if (bcch->boLst.first != NULLP)
3363    {
3364       bo = (RgSchClcBoRpt *)(bcch->boLst.first->node);
3365
3366       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3367       {
3368          allocInfo->bcchAlloc.schdFirst = TRUE;
3369          /* Time to perform allocation for this BCCH transmission */
3370          rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3371       }
3372    }
3373
3374    if(!allocInfo->bcchAlloc.schdFirst)
3375    {
3376       CmLList   *lnk;
3377       bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
3378 #if (ERRCLASS & ERRCLS_DEBUG)
3379       if (bcch == NULLP)
3380       {
3381          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured");
3382          return;
3383       }
3384 #endif
3385       lnk = bcch->boLst.first;
3386       while (lnk != NULLP)
3387       {
3388          bo = (RgSchClcBoRpt *)(lnk->node);
3389          lnk = lnk->next;
3390          valid = rgSCHCmnChkInWin(frm, bo->timeToTx, bo->maxTimeToTx);
3391
3392          if(valid)
3393          {
3394             bo->i = RGSCH_CALC_SF_DIFF(frm, bo->timeToTx);
3395             /* Time to perform allocation for this BCCH transmission */
3396             rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo);
3397             break;
3398          }
3399          else
3400          {
3401             valid = rgSCHCmnChkPastWin(frm, bo->maxTimeToTx);
3402             if(valid)
3403             {
3404                cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
3405                /* ccpu00117052 - MOD - Passing double pointer
3406                   for proper NULLP assignment*/
3407                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo,
3408                      sizeof(RgSchClcBoRpt));
3409             }
3410          }
3411       }
3412    }
3413 #else
3414    rgSCHDlSiSched(cell, allocInfo, subfrmAlloc);
3415 #endif/*RGR_SI_SCH*/
3416
3417    pcch = rgSCHDbmGetPcch(cell);
3418 #ifdef ERRCLS_KW
3419    if (pcch == NULLP)
3420    {
3421       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"PCCH on DLSCH is not configured");
3422       return;
3423    }
3424 #endif
3425    if (pcch->boLst.first != NULLP)
3426    {
3427       bo = (RgSchClcBoRpt *)(pcch->boLst.first->node);
3428
3429       if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx))
3430       {
3431          /* Time to perform allocation for this PCCH transmission */
3432          rgSCHCmnClcAlloc(cell, sf, pcch, RGSCH_P_RNTI, allocInfo);
3433       }
3434    }
3435    return;
3436 }
3437
3438 /*
3439 *
3440 *       Fun:   rgSCHCmnChkInWin
3441 *
3442 *       Desc:  This function checks if frm occurs in window
3443 *
3444 *       Ret:   TRUE      - if in window
3445 *              FALSE     - otherwise
3446 *
3447 *       Notes: None
3448 *
3449 *       File:  rg_sch_cmn.c
3450 *
3451 */
3452 #ifdef ANSI
3453 Bool rgSCHCmnChkInWin
3454 (
3455 CmLteTimingInfo   frm,
3456 CmLteTimingInfo   start,
3457 CmLteTimingInfo   end
3458 )
3459 #else
3460 Bool rgSCHCmnChkInWin(frm, start, end)
3461 CmLteTimingInfo   frm;
3462 CmLteTimingInfo   start;
3463 CmLteTimingInfo   end;
3464 #endif
3465 {
3466    Bool    inWin = FALSE;
3467
3468
3469    if (end.sfn > start.sfn)
3470    {
3471       if (frm.sfn > start.sfn
3472             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3473       {
3474          if (frm.sfn < end.sfn
3475 #ifdef EMTC_ENABLE
3476                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3477 #else
3478                || (frm.sfn == end.sfn && frm.slot <= start.slot))
3479 #endif
3480          {
3481             inWin = TRUE;
3482          }
3483       }
3484    }
3485    /* Testing for wrap around, sfn wraparound check should be enough */
3486    else if (end.sfn < start.sfn)
3487    {
3488       if (frm.sfn > start.sfn
3489             || (frm.sfn == start.sfn && frm.slot >= start.slot))
3490       {
3491          inWin = TRUE;
3492       }
3493       else
3494       {
3495          if (frm.sfn < end.sfn
3496                || (frm.sfn == end.sfn && frm.slot <= end.slot))
3497          {
3498             inWin = TRUE;
3499          }
3500       }
3501    }
3502    else  /* start.sfn == end.sfn */
3503    {
3504       if (frm.sfn == start.sfn
3505             && (frm.slot >= start.slot
3506                && frm.slot <= end.slot))
3507       {
3508          inWin = TRUE;
3509       }
3510    }
3511
3512    return (inWin);
3513 } /* end of rgSCHCmnChkInWin*/
3514
3515 /*
3516 *
3517 *       Fun:   rgSCHCmnChkPastWin
3518 *
3519 *       Desc:  This function checks if frm has gone past window edge
3520 *
3521 *       Ret:   TRUE      - if past window edge
3522 *              FALSE     - otherwise
3523 *
3524 *       Notes: None
3525 *
3526 *       File:  rg_sch_cmn.c
3527 *
3528 */
3529 #ifdef ANSI
3530 Bool rgSCHCmnChkPastWin
3531 (
3532 CmLteTimingInfo   frm,
3533 CmLteTimingInfo   end
3534 )
3535 #else
3536 Bool rgSCHCmnChkPastWin(frm, end)
3537 CmLteTimingInfo   frm;
3538 CmLteTimingInfo   end;
3539 #endif
3540 {
3541    CmLteTimingInfo  refFrm = end;
3542    Bool             pastWin;
3543
3544
3545    RGSCH_INCR_FRAME(refFrm.sfn);
3546    RGSCH_INCR_SUB_FRAME(end, 1);
3547    pastWin = rgSCHCmnChkInWin(frm, end, refFrm);
3548
3549    return (pastWin);
3550 } /* end of rgSCHCmnChkPastWin*/
3551 \f
3552 /**
3553  * @brief This function implements allocation of the resources for common
3554  * channels BCCH, PCCH.
3555  *
3556  * @details
3557  *
3558  *     Function: rgSCHCmnClcAlloc
3559  *     Purpose:  This function implements selection of number of RBs based
3560  *               the allowed grant for the service. It is also responsible
3561  *               for selection of MCS for the transmission.
3562  *
3563  *     Invoked by: Scheduler
3564  *
3565  *  @param[in]  RgSchCellCb                *cell,
3566  *  @param[in]  RgSchDlSf                  *sf,
3567  *  @param[in]  RgSchClcDlLcCb             *lch,
3568  *  @param[in]  uint16_t                        rnti,
3569  *  @param[out] RgSchCmnDlRbAllocInfo      *allocInfo
3570  *  @return     Void
3571  *
3572  **/
3573 #ifdef ANSI
3574 static Void rgSCHCmnClcAlloc
3575 (
3576 RgSchCellCb             *cell,
3577 RgSchDlSf               *sf,
3578 RgSchClcDlLcCb          *lch,
3579 uint16_t                     rnti,
3580 RgSchCmnDlRbAllocInfo   *allocInfo
3581 )
3582 #else
3583 static Void rgSCHCmnClcAlloc(cell, sf, lch, rnti, allocInfo)
3584 RgSchCellCb             *cell;
3585 RgSchDlSf               *sf;
3586 RgSchClcDlLcCb          *lch;
3587 uint16_t                     rnti;
3588 RgSchCmnDlRbAllocInfo   *allocInfo;
3589 #endif
3590 {
3591    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
3592    RgSchClcBoRpt        *bo;
3593    uint32_t                  rb=0;
3594    uint8_t                   mcs;
3595    uint32_t                  tbs;
3596 #ifdef LTE_TDD   
3597    uint8_t                   lostRe;
3598    uint8_t                   cfi = cellDl->currCfi;  
3599 #endif
3600
3601
3602    bo = (RgSchClcBoRpt *)(lch->boLst.first->node);
3603
3604    mcs = bo->mcs;
3605    tbs = bo->bo;
3606    /* rgSCHCmnClcRbAllocForFxdTb(cell, bo->bo, cellDl->ccchCqi, &rb);*/
3607    if(cellDl->bitsPerRb==0)
3608    {
3609       while ((rgTbSzTbl[0][0][rb]) < (tbs*8))
3610       {
3611          rb++;
3612       }
3613       rb = rb+1;
3614    }
3615    else
3616    {
3617       rb = RGSCH_CEIL((tbs*8), cellDl->bitsPerRb);
3618    }
3619    /* DwPTS Scheduling Changes Start */   
3620 #ifdef LTE_TDD
3621    if(sf->sfType == RG_SCH_SPL_SF_DATA) 
3622    {
3623       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
3624
3625       /* Calculate the less RE's because of DwPTS */
3626       lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
3627
3628       /* Increase number of RBs in Spl SF to compensate for lost REs */
3629       rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
3630    }
3631 #endif
3632    /* DwPTS Scheduling Changes End */   
3633    /*ccpu00115595- end*/
3634    /* additional check to see if required RBs
3635     * exceeds the available */
3636    if (rb > sf->bw - sf->bwAssigned)
3637    {
3638       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"BW allocation "
3639                 "failed for CRNTI:%d",rnti);
3640       return;
3641    }
3642
3643    /* Update the subframe Allocated BW field */
3644    sf->bwAssigned = sf->bwAssigned + rb;
3645    /* Fill in the BCCH/PCCH transmission info to the RBAllocInfo struct */
3646    if (rnti == RGSCH_SI_RNTI)
3647    {
3648       allocInfo->bcchAlloc.rnti = rnti;
3649       allocInfo->bcchAlloc.dlSf = sf;
3650       allocInfo->bcchAlloc.tbInfo[0].bytesReq = tbs;
3651       allocInfo->bcchAlloc.rbsReq = rb;
3652       allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
3653       allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
3654       /* Nprb indication at PHY for common Ch */
3655       allocInfo->bcchAlloc.nPrb = bo->nPrb;
3656    }
3657    else
3658    {
3659       allocInfo->pcchAlloc.rnti = rnti;
3660       allocInfo->pcchAlloc.dlSf = sf;
3661       allocInfo->pcchAlloc.tbInfo[0].bytesReq = tbs;
3662       allocInfo->pcchAlloc.rbsReq = rb;
3663       allocInfo->pcchAlloc.tbInfo[0].imcs = mcs;
3664       allocInfo->pcchAlloc.tbInfo[0].noLyr = 1;
3665       allocInfo->pcchAlloc.nPrb = bo->nPrb;
3666    }
3667    return;
3668 }
3669
3670 \f
3671 /**
3672  * @brief This function implements PDCCH allocation for common channels.
3673  *
3674  * @details
3675  *
3676  *     Function: rgSCHCmnCmnPdcchAlloc
3677  *     Purpose:  This function implements allocation of PDCCH for a UE.
3678  *               1. This uses index 0 of PDCCH table for efficiency.
3679  *               2. Uses he candidate PDCCH count for the aggr level.
3680  *               3. Look for availability for each candidate and choose
3681  *                  the first one available.
3682  *
3683  *     Invoked by: Scheduler
3684  *
3685  *  @param[in]  RgSchCellCb           *cell
3686  *  @param[in]  RgSchDlSf             *sf
3687  *  @return     RgSchPdcch *
3688  *               -# NULLP when unsuccessful
3689  *
3690  **/
3691 #ifdef ANSI
3692 RgSchPdcch *rgSCHCmnCmnPdcchAlloc
3693 (
3694 RgSchCellCb                *cell,
3695 RgSchDlSf                  *subFrm
3696 )
3697 #else
3698 RgSchPdcch *rgSCHCmnCmnPdcchAlloc(cell, subFrm)
3699 RgSchCellCb                *cell;
3700 RgSchDlSf                  *subFrm;
3701 #endif
3702 {
3703    CmLteAggrLvl         aggrLvl;
3704    RgSchPdcchInfo       *pdcchInfo;
3705    RgSchPdcch           *pdcch;
3706    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
3707    uint8_t                   numCce;  /*store num CCEs based on 
3708                                   aggregation level */
3709
3710    aggrLvl   = cellSch->dl.cmnChAggrLvl;
3711
3712    pdcchInfo = &(subFrm->pdcchInfo);
3713
3714     /* Updating the no. of nCce in pdcchInfo, in case if CFI
3715     * was changed  */
3716 #ifdef LTE_TDD
3717    if(subFrm->nCce != pdcchInfo->nCce)
3718    {   
3719       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
3720    }
3721 #else   
3722    if(cell->nCce != pdcchInfo->nCce)
3723    {
3724       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
3725    }
3726 #endif  
3727
3728    switch (aggrLvl)
3729    {
3730       case CM_LTE_AGGR_LVL4:
3731         numCce = 4;
3732         break;
3733       case CM_LTE_AGGR_LVL8:
3734         numCce = 8;
3735         break;
3736                 case CM_LTE_AGGR_LVL16:
3737         numCce = 16;
3738         break;
3739       default:
3740         return (NULLP);
3741    }
3742
3743    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
3744    {
3745 #ifdef LTEMAC_SPS
3746       pdcch->isSpsRnti = FALSE;
3747 #endif
3748       /* Increment the CCE used counter in the current subframe */
3749       subFrm->cceCnt += numCce;
3750       pdcch->pdcchSearchSpace = RG_SCH_CMN_SEARCH_SPACE;
3751
3752       return (pdcch);
3753    }
3754
3755    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
3756    subFrm->isCceFailure = TRUE;
3757
3758    RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
3759             "PDCCH ERR: NO PDDCH AVAIL IN COMMON SEARCH SPACE aggr:%u", 
3760             aggrLvl);
3761    return (NULLP);
3762 }
3763
3764 \f
3765 /**
3766  * @brief This function implements bandwidth allocation for common channels.
3767  *
3768  * @details
3769  *
3770  *     Function: rgSCHCmnClcRbAlloc
3771  *     Purpose:  This function implements bandwith allocation logic
3772  *               for common control channels.
3773  *
3774  *     Invoked by: Scheduler
3775  *
3776  *  @param[in]  RgSchCellCb*  cell
3777  *  @param[in]  uint32_t           bo
3778  *  @param[in]  uint8_t            cqi
3779  *  @param[in]  uint8_t            *rb
3780  *  @param[in]  uint32_t           *tbs
3781  *  @param[in]  uint8_t            *mcs
3782  *  @param[in]  RgSchDlSf     *sf
3783  *  @return  Void
3784  *
3785  **/
3786 #ifdef LTEMAC_SPS
3787 #ifdef ANSI
3788 Void rgSCHCmnClcRbAlloc
3789 (
3790 RgSchCellCb                 *cell,
3791 uint32_t                     bo,
3792 uint8_t                      cqi,
3793 uint8_t                      *rb,
3794 uint32_t                     *tbs,
3795 uint8_t                      *mcs,
3796 uint8_t                      *iTbs,
3797 Bool                         isSpsBo,
3798 RgSchDlSf                    *sf 
3799 )
3800 #else
3801 Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, iTbs, isSpsBo)
3802 RgSchCellCb                  *cell;
3803 uint32_t                     bo;
3804 uint8_t                      cqi;
3805 uint8_t                      *rb;
3806 uint32_t                     *tbs;
3807 uint8_t                      *mcs;
3808 uint8_t                      *iTbs;
3809 Bool                         isSpsBo;
3810 RgSchDlSf                    *sf; 
3811 #endif
3812 #else
3813 #ifdef ANSI
3814 static Void rgSCHCmnClcRbAlloc
3815 (
3816 RgSchCellCb                  *cell,
3817 uint32_t                     bo,
3818 uint8_t                      cqi,
3819 uint8_t                      *rb,
3820 uint32_t                     *tbs,
3821 uint8_t                      *mcs,
3822 RgSchDlSf                    *sf 
3823 )
3824 #else
3825 static Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, sf)
3826 RgSchCellCb                  *cell;
3827 uint32_t                     bo;
3828 uint8_t                      cqi;
3829 uint8_t                      *rb;
3830 uint32_t                     *tbs;
3831 uint8_t                      *mcs;
3832 RgSchDlSf                    *sf; 
3833 #endif
3834 #endif /* LTEMAC_SPS */
3835 {
3836    uint8_t                   iTbsVal;
3837    RgSchCmnTbSzEff           *effTbl;
3838    uint32_t                  eff;
3839    uint32_t                  noRes;
3840    RgSchCmnCell              *cellSch = RG_SCH_CMN_GET_CELL(cell);
3841    uint8_t                   cfi = cellSch->dl.currCfi;
3842    uint32_t                  tmpRb=0;
3843
3844    /* first get the CQI to MCS table and determine the number of RBs */
3845    effTbl = (RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]);
3846    iTbsVal = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[cqi];
3847    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3848
3849    /* Efficiency is number of bits per 1024 REs */
3850    eff  = (*effTbl)[iTbsVal];
3851
3852    /* Get the number of REs needed for this bo  */
3853    noRes = ((bo * 8 * 1024) / eff );
3854
3855    /* Get the number of RBs needed for this transmission */
3856    /* Number of RBs = No of REs / No of REs per RB       */
3857    tmpRb = RGSCH_CEIL(noRes, cellSch->dl.noResPerRb[cfi]);
3858    /* KWORK_FIX: added check to see if rb has crossed maxRb*/
3859    RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3860    if (tmpRb > cellSch->dl.maxDlBwPerUe)
3861    {
3862       tmpRb = cellSch->dl.maxDlBwPerUe;
3863    }
3864    while ((rgTbSzTbl[0][iTbsVal][tmpRb-1]/8) < bo && 
3865            (tmpRb < cellSch->dl.maxDlBwPerUe))
3866    {
3867       tmpRb++;
3868       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1));
3869    }
3870    *tbs =  rgTbSzTbl[0][iTbsVal][tmpRb-1]/8;
3871    *rb = (uint8_t)tmpRb;
3872    RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs);
3873
3874    return;
3875 }
3876
3877 \f
3878
3879 /**
3880  * @brief Scheduling for MSG4.
3881  *
3882  * @details
3883  *
3884  *     Function: rgSCHCmnMsg4Alloc
3885  *     Purpose:  Scheduling for MSG4
3886  *
3887  *     Invoked by: Scheduler
3888  *
3889  *  @param[in]  RgSchCellCb*          cell
3890  *  @param[in]  RgSchRaCb*            raCb
3891  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
3892  *  @return  S16
3893  *
3894  **/
3895 #ifdef ANSI
3896 static S16 rgSCHCmnMsg4Alloc
3897 (
3898 RgSchCellCb                *cell,
3899 RgSchRaCb                  *raCb,
3900 RgSchCmnDlRbAllocInfo      *allocInfo
3901 )
3902 #else
3903 static S16 rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)
3904 RgSchCellCb                *cell;
3905 RgSchRaCb                  *raCb;
3906 RgSchCmnDlRbAllocInfo      *allocInfo;
3907 #endif
3908 {
3909    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
3910
3911
3912  /* SR_RACH_STATS : MSG4 TO BE TXED */
3913    rgNumMsg4ToBeTx++;
3914    /* Return if subframe BW exhausted */
3915    if (allocInfo->msg4Alloc.msg4DlSf->bw <=
3916        allocInfo->msg4Alloc.msg4DlSf->bwAssigned)
3917    {
3918       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId ,
3919          "bw<=bwAssigned");
3920       return RFAILED;
3921    }
3922
3923    if (rgSCHDhmGetMsg4HqProc(raCb, cellSch->dl.time) != ROK)
3924    {
3925       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
3926          "rgSCHDhmGetMsg4HqProc failed");
3927       return RFAILED;
3928    }
3929
3930    raCb->rbAllocInfo.dlSf = allocInfo->msg4Alloc.msg4DlSf;
3931
3932    if (rgSCHCmnMsg4DedAlloc(cell, raCb) != ROK)
3933    {
3934       /* Fix : syed Minor failure handling, release hqP if Unsuccessful */    
3935       rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, FALSE);
3936       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
3937          "rgSCHCmnMsg4DedAlloc failed.");
3938       return RFAILED;
3939    }
3940    cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4TxLst, &raCb->dlHqE->msg4Proc->reqLnk);
3941    raCb->dlHqE->msg4Proc->reqLnk.node = (PTR)raCb->dlHqE->msg4Proc;
3942    allocInfo->msg4Alloc.msg4DlSf->schdCcchUe++;
3943
3944    return ROK;
3945 }
3946
3947 \f
3948 /**
3949  * @brief This function implements PDCCH allocation for an UE.
3950  *
3951  * @details
3952  *
3953  *     Function: PdcchAlloc
3954  *     Purpose:  This function implements allocation of PDCCH for an UE.
3955  *               1. Get the aggregation level for the CQI of the UE.
3956  *               2. Get the candidate PDCCH count for the aggr level.
3957  *               3. Look for availability for each candidate and choose
3958  *                  the first one available.
3959  *
3960  *     Invoked by: Scheduler
3961  *
3962  *  @param[in]  cell
3963  *  @param[in]  subFrm
3964  *  @param[in]  cqi
3965  *  @param[in]  dciFrmt
3966  *  @return  RgSchPdcch *
3967  *         -# NULLP when unsuccessful
3968  *
3969  **/
3970 #ifdef ANSI
3971 RgSchPdcch *rgSCHCmnPdcchAlloc
3972 (
3973 RgSchCellCb             *cell,
3974 RgSchUeCb               *ue,
3975 RgSchDlSf               *subFrm,
3976 uint8_t                      cqi,
3977 TfuDciFormat            dciFrmt,
3978 Bool                    isDtx
3979 )
3980 #else
3981 RgSchPdcch *rgSCHCmnPdcchAlloc(cell, subFrm, cqi, dciFrmt, isDtx)
3982 RgSchCellCb             *cell;
3983 RgSchUeCb               *ue;
3984 RgSchDlSf               *subFrm;
3985 uint8_t                      cqi;
3986 TfuDciFormat            dciFrmt;
3987 Bool                    isDtx;
3988 #endif
3989 {
3990    CmLteAggrLvl     aggrLvl;
3991    RgSchPdcchInfo   *pdcchInfo;
3992    RgSchPdcch       *pdcch;
3993
3994
3995    /* 3.1 consider the selected DCI format size in determining the
3996     * aggregation level */
3997    //TODO_SID Need to update. Currently using 4 aggregation level
3998    aggrLvl   = CM_LTE_AGGR_LVL2;//cellSch->dciAggrLvl[cqi][dciFrmt];
3999
4000 #ifdef LTE_ADV
4001    if((dciFrmt == TFU_DCI_FORMAT_1A) &&
4002       ((ue) && (ue->allocCmnUlPdcch)) )
4003    {
4004       pdcch = rgSCHCmnCmnPdcchAlloc(cell, subFrm);
4005       /* Since CRNTI Scrambled */
4006       if(NULLP != pdcch)
4007       {
4008          pdcch->dciNumOfBits = ue->dciSize.cmnSize[dciFrmt];
4009         // prc_trace_format_string(PRC_TRACE_GROUP_PS, PRC_TRACE_INFO_LOW,"Forcing alloc in CMN search spc size %d fmt %d \n",
4010         // pdcch->dciNumOfBits, dciFrmt);
4011       }
4012       return (pdcch);
4013    }
4014 #endif
4015
4016    /* Incrementing aggrLvl by 1 if it not AGGR_LVL8(MAX SIZE)
4017     * inorder to increse the redudancy bits for better decoding of UE */
4018    if (isDtx)
4019    {
4020       if (aggrLvl != CM_LTE_AGGR_LVL16)
4021       {
4022          switch(aggrLvl)
4023          {
4024             case CM_LTE_AGGR_LVL2:
4025                aggrLvl = CM_LTE_AGGR_LVL4;
4026                 break;
4027             case CM_LTE_AGGR_LVL4:
4028                aggrLvl = CM_LTE_AGGR_LVL8;
4029                break;
4030             case CM_LTE_AGGR_LVL8:
4031                aggrLvl = CM_LTE_AGGR_LVL16;
4032                break;
4033             default:
4034                break;
4035          }
4036          /* aggrLvl   += 1; */
4037       }
4038    }
4039
4040    pdcchInfo = &subFrm->pdcchInfo;
4041
4042    /* Updating the no. of nCce in pdcchInfo, in case if CFI
4043     * was changed  */
4044 #ifdef LTE_TDD
4045    if(subFrm->nCce != pdcchInfo->nCce)
4046    {   
4047       rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce);
4048    }
4049 #else   
4050    if(cell->nCce != pdcchInfo->nCce)
4051    {
4052       rgSCHUtlPdcchInit(cell, subFrm, cell->nCce);
4053    }
4054 #endif       
4055
4056    if (pdcchInfo->nCce < (1 << (aggrLvl - 1)))
4057    {
4058       /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
4059       subFrm->isCceFailure = TRUE;
4060       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
4061             "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", 
4062             aggrLvl);
4063
4064       return (NULLP);
4065    }
4066
4067    if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE)
4068    {
4069       /* SR_RACH_STATS : Reset isTBMsg4 */
4070       pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4= FALSE;         
4071       pdcch->dci.u.format0Info.isSrGrant = FALSE;
4072 #ifdef LTEMAC_SPS
4073       pdcch->isSpsRnti = FALSE;
4074 #endif
4075       /* Increment the CCE used counter in the current subframe */
4076       subFrm->cceCnt += aggrLvl;
4077       pdcch->pdcchSearchSpace = RG_SCH_UE_SPECIFIC_SEARCH_SPACE;
4078       if (ue != NULLP)
4079                 {
4080 #ifdef LTE_ADV
4081                  if (ue->cell != cell)
4082                  {
4083                     /* Secondary Cell */
4084                     //pdcch->dciNumOfBits = ue->dciSize.noUlCcSize[dciFrmt];
4085                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
4086                  }
4087                  else
4088 #endif
4089                  {
4090                     //pdcch->dciNumOfBits = ue->dciSize.dedSize[dciFrmt];
4091                     //TODO_SID Need to update dci size.
4092                     pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE;
4093                  }
4094                 }
4095       else
4096       {
4097          /* MSG4 */
4098          pdcch->dciNumOfBits = cell->dciSize.size[dciFrmt];
4099       }
4100       return (pdcch);
4101    }
4102
4103    /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */
4104    subFrm->isCceFailure = TRUE;
4105
4106    RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
4107          "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)",
4108          aggrLvl);
4109    return (NULLP);
4110 }
4111
4112 #ifdef RGR_V1
4113 /**
4114  * @brief This function implements BW allocation for CCCH SDU
4115  *
4116  * @details
4117  *
4118  *     Function: rgSCHCmnCcchSduDedAlloc
4119  *     Purpose:  Downlink bandwidth Allocation for CCCH SDU.
4120  *
4121  *     Invoked by: Scheduler
4122  *
4123  *  @param[in]  RgSchCellCb*     cell
4124  *  @param[out] RgSchUeCb        *ueCb
4125  *  @return S16
4126  *
4127  **/
4128 #ifdef ANSI
4129 static S16 rgSCHCmnCcchSduDedAlloc
4130 (
4131 RgSchCellCb      *cell,
4132 RgSchUeCb        *ueCb
4133 )
4134 #else
4135 static S16 rgSCHCmnCcchSduDedAlloc(cell, ueCb)
4136 RgSchCellCb      *cell;
4137 RgSchUeCb        *ueCb;
4138 #endif
4139 {
4140    RgSchDlHqEnt      *hqE = NULLP;
4141    uint32_t                  effBo;
4142    RgSchDlRbAlloc       *rbAllocinfo = NULLP;
4143    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4144    uint8_t                   iTbs;
4145    uint8_t                   numRb;
4146 #ifdef LTE_TDD
4147    uint8_t                   cfi     = cellDl->currCfi;
4148 #endif
4149
4150
4151    rbAllocinfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
4152
4153    effBo  =   ueCb->dlCcchInfo.bo + RGSCH_CCCH_SDU_HDRSIZE;
4154
4155 #ifndef LTEMAC_SPS
4156    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
4157                       &rbAllocinfo->tbInfo[0].bytesReq,
4158                       &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
4159 #else /* LTEMAC_SPS */
4160    rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \
4161                       &rbAllocinfo->tbInfo[0].bytesReq,\
4162                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, 
4163                       rbAllocinfo->dlSf);
4164 #endif /* LTEMAC_SPS */
4165
4166    iTbs = 0;
4167    /* Cannot exceed the total number of RBs in the cell */
4168    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
4169                                    rbAllocinfo->dlSf->bwAssigned)))
4170    {
4171       /* Check if atleast one allocation was possible.
4172          This may be the case where the Bw is very less and
4173          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
4174       if (rbAllocinfo->dlSf->bwAssigned == 0)
4175       {
4176          numRb   = rbAllocinfo->dlSf->bw;
4177          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
4178          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
4179          {
4180             iTbs++;
4181          }
4182          rbAllocinfo->rbsReq = numRb;
4183          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
4184          /* DwPTS Scheduling Changes Start */
4185 #ifdef LTE_TDD
4186          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
4187          {
4188             rbAllocinfo->tbInfo[0].bytesReq =
4189                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1,cfi);
4190          }
4191 #endif
4192          /* DwPTS Scheduling Changes End */
4193          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
4194       }
4195       else
4196       {
4197          return RFAILED;
4198       }
4199    }
4200
4201    /* Update the subframe Allocated BW field */
4202    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4203                                    rbAllocinfo->rbsReq;
4204    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
4205    rbAllocinfo->tbInfo[0].tbCb = &hqE->ccchSduProc->tbInfo[0];
4206    rbAllocinfo->rnti = ueCb->ueId;
4207    rbAllocinfo->tbInfo[0].noLyr = 1;
4208
4209    return ROK;
4210 }
4211 #endif
4212 \f
4213 /**
4214  * @brief This function implements BW allocation for MSG4
4215  *
4216  * @details
4217  *
4218  *     Function: rgSCHCmnMsg4DedAlloc
4219  *     Purpose:  Downlink bandwidth Allocation for MSG4.
4220  *
4221  *     Invoked by: Scheduler
4222  *
4223  *  @param[in]  RgSchCellCb*     cell
4224  *  @param[out] RgSchRaCb        *raCb
4225  *  @return S16
4226  *
4227  **/
4228 #ifdef ANSI
4229 static S16 rgSCHCmnMsg4DedAlloc
4230 (
4231 RgSchCellCb      *cell,
4232 RgSchRaCb        *raCb
4233 )
4234 #else
4235 static S16 rgSCHCmnMsg4DedAlloc(cell, raCb)
4236 RgSchCellCb      *cell;
4237 RgSchRaCb        *raCb;
4238 #endif
4239 {
4240    uint32_t                  effBo;
4241    RgSchDlRbAlloc       *rbAllocinfo = &raCb->rbAllocInfo;
4242    uint8_t                   iTbs;
4243    uint8_t                   numRb;
4244 #ifdef LTE_TDD
4245    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4246    uint8_t                   cfi     = cellDl->currCfi;
4247 #endif
4248
4249
4250    effBo  = raCb->dlCcchInfo.bo + RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE;
4251
4252 #ifndef LTEMAC_SPS
4253    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
4254          &rbAllocinfo->tbInfo[0].bytesReq,\
4255          &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf);
4256 #else /* LTEMAC_SPS */
4257    rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \
4258                       &rbAllocinfo->tbInfo[0].bytesReq,\
4259                       &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE,
4260                       rbAllocinfo->dlSf);
4261 #endif /* LTEMAC_SPS */
4262
4263    iTbs = 0;
4264    /* Cannot exceed the total number of RBs in the cell */
4265    if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \
4266                rbAllocinfo->dlSf->bwAssigned)))
4267    {
4268       /* Check if atleast one allocation was possible.
4269          This may be the case where the Bw is very less and
4270          with the configured CCCH CQI, CCCH SDU exceeds the min Bw */
4271       if (rbAllocinfo->dlSf->bwAssigned == 0)
4272       {
4273          numRb   = rbAllocinfo->dlSf->bw;
4274          RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs);
4275          while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo)
4276          {
4277             iTbs++;
4278          }
4279          rbAllocinfo->rbsReq = numRb;
4280          rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8;
4281          /* DwPTS Scheduling Changes Start */
4282 #ifdef LTE_TDD
4283          if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA)
4284          {
4285             rbAllocinfo->tbInfo[0].bytesReq =
4286                rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1, cfi);
4287          }
4288 #endif
4289          /* DwPTS Scheduling Changes End */
4290          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs);
4291       }
4292       else
4293       {
4294          return RFAILED;
4295       }
4296    }
4297
4298    /* Update the subframe Allocated BW field */
4299    rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \
4300                                    rbAllocinfo->rbsReq;
4301    rbAllocinfo->rnti = raCb->tmpCrnti;
4302    rbAllocinfo->tbInfo[0].tbCb = &raCb->dlHqE->msg4Proc->tbInfo[0];
4303    rbAllocinfo->tbInfo[0].schdlngForTb = TRUE;
4304    rbAllocinfo->tbInfo[0].noLyr = 1;
4305
4306    return ROK;
4307 }
4308
4309 #ifdef LTE_TDD
4310 /**
4311  * @brief This function implements scheduling for RA Response.
4312  *
4313  * @details
4314  *
4315  *     Function: rgSCHCmnDlRaRsp
4316  *     Purpose:  Downlink scheduling for RA responses.
4317  *
4318  *     Invoked by: Scheduler
4319  *
4320  *  @param[in]  RgSchCellCb*     cell
4321  *  @return  Void
4322  *
4323  **/
4324 #ifdef ANSI
4325 static Void rgSCHCmnDlRaRsp
4326 (
4327 RgSchCellCb                *cell,
4328 RgSchCmnDlRbAllocInfo      *allocInfo
4329 )
4330 #else
4331 static Void rgSCHCmnDlRaRsp(cell, allocInfo)
4332 RgSchCellCb                *cell;
4333 RgSchCmnDlRbAllocInfo      *allocInfo;
4334 #endif
4335 {
4336    CmLteTimingInfo      frm;
4337    CmLteTimingInfo      schFrm;
4338    RgSchDlSf            *subFrm;
4339    uint16_t             rarnti;
4340    uint8_t              i;
4341    uint8_t              noRaRnti=0;
4342    uint8_t              raIdx;
4343    RgSchTddRachRspLst   *rachRsp;
4344    uint8_t              ulDlCfgIdx = cell->ulDlCfgIdx;
4345    uint8_t              sfnIdx;
4346    uint8_t              subfrmIdx;
4347    uint16_t             rntiIdx=0;
4348
4349    frm   = cell->crntTime;
4350    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4351
4352    /* Compute the subframe for which allocation is being made        */
4353    /* essentially, we need pointer to the dl frame for this subframe */
4354    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4355
4356    /* Get the RACH Response scheduling related information
4357     * for the subframe with RA index */
4358    raIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][frm.subframe]-1;
4359
4360    rachRsp = &cell->rachRspLst[raIdx];
4361
4362    for(sfnIdx = 0; sfnIdx < rachRsp->numRadiofrms; sfnIdx++)
4363    {
4364       /* For all scheduled RACH Responses in SFNs */
4365       schFrm = frm;
4366       RG_SCH_CMN_DECR_FRAME(schFrm.sfn, rachRsp->rachRsp[sfnIdx].sfnOffset);
4367       /* For all scheduled RACH Responses in subframes */
4368       for(subfrmIdx = 0;
4369             subfrmIdx < rachRsp->rachRsp[sfnIdx].numSubfrms; subfrmIdx++)
4370       {
4371          schFrm.subframe = rachRsp->rachRsp[sfnIdx].subframe[subfrmIdx];
4372          /* compute the last RA RNTI used in the previous subframe */
4373          raIdx = (((schFrm.sfn % cell->raInfo.maxRaSize) * \
4374                   RGSCH_NUM_SUB_FRAMES * RGSCH_MAX_RA_RNTI_PER_SUBFRM) \
4375                                     + schFrm.subframe);
4376
4377          /* For all RA RNTIs within a subframe */
4378
4379          for(i=0; (i < RGSCH_MAX_RA_RNTI_PER_SUBFRM) && \
4380                (noRaRnti < RGSCH_MAX_TDD_RA_RSP_ALLOC); i++)
4381          {
4382             rarnti = (schFrm.subframe + RGSCH_NUM_SUB_FRAMES*i + 1);
4383             rntiIdx = (raIdx + RGSCH_NUM_SUB_FRAMES*i);
4384
4385             if (cell->raInfo.raReqLst[rntiIdx].first != NULLP)
4386             {
4387                /* compute the next RA RNTI */
4388                if (rgSCHCmnRaRspAlloc(cell, subFrm, rntiIdx,
4389                         rarnti, noRaRnti, allocInfo) != ROK)
4390                {
4391                   /* The resources are exhausted */
4392                   break;
4393                }
4394                noRaRnti++;
4395             }
4396          }
4397          noRaRnti=0;
4398       }
4399    }
4400
4401    return;
4402 }
4403 #else
4404 /**
4405  * @brief This function implements scheduling for RA Response.
4406  *
4407  * @details
4408  *
4409  *     Function: rgSCHCmnDlRaRsp
4410  *     Purpose:  Downlink scheduling for RA responses.
4411  *
4412  *     Invoked by: Scheduler
4413  *
4414  *  @param[in]  RgSchCellCb*          cell
4415  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
4416  *  @return  Void
4417  *
4418  **/
4419 #ifdef ANSI
4420 static Void rgSCHCmnDlRaRsp  //FDD
4421 (
4422 RgSchCellCb                *cell,
4423 RgSchCmnDlRbAllocInfo      *allocInfo
4424 )
4425 #else
4426 static Void rgSCHCmnDlRaRsp(cell, allocInfo)
4427 RgSchCellCb                *cell;
4428 RgSchCmnDlRbAllocInfo      *allocInfo;
4429 #endif
4430 {
4431    CmLteTimingInfo      frm;
4432    CmLteTimingInfo      winStartFrm;
4433    RgSchDlSf            *subFrm;
4434    uint8_t              winStartIdx;
4435    uint8_t              winGap;
4436    uint8_t              rarnti;
4437    uint8_t              raIdx;
4438    RgSchCmnCell         *sched;
4439    uint8_t              i,noRaRnti=0;
4440
4441    frm   = cell->crntTime;
4442    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4443
4444    /* Compute the subframe for which allocation is being made        */
4445    /* essentially, we need pointer to the dl frame for this subframe */
4446    subFrm  = rgSCHUtlSubFrmGet(cell, frm);
4447    sched   = RG_SCH_CMN_GET_CELL(cell);
4448
4449    /* ccpu00132523 - Window Start calculated by considering RAR window size, 
4450     * RAR Wait period, Subframes occuppied for respective preamble format*/
4451    winGap = (sched->dl.numRaSubFrms-1) + (cell->rachCfg.raWinSize-1) 
4452              +RGSCH_RARSP_WAIT_PERIOD;
4453
4454    /* Window starting occassion is retrieved using the gap and tried to 
4455     * fit to the size of raReqLst array*/ 
4456    RGSCHDECRFRMCRNTTIME(frm, winStartFrm, winGap);
4457
4458         //5G_TODO TIMING update. Need to check
4459    winStartIdx = (winStartFrm.sfn & 1) * RGSCH_MAX_RA_RNTI+ winStartFrm.slot;
4460
4461    for(i = 0; ((i < cell->rachCfg.raWinSize) && (noRaRnti < RG_SCH_CMN_MAX_CMN_PDCCH)); i++)
4462    {
4463       raIdx = (winStartIdx + i) % RGSCH_RAREQ_ARRAY_SIZE;
4464
4465       if (cell->raInfo.raReqLst[raIdx].first != NULLP)
4466       {
4467          allocInfo->raRspAlloc[noRaRnti].biEstmt = \
4468                          (!i * RGSCH_ONE_BIHDR_SIZE);
4469          rarnti = raIdx % RGSCH_MAX_RA_RNTI+ 1;
4470          if (rgSCHCmnRaRspAlloc(cell, subFrm, raIdx,
4471                                  rarnti, noRaRnti, allocInfo) != ROK)
4472          {
4473             /* The resources are exhausted */
4474             break;
4475          }
4476          /* ccpu00132523- If all the RAP ids are not scheduled then need not 
4477           * proceed for next RA RNTIs*/
4478          if(allocInfo->raRspAlloc[noRaRnti].numRapids < cell->raInfo.raReqLst[raIdx].count)
4479          {
4480             break;
4481          }
4482          noRaRnti++; /* Max of RG_SCH_CMN_MAX_CMN_PDCCH RARNTIs
4483                         for response allocation */
4484       }
4485    }
4486    return;
4487 }
4488 #endif
4489
4490 \f
4491 /**
4492  * @brief This function allocates the resources for an RARNTI.
4493  *
4494  * @details
4495  *
4496  *     Function: rgSCHCmnRaRspAlloc
4497  *     Purpose:  Allocate resources to a RARNTI.
4498  *               0. Allocate PDCCH for sending the response.
4499  *               1. Locate the number of RA requests pending for the RARNTI.
4500  *               2. Compute the size of data to be built.
4501  *               3. Using common channel CQI, compute the number of RBs.
4502  *
4503  *     Invoked by: Scheduler
4504  *
4505  *  @param[in]  RgSchCellCb             *cell,
4506  *  @param[in]  RgSchDlSf               *subFrm,
4507  *  @param[in]  uint16_t                     rarnti,
4508  *  @param[in]  uint8_t                      noRaRnti
4509  *  @param[out] RgSchCmnDlRbAllocInfo   *allocInfo
4510  *  @return  S16
4511  *
4512  **/
4513 #ifdef ANSI
4514 static S16 rgSCHCmnRaRspAlloc
4515 (
4516 RgSchCellCb             *cell,
4517 RgSchDlSf               *subFrm,
4518 uint16_t                     raIndex,
4519 uint16_t                     rarnti,
4520 uint8_t                      noRaRnti,
4521 RgSchCmnDlRbAllocInfo   *allocInfo
4522 )
4523 #else
4524 static S16 rgSCHCmnRaRspAlloc(cell,subFrm,raIndex,rarnti,noRaRnti,allocInfo)
4525 RgSchCellCb             *cell;
4526 RgSchDlSf               *subFrm;
4527 uint16_t                     raIndex;
4528 uint16_t                     rarnti;
4529 uint8_t                      noRaRnti;
4530 RgSchCmnDlRbAllocInfo   *allocInfo;
4531 #endif
4532 {
4533    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4534    RgSchCmnUlCell       *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4535    uint16_t                  noBytes;
4536    uint32_t                  rb = 0;
4537    uint32_t                  tbs;
4538    /*ccpu00116700,ccpu00116708- Corrected the wrong type for mcs*/
4539    uint8_t                   mcs;
4540    CmLListCp            *reqLst;
4541    /* RACH handling related changes */
4542    Bool                 isAlloc = FALSE;
4543    static uint8_t            schdNumRapid = 0;
4544    uint8_t                   remNumRapid = 0;
4545    uint8_t                   nPrb = 0;
4546    S32                  allwdTbSz = 0;
4547 #ifdef LTE_TDD   
4548    uint16_t                  lostRe;  
4549    uint8_t                   cfi = cellDl->currCfi;  
4550 #endif   
4551
4552 #ifndef RGR_V1
4553    UNUSED(cellUl);
4554 #endif
4555
4556    /* ccpu00132523: Resetting the schdRap Id count in every scheduling subframe*/
4557    if(noRaRnti == 0)
4558    {
4559       schdNumRapid = 0;
4560    }
4561
4562
4563    if (subFrm->bw == subFrm->bwAssigned)
4564    {
4565       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4566          "bw == bwAssigned RARNTI:%d",rarnti);
4567       return RFAILED;
4568    }
4569
4570    reqLst = &cell->raInfo.raReqLst[raIndex];
4571    if (reqLst->count == 0)
4572    {
4573       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4574          "reqLst Count=0 RARNTI:%d",rarnti);
4575       return RFAILED;
4576    }
4577    remNumRapid = reqLst->count;
4578
4579 #ifdef RGR_V1
4580    /* Limit number of rach rsps to maxMsg3PerUlsf */
4581    if ( schdNumRapid+remNumRapid > cellUl->maxMsg3PerUlSf )
4582    {
4583       remNumRapid = cellUl->maxMsg3PerUlSf-schdNumRapid;
4584    }
4585 #endif
4586  
4587    while (remNumRapid)
4588    {
4589       /* Try allocating for as many RAPIDs as possible */
4590       /* BI sub-header size to the tbSize requirement */
4591       noBytes  = RGSCH_GET_RAR_BYTES(remNumRapid) +\
4592                  allocInfo->raRspAlloc[noRaRnti].biEstmt;
4593       if ((allwdTbSz = rgSCHUtlGetAllwdCchTbSz(noBytes*8, &nPrb, &mcs)) == -1)
4594       {
4595          remNumRapid--;
4596          continue;
4597       }
4598
4599       /* rgSCHCmnClcRbAllocForFxdTb(cell, allwdTbSz/8, cellDl->ccchCqi, &rb);*/
4600       if(cellDl->bitsPerRb==0)
4601       {
4602          while ((rgTbSzTbl[0][0][rb]) <(uint32_t) allwdTbSz)
4603          {
4604             rb++;
4605          }
4606          rb = rb+1;
4607       }
4608       else
4609       {
4610          rb = RGSCH_CEIL(allwdTbSz, cellDl->bitsPerRb);
4611       }
4612       /* DwPTS Scheduling Changes Start */      
4613 #ifdef LTE_TDD      
4614       if (subFrm->sfType == RG_SCH_SPL_SF_DATA)
4615       {
4616          RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
4617
4618          /* Calculate the less RE's because of DwPTS */
4619          lostRe = rb * (cellDl->noResPerRb[cfi] - 
4620                                   cellDl->numReDwPts[cfi]);
4621           
4622          /* Increase number of RBs in Spl SF to compensate for lost REs */
4623          rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]);
4624       }
4625 #endif      
4626       /* DwPTS Scheduling Changes End */
4627
4628       /*ccpu00115595- end*/
4629       if (rb > subFrm->bw - subFrm->bwAssigned)
4630       {
4631          remNumRapid--;
4632          continue;
4633       }
4634       /* Allocation succeeded for 'remNumRapid' */
4635       isAlloc = TRUE;
4636       tbs = allwdTbSz/8;
4637       printf("\n!!!RAR alloc noBytes:%u,allwdTbSz:%u,tbs:%u,rb:%u\n",
4638                                       noBytes,allwdTbSz,tbs,rb);
4639       break;
4640    }
4641    if (!isAlloc)
4642    {
4643       RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"BW alloc Failed");
4644       return RFAILED;
4645    }
4646
4647    subFrm->bwAssigned = subFrm->bwAssigned + rb;
4648
4649    /* Fill AllocInfo structure */
4650    allocInfo->raRspAlloc[noRaRnti].rnti = rarnti;
4651    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].bytesReq = tbs;
4652    allocInfo->raRspAlloc[noRaRnti].rbsReq = rb;
4653    allocInfo->raRspAlloc[noRaRnti].dlSf = subFrm;
4654    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].imcs = mcs;
4655    allocInfo->raRspAlloc[noRaRnti].raIndex = raIndex;
4656    /* RACH changes for multiple RAPID handling */
4657    allocInfo->raRspAlloc[noRaRnti].numRapids = remNumRapid;
4658    allocInfo->raRspAlloc[noRaRnti].nPrb = nPrb;
4659    allocInfo->raRspAlloc[noRaRnti].tbInfo[0].noLyr = 1;
4660    allocInfo->raRspAlloc[noRaRnti].vrbgReq = RGSCH_CEIL(nPrb,MAX_5GTF_VRBG_SIZE); 
4661    schdNumRapid += remNumRapid; 
4662    return ROK;
4663 }
4664
4665 /***********************************************************
4666  *
4667  *     Func : rgSCHCmnUlAllocFillRbInfo
4668  *
4669  *     Desc : Fills the start RB and the number of RBs for
4670  *            uplink allocation.
4671  *
4672  *     Ret  : void
4673  *
4674  *     Notes:
4675  *
4676  *     File :
4677  *
4678  **********************************************************/
4679 #ifdef ANSI
4680 Void rgSCHCmnUlAllocFillRbInfo
4681 (
4682 RgSchCellCb   *cell,
4683 RgSchUlSf      *sf,
4684 RgSchUlAlloc  *alloc
4685 )
4686 #else
4687 Void rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc)
4688 RgSchCellCb    *cell;
4689 RgSchUlSf      *sf;
4690 RgSchUlAlloc   *alloc;
4691 #endif
4692 {
4693     RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4694     RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4695     uint8_t             cfi = cellDl->currCfi;
4696
4697
4698    alloc->grnt.rbStart = (alloc->sbStart * cellUl->sbSize) + 
4699                                     cell->dynCfiCb.bwInfo[cfi].startRb;
4700
4701    /* Num RBs = numSbAllocated * sbSize - less RBs in the last SB */
4702    alloc->grnt.numRb = (alloc->numSb * cellUl->sbSize);
4703
4704    return;
4705 }
4706
4707 /**
4708  * @brief Grant request for Msg3.
4709  *
4710  * @details
4711  *
4712  *     Function : rgSCHCmnMsg3GrntReq
4713  *
4714  *     This is invoked by downlink scheduler to request allocation
4715  *     for msg3.
4716  *     Steps:
4717  *     - Attempt to allocate msg3 in the current msg3 subframe
4718  *       Allocation attempt based on whether preamble is from group A
4719  *       and the value of MESSAGE_SIZE_GROUP_A
4720  *     - Link allocation with passed RNTI and msg3 HARQ process
4721  *     - Set the HARQ process ID (*hqProcIdRef)
4722  *
4723  *  @param[in]  RgSchCellCb       *cell
4724  *  @param[in]  CmLteRnti         rnti
4725  *  @param[in]  Bool              preamGrpA
4726  *  @param[in]  RgSchUlHqProcCb   *hqProc
4727  *  @param[out] RgSchUlAlloc      **ulAllocRef
4728  *  @param[out] uint8_t                *hqProcIdRef
4729  *  @return  Void
4730  **/
4731 #ifdef ANSI
4732 static Void rgSCHCmnMsg3GrntReq
4733 (
4734 RgSchCellCb     *cell,
4735 CmLteRnti       rnti,
4736 Bool            preamGrpA,
4737 RgSchUlHqProcCb *hqProc,
4738 RgSchUlAlloc    **ulAllocRef,
4739 uint8_t              *hqProcIdRef
4740 )
4741 #else
4742 static Void rgSCHCmnMsg3GrntReq(cell, rnti, preamGrpA, hqProc,
4743                                  ulAllocRef, hqProcIdRef)
4744 RgSchCellCb     *cell;
4745 CmLteRnti       rnti;
4746 Bool            preamGrpA;
4747 RgSchUlHqProcCb *hqProc;
4748 RgSchUlAlloc    **ulAllocRef;
4749 uint8_t              *hqProcIdRef;
4750 #endif
4751 {
4752    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4753    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
4754    RgSchUlHole     *hole;
4755    RgSchUlAlloc    *alloc;
4756    uint8_t              iMcs;
4757    uint8_t              numSb;
4758
4759
4760    *ulAllocRef = NULLP;
4761
4762    /* Fix: ccpu00120610 Use remAllocs from subframe during msg3 allocation */
4763    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
4764    {
4765       return;
4766    }
4767    if (preamGrpA == FALSE)
4768    {
4769       numSb = cellUl->ra.prmblBNumSb;
4770       iMcs  = cellUl->ra.prmblBIMcs;
4771    }
4772    else
4773    {
4774       numSb = cellUl->ra.prmblANumSb;
4775       iMcs  = cellUl->ra.prmblAIMcs;
4776    }
4777
4778    if ((hole = rgSCHUtlUlHoleFirst(sf)) != NULLP)
4779    {
4780       if(*sf->allocCountRef == 0)
4781       {
4782          RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4783          /* Reinitialize the hole */
4784          if (sf->holeDb->count == 1 && (hole->start == 0)) /* Sanity check of holeDb */
4785          {
4786             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;
4787             /* Re-Initialize available subbands because of CFI change*/
4788             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
4789          }
4790          else
4791          {
4792             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4793                      "Error! holeDb sanity check failed RNTI:%d",rnti);
4794          } 
4795       }
4796       if (numSb <= hole->num)
4797       {
4798          uint8_t iTbs;
4799          alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
4800          rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
4801          alloc->grnt.iMcs     = iMcs;
4802          alloc->grnt.iMcsCrnt = iMcs;
4803          iTbs                 = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
4804          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); 
4805          /* To include the length and ModOrder in DataRecp Req.*/
4806          alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
4807          RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
4808          /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
4809          alloc->grnt.nDmrs    = 0;
4810          alloc->grnt.hop      = 0;
4811          alloc->grnt.delayBit = 0;
4812          alloc->grnt.isRtx    = FALSE;
4813          *ulAllocRef          = alloc;
4814          *hqProcIdRef         = (cellUl->msg3SchdHqProcIdx);
4815          hqProc->procId       = *hqProcIdRef;
4816          hqProc->ulSfIdx      = (cellUl->msg3SchdIdx);
4817          alloc->rnti          = rnti;
4818          alloc->ue            = NULLP;
4819          alloc->pdcch         = FALSE;
4820          alloc->forMsg3       = TRUE;
4821          alloc->hqProc        = hqProc;
4822          rgSCHUhmNewTx(hqProc, (uint8_t)(cell->rachCfg.maxMsg3Tx - 1), alloc);
4823          //RLOG_ARG4(L_DEBUG,DBG_CELLID,cell->cellId,
4824          printf(
4825                "\nRNTI:%d MSG3 ALLOC proc(%lu)procId(%d)schdIdx(%d)\n",
4826                alloc->rnti,
4827                ((PTR)alloc->hqProc),
4828                alloc->hqProc->procId,
4829                alloc->hqProc->ulSfIdx);
4830          RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
4831                "alloc(%p)maxMsg3Tx(%d)",
4832                ((PTR)alloc),
4833                cell->rachCfg.maxMsg3Tx);
4834       }
4835    }
4836
4837    return;
4838 }
4839
4840 \f
4841 /**
4842  * @brief This function determines the allocation limits and
4843  *        parameters that aid in DL scheduling.
4844  *
4845  * @details
4846  *
4847  *     Function: rgSCHCmnDlSetUeAllocLmt
4848  *     Purpose:  This function determines the Maximum RBs
4849  *               a UE is eligible to get based on softbuffer
4850  *               limitation and cell->>>maxDlBwPerUe. The Codeword
4851  *               specific parameters like iTbs, eff and noLyrs
4852  *               are also set in this function. This function
4853  *               is called while UE configuration and UeDlCqiInd.
4854  *
4855  *     Invoked by: Scheduler
4856  *
4857  *  @param[in]  RgSchCellCb   *cellCb
4858  *  @param[in]  RgSchCmnDlUe  *ueDl
4859  *  @return  Void
4860  *
4861  **/
4862 #ifdef ANSI
4863 static Void rgSCHCmnDlSetUeAllocLmt
4864 (
4865 RgSchCellCb   *cell,
4866 RgSchCmnDlUe  *ueDl,
4867 Bool          isEmtcUe
4868 )
4869 #else
4870 static Void rgSCHCmnDlSetUeAllocLmt(cell, ueDl, isEmtcUe)
4871 RgSchCellCb   *cell;
4872 RgSchCmnDlUe  *ueDl;
4873 Bool          isEmtcUe;
4874 #endif
4875 {
4876    uint8_t            modOrder;
4877    uint32_t           maxRb;
4878    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
4879    uint8_t            cfi = cellSch->dl.currCfi;
4880
4881
4882 #ifdef EMTC_ENABLE
4883    if(TRUE == isEmtcUe)
4884    {
4885       /* ITbs for CW0 for 1 Layer Tx */
4886       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4887                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4888       /* ITbs for CW0 for 2 Layer Tx */
4889       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4890                                              [ueDl->mimoInfo.cwInfo[0].cqi];
4891       /* Eff for CW0 for 1 Layer Tx */
4892       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4893                                             [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4894       /* Eff for CW0 for 2 Layer Tx */
4895       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4896                                             [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4897
4898       /* ITbs for CW1 for 1 Layer Tx */
4899       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\
4900                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4901       /* ITbs for CW1 for 2 Layer Tx */
4902       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\
4903                                              [ueDl->mimoInfo.cwInfo[1].cqi];
4904       /* Eff for CW1 for 1 Layer Tx */
4905       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4906                                             [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4907       /* Eff for CW1 for 2 Layer Tx */
4908       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4909                                             [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4910    }
4911    else
4912 #endif 
4913    {
4914       /* ITbs for CW0 for 1 Layer Tx */
4915       ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4916                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4917       /* ITbs for CW0 for 2 Layer Tx */
4918       ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4919                                          [ueDl->mimoInfo.cwInfo[0].cqi];
4920       /* Eff for CW0 for 1 Layer Tx */
4921       ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4922                                         [ueDl->mimoInfo.cwInfo[0].iTbs[0]];
4923       /* Eff for CW0 for 2 Layer Tx */
4924       ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4925                                         [ueDl->mimoInfo.cwInfo[0].iTbs[1]];
4926       
4927       /* ITbs for CW1 for 1 Layer Tx */
4928       ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
4929                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4930       /* ITbs for CW1 for 2 Layer Tx */
4931       ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\
4932                                          [ueDl->mimoInfo.cwInfo[1].cqi];
4933       /* Eff for CW1 for 1 Layer Tx */
4934       ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
4935                                         [ueDl->mimoInfo.cwInfo[1].iTbs[0]];
4936       /* Eff for CW1 for 2 Layer Tx */
4937       ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
4938                                         [ueDl->mimoInfo.cwInfo[1].iTbs[1]];
4939    }
4940
4941 //#ifdef DL_LA 
4942   // ueDl->laCb.cqiBasediTbs =  ueDl->mimoInfo.cwInfo[0].iTbs[0] * 100;
4943 //#endif
4944    /* Assigning noLyrs to each CW assuming optimal Spatial multiplexing
4945     * capability */
4946    (ueDl->mimoInfo.ri/2 == 0)? (ueDl->mimoInfo.cwInfo[0].noLyr = 1) : \
4947               (ueDl->mimoInfo.cwInfo[0].noLyr = ueDl->mimoInfo.ri/2);
4948    ueDl->mimoInfo.cwInfo[1].noLyr = ueDl->mimoInfo.ri - ueDl->mimoInfo.cwInfo[0].noLyr;
4949    /* rg002.101:ccpu00102106: correcting DL harq softbuffer limitation logic.
4950     * The maxTbSz is the maximum number of PHY bits a harq process can
4951     * hold. Hence we limit our allocation per harq process based on this.
4952     * Earlier implementation we misinterpreted the maxTbSz to be per UE
4953     * per TTI, but in fact it is per Harq per TTI. */
4954    /* rg002.101:ccpu00102106: cannot exceed the harq Tb Size
4955     * and harq Soft Bits limit.*/
4956
4957    /* Considering iTbs corresponding to 2 layer transmission for
4958     * codeword0(approximation) and the maxLayers supported by
4959     * this UE at this point of time. */
4960    RG_SCH_CMN_TBS_TO_MODODR(ueDl->mimoInfo.cwInfo[0].iTbs[1], modOrder);
4961
4962    /* Bits/modOrder gives #REs, #REs/noResPerRb gives #RBs */
4963    /* rg001.301 -MOD- [ccpu00119213] : avoiding wraparound */
4964    maxRb = ((ueDl->maxSbSz)/(cellSch->dl.noResPerRb[cfi] * modOrder *\
4965                    ueDl->mimoInfo.ri));
4966    if (cellSch->dl.isDlFreqSel)
4967    {
4968       /* Rounding off to left nearest multiple of RBG size */
4969       maxRb -= maxRb % cell->rbgSize;
4970    }
4971    ueDl->maxRb = RGSCH_MIN(maxRb, cellSch->dl.maxDlBwPerUe);
4972    if (cellSch->dl.isDlFreqSel)
4973    {
4974       /* Rounding off to right nearest multiple of RBG size */
4975       if (ueDl->maxRb % cell->rbgSize)
4976       {
4977          ueDl->maxRb += (cell->rbgSize - 
4978                          (ueDl->maxRb % cell->rbgSize));
4979       }
4980    }
4981
4982    /* Set the index of the cwInfo, which is better in terms of
4983     * efficiency. If RI<2, only 1 CW, hence btrCwIdx shall be 0 */
4984    if (ueDl->mimoInfo.ri < 2)
4985    {
4986       ueDl->mimoInfo.btrCwIdx = 0;
4987    }
4988    else
4989    {
4990       if (ueDl->mimoInfo.cwInfo[0].eff[ueDl->mimoInfo.cwInfo[0].noLyr-1] <\
4991           ueDl->mimoInfo.cwInfo[1].eff[ueDl->mimoInfo.cwInfo[1].noLyr-1])
4992       {
4993          ueDl->mimoInfo.btrCwIdx = 1;
4994       }
4995       else
4996       {
4997          ueDl->mimoInfo.btrCwIdx = 0;
4998       }
4999    }
5000
5001    return;
5002    }
5003
5004 #ifdef DL_LA
5005
5006 /**
5007  * @brief This function updates TX Scheme.
5008  *
5009  * @details
5010  *
5011  *     Function: rgSCHCheckAndSetTxScheme 
5012  *     Purpose:  This function determines the Maximum RBs
5013  *               a UE is eligible to get based on softbuffer
5014  *               limitation and cell->>>maxDlBwPerUe. The Codeword
5015  *               specific parameters like iTbs, eff and noLyrs
5016  *               are also set in this function. This function
5017  *               is called while UE configuration and UeDlCqiInd.
5018  *
5019  *     Invoked by: Scheduler
5020  *
5021  *  @param[in]  RgSchCellCb   *cell
5022  *  @param[in]  RgSchUeCb     *ue
5023  *  @return  Void
5024  *
5025  **/
5026 #ifdef ANSI
5027 static Void rgSCHCheckAndSetTxScheme 
5028 (
5029 RgSchCellCb   *cell,
5030 RgSchUeCb     *ue
5031 )
5032 #else
5033 static Void rgSCHCheckAndSetTxScheme(cell, ue)
5034 RgSchCellCb   *cell;
5035 RgSchUeCb     *ue;
5036 #endif
5037 {
5038    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
5039    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue ,cell);
5040    uint8_t            cfi = cellSch->dl.currCfi;
5041    uint8_t            maxiTbs;
5042    uint8_t            cqiBasediTbs;
5043    uint8_t            actualiTbs;
5044
5045
5046    maxiTbs      = (*(RgSchCmnCqiToTbs*)(cellSch->dl.cqiToTbsTbl[0][cfi]))\
5047                 [RG_SCH_CMN_MAX_CQI - 1];
5048    cqiBasediTbs = (ueDl->laCb[0].cqiBasediTbs)/100;
5049    actualiTbs   = ueDl->mimoInfo.cwInfo[0].iTbs[0];
5050
5051    if((actualiTbs < RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR) && (cqiBasediTbs >
5052      actualiTbs) && ((cqiBasediTbs - actualiTbs) > RG_SCH_TXSCHEME_CHNG_THRSHD)) 
5053    {
5054       RG_SCH_CMN_SET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
5055    }
5056    
5057    if(actualiTbs >= maxiTbs)
5058    {
5059       RG_SCH_CMN_UNSET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG);
5060    }
5061
5062    return;
5063 }
5064
5065 /**
5066  * @brief This function determines the allocation limits and
5067  *        parameters that aid in DL scheduling.
5068  *
5069  * @details
5070  *
5071  *     Function: rgSCHCmnDlSetUeAllocLmtLa
5072  *     Purpose:  This function determines the Maximum RBs
5073  *               a UE is eligible to get based on softbuffer
5074  *               limitation and cell->>>maxDlBwPerUe. The Codeword
5075  *               specific parameters like iTbs, eff and noLyrs
5076  *               are also set in this function. This function
5077  *               is called while UE configuration and UeDlCqiInd.
5078  *
5079  *     Invoked by: Scheduler
5080  *
5081  *  @param[in]  RgSchCellCb   *cell
5082  *  @param[in]  RgSchUeCb     *ue
5083  *  @return  Void
5084  *
5085  **/
5086 #ifdef ANSI
5087 Void rgSCHCmnDlSetUeAllocLmtLa
5088 (
5089 RgSchCellCb   *cell,
5090 RgSchUeCb     *ue
5091 )
5092 #else
5093 Void rgSCHCmnDlSetUeAllocLmtLa(cell, ue)
5094 RgSchCellCb   *cell;
5095 RgSchUeCb     *ue;
5096 #endif
5097 {
5098    uint8_t            modOrder;
5099    uint32_t           maxRb;
5100    uint8_t            reportediTbs;
5101    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
5102    RgSchCmnDlUe  *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
5103    uint8_t            cfi = cellSch->dl.currCfi;
5104    uint8_t            maxiTbs;
5105    uint8_t            cwIdx = 0; 
5106
5107
5108    maxiTbs      = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1];
5109    if(ueDl->cqiFlag == TRUE)
5110    {
5111       for(cwIdx=0; cwIdx < RG_SCH_CMN_MAX_CW_PER_UE; cwIdx++)
5112       {
5113          S32 iTbsNew;
5114
5115          /* Calcluating the reported iTbs for code word 0 */
5116          reportediTbs = ue->ue5gtfCb.mcs; 
5117
5118          iTbsNew = (S32) reportediTbs;
5119
5120          if(!ueDl->laCb[cwIdx].notFirstCqi)
5121          {
5122             /* This is the first CQI report from UE */
5123             ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
5124             ueDl->laCb[cwIdx].notFirstCqi  =  TRUE;
5125          }
5126          else if ((RG_ITBS_DIFF(reportediTbs, ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0])) > 5)
5127          {
5128             /* Ignore this iTBS report and mark that last iTBS report was */
5129             /* ignored so that subsequently we reset the LA algorithm     */
5130             ueDl->laCb[cwIdx].lastiTbsIgnored = TRUE;
5131             ueDl->laCb[cwIdx].numLastiTbsIgnored++;
5132             if( ueDl->laCb[cwIdx].numLastiTbsIgnored > 10)
5133             {
5134                /* CQI reported by UE is not catching up. Reset the LA algorithm */
5135                ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100);
5136                ueDl->laCb[cwIdx].deltaiTbs = 0;
5137                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
5138                ueDl->laCb[cwIdx].numLastiTbsIgnored = 0;
5139             }
5140          }
5141          else
5142          {
5143             if (ueDl->laCb[cwIdx].lastiTbsIgnored != TRUE)
5144             {
5145                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
5146                      (80 * ueDl->laCb[cwIdx].cqiBasediTbs))/100;
5147             }
5148             else
5149             {
5150                /* Reset the LA as iTbs in use caught up with the value   */
5151                /* reported by UE.                                        */
5152                ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) +
5153                      (80 * ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] * 100))/100;
5154                ueDl->laCb[cwIdx].deltaiTbs = 0;
5155                ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE;
5156             }
5157          }
5158
5159          iTbsNew = (ueDl->laCb[cwIdx].cqiBasediTbs + ueDl->laCb[cwIdx].deltaiTbs)/100;
5160
5161          RG_SCH_CHK_ITBS_RANGE(iTbsNew, maxiTbs);       
5162
5163          ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] = RGSCH_MIN(iTbsNew, cell->thresholds.maxDlItbs);
5164          //ueDl->mimoInfo.cwInfo[cwIdx].iTbs[1] = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
5165 #ifdef RG_5GTF
5166          ue->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0];
5167          /*
5168          printf("reportediTbs[%d] cqiBasediTbs[%d] deltaiTbs[%d] iTbsNew[%d] mcs[%d] cwIdx[%d]\n", 
5169                  reportediTbs, ueDl->laCb[cwIdx].cqiBasediTbs, ueDl->laCb[cwIdx].deltaiTbs,
5170                  iTbsNew, ue->ue5gtfCb.mcs, cwIdx);
5171          */
5172 #endif
5173
5174          if((ue->mimoInfo.txMode != RGR_UE_TM_3) && (ue->mimoInfo.txMode != RGR_UE_TM_4))
5175          {
5176             break; 
5177          }
5178       }
5179       ueDl->cqiFlag = FALSE;
5180    } 
5181
5182
5183    return;
5184 }
5185 #endif
5186 /***********************************************************
5187  *
5188  *     Func : rgSCHCmnDlUeResetTemp
5189  *
5190  *     Desc : Reset whatever variables where temporarily used
5191  *            during UE scheduling.
5192  *
5193  *     Ret  : Void
5194  *
5195  *     Notes:
5196  *
5197  *     File :
5198  *
5199  **********************************************************/
5200 #ifdef ANSI
5201 Void rgSCHCmnDlHqPResetTemp 
5202 (
5203 RgSchDlHqProcCb         *hqP
5204 )
5205 #else
5206 Void rgSCHCmnDlHqPResetTemp(hqP)
5207 RgSchDlHqProcCb         *hqP;
5208 #endif
5209 {
5210
5211
5212    /* Fix: syed having a hqP added to Lists for RB assignment rather than
5213     * a UE, as adding UE was limiting handling some scenarios */ 
5214     hqP->reqLnk.node = (PTR)NULLP;
5215     hqP->schdLstLnk.node = (PTR)NULLP;
5216
5217    return;
5218 }  /* rgSCHCmnDlHqPResetTemp */
5219
5220 /***********************************************************
5221  *
5222  *     Func : rgSCHCmnDlUeResetTemp
5223  *
5224  *     Desc : Reset whatever variables where temporarily used
5225  *            during UE scheduling.
5226  *
5227  *     Ret  : Void
5228  *
5229  *     Notes:
5230  *
5231  *     File :
5232  *
5233  **********************************************************/
5234 #ifdef ANSI
5235 Void rgSCHCmnDlUeResetTemp
5236 (
5237 RgSchUeCb               *ue,
5238 RgSchDlHqProcCb         *hqP
5239 )
5240 #else
5241 Void rgSCHCmnDlUeResetTemp(ue, hqP)
5242 RgSchUeCb               *ue;
5243 RgSchDlHqProcCb         *hqP;
5244 #endif
5245 {
5246    RgSchDlRbAlloc  *allocInfo;
5247    RgSchCmnDlUe       *cmnUe = RG_SCH_CMN_GET_DL_UE(ue,hqP->hqE->cell);
5248 #ifdef LTE_ADV
5249    Void           *tmpCb;
5250 #endif
5251
5252
5253    /* Fix : syed check for UE's existence was useless.
5254     * Instead we need to check that reset is done only for the 
5255     * information of a scheduled harq proc, which is cmnUe->proc.
5256     * Reset should not be done for non-scheduled hqP */
5257    if((cmnUe->proc == hqP) || (cmnUe->proc == NULLP))
5258    {
5259       cmnUe->proc = NULLP;
5260       allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, hqP->hqE->cell);
5261 #ifdef LTE_ADV
5262       tmpCb = allocInfo->laaCb;
5263 #endif
5264       memset(allocInfo, 0, sizeof(RgSchDlRbAlloc));
5265       allocInfo->rnti = ue->ueId;
5266 #ifdef LTE_ADV
5267       allocInfo->laaCb = tmpCb;
5268 #endif
5269       /* Fix: syed moving this to a common function for both scheduled
5270        * and non-scheduled UEs */
5271       cmnUe->outStndAlloc = 0;
5272    }
5273    rgSCHCmnDlHqPResetTemp(hqP);
5274
5275    return;
5276 }  /* rgSCHCmnDlUeResetTemp */
5277
5278 /***********************************************************
5279  *
5280  *     Func : rgSCHCmnUlUeResetTemp
5281  *
5282  *     Desc : Reset whatever variables where temporarily used
5283  *            during UE scheduling.
5284  *
5285  *     Ret  : Void
5286  *
5287  *     Notes:
5288  *
5289  *     File :
5290  *
5291  **********************************************************/
5292 #ifdef ANSI
5293 Void rgSCHCmnUlUeResetTemp
5294 (
5295 RgSchCellCb             *cell,
5296 RgSchUeCb               *ue
5297 )
5298 #else
5299 Void rgSCHCmnUlUeResetTemp(cell, ue)
5300 RgSchCellCb             *cell;
5301 RgSchUeCb               *ue;
5302 #endif
5303 {
5304    RgSchCmnUlUe       *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue,cell);
5305
5306
5307    memset(&cmnUlUe->alloc, 0, sizeof(cmnUlUe->alloc));
5308
5309    return;
5310 }  /* rgSCHCmnUlUeResetTemp */
5311
5312
5313 \f
5314 /**
5315  * @brief This function fills the PDCCH information from dlProc.
5316  *
5317  * @details
5318  *
5319  *     Function: rgSCHCmnFillPdcch
5320  *     Purpose:  This function fills in the PDCCH information
5321  *               obtained from the RgSchDlRbAlloc
5322  *               during common channel scheduling(P, SI, RA - RNTI's).
5323  *
5324  *     Invoked by: Downlink Scheduler
5325  *
5326  *  @param[out] RgSchPdcch*       pdcch
5327  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5328  *  @return  Void
5329  *
5330  **/
5331 #ifdef ANSI
5332 Void rgSCHCmnFillPdcch
5333 (
5334 RgSchCellCb                *cell,
5335 RgSchPdcch                 *pdcch,
5336 RgSchDlRbAlloc             *rbAllocInfo
5337 )
5338 #else
5339 Void rgSCHCmnFillPdcch(cell, pdcch, rbAllocInfo)
5340 RgSchCellCb                *cell;
5341 RgSchPdcch                 *pdcch;
5342 RgSchDlRbAlloc             *rbAllocInfo;
5343 #endif
5344 {
5345
5346
5347    /* common channel pdcch filling,
5348     * only 1A and Local is supported */
5349    pdcch->rnti                       = rbAllocInfo->rnti;
5350    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
5351    switch(rbAllocInfo->dciFormat)
5352    {
5353 #ifdef RG_5GTF  /* ANOOP: ToDo: DCI format B1/B2 filling */
5354       case TFU_DCI_FORMAT_B1:
5355          {
5356             /* ToDo: Anoop */
5357             pdcch->dci.u.formatB1Info.formatType = 0;
5358             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].cmnGrnt.xPDSCHRange;
5359             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].cmnGrnt.rbAssign;
5360             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = 0;
5361             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5362             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = 0;
5363             //pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].ndi;
5364             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].cmnGrnt.rv;
5365             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5366             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5367             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5368             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5369             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5370             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5371             //TODO_SID: Need to update
5372             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5373             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5374             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5375             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5376             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5377             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5378             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].cmnGrnt.SCID;
5379             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5380             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5381             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5382
5383             break; /* case TFU_DCI_FORMAT_B1: */
5384          }
5385
5386       case TFU_DCI_FORMAT_B2:
5387          {
5388             //printf(" RG_5GTF:: Pdcch filling with DCI format B2\n");
5389             /* ToDo: Anoop */
5390             break; /* case TFU_DCI_FORMAT_B2: */
5391          }
5392 #endif
5393       case TFU_DCI_FORMAT_1A:
5394          pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
5395
5396          /*Nprb indication at PHY for common Ch
5397           *setting least significant bit of tpc field to 1 if
5398           nPrb=3 and 0 otherwise. */
5399          if (rbAllocInfo->nPrb == 3)
5400          {
5401             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 1;
5402          }
5403          else
5404          {
5405             pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = 0;
5406          }
5407          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
5408          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
5409          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
5410                                                                    rbAllocInfo->tbInfo[0].imcs;
5411          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = 0;
5412          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = 0;
5413          /* Add RIV CALC */
5414          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
5415             TFU_ALLOC_TYPE_RIV;
5416          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
5417             rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
5418                   rbAllocInfo->allocInfo.raType2.rbStart,
5419                   rbAllocInfo->allocInfo.raType2.numRb);
5420
5421 #ifdef LTE_TDD
5422          pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = \
5423                                                                            FALSE;
5424 #ifdef TFU_TDD
5425          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
5426          pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
5427 #endif
5428 #endif
5429          break; /* case TFU_DCI_FORMAT_1A: */
5430       case TFU_DCI_FORMAT_1:
5431          pdcch->dci.u.format1Info.tpcCmd = 0;
5432          /* Avoiding this check,as we dont support Type1 RA */
5433 #ifdef RG_UNUSED
5434          if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
5435          {
5436 #endif
5437             pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
5438             pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
5439                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
5440                 & 0xff);
5441             pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
5442                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
5443                 & 0x00ff);
5444             pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
5445                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
5446                 & 0x0000ff);
5447             pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
5448                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
5449 #ifdef RG_UNUSED
5450          }
5451 #endif
5452          pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
5453          pdcch->dci.u.format1Info.allocInfo.ndi = 0;
5454          pdcch->dci.u.format1Info.allocInfo.mcs = rbAllocInfo->tbInfo[0].imcs;
5455          pdcch->dci.u.format1Info.allocInfo.rv = 0;
5456 #ifdef TFU_TDD
5457          pdcch->dci.u.format1Info.dai = 1;
5458 #endif
5459          break;
5460       default:
5461          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Allocator's icorrect "
5462             "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5463          break;
5464    }
5465    return;
5466 }
5467
5468 #ifdef LTE_TDD
5469 /**
5470  * @brief This function finds whether the subframe is special subframe or not.
5471  *
5472  * @details
5473  *
5474  *     Function: rgSCHCmnIsSplSubfrm
5475  *     Purpose:  This function finds the subframe index of the special subframe
5476  *               and finds whether the current DL index matches it or not.
5477  *
5478  *     Invoked by: Scheduler
5479  *
5480  *  @param[in] uint8_t                   splfrmCnt
5481  *  @param[in] uint8_t                   curSubfrmIdx
5482  *  @param[in] uint8_t                   periodicity
5483  *  @param[in] RgSchTddSubfrmInfo   *subfrmInfo
5484  *  @return  Bool
5485  *
5486  **/
5487 #ifdef ANSI
5488 static Bool rgSCHCmnIsSplSubfrm
5489 (
5490 uint8_t                   splfrmCnt,
5491 uint8_t                   curSubfrmIdx,
5492 uint8_t                   periodicity,
5493 RgSchTddSubfrmInfo   *subfrmInfo
5494 )
5495 #else
5496 static Bool rgSCHCmnIsSplSubfrm(splfrmCnt, curSubfrmIdx, periodicity, subfrmInfo)
5497 uint8_t                   splfrmCnt;
5498 uint8_t                   curSubfrmIdx;
5499 uint8_t                   periodicity;
5500 RgSchTddSubfrmInfo   *subfrmInfo;
5501 #endif
5502 {
5503    uint8_t dlSfCnt = 0;
5504    uint8_t splfrmIdx  = 0;
5505
5506
5507    if(splfrmCnt > 0)
5508    {
5509       if(periodicity == RG_SCH_CMN_5_MS_PRD)
5510       {
5511          if(splfrmCnt%2)
5512          {
5513             dlSfCnt = ((splfrmCnt-1)/2) *\
5514                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5515             dlSfCnt = dlSfCnt + subfrmInfo->numFrmHf1;
5516          }
5517          else
5518          {
5519             dlSfCnt = (splfrmCnt/2) * \
5520                       (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2);
5521          }
5522       }
5523       else
5524       {
5525          dlSfCnt = splfrmCnt * subfrmInfo->numFrmHf1;
5526       }
5527       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1 +\
5528                   (periodicity*splfrmCnt - dlSfCnt);
5529    }
5530    else
5531    {
5532       splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1;
5533    }
5534
5535    if(splfrmIdx == curSubfrmIdx)
5536    {
5537       return (TRUE);
5538    }
5539
5540    return (FALSE);
5541 }
5542
5543 /**
5544  * @brief This function updates DAI or UL index.
5545  *
5546  * @details
5547  *
5548  *     Function: rgSCHCmnUpdHqAndDai
5549  *     Purpose:  Updates the DAI based on UL-DL Configuration
5550  *               index and UE. It also updates the HARQ feedback
5551  *               time and 'm' index.
5552  *
5553  *     Invoked by: TOM
5554  *
5555  *  @param[in]  RgDlHqProcCb  *hqP
5556  *  @param[in]  RgSchDlSf     *subFrm
5557  *  @param[in]  RgSchDlHqTbCb *tbCb
5558  *  @param[in]  uint8_t            tbAllocIdx
5559  *  @return  Void
5560  *
5561  **/
5562 #ifdef ANSI
5563 static Void rgSCHCmnUpdHqAndDai
5564 (
5565 RgSchDlHqProcCb   *hqP,
5566 RgSchDlSf         *subFrm,
5567 RgSchDlHqTbCb     *tbCb,
5568 uint8_t                tbAllocIdx
5569 )
5570 #else
5571 static Void rgSCHCmnUpdHqAndDai(hqP, subFrm, tbCb,tbAllocIdx)
5572 RgSchDlHqProcCb   *hqP;
5573 RgSchDlSf         *subFrm;
5574 RgSchDlHqTbCb     *tbCb;
5575 uint8_t                tbAllocIdx;
5576 #endif
5577 {
5578    RgSchUeCb      *ue = hqP->hqE->ue;
5579    
5580
5581    if(subFrm != NULLP)
5582    {
5583       /* set the time at which UE shall send the feedback
5584        * for this process */
5585       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5586             subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5587       tbCb->fdbkTime.subframe = subFrm->dlFdbkInfo.subframe;
5588       tbCb->m = subFrm->dlFdbkInfo.m;
5589    }
5590    else
5591    {
5592       /* set the time at which UE shall send the feedback
5593        * for this process */
5594       tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \
5595             hqP->subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN;
5596       tbCb->fdbkTime.subframe = hqP->subFrm->dlFdbkInfo.subframe;
5597       tbCb->m = hqP->subFrm->dlFdbkInfo.m;
5598    }
5599
5600    /* ccpu00132340-MOD- DAI need to be updated for first TB only*/
5601    if(ue && !tbAllocIdx)
5602    {
5603       Bool   havePdcch = (tbCb->hqP->pdcch ? TRUE : FALSE);
5604       uint8_t     dlDai;
5605       
5606       dlDai = rgSCHCmnUpdDai(ue, &tbCb->fdbkTime, tbCb->m, havePdcch,tbCb->hqP,
5607             &tbCb->dai);
5608       if(havePdcch)
5609       {/* Non SPS occasions */
5610          tbCb->hqP->pdcch->dlDai = dlDai;
5611          /* hqP->ulDai is used for N1 resource filling
5612           * when SPS occaions present in a bundle */
5613          tbCb->hqP->ulDai = tbCb->dai;
5614          tbCb->hqP->dlDai = dlDai;
5615       }
5616    }
5617
5618    /* Updatijng pucchFdbkIdx for both PUCCH or PUSCH
5619       fdbk reception */
5620    tbCb->pucchFdbkIdx = tbCb->hqP->ulDai;
5621
5622    return;
5623 }
5624
5625
5626 /**
5627  * @brief This function updates DAI or UL index.
5628  *
5629  * @details
5630  *
5631  *     Function: rgSCHCmnUpdDai
5632  *     Purpose:  Updates the DAI in the ack-nack info, a valid
5633  *               ue should be passed
5634  *
5635  *     Invoked by: TOM
5636  *
5637  *  @param[in]  RgDlHqProcCb  *hqP
5638  *  @param[in]  RgSchDlSf     *subFrm
5639  *  @param[in]  RgSchDlHqTbCb *tbCb
5640  *  @return  uint8_t dlDai 
5641  *
5642  **/
5643 #ifdef ANSI
5644 uint8_t rgSCHCmnUpdDai
5645 (
5646 RgSchUeCb         *ue,
5647 CmLteTimingInfo   *fdbkTime,
5648 uint8_t                 m,
5649 Bool               havePdcch,
5650 RgSchDlHqProcCb   *hqP,
5651 uint8_t                *ulDai
5652 )
5653 #else
5654 uint8_t rgSCHCmnUpdDai(ue, fdbkTime, m, havePdcch,tbCb,servCellId,hqP,ulDai)
5655 RgSchUeCb         *ue;
5656 CmLteTimingInfo   *fdbkTime;
5657 uint8_t                 m;
5658 Bool               havePdcch;
5659 RgSchDlHqProcCb   *hqP;
5660 uint8_t                *ulDai;
5661 #endif
5662 {
5663    RgSchTddANInfo *anInfo;
5664    uint8_t             servCellIdx;
5665    uint8_t             ackNackFdbkArrSize;
5666   
5667
5668
5669    if(hqP != NULLP)
5670    {/* Non SPS */
5671 #ifdef LTE_ADV
5672       servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
5673             hqP->hqE->cell->cellId,
5674             ue);
5675 #else
5676      servCellIdx = RGSCH_PCELL_INDEX;
5677 #endif
5678       ackNackFdbkArrSize = hqP->hqE->cell->ackNackFdbkArrSize;
5679    }else
5680    {/* SPS on primary cell */
5681       servCellIdx = RGSCH_PCELL_INDEX;
5682       ackNackFdbkArrSize = ue->cell->ackNackFdbkArrSize;
5683    }
5684
5685
5686    anInfo = rgSCHUtlGetUeANFdbkInfo(ue, fdbkTime,servCellIdx);
5687
5688    /* If no ACK/NACK feedback already present, create a new one */
5689    if(NULLP == anInfo)
5690    {
5691       anInfo = &ue->cellInfo[servCellIdx]->anInfo[ue->cellInfo[servCellIdx]->nextFreeANIdx];
5692       anInfo->sfn = fdbkTime->sfn;
5693       anInfo->subframe = fdbkTime->subframe;
5694       anInfo->latestMIdx = m;
5695       /* Fixing DAI value - ccpu00109162 */
5696       /* Handle TDD case as in MIMO definition of the function */
5697       anInfo->ulDai = 1;
5698       if (havePdcch)
5699       {
5700          anInfo->dlDai = 1;
5701       }
5702       anInfo->isSpsOccasion = FALSE;
5703       /* set the free Index to store  Ack/Nack Information*/
5704       ue->cellInfo[servCellIdx]->nextFreeANIdx = (ue->cellInfo[servCellIdx]->nextFreeANIdx + 1) %
5705          ackNackFdbkArrSize;
5706
5707    }
5708    else
5709    {
5710       anInfo->latestMIdx = m;
5711       /* Fixing DAI value - ccpu00109162 */
5712       /* Handle TDD case as in MIMO definition of the function */
5713       anInfo->ulDai = anInfo->ulDai + 1;
5714       if (havePdcch)
5715       {
5716          anInfo->dlDai = anInfo->dlDai + 1;
5717       }
5718    }
5719 #ifdef LTE_ADV
5720    /* ignoring the Scell check,
5721     * for primary cell this field is unused*/
5722    if(hqP != NULLP)
5723    {/* SPS*/
5724       anInfo->n1ResTpcIdx = hqP->tpc;
5725    }
5726
5727    if(ulDai)
5728    {/* As this not required for release pdcch */
5729       *ulDai = anInfo->ulDai;
5730    }
5731 #endif
5732    return (anInfo->dlDai);
5733
5734 }
5735 #endif /* ifdef LTE_TDD */
5736
5737 uint32_t rgHqRvRetxCnt[4][2];
5738 uint32_t rgUlrate_grant;
5739
5740 /**
5741  * @brief This function fills the HqP TB with rbAllocInfo.
5742  *
5743  * @details
5744  *
5745  *     Function: rgSCHCmnFillHqPTb
5746  *     Purpose:  This function fills in the HqP TB with rbAllocInfo.
5747  *
5748  *     Invoked by: rgSCHCmnFillHqPTb
5749  *
5750  *  @param[in]  RgSchCellCb*      cell
5751  *  @param[in]  RgSchDlRbAlloc    *rbAllocInfo,
5752  *  @param[in]  uint8_t                tbAllocIdx
5753  *  @param[in]  RgSchPdcch        *pdcch
5754  *  @return  Void
5755  *
5756  **/
5757 #ifdef LTEMAC_SPS
5758 #ifdef ANSI
5759 Void rgSCHCmnFillHqPTb
5760 (
5761 RgSchCellCb                *cell,
5762 RgSchDlRbAlloc             *rbAllocInfo,
5763 uint8_t                         tbAllocIdx,
5764 RgSchPdcch                 *pdcch
5765 )
5766 #else
5767 Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch)
5768 RgSchCellCb                *cell;
5769 RgSchDlRbAlloc             *rbAllocInfo;
5770 uint8_t                         tbAllocIdx;
5771 RgSchPdcch                 *pdcch;
5772 #endif
5773 #else
5774 #ifdef ANSI
5775 static Void rgSCHCmnFillHqPTb
5776 (
5777 RgSchCellCb                *cell,
5778 RgSchDlRbAlloc             *rbAllocInfo,
5779 uint8_t                         tbAllocIdx,
5780 RgSchPdcch                 *pdcch
5781 )
5782 #else
5783 static Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch)
5784 RgSchCellCb                *cell;
5785 RgSchDlRbAlloc             *rbAllocInfo;
5786 uint8_t                         tbAllocIdx;
5787 RgSchPdcch                 *pdcch;
5788 #endif
5789 #endif /* LTEMAC_SPS */
5790 {
5791    RgSchCmnDlCell     *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5792    RgSchDlTbAllocInfo *tbAllocInfo = &rbAllocInfo->tbInfo[tbAllocIdx];
5793    RgSchDlHqTbCb      *tbInfo = tbAllocInfo->tbCb;
5794    RgSchDlHqProcCb    *hqP = tbInfo->hqP;
5795
5796
5797    /*ccpu00120365-ADD-if tb is disabled, set mcs=0,rv=1.
5798     * Relevant for DCI format 2 & 2A as per 36.213-7.1.7.2
5799     */
5800    if ( tbAllocInfo->isDisabled)
5801    {
5802
5803       tbInfo->dlGrnt.iMcs = 0;
5804       tbInfo->dlGrnt.rv   = 1;
5805    }
5806    /* Fill for TB retransmission */
5807    else if (tbInfo->txCntr > 0)
5808    {
5809
5810       tbInfo->timingInfo = cmnCellDl->time;
5811       /* Fix */
5812       if ((tbInfo->isAckNackDtx == TFU_HQFDB_DTX)) 
5813       {
5814          tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;         
5815          rgHqRvRetxCnt[tbInfo->dlGrnt.rv][tbInfo->tbIdx]++;
5816       }
5817       else
5818       {
5819          tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[++(tbInfo->ccchSchdInfo.rvIdx) & 0x03];
5820       }
5821
5822       /* fill the scheduler information of hqProc */
5823       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5824       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx,hqP->tbInfo,tbInfo->tbIdx );
5825       rgSCHDhmHqTbRetx(hqP->hqE, tbInfo->timingInfo, hqP, tbInfo->tbIdx);
5826    }
5827    /* Fill for TB transmission */
5828    else
5829    {
5830       /* Fill the HqProc */
5831       tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs;
5832       tbInfo->tbSz = tbAllocInfo->bytesAlloc;
5833       tbInfo->timingInfo = cmnCellDl->time;
5834
5835       tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[0];
5836       /* fill the scheduler information of hqProc */
5837       tbInfo->ccchSchdInfo.rvIdx = 0;
5838       tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc;
5839       /* DwPts Scheduling Changes Start */
5840       /* DwPts Scheduling Changes End */ 
5841       cell->measurements.dlBytesCnt += tbAllocInfo->bytesAlloc;
5842    }
5843
5844    /*ccpu00120365:-ADD-only add to subFrm list if tb is not disabled */
5845    if ( tbAllocInfo->isDisabled == FALSE )
5846    {
5847       /* Set the number of transmitting SM layers for this TB */
5848       tbInfo->numLyrs = tbAllocInfo->noLyr;
5849       /* Set the TB state as WAITING to indicate TB has been
5850        * considered for transmission */
5851       tbInfo->state  = HQ_TB_WAITING;
5852       hqP->subFrm = rbAllocInfo->dlSf;
5853       tbInfo->hqP->pdcch  = pdcch;
5854       //tbInfo->dlGrnt.numRb = rbAllocInfo->rbsAlloc;
5855       rgSCHUtlDlHqPTbAddToTx(hqP->subFrm, hqP, tbInfo->tbIdx);
5856    }
5857    return;
5858 }
5859
5860 /**
5861  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
5862  *
5863  * @details
5864  *
5865  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
5866  *     Purpose:  This function fills in the PDCCH information
5867  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5868  *               for dedicated service scheduling. It also
5869  *               obtains TPC to be filled in from the power module.
5870  *               Assign the PDCCH to HQProc.
5871  *
5872  *     Invoked by: Downlink Scheduler
5873  *
5874  *  @param[in]  RgSchCellCb*      cell
5875  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5876  *  @param[in]  RgDlHqProc*       hqP
5877  *  @param[out]  RgSchPdcch        *pdcch
5878  *  @param[in]   uint8_t               tpc
5879  *  @return  Void
5880  *
5881  **/
5882 #ifdef ANSI
5883 static Void rgSCHCmnFillHqPPdcchDciFrmtB1B2
5884 (
5885 RgSchCellCb                *cell,
5886 RgSchDlRbAlloc             *rbAllocInfo,
5887 RgSchDlHqProcCb            *hqP,
5888 RgSchPdcch                 *pdcch,
5889 uint8_t                         tpc
5890 )
5891 #else
5892 static Void rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, pdcch, tpc)
5893 RgSchCellCb                *cell;
5894 RgSchDlRbAlloc             *rbAllocInfo;
5895 RgSchDlHqProcCb            *hqP;
5896 RgSchPdcch                 *pdcch;
5897 uint8_t                         tpc;
5898 #endif
5899 {
5900
5901
5902    rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);   
5903    //Currently hardcoding values here.
5904    //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
5905    switch(rbAllocInfo->dciFormat)
5906    {
5907       case TFU_DCI_FORMAT_B1:
5908          {
5909             pdcch->dci.u.formatB1Info.formatType = 0;
5910             pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5911             pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5912             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5913             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5914             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5915             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5916             pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5917             pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0;
5918             pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0;
5919             pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0;
5920             pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0;
5921             pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0;
5922             //TODO_SID: Need to update
5923             pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0;
5924             pdcch->dci.u.formatB1Info.beamSwitch  = 0;
5925             pdcch->dci.u.formatB1Info.SRS_Config = 0;
5926             pdcch->dci.u.formatB1Info.SRS_Symbol = 0;
5927             //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC).
5928             pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0;
5929             pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5930             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5931             pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc;
5932             pdcch->dci.u.formatB1Info.DL_PCRS = 0;
5933             break;
5934          }
5935       case TFU_DCI_FORMAT_B2:
5936          {
5937             pdcch->dci.u.formatB2Info.formatType = 1;
5938             pdcch->dci.u.formatB2Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange;
5939             pdcch->dci.u.formatB2Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign;
5940             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.hqProcId = hqP->procId;
5941             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs;
5942             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
5943             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
5944             pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.bmiHqAckNack = 0;
5945             pdcch->dci.u.formatB2Info.CSI_BSI_BRI_Req = 0;
5946             pdcch->dci.u.formatB2Info.CSIRS_BRRS_TxTiming = 0;
5947             pdcch->dci.u.formatB2Info.CSIRS_BRRS_SymbIdx = 0;
5948             pdcch->dci.u.formatB2Info.CSIRS_BRRS_ProcInd = 0;
5949             pdcch->dci.u.formatB2Info.xPUCCH_TxTiming = 0;
5950             //TODO_SID: Need to update
5951             pdcch->dci.u.formatB2Info.freqResIdx_xPUCCH = 0;
5952             pdcch->dci.u.formatB2Info.beamSwitch  = 0;
5953             pdcch->dci.u.formatB2Info.SRS_Config = 0;
5954             pdcch->dci.u.formatB2Info.SRS_Symbol = 0;
5955             //TODO_SID: Need to check.Currently setting 4(2 layer, ports(8,9) w/o OCC).
5956             pdcch->dci.u.formatB2Info.AntPorts_numLayers = 4;
5957             pdcch->dci.u.formatB2Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID;
5958             //TODO_SID: Hardcoding TPC command to 1 i.e. No change
5959             pdcch->dci.u.formatB2Info.tpcCmd = 1; //tpc;
5960             pdcch->dci.u.formatB2Info.DL_PCRS = 0;
5961             break;
5962          }
5963          default:
5964             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId," 5GTF_ERROR Allocator's icorrect "
5965                "dciForamt Fill RNTI:%d",rbAllocInfo->rnti);
5966             break;
5967    }
5968    
5969    return;
5970 }
5971
5972 uint32_t totPcellSCell;
5973 uint32_t addedForScell;
5974 uint32_t addedForScell1;
5975 uint32_t addedForScell2;
5976 /**
5977  * @brief This function fills the PDCCH information from dlProc.
5978  *
5979  * @details
5980  *
5981  *     Function: rgSCHCmnFillHqPPdcch
5982  *     Purpose:  This function fills in the PDCCH information
5983  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
5984  *               for dedicated service scheduling. It also
5985  *               obtains TPC to be filled in from the power module.
5986  *               Assign the PDCCH to HQProc.
5987  *
5988  *     Invoked by: Downlink Scheduler
5989  *
5990  *  @param[in]  RgSchCellCb*      cell
5991  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
5992  *  @param[in]  RgDlHqProc*       hqP
5993  *  @return  Void
5994  *
5995  **/
5996 #ifdef ANSI
5997 Void rgSCHCmnFillHqPPdcch
5998 (
5999 RgSchCellCb                *cell,
6000 RgSchDlRbAlloc             *rbAllocInfo,
6001 RgSchDlHqProcCb            *hqP
6002 )
6003 #else
6004 Void rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP)
6005 RgSchCellCb                *cell;
6006 RgSchDlRbAlloc             *rbAllocInfo;
6007 RgSchDlHqProcCb            *hqP;
6008 #endif
6009 {
6010    RgSchCmnDlCell     *cmnCell = RG_SCH_CMN_GET_DL_CELL(cell);
6011    RgSchPdcch         *pdcch = rbAllocInfo->pdcch;
6012    uint8_t                 tpc = 1;
6013
6014
6015    if (hqP->hqE->ue)
6016    {
6017 #ifdef LTE_ADV
6018       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6019       {
6020          tpc = hqP->tpc;
6021       }
6022       else
6023 #endif
6024       {
6025          tpc = rgSCHPwrPucchTpcForUe(cell, hqP->hqE->ue);
6026       }
6027       /* Fix: syed moving this to a common function for both scheduled
6028        * and non-scheduled UEs */
6029
6030       pdcch->ue = hqP->hqE->ue;
6031       if (hqP->hqE->ue->csgMmbrSta == FALSE)
6032       {
6033          cmnCell->ncsgPrbCnt += rbAllocInfo->rbsAlloc;
6034       }
6035       cmnCell->totPrbCnt += rbAllocInfo->rbsAlloc;
6036 #ifdef TENB_STATS
6037       {
6038          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlPrbUsg += 
6039             rbAllocInfo->rbsAlloc;
6040          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw0iTbs += 
6041             rbAllocInfo->tbInfo[0].iTbs;
6042          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw0iTbs ++; 
6043          hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
6044             (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6045
6046 #ifdef LTE_ADV
6047       totPcellSCell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6048       if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6049       {
6050          addedForScell +=  (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6051          addedForScell1 += (rbAllocInfo->tbInfo[0].bytesAlloc << 3);
6052 /*
6053          printf (" Hqp %d cell %d addedForScell %lu addedForScell1 %lu sfn:sf %d:%d \n",
6054          hqP->procId,
6055          hqP->hqE->cell->cellId,
6056          addedForScell,
6057          addedForScell1,
6058          cell->crntTime.sfn,
6059          cell->crntTime.slot);
6060          */
6061       }
6062 #endif
6063          hqP->hqE->cell->tenbStats->sch.dlPrbUsage[0] += 
6064             rbAllocInfo->rbsAlloc;
6065          hqP->hqE->cell->tenbStats->sch.dlSumCw0iTbs += 
6066             rbAllocInfo->tbInfo[0].iTbs;
6067          hqP->hqE->cell->tenbStats->sch.dlNumCw0iTbs ++; 
6068          hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
6069             (rbAllocInfo->tbInfo[0].bytesAlloc << 3); 
6070          if (rbAllocInfo->tbInfo[1].schdlngForTb)
6071          {
6072             hqP->hqE->cell->tenbStats->sch.dlSumCw1iTbs += 
6073                rbAllocInfo->tbInfo[1].iTbs;
6074             hqP->hqE->cell->tenbStats->sch.dlNumCw1iTbs ++; 
6075             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw1iTbs += 
6076                rbAllocInfo->tbInfo[1].iTbs;
6077             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw1iTbs ++; 
6078             hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt +=
6079                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6080
6081
6082 #ifdef LTE_ADV
6083             if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell))
6084             {
6085                addedForScell +=  (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6086                addedForScell2 += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6087 /*
6088          printf (" Hqp %d cell %d addedForScell %lu addedForScell2 %lu \n",
6089          hqP->procId,
6090          hqP->hqE->cell->cellId,
6091          addedForScell,
6092          addedForScell2);
6093          */
6094             }
6095             totPcellSCell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6096 #endif
6097
6098
6099             hqP->hqE->cell->tenbStats->sch.dlTtlTpt +=
6100                (rbAllocInfo->tbInfo[1].bytesAlloc << 3);
6101          }
6102          /*
6103          printf ("add DL TPT is %lu  sfn:sf %d:%d \n", hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt ,
6104          cell->crntTime.sfn,
6105          cell->crntTime.slot);
6106          */
6107       }
6108 #endif
6109    }
6110
6111    pdcch->rnti                       = rbAllocInfo->rnti;
6112    pdcch->dci.dciFormat              = rbAllocInfo->dciFormat;
6113    /* Update subframe and pdcch info in HqTb control block */
6114    switch(rbAllocInfo->dciFormat)
6115    {
6116 #ifdef RG_5GTF  
6117       case TFU_DCI_FORMAT_B1:
6118       case TFU_DCI_FORMAT_B2:
6119            {
6120         // printf(" RG_5GTF:: Pdcch filling with DCI format B1/B2\n");
6121               rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, \
6122                     pdcch, tpc);
6123               break;
6124            }
6125 #endif
6126       default:
6127          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6128             "Allocator's incorrect dciForamt Fill for RNTI:%d",rbAllocInfo->rnti);
6129          break;
6130    }
6131    return;
6132 }
6133 #ifdef UNUSED_FUNC
6134 /**
6135  * @brief This function fills the PDCCH DCI format 1 information from dlProc.
6136  *
6137  * @details
6138  *
6139  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1
6140  *     Purpose:  This function fills in the PDCCH information
6141  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6142  *               for dedicated service scheduling. It also
6143  *               obtains TPC to be filled in from the power module.
6144  *               Assign the PDCCH to HQProc.
6145  *
6146  *     Invoked by: Downlink Scheduler
6147  *
6148  *  @param[in]  RgSchCellCb*      cell
6149  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6150  *  @param[in]  RgDlHqProc*       hqP
6151  *  @param[out]  RgSchPdcch        *pdcch
6152  *  @param[in]   uint8_t               tpc
6153  *  @return  Void
6154  *
6155  **/
6156
6157 #ifdef ANSI
6158 static Void rgSCHCmnFillHqPPdcchDciFrmt1
6159 (
6160 RgSchCellCb                *cell,
6161 RgSchDlRbAlloc             *rbAllocInfo,
6162 RgSchDlHqProcCb            *hqP,
6163 RgSchPdcch                 *pdcch,
6164 uint8_t                         tpc
6165 )
6166 #else
6167 static Void rgSCHCmnFillHqPPdcchDciFrmt1(cell, rbAllocInfo, hqP, pdcch, tpc)
6168 RgSchCellCb                *cell;
6169 RgSchDlRbAlloc             *rbAllocInfo;
6170 RgSchDlHqProcCb            *hqP;
6171 RgSchPdcch                 *pdcch;
6172 uint8_t                         tpc;
6173 #endif
6174 {
6175
6176 #ifdef LTE_TDD
6177    RgSchTddANInfo     *anInfo;
6178 #endif
6179
6180 #ifdef LTEMAC_SPS
6181 /* For activation or reactivation,
6182  * Harq ProcId should be 0 */
6183    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6184 #endif
6185
6186
6187     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6188     pdcch->dci.u.format1Info.tpcCmd = tpc;
6189      /* Avoiding this check,as we dont support Type1 RA */
6190 #ifdef RG_UNUSED
6191     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6192     {
6193 #endif
6194        pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE;
6195        pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] =
6196          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6197                & 0xff);
6198        pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] =
6199          ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6200                & 0x00ff);
6201        pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] =
6202            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6203                & 0x0000ff);
6204        pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] =
6205            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6206 #ifdef RG_UNUSED
6207     }
6208 #endif
6209 #ifdef LTEMAC_SPS
6210     if ((!(hqP->tbInfo[0].txCntr)) &&
6211        (cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6212          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6213          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)))
6214        )
6215     {
6216        pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
6217     }
6218     else
6219     {
6220       pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
6221     }
6222 #else
6223     pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId;
6224 #endif
6225
6226     pdcch->dci.u.format1Info.allocInfo.ndi = 
6227                         rbAllocInfo->tbInfo[0].tbCb->ndi;
6228     pdcch->dci.u.format1Info.allocInfo.mcs = 
6229                         rbAllocInfo->tbInfo[0].imcs;
6230     pdcch->dci.u.format1Info.allocInfo.rv = 
6231                         rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6232 #ifdef LTE_TDD
6233        if(hqP->hqE->ue != NULLP)
6234        {
6235 #ifdef LTE_ADV
6236            uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6237                                         hqP->hqE->cell->cellId,
6238                                         hqP->hqE->ue);
6239
6240            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6241                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6242 #else
6243            anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6244                             &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6245 #endif
6246 #ifdef TFU_TDD
6247           if(anInfo)
6248           {
6249              pdcch->dci.u.format1Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6250           }
6251           else
6252           {
6253                /* Fixing DAI value - ccpu00109162 */
6254              pdcch->dci.u.format1Info.dai = RG_SCH_MAX_DAI_IDX;
6255           }
6256 #endif
6257        }
6258        else
6259        {
6260             /* always 0 for RACH */
6261            pdcch->dci.u.format1Info.allocInfo.harqProcId = 0;
6262 #ifdef TFU_TDD
6263             /* Fixing DAI value - ccpu00109162 */
6264            pdcch->dci.u.format1Info.dai = 1;
6265 #endif
6266        }
6267 #endif
6268  
6269
6270        return;
6271 }
6272 /**
6273  * @brief This function fills the PDCCH DCI format 1A information from dlProc.
6274  *
6275  * @details
6276  *
6277  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1A
6278  *     Purpose:  This function fills in the PDCCH information
6279  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6280  *               for dedicated service scheduling. It also
6281  *               obtains TPC to be filled in from the power module.
6282  *               Assign the PDCCH to HQProc.
6283  *
6284  *     Invoked by: Downlink Scheduler
6285  *
6286  *  @param[in]  RgSchCellCb*      cell
6287  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6288  *  @param[in]  RgDlHqProc*       hqP
6289  *  @param[out]  RgSchPdcch        *pdcch
6290  *  @param[in]   uint8_t               tpc
6291  *  @return  Void
6292  *
6293  **/
6294 #ifdef ANSI
6295 static Void rgSCHCmnFillHqPPdcchDciFrmt1A
6296 (
6297 RgSchCellCb                *cell,
6298 RgSchDlRbAlloc             *rbAllocInfo,
6299 RgSchDlHqProcCb            *hqP,
6300 RgSchPdcch                 *pdcch,
6301 uint8_t                         tpc
6302 )
6303 #else
6304 static Void rgSCHCmnFillHqPPdcchDciFrmt1A(cell, rbAllocInfo, hqP, pdcch, tpc)
6305 RgSchCellCb                *cell;
6306 RgSchDlRbAlloc             *rbAllocInfo;
6307 RgSchDlHqProcCb            *hqP;
6308 RgSchPdcch                 *pdcch;
6309 uint8_t                         tpc;
6310 #endif
6311 {
6312
6313 #ifdef LTE_TDD
6314    RgSchTddANInfo     *anInfo;
6315 #endif
6316
6317 #ifdef LTEMAC_SPS
6318    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6319 #endif
6320
6321
6322     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6323     pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE;
6324     pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd  = tpc;
6325     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs     = \
6326       rbAllocInfo->tbInfo[0].imcs;
6327     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = TRUE;
6328 #ifdef LTEMAC_SPS
6329     if ((!(hqP->tbInfo[0].txCntr)) &&
6330        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6331          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6332          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6333        ))
6334     {
6335        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = 0;
6336     }
6337     else
6338     {
6339       pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val
6340                                                 = hqP->procId;
6341     }
6342 #else
6343     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val =
6344                                               hqP->procId;
6345 #endif
6346     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi     = \
6347        rbAllocInfo->tbInfo[0].tbCb->ndi;
6348     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv      = \
6349        rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6350          /* As of now, we do not support Distributed allocations */
6351     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE;
6352     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT;
6353     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type =
6354             TFU_ALLOC_TYPE_RIV;
6355     pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv =
6356     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
6357                   rbAllocInfo->allocInfo.raType2.rbStart,
6358                   rbAllocInfo->allocInfo.raType2.numRb);
6359 #ifdef LTE_TDD
6360     if(hqP->hqE->ue != NULLP)
6361     {
6362 #ifdef LTE_ADV
6363        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6364                                         hqP->hqE->cell->cellId,
6365                                         hqP->hqE->ue);
6366        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6367                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6368 #else
6369        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6370                               &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6371 #endif
6372 #ifdef TFU_TDD
6373        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
6374        if(anInfo)
6375        {
6376           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 
6377                               RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6378        }
6379        else
6380        {
6381           /* Fixing DAI value - ccpu00109162 */
6382           pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = RG_SCH_MAX_DAI_IDX;
6383           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6384                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6385                     rbAllocInfo->rnti);
6386        }
6387 #endif
6388     }
6389     else
6390     {
6391             /* always 0 for RACH */
6392        pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres
6393                                                                      = FALSE;
6394 #ifdef TFU_TDD
6395        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE;
6396             /* Fixing DAI value - ccpu00109162 */
6397        pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1;
6398 #endif
6399     }
6400 #endif
6401  
6402     return;
6403 }       
6404 /**
6405  * @brief This function fills the PDCCH DCI format 1B information from dlProc.
6406  *
6407  * @details
6408  *
6409  *     Function: rgSCHCmnFillHqPPdcchDciFrmt1B
6410  *     Purpose:  This function fills in the PDCCH information
6411  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6412  *               for dedicated service scheduling. It also
6413  *               obtains TPC to be filled in from the power module.
6414  *               Assign the PDCCH to HQProc.
6415  *
6416  *     Invoked by: Downlink Scheduler
6417  *
6418  *  @param[in]  RgSchCellCb*      cell
6419  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6420  *  @param[in]  RgDlHqProc*       hqP
6421  *  @param[out]  RgSchPdcch        *pdcch
6422  *  @param[in]   uint8_t               tpc
6423  *  @return  Void
6424  *
6425  **/
6426 #ifdef ANSI
6427 static Void rgSCHCmnFillHqPPdcchDciFrmt1B
6428 (
6429 RgSchCellCb                *cell,
6430 RgSchDlRbAlloc             *rbAllocInfo,
6431 RgSchDlHqProcCb            *hqP,
6432 RgSchPdcch                 *pdcch,
6433 uint8_t                         tpc
6434 )
6435 #else
6436 static Void rgSCHCmnFillHqPPdcchDciFrmt1B(cell, rbAllocInfo, hqP, pdcch, tpc)
6437 RgSchCellCb                *cell;
6438 RgSchDlRbAlloc             *rbAllocInfo;
6439 RgSchDlHqProcCb            *hqP;
6440 RgSchPdcch                 *pdcch;
6441 uint8_t                         tpc;
6442 #endif
6443 {
6444
6445 #ifdef LTE_TDD
6446    RgSchTddANInfo     *anInfo;
6447 #endif
6448
6449 #ifdef LTEMAC_SPS
6450    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6451 #endif
6452
6453
6454     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6455     pdcch->dci.u.format1bInfo.tpcCmd  = tpc;
6456     pdcch->dci.u.format1bInfo.allocInfo.mcs     = \
6457            rbAllocInfo->tbInfo[0].imcs;
6458 #ifdef LTEMAC_SPS
6459     if ((!(hqP->tbInfo[0].txCntr)) &&
6460        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6461          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6462          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6463        ))
6464     {
6465        pdcch->dci.u.format1bInfo.allocInfo.harqProcId = 0;
6466     }
6467     else
6468     {
6469       pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
6470     }
6471 #else
6472     pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId;
6473 #endif
6474     pdcch->dci.u.format1bInfo.allocInfo.ndi     = \
6475           rbAllocInfo->tbInfo[0].tbCb->ndi;
6476     pdcch->dci.u.format1bInfo.allocInfo.rv      = \
6477            rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6478          /* As of now, we do not support Distributed allocations */
6479     pdcch->dci.u.format1bInfo.allocInfo.isLocal = TRUE;
6480     pdcch->dci.u.format1bInfo.allocInfo.nGap2.pres = NOTPRSNT;
6481     pdcch->dci.u.format1bInfo.allocInfo.alloc.type =
6482             TFU_ALLOC_TYPE_RIV;
6483     pdcch->dci.u.format1bInfo.allocInfo.alloc.u.riv =
6484     rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw,
6485                   rbAllocInfo->allocInfo.raType2.rbStart,
6486                   rbAllocInfo->allocInfo.raType2.numRb);
6487          /* Fill precoding Info */
6488     pdcch->dci.u.format1bInfo.allocInfo.pmiCfm = \
6489                rbAllocInfo->mimoAllocInfo.precIdxInfo >> 4;
6490     pdcch->dci.u.format1bInfo.allocInfo.tPmi   = \
6491                rbAllocInfo->mimoAllocInfo.precIdxInfo & 0x0F;
6492 #ifdef LTE_TDD
6493     if(hqP->hqE->ue != NULLP)
6494     {
6495 #ifdef LTE_ADV
6496        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6497                                         hqP->hqE->cell->cellId,
6498                                         hqP->hqE->ue);
6499        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6500              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6501 #else
6502        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6503              &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6504 #endif
6505 #ifdef TFU_TDD
6506        if(anInfo)
6507        {
6508           pdcch->dci.u.format1bInfo.dai = 
6509                          RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6510        }
6511        else
6512        {
6513           pdcch->dci.u.format1bInfo.dai = RG_SCH_MAX_DAI_IDX;
6514           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6515                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6516                    rbAllocInfo->rnti);
6517        }
6518 #endif
6519     }
6520 #endif
6521        
6522     return;
6523
6524 }
6525 /**
6526  * @brief This function fills the PDCCH DCI format 2 information from dlProc.
6527  *
6528  * @details
6529  *
6530  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2
6531  *     Purpose:  This function fills in the PDCCH information
6532  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6533  *               for dedicated service scheduling. It also
6534  *               obtains TPC to be filled in from the power module.
6535  *               Assign the PDCCH to HQProc.
6536  *
6537  *     Invoked by: Downlink Scheduler
6538  *
6539  *  @param[in]  RgSchCellCb*      cell
6540  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6541  *  @param[in]  RgDlHqProc*       hqP
6542  *  @param[out]  RgSchPdcch        *pdcch
6543  *  @param[in]   uint8_t               tpc
6544  *  @return  Void
6545  *
6546  **/
6547 #ifdef ANSI
6548 static Void rgSCHCmnFillHqPPdcchDciFrmt2
6549 (
6550 RgSchCellCb                *cell,
6551 RgSchDlRbAlloc             *rbAllocInfo,
6552 RgSchDlHqProcCb            *hqP,
6553 RgSchPdcch                 *pdcch,
6554 uint8_t                         tpc
6555 )
6556 #else
6557 static Void rgSCHCmnFillHqPPdcchDciFrmt2(cell, rbAllocInfo, hqP, pdcch, tpc)
6558 RgSchCellCb                *cell;
6559 RgSchDlRbAlloc             *rbAllocInfo;
6560 RgSchDlHqProcCb            *hqP;
6561 RgSchPdcch                 *pdcch;
6562 uint8_t                         tpc;
6563 #endif
6564 {
6565
6566 #ifdef LTE_TDD
6567    RgSchTddANInfo     *anInfo;
6568 #endif
6569
6570 #ifdef LTEMAC_SPS
6571 /* ccpu00119023-ADD-For activation or reactivation,
6572  * Harq ProcId should be 0 */
6573    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6574 #endif
6575
6576
6577     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6578     /*ccpu00120365:-ADD-call also if tb is disabled */
6579     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6580         rbAllocInfo->tbInfo[1].isDisabled)
6581     {
6582         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6583     }
6584     pdcch->dci.u.format2Info.tpcCmd = tpc;
6585          /* Avoiding this check,as we dont support Type1 RA */
6586 #ifdef RG_UNUSED
6587     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6588     {
6589 #endif
6590         pdcch->dci.u.format2Info.allocInfo.isAllocType0 = TRUE;
6591         pdcch->dci.u.format2Info.allocInfo.resAllocMap[0] =
6592           ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6593                & 0xff);
6594         pdcch->dci.u.format2Info.allocInfo.resAllocMap[1] =
6595            ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6596                & 0x00ff);
6597         pdcch->dci.u.format2Info.allocInfo.resAllocMap[2] =
6598                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6599                 & 0x0000ff);
6600         pdcch->dci.u.format2Info.allocInfo.resAllocMap[3] =
6601                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6602 #ifdef RG_UNUSED
6603     }
6604 #endif
6605 #ifdef LTEMAC_SPS
6606     if ((!(hqP->tbInfo[0].txCntr)) &&
6607        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6608          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6609          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6610        ))
6611     {
6612        pdcch->dci.u.format2Info.allocInfo.harqProcId = 0;
6613     }
6614     else
6615     {
6616       pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6617     }
6618 #else
6619      pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId;
6620 #endif
6621          /* Initialize the TB info for both the TBs */
6622      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].mcs = 0;
6623      pdcch->dci.u.format2Info.allocInfo.tbInfo[0].rv  = 1;
6624      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].mcs = 0;
6625      pdcch->dci.u.format2Info.allocInfo.tbInfo[1].rv  = 1;
6626          /* Fill tbInfo for scheduled TBs */
6627      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6628         tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6629      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6630         tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6631      pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6632             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6633           /* If we reach this function. It is safely assumed that
6634            *  rbAllocInfo->tbInfo[0] always has non default valid values.
6635            *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6636      if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6637      {
6638             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6639                 tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6640             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6641                 tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6642             pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6643                 tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6644      }
6645      pdcch->dci.u.format2Info.allocInfo.transSwap =
6646              rbAllocInfo->mimoAllocInfo.swpFlg;
6647      pdcch->dci.u.format2Info.allocInfo.precoding =
6648              rbAllocInfo->mimoAllocInfo.precIdxInfo;
6649 #ifdef LTE_TDD
6650      if(hqP->hqE->ue != NULLP)
6651      {
6652
6653 #ifdef LTE_ADV
6654         uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6655                                         hqP->hqE->cell->cellId,
6656                                         hqP->hqE->ue);
6657         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6658                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6659 #else
6660         anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6661                            &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6662 #endif
6663 #ifdef TFU_TDD
6664         if(anInfo)
6665         {
6666            pdcch->dci.u.format2Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6667         }
6668         else
6669         {
6670            pdcch->dci.u.format2Info.dai = RG_SCH_MAX_DAI_IDX;
6671            RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6672                     "PDCCH is been scheduled without updating anInfo RNTI:%d",
6673                     rbAllocInfo->rnti);
6674         }
6675 #endif
6676      }
6677 #endif
6678
6679      return;
6680 }
6681 /**
6682  * @brief This function fills the PDCCH DCI format 2A information from dlProc.
6683  *
6684  * @details
6685  *
6686  *     Function: rgSCHCmnFillHqPPdcchDciFrmt2A
6687  *     Purpose:  This function fills in the PDCCH information
6688  *               obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc
6689  *               for dedicated service scheduling. It also
6690  *               obtains TPC to be filled in from the power module.
6691  *               Assign the PDCCH to HQProc.
6692  *
6693  *     Invoked by: Downlink Scheduler
6694  *
6695  *  @param[in]  RgSchCellCb*      cell
6696  *  @param[in]  RgSchDlRbAlloc*   rbAllocInfo
6697  *  @param[in]  RgDlHqProc*       hqP
6698  *  @param[out]  RgSchPdcch        *pdcch
6699  *  @param[in]   uint8_t               tpc
6700  *  @return  Void
6701  *
6702  **/
6703 #ifdef ANSI
6704 static Void rgSCHCmnFillHqPPdcchDciFrmt2A
6705 (
6706 RgSchCellCb                *cell,
6707 RgSchDlRbAlloc             *rbAllocInfo,
6708 RgSchDlHqProcCb            *hqP,
6709 RgSchPdcch                 *pdcch,
6710 uint8_t                         tpc
6711 )
6712 #else
6713 static Void rgSCHCmnFillHqPPdcchDciFrmt2A(cell, rbAllocInfo, hqP, pdcch, tpc)
6714 RgSchCellCb                *cell;
6715 RgSchDlRbAlloc             *rbAllocInfo;
6716 RgSchDlHqProcCb            *hqP;
6717 RgSchPdcch                 *pdcch;
6718 uint8_t                         tpc;
6719 #endif
6720 {
6721 #ifdef LTE_TDD
6722    RgSchTddANInfo     *anInfo;
6723 #endif
6724
6725 #ifdef LTEMAC_SPS
6726    RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
6727 #endif
6728
6729
6730     rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch);
6731     /*ccpu00120365:-ADD-call also if tb is disabled */
6732     if (rbAllocInfo->tbInfo[1].schdlngForTb ||
6733           rbAllocInfo->tbInfo[1].isDisabled)
6734     {
6735
6736         rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch);
6737     }
6738
6739     pdcch->dci.u.format2AInfo.tpcCmd = tpc;
6740          /* Avoiding this check,as we dont support Type1 RA */
6741 #ifdef RG_UNUSED
6742     if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
6743     {
6744 #endif
6745         pdcch->dci.u.format2AInfo.allocInfo.isAllocType0 = TRUE;
6746         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[0] =
6747               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24)
6748                & 0xff);
6749         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[1] =
6750               ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16)
6751                & 0x00ff);
6752         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[2] =
6753                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8)
6754                 & 0x0000ff);
6755         pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[3] =
6756                ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff));
6757 #ifdef RG_UNUSED
6758     }
6759 #endif
6760 #ifdef LTEMAC_SPS
6761     if ((!(hqP->tbInfo[0].txCntr)) &&
6762        ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP  &&
6763          ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) ||
6764          (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))
6765        ))
6766     {
6767        pdcch->dci.u.format2AInfo.allocInfo.harqProcId = 0;
6768     }
6769     else
6770     {
6771       pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6772     }
6773 #else
6774     pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId;
6775 #endif
6776          /* Initialize the TB info for both the TBs */
6777     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].mcs = 0;
6778     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].rv  = 1;
6779     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].mcs = 0;
6780     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].rv  = 1;
6781          /* Fill tbInfo for scheduled TBs */
6782     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6783             tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi;
6784     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6785             tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs;
6786     pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\
6787             tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv;
6788          /* If we reach this function. It is safely assumed that
6789           *  rbAllocInfo->tbInfo[0] always has non default valid values.
6790           *  rbAllocInfo->tbInfo[1]'s scheduling is optional */
6791
6792     if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE)
6793     {
6794             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6795                tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi;
6796             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6797                tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs;
6798             pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\
6799                tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv;
6800
6801     }
6802     pdcch->dci.u.format2AInfo.allocInfo.transSwap =
6803             rbAllocInfo->mimoAllocInfo.swpFlg;
6804     pdcch->dci.u.format2AInfo.allocInfo.precoding =
6805             rbAllocInfo->mimoAllocInfo.precIdxInfo;
6806 #ifdef LTE_TDD
6807     if(hqP->hqE->ue != NULLP)
6808     {
6809 #ifdef LTE_ADV
6810        uint8_t servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
6811                                         hqP->hqE->cell->cellId,
6812                                         hqP->hqE->ue);
6813        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6814                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx);
6815 #else
6816        anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue,
6817                          &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0);
6818 #endif
6819 #ifdef TFU_TDD
6820        if(anInfo)
6821        {
6822           pdcch->dci.u.format2AInfo.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai);
6823        }
6824        else
6825        {
6826           pdcch->dci.u.format2AInfo.dai = RG_SCH_MAX_DAI_IDX;
6827           RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6828                    "PDCCH is been scheduled without updating anInfo RNTI:%d",
6829                    rbAllocInfo->rnti);
6830        }
6831 #endif
6832      }
6833 #endif
6834
6835
6836     return;
6837 }
6838 #endif
6839 /**
6840  * @brief init of Sch vars.
6841  *
6842  * @details
6843  *
6844  *     Function: rgSCHCmnInitVars
6845        Purpose:  Initialization of various UL subframe indices
6846  *
6847  *  @param[in]  RgSchCellCb *cell
6848  *  @return  Void
6849  *
6850  **/
6851 #ifdef ANSI
6852 static Void rgSCHCmnInitVars
6853 (
6854 RgSchCellCb *cell
6855 )
6856 #else
6857 static Void rgSCHCmnInitVars(cell)
6858 RgSchCellCb *cell;
6859 #endif
6860 {
6861    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6862
6863
6864    cellUl->idx         = RGSCH_INVALID_INFO;
6865    cellUl->schdIdx     = RGSCH_INVALID_INFO;
6866    cellUl->schdHqProcIdx = RGSCH_INVALID_INFO;
6867    cellUl->msg3SchdIdx = RGSCH_INVALID_INFO;
6868 #ifdef EMTC_ENBLE
6869    cellUl->emtcMsg3SchdIdx = RGSCH_INVALID_INFO;
6870 #endif
6871    cellUl->msg3SchdHqProcIdx = RGSCH_INVALID_INFO;
6872    cellUl->rcpReqIdx   = RGSCH_INVALID_INFO;
6873    cellUl->hqFdbkIdx[0] = RGSCH_INVALID_INFO;
6874    cellUl->hqFdbkIdx[1] = RGSCH_INVALID_INFO;
6875    cellUl->reTxIdx[0]   = RGSCH_INVALID_INFO;
6876    cellUl->reTxIdx[1]   = RGSCH_INVALID_INFO;
6877   /* Stack Crash problem for TRACE5 Changes. Added the return below */
6878   return;
6879
6880 }
6881
6882 #ifndef LTE_TDD
6883 /**
6884  * @brief Updation of Sch vars per TTI.
6885  *
6886  * @details
6887  *
6888  *     Function: rgSCHCmnUpdVars
6889  *     Purpose:  Updation of Sch vars per TTI.
6890  *
6891  *  @param[in]  RgSchCellCb *cell
6892  *  @return  Void
6893  *
6894  **/
6895 #ifdef ANSI
6896 Void rgSCHCmnUpdVars
6897 (
6898 RgSchCellCb *cell
6899 )
6900 #else
6901 Void rgSCHCmnUpdVars(cell)
6902 RgSchCellCb *cell;
6903 #endif
6904 {
6905    CmLteTimingInfo   timeInfo;
6906    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6907    uint16_t idx;
6908
6909
6910    idx = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot);
6911    cellUl->idx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6912 #ifdef UL_ADPT_DBG     
6913    printf("idx %d cellUl->idx  %d RGSCH_NUM_SUB_FRAMES_5G %d  time(%d %d) \n",idx,cellUl->idx ,RGSCH_NUM_SUB_FRAMES_5G,cell->crntTime.sfn,cell->crntTime.slot);
6914 #endif    
6915    /* Need to scheduler for after SCHED_DELTA */
6916    /* UL allocation has been advanced by 1 subframe
6917     * so that we do not wrap around and send feedback
6918     * before the data is even received by the PHY */
6919    /* Introduced timing delta for UL control */
6920    idx = (cellUl->idx + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA);
6921    cellUl->schdIdx     = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6922
6923    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6924             TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)
6925    cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6926
6927    /* ccpu00127193 filling schdTime for logging and enhancement purpose*/
6928    cellUl->schdTime = timeInfo;
6929
6930    /* msg3 scheduling two subframes after general scheduling */
6931    idx = (cellUl->idx + RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA);
6932    cellUl->msg3SchdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6933
6934    RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,
6935             RG_SCH_CMN_DL_DELTA+ RGSCH_RARSP_MSG3_DELTA)
6936    cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
6937
6938    idx = (cellUl->idx + TFU_RECPREQ_DLDELTA);
6939
6940    cellUl->rcpReqIdx   = ((idx) % (RG_SCH_CMN_UL_NUM_SF));
6941
6942    /* Downlink harq feedback is sometime after data reception / harq failure */
6943    /* Since feedback happens prior to scheduling being called, we add 1 to   */
6944    /* take care of getting the correct subframe for feedback                 */
6945    idx = (cellUl->idx - TFU_CRCIND_ULDELTA + RG_SCH_CMN_UL_NUM_SF);
6946 #ifdef UL_ADPT_DBG     
6947    printf("Finally setting cellUl->hqFdbkIdx[0] = %d TFU_CRCIND_ULDELTA %d RG_SCH_CMN_UL_NUM_SF %d\n",idx,TFU_CRCIND_ULDELTA,RG_SCH_CMN_UL_NUM_SF);
6948 #endif
6949    cellUl->hqFdbkIdx[0]   = (idx % (RG_SCH_CMN_UL_NUM_SF));
6950
6951    idx = ((cellUl->schdIdx) % (RG_SCH_CMN_UL_NUM_SF));
6952
6953    cellUl->reTxIdx[0] = (uint8_t) idx;
6954 #ifdef UL_ADPT_DBG     
6955    printf("cellUl->hqFdbkIdx[0] %d cellUl->reTxIdx[0] %d \n",cellUl->hqFdbkIdx[0], cellUl->reTxIdx[0] );
6956 #endif
6957    /* RACHO: update cmn sched specific RACH variables,
6958     * mainly the prachMaskIndex */
6959    rgSCHCmnUpdRachParam(cell);
6960
6961    return;
6962 }
6963 #endif
6964
6965 #ifdef LTE_TDD
6966
6967 /**
6968  * @brief To get uplink subframe index associated with current PHICH
6969  *        transmission.
6970  *
6971  * @details
6972  *
6973  *     Function: rgSCHCmnGetPhichUlSfIdx
6974  *     Purpose:  Gets uplink subframe index associated with current PHICH
6975  *               transmission based on SFN and subframe no
6976  *
6977  *  @param[in]  CmLteTimingInfo  *timeInfo
6978  *  @param[in]  RgSchCellCb              *cell
6979  *  @return uint8_t
6980  *
6981  **/
6982 #ifdef ANSI
6983 uint8_t  rgSCHCmnGetPhichUlSfIdx
6984 (
6985 CmLteTimingInfo *timeInfo,
6986 RgSchCellCb *cell
6987 )
6988 #else
6989 uint8_t  rgSCHCmnGetPhichUlSfIdx(timeInfo, cell)
6990 CmLteTimingInfo *timeInfo;
6991 RgSchCellCb        *cell;
6992 #endif
6993 {
6994    RgSchCmnUlCell       *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
6995    RgSchDlSf            *dlsf;
6996    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
6997    uint8_t                   idx;
6998    uint16_t                  numUlSf;
6999    uint16_t                  sfn;
7000    uint8_t                   subframe;
7001
7002
7003    dlsf = rgSCHUtlSubFrmGet(cell, *timeInfo);
7004
7005    if(dlsf->phichOffInfo.sfnOffset == RGSCH_INVALID_INFO)
7006    {
7007       return (RGSCH_INVALID_INFO);
7008    }
7009    subframe = dlsf->phichOffInfo.subframe;
7010
7011    sfn = (RGSCH_MAX_SFN + timeInfo->sfn -
7012                    dlsf->phichOffInfo.sfnOffset) % RGSCH_MAX_SFN;
7013
7014    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
7015     * wrap case such that idx will be proper*/
7016    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7017    numUlSf = ((numUlSf * sfn) + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subframe]) - 1;
7018    idx = numUlSf % (cellUl->numUlSubfrms);
7019
7020    return (idx);
7021 }
7022
7023 /**
7024  * @brief To get uplink subframe index.
7025  *
7026  * @details
7027  *
7028  *
7029  *     Function: rgSCHCmnGetUlSfIdx
7030  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
7031  *
7032  *  @param[in]  CmLteTimingInfo  *timeInfo
7033  *  @param[in]  uint8_t               ulDlCfgIdx
7034  *  @return uint8_t
7035  *
7036  **/
7037 #ifdef ANSI
7038 uint8_t  rgSCHCmnGetUlSfIdx
7039 (
7040 CmLteTimingInfo *timeInfo,
7041 RgSchCellCb *cell
7042 )
7043 #else
7044 uint8_t  rgSCHCmnGetUlSfIdx(timeInfo, cell)
7045 CmLteTimingInfo *timeInfo;
7046 RgSchCellCb *cell;
7047 #endif
7048 {
7049    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
7050    uint8_t                ulDlCfgIdx = cell->ulDlCfgIdx;
7051    uint8_t                idx = 0;
7052    uint16_t               numUlSf;
7053
7054
7055    /* ccpu00130980: numUlSf(uint16_t) parameter added to avoid integer
7056     * wrap case such that idx will be proper*/
7057    numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7058    numUlSf = ((numUlSf * timeInfo->sfn) + \
7059          rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe]) - 1;
7060    idx = numUlSf % (cellUl->numUlSubfrms);
7061
7062    return (idx);
7063 }
7064
7065 #endif
7066
7067 /**
7068  * @brief To get uplink hq index.
7069  *
7070  * @details
7071  *
7072  *
7073  *     Function: rgSCHCmnGetUlHqProcIdx
7074  *     Purpose:  Gets uplink subframe index based on SFN and subframe number.
7075  *
7076  *  @param[in]  CmLteTimingInfo  *timeInfo
7077  *  @param[in]  uint8_t               ulDlCfgIdx
7078  *  @return uint8_t
7079  *
7080  **/
7081 #ifdef ANSI
7082 uint8_t  rgSCHCmnGetUlHqProcIdx
7083 (
7084 CmLteTimingInfo *timeInfo,
7085 RgSchCellCb *cell
7086 )
7087 #else
7088 uint8_t  rgSCHCmnGetUlHqProcIdx(timeInfo, cell)
7089 CmLteTimingInfo *timeInfo;
7090 RgSchCellCb *cell;
7091 #endif
7092 {
7093    uint8_t            procId;
7094    uint32_t           numUlSf;
7095   
7096 #ifndef LTE_TDD
7097    numUlSf  = (timeInfo->sfn * RGSCH_NUM_SUB_FRAMES_5G + timeInfo->slot);
7098    procId   = numUlSf % RGSCH_NUM_UL_HQ_PROC;
7099 #else
7100    uint8_t            ulDlCfgIdx = cell->ulDlCfgIdx;
7101    /*ccpu00130639 - MOD - To get correct UL HARQ Proc IDs for all UL/DL Configs*/
7102    uint8_t            numUlSfInSfn;
7103    S8            sfnCycle = cell->tddHqSfnCycle;
7104    uint8_t            numUlHarq = rgSchTddUlNumHarqProcTbl[ulDlCfgIdx]
7105
7106    /* TRACE 5 Changes */
7107
7108    /* Calculate the number of UL SF in one SFN */
7109    numUlSfInSfn = RGSCH_NUM_SUB_FRAMES -
7110                rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7111
7112    /* Check for the SFN wrap around case */
7113    if(cell->crntTime.sfn == 1023 && timeInfo->sfn == 0)
7114    {
7115       sfnCycle++;
7116    }
7117    else if(cell->crntTime.sfn == 0 && timeInfo->sfn == 1023)
7118    {
7119       /* sfnCycle decremented by 1 */
7120       sfnCycle = (sfnCycle + numUlHarq-1) % numUlHarq;
7121    }
7122    /* Calculate the total number of UL sf */
7123    /*  -1 is done since uplink sf are counted from 0 */
7124    numUlSf = numUlSfInSfn *  (timeInfo->sfn + (sfnCycle*1024)) +
7125                   rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->slot] - 1;
7126
7127    procId = numUlSf % numUlHarq;   
7128 #endif
7129    return (procId);
7130 }
7131
7132
7133 /* UL_ALLOC_CHANGES */
7134 /***********************************************************
7135  *
7136  *     Func : rgSCHCmnUlFreeAlloc
7137  *
7138  *     Desc : Free an allocation - invokes UHM and releases
7139  *            alloc for the scheduler
7140  *            Doest need subframe as argument
7141  *
7142  *     Ret  :
7143  *
7144  *     Notes:
7145  *
7146  *     File :
7147  *
7148  **********************************************************/
7149 #ifdef ANSI
7150 Void rgSCHCmnUlFreeAlloc
7151 (
7152 RgSchCellCb     *cell,
7153 RgSchUlAlloc    *alloc
7154 )
7155 #else
7156 Void rgSCHCmnUlFreeAlloc(cell, alloc)
7157 RgSchCellCb     *cell;
7158 RgSchUlAlloc    *alloc;
7159 #endif
7160 {
7161    RgSchUlHqProcCb *hqProc;
7162
7163    if (alloc->forMsg3)
7164    {
7165       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
7166       if ((alloc->hqProc->remTx == 0) &&
7167           (alloc->hqProc->rcvdCrcInd == FALSE) &&
7168           (alloc->raCb))
7169       {
7170          RgSchRaCb      *raCb = alloc->raCb;
7171          rgSCHUhmFreeProc(alloc->hqProc, cell);
7172          rgSCHUtlUlAllocRelease(alloc);
7173          rgSCHRamDelRaCb(cell, raCb, TRUE);
7174          return;
7175       }
7176    }
7177    
7178    hqProc = alloc->hqProc;
7179    rgSCHUtlUlAllocRelease(alloc);
7180    rgSCHUhmFreeProc(hqProc, cell);
7181    return;
7182 }
7183
7184
7185 /***********************************************************
7186  *
7187  *     Func : rgSCHCmnUlFreeAllocation
7188  *
7189  *     Desc : Free an allocation - invokes UHM and releases
7190  *            alloc for the scheduler
7191  *
7192  *     Ret  :
7193  *
7194  *     Notes:
7195  *
7196  *     File :
7197  *
7198  **********************************************************/
7199 #ifdef ANSI
7200 Void rgSCHCmnUlFreeAllocation
7201 (
7202 RgSchCellCb     *cell,
7203 RgSchUlSf       *sf,
7204 RgSchUlAlloc    *alloc
7205 )
7206 #else
7207 Void rgSCHCmnUlFreeAllocation(cell, sf, alloc)
7208 RgSchCellCb     *cell;
7209 RgSchUlSf       *sf;
7210 RgSchUlAlloc    *alloc;
7211 #endif
7212 {
7213    RgSchUlHqProcCb *hqProc;
7214
7215
7216    if (alloc->forMsg3)
7217    {
7218       /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */
7219       if ((alloc->hqProc->remTx == 0) &&
7220           (alloc->hqProc->rcvdCrcInd == FALSE) &&
7221           (alloc->raCb))
7222       {
7223          RgSchRaCb      *raCb = alloc->raCb;
7224          rgSCHUhmFreeProc(alloc->hqProc, cell);
7225          rgSCHUtlUlAllocRls(sf, alloc);
7226          rgSCHRamDelRaCb(cell, raCb, TRUE);
7227          return;
7228       }
7229    }
7230    
7231    hqProc = alloc->hqProc;
7232    rgSCHUhmFreeProc(hqProc, cell);
7233 #ifdef LTE_L2_MEAS
7234    /* re-setting the PRB count while freeing the allocations */
7235    sf->totPrb = 0;
7236 #endif
7237    rgSCHUtlUlAllocRls(sf, alloc);
7238
7239    return;
7240 }
7241
7242 /**
7243  * @brief This function implements PDCCH allocation for an UE
7244  *        in the currently running subframe.
7245  *
7246  * @details
7247  *
7248  *     Function: rgSCHCmnPdcchAllocCrntSf
7249  *     Purpose:  This function determines current DL subframe
7250  *               and UE DL CQI to call the actual pdcch allocator
7251  *               function.
7252  *               Note that this function is called only
7253  *               when PDCCH request needs to be made during
7254  *               uplink scheduling.
7255  *
7256  *     Invoked by: Scheduler
7257  *
7258  *  @param[in]  RgSchCellCb  *cell
7259  *  @param[in]  RgSchUeCb    *ue
7260  *  @return  RgSchPdcch *
7261  *         -# NULLP when unsuccessful
7262  **/
7263 #ifdef ANSI
7264 RgSchPdcch *rgSCHCmnPdcchAllocCrntSf
7265 (
7266 RgSchCellCb                *cell,
7267 RgSchUeCb                  *ue
7268 )
7269 #else
7270 RgSchPdcch *rgSCHCmnPdcchAllocCrntSf(cell, ue)
7271 RgSchCellCb                *cell;
7272 RgSchUeCb                  *ue;
7273 #endif
7274 {
7275    CmLteTimingInfo      frm = cell->crntTime;
7276    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7277    RgSchDlSf            *sf;
7278    RgSchPdcch           *pdcch = NULLP;
7279
7280    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
7281    sf = rgSCHUtlSubFrmGet(cell, frm);
7282
7283 #ifdef LTE_ADV
7284    if (ue->allocCmnUlPdcch)
7285    {
7286       pdcch = rgSCHCmnCmnPdcchAlloc(cell, sf);
7287       /* Since CRNTI Scrambled */
7288       if(NULLP != pdcch)
7289       {
7290          pdcch->dciNumOfBits = ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
7291       }
7292    }
7293    else
7294 #endif
7295    {
7296       //pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, y, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_0, FALSE);
7297                 pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_A1, FALSE);
7298    }
7299    return (pdcch);
7300 }
7301
7302 /***********************************************************
7303  *
7304  *     Func : rgSCHCmnUlAllocFillNdmrs
7305  *
7306  *     Desc : Determines and fills N_dmrs for a UE uplink
7307  *            allocation.
7308  *
7309  *     Ret  :
7310  *
7311  *     Notes: N_dmrs determination is straightforward, so
7312  *            it is configured per subband
7313  *
7314  *     File :
7315  *
7316  **********************************************************/
7317 #ifdef ANSI
7318 Void rgSCHCmnUlAllocFillNdmrs
7319 (
7320 RgSchCmnUlCell *cellUl,
7321 RgSchUlAlloc   *alloc
7322 )
7323 #else
7324 Void rgSCHCmnUlAllocFillNdmrs(cellUl, alloc)
7325 RgSchCmnUlCell *cellUl;
7326 RgSchUlAlloc   *alloc;
7327 #endif
7328 {
7329    alloc->grnt.nDmrs = cellUl->dmrsArr[alloc->sbStart];
7330    return;
7331 }
7332
7333 /***********************************************************
7334  *
7335  *     Func : rgSCHCmnUlAllocLnkHqProc
7336  *
7337  *     Desc : Links a new allocation for an UE with the
7338  *            appropriate HARQ process of the UE.
7339  *
7340  *     Ret  :
7341  *
7342  *     Notes:
7343  *
7344  *     File :
7345  *
7346  **********************************************************/
7347 #ifdef ANSI
7348 Void rgSCHCmnUlAllocLnkHqProc
7349 (
7350 RgSchUeCb       *ue,
7351 RgSchUlAlloc    *alloc,
7352 RgSchUlHqProcCb *proc,
7353 Bool            isRetx
7354 )
7355 #else
7356 Void rgSCHCmnUlAllocLnkHqProc(ue, alloc, proc, isRetx)
7357 RgSchUeCb       *ue;
7358 RgSchUlAlloc    *alloc;
7359 RgSchUlHqProcCb *proc;
7360 Bool            isRetx;
7361 #endif
7362 {
7363
7364    if(TRUE == isRetx)
7365    {
7366       rgSCHCmnUlAdapRetx(alloc, proc);
7367    }
7368    else
7369    {
7370 #ifdef LTE_L2_MEAS /* L2_COUNTERS */
7371       alloc->ue = ue;
7372 #endif
7373       rgSCHUhmNewTx(proc, (((RgUeUlHqCb*)proc->hqEnt)->maxHqRetx), alloc);
7374    }
7375    return;
7376 }
7377
7378 /**
7379  * @brief This function releases a PDCCH in the subframe that is
7380  *        currently being allocated for.
7381  *
7382  * @details
7383  *
7384  *     Function: rgSCHCmnPdcchRlsCrntSf
7385  *     Purpose:  This function determines current DL subframe
7386  *               which is considered for PDCCH allocation,
7387  *               and then calls the actual function that
7388  *               releases a PDCCH in a specific subframe.
7389  *               Note that this function is called only
7390  *               when PDCCH release needs to be made during
7391  *               uplink scheduling.
7392  *
7393  *     Invoked by: Scheduler
7394  *
7395  *  @param[in]  RgSchCellCb  *cell
7396  *  @param[in]  RgSchPdcch   *pdcch
7397  *  @return  Void
7398  **/
7399 #ifdef ANSI
7400 Void rgSCHCmnPdcchRlsCrntSf
7401 (
7402 RgSchCellCb                *cell,
7403 RgSchPdcch                 *pdcch
7404 )
7405 #else
7406 Void rgSCHCmnPdcchRlsCrntSf(cell, pdcch)
7407 RgSchCellCb                *cell;
7408 RgSchPdcch                 *pdcch;
7409 #endif
7410 {
7411    CmLteTimingInfo      frm = cell->crntTime;
7412    RgSchDlSf               *sf;
7413
7414
7415    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
7416    sf = rgSCHUtlSubFrmGet(cell, frm);
7417    rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, pdcch);
7418    return;
7419 }
7420 /***********************************************************
7421  *
7422  *     Func : rgSCHCmnUlFillPdcchWithAlloc
7423  *
7424  *     Desc : Fills a PDCCH with format 0 information.
7425  *
7426  *     Ret  :
7427  *
7428  *     Notes:
7429  *
7430  *     File :
7431  *
7432  **********************************************************/
7433 #ifdef ANSI
7434 Void rgSCHCmnUlFillPdcchWithAlloc
7435 (
7436 RgSchPdcch      *pdcch,
7437 RgSchUlAlloc    *alloc,
7438 RgSchUeCb       *ue
7439 )
7440 #else
7441 Void rgSCHCmnUlFillPdcchWithAlloc(pdcch, alloc, ue)
7442 RgSchPdcch      *pdcch;
7443 RgSchUlAlloc    *alloc;
7444 RgSchUeCb       *ue;
7445 #endif
7446 {
7447
7448
7449    pdcch->ue = ue;
7450    pdcch->rnti = alloc->rnti;
7451    //pdcch->dci.dciFormat = TFU_DCI_FORMAT_A2;
7452    pdcch->dci.dciFormat = alloc->grnt.dciFrmt;
7453
7454    //Currently hardcoding values here.
7455    //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti);
7456    switch(pdcch->dci.dciFormat)
7457    {
7458       case TFU_DCI_FORMAT_A1:
7459                 {
7460                         pdcch->dci.u.formatA1Info.formatType = 0;
7461          pdcch->dci.u.formatA1Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
7462          pdcch->dci.u.formatA1Info.xPUSCH_TxTiming = 0;
7463          pdcch->dci.u.formatA1Info.RBAssign = alloc->grnt.rbAssign;
7464          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
7465          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
7466          pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
7467          pdcch->dci.u.formatA1Info.CSI_BSI_BRI_Req = 0;
7468          pdcch->dci.u.formatA1Info.CSIRS_BRRS_TxTiming = 0;
7469          pdcch->dci.u.formatA1Info.CSIRS_BRRS_SymbIdx = 0;
7470          pdcch->dci.u.formatA1Info.CSIRS_BRRS_ProcInd = 0;
7471          pdcch->dci.u.formatA1Info.numBSI_Reports = 0;
7472          pdcch->dci.u.formatA1Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
7473          pdcch->dci.u.formatA1Info.beamSwitch  = 0;
7474          pdcch->dci.u.formatA1Info.SRS_Config = 0;
7475          pdcch->dci.u.formatA1Info.SRS_Symbol = 0;
7476          pdcch->dci.u.formatA1Info.REMapIdx_DMRS_PCRS_numLayers = 0;
7477          pdcch->dci.u.formatA1Info.SCID = alloc->grnt.SCID;
7478          pdcch->dci.u.formatA1Info.PMI = alloc->grnt.PMI;
7479          pdcch->dci.u.formatA1Info.UL_PCRS = 0;
7480          pdcch->dci.u.formatA1Info.tpcCmd = alloc->grnt.tpc;
7481                         break;
7482       }
7483                 case TFU_DCI_FORMAT_A2:
7484                 {
7485                         pdcch->dci.u.formatA2Info.formatType = 1;
7486          pdcch->dci.u.formatA2Info.xPUSCHRange = alloc->grnt.xPUSCHRange;
7487          pdcch->dci.u.formatA2Info.xPUSCH_TxTiming = 0;
7488          pdcch->dci.u.formatA2Info.RBAssign = alloc->grnt.rbAssign;
7489          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId;
7490          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt;
7491          pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi;
7492          pdcch->dci.u.formatA2Info.CSI_BSI_BRI_Req = 0;
7493          pdcch->dci.u.formatA2Info.CSIRS_BRRS_TxTiming = 0;
7494          pdcch->dci.u.formatA2Info.CSIRS_BRRS_SymbIdx = 0;
7495          pdcch->dci.u.formatA2Info.CSIRS_BRRS_ProcInd = 0;
7496          pdcch->dci.u.formatA2Info.numBSI_Reports = 0;
7497          pdcch->dci.u.formatA2Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH;
7498          pdcch->dci.u.formatA2Info.beamSwitch  = 0;
7499          pdcch->dci.u.formatA2Info.SRS_Config = 0;
7500          pdcch->dci.u.formatA2Info.SRS_Symbol = 0;
7501          pdcch->dci.u.formatA2Info.REMapIdx_DMRS_PCRS_numLayers = 0;
7502          pdcch->dci.u.formatA2Info.SCID = alloc->grnt.SCID;
7503          pdcch->dci.u.formatA2Info.PMI = alloc->grnt.PMI;
7504          pdcch->dci.u.formatA2Info.UL_PCRS = 0;
7505          pdcch->dci.u.formatA2Info.tpcCmd = alloc->grnt.tpc;
7506                         break;
7507                 }
7508       default:
7509          RLOG1(L_ERROR," 5GTF_ERROR UL Allocator's icorrect "
7510                "dciForamt Fill RNTI:%d",alloc->rnti);
7511          break;
7512    }    
7513    
7514
7515    return;
7516 }
7517
7518 /***********************************************************
7519  *
7520  *     Func : rgSCHCmnUlAllocFillTpc
7521  *
7522  *     Desc : Determines and fills TPC for an UE allocation.
7523  *
7524  *     Ret  :
7525  *
7526  *     Notes:
7527  *
7528  *     File :
7529  *
7530  **********************************************************/
7531 #ifdef ANSI
7532 Void rgSCHCmnUlAllocFillTpc
7533 (
7534 RgSchCellCb  *cell,
7535 RgSchUeCb    *ue,
7536 RgSchUlAlloc *alloc
7537 )
7538 #else
7539 Void rgSCHCmnUlAllocFillTpc(cell, ue, alloc)
7540 RgSchCellCb  *cell;
7541 RgSchUeCb    *ue;
7542 RgSchUlAlloc *alloc;
7543 #endif
7544 {
7545    alloc->grnt.tpc = rgSCHPwrPuschTpcForUe(cell, ue);
7546    return;
7547 }
7548
7549
7550 /***********************************************************
7551  *
7552  *     Func : rgSCHCmnAddUeToRefreshQ
7553  *
7554  *     Desc : Adds a UE to refresh queue, so that the UE is
7555  *            periodically triggered to refresh it's GBR and
7556  *            AMBR values.
7557  *
7558  *     Ret  :
7559  *
7560  *     Notes:
7561  *
7562  *     File :
7563  *
7564  **********************************************************/
7565 #ifdef ANSI
7566 static Void rgSCHCmnAddUeToRefreshQ
7567 (
7568 RgSchCellCb     *cell,
7569 RgSchUeCb       *ue,
7570 uint32_t             wait
7571 )
7572 #else
7573 static Void rgSCHCmnAddUeToRefreshQ(cell, ue, wait)
7574 RgSchCellCb     *cell;
7575 RgSchUeCb       *ue;
7576 uint32_t             wait;
7577 #endif
7578 {
7579    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
7580    CmTmrArg       arg;
7581    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
7582
7583    UNUSED(cell);
7584
7585    memset(&arg, 0, sizeof(arg));
7586    arg.tqCp   = &sched->tmrTqCp;
7587    arg.tq     = sched->tmrTq;
7588    arg.timers = &ueSchd->tmr;
7589    arg.cb     = (PTR)ue;
7590    arg.tNum   = 0;
7591    arg.max    = 1;
7592    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
7593    arg.wait   = wait;
7594    cmPlcCbTq(&arg);
7595    return;
7596 }
7597
7598 /**
7599  * @brief Perform UE reset procedure.
7600  *
7601  * @details
7602  *
7603  *     Function : rgSCHCmnUlUeReset
7604  *
7605  *     This functions performs BSR resetting and
7606  *     triggers UL specific scheduler
7607  *     to Perform UE reset procedure.
7608  *
7609  *  @param[in]  RgSchCellCb  *cell
7610  *  @param[in]  RgSchUeCb    *ue
7611  *  @return  Void
7612  **/
7613 #ifdef ANSI
7614 static Void rgSCHCmnUlUeReset
7615 (
7616 RgSchCellCb  *cell,
7617 RgSchUeCb    *ue
7618 )
7619 #else
7620 static Void rgSCHCmnUlUeReset(cell, ue)
7621 RgSchCellCb  *cell;
7622 RgSchUeCb    *ue;
7623 #endif
7624 {
7625    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7626    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
7627    uint8_t                   lcgCnt=0;
7628    RgSchCmnLcg          *lcgCmn;
7629    CmLList              *node;
7630    RgSchCmnAllocRecord  *allRcd;
7631
7632    ue->ul.minReqBytes = 0;
7633    ue->ul.totalBsr = 0;
7634    ue->ul.effBsr = 0;
7635    ue->ul.nonGbrLcgBs = 0;
7636    ue->ul.effAmbr = ue->ul.cfgdAmbr;
7637
7638    node = ueUl->ulAllocLst.first;
7639    while (node)
7640    {
7641       allRcd = (RgSchCmnAllocRecord *)node->node;
7642       allRcd->alloc = 0;
7643       node = node->next;
7644    }
7645    for(lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++)
7646    {
7647       lcgCmn = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[lcgCnt]);
7648       lcgCmn->bs = 0;
7649       lcgCmn->reportedBs = 0;
7650       lcgCmn->effGbr = lcgCmn->cfgdGbr;
7651       lcgCmn->effDeltaMbr = lcgCmn->deltaMbr;
7652    }
7653    rgSCHCmnUlUeDelAllocs(cell, ue);
7654
7655    ue->isSrGrant = FALSE;
7656
7657    cellSchd->apisUl->rgSCHUlUeReset(cell, ue);
7658
7659    /* Stack Crash problem for TRACE5 changes. Added the return below */
7660    return;
7661
7662 }
7663
7664 /**
7665  * @brief RESET UL CQI and DL CQI&RI to conservative values
7666     * for a reestablishing UE.
7667  *
7668  * @details
7669  *
7670  *     Function : rgSCHCmnResetRiCqi 
7671  *     
7672  *     RESET UL CQI and DL CQI&RI to conservative values
7673  *     for a reestablishing UE
7674  *
7675  *  @param[in]  RgSchCellCb  *cell
7676  *  @param[in]  RgSchUeCb    *ue
7677  *  @return  Void
7678  **/
7679 #ifdef ANSI
7680 static Void rgSCHCmnResetRiCqi 
7681 (
7682 RgSchCellCb  *cell,
7683 RgSchUeCb    *ue
7684 )
7685 #else
7686 static Void rgSCHCmnResetRiCqi(cell, ue)
7687 RgSchCellCb  *cell;
7688 RgSchUeCb    *ue;
7689 #endif
7690 {
7691    RgSchCmnCell  *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7692    RgSchCmnUe    *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
7693    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7694    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
7695
7696
7697    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, 
7698          cell->isCpUlExtend);
7699
7700    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
7701    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
7702    ueDl->mimoInfo.ri = 1;
7703    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
7704           (ue->mimoInfo.txMode == RGR_UE_TM_6))
7705    {
7706       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
7707    }
7708    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
7709    {
7710       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
7711    }
7712 #ifdef EMTC_ENABLE   
7713    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
7714 #else
7715    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
7716 #endif      
7717
7718 #ifdef TFU_UPGRADE
7719    /* Request for an early Aper CQI in case of reest */
7720    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
7721    if(acqiCb && acqiCb->aCqiCfg.pres)
7722    {
7723       acqiCb->aCqiTrigWt = 0;
7724    }
7725 #endif   
7726
7727    return;
7728 }
7729
7730 /**
7731  * @brief Perform UE reset procedure.
7732  *
7733  * @details
7734  *
7735  *     Function : rgSCHCmnDlUeReset
7736  *
7737  *     This functions performs BO resetting and
7738  *     triggers DL specific scheduler
7739  *     to Perform UE reset procedure.
7740  *
7741  *  @param[in]  RgSchCellCb  *cell
7742  *  @param[in]  RgSchUeCb    *ue
7743  *  @return  Void
7744  **/
7745 #ifdef ANSI
7746 static Void rgSCHCmnDlUeReset
7747 (
7748 RgSchCellCb  *cell,
7749 RgSchUeCb    *ue
7750 )
7751 #else
7752 static Void rgSCHCmnDlUeReset(cell, ue)
7753 RgSchCellCb  *cell;
7754 RgSchUeCb    *ue;
7755 #endif
7756 {
7757    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7758    RgSchCmnDlCell       *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
7759    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
7760
7761
7762    if (ueDl->rachInfo.poLnk.node != NULLP)
7763    {
7764       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
7765    }
7766
7767    /* Fix: syed Remove from TA List if this UE is there.
7768     * If TA Timer is running. Stop it */
7769    if (ue->dlTaLnk.node)
7770    {
7771       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
7772       ue->dlTaLnk.node = (PTR)NULLP;
7773    }
7774    else if (ue->taTmr.tmrEvnt != TMR_NONE)
7775    {
7776       rgSCHTmrStopTmr(cell, ue->taTmr.tmrEvnt, ue);
7777    }
7778
7779    cellSchd->apisDl->rgSCHDlUeReset(cell, ue);
7780 #ifdef LTE_ADV
7781    if (ue->numSCells)
7782    {
7783       rgSCHSCellDlUeReset(cell,ue);
7784    }
7785 #endif
7786 }
7787
7788 /**
7789  * @brief Perform UE reset procedure.
7790  *
7791  * @details
7792  *
7793  *     Function : rgSCHCmnUeReset
7794  *
7795  *     This functions triggers specific scheduler
7796  *     to Perform UE reset procedure.
7797  *
7798  *  @param[in]  RgSchCellCb  *cell
7799  *  @param[in]  RgSchUeCb    *ue
7800  *  @return  S16
7801  *      -# ROK
7802  *      -# RFAILED
7803  **/
7804 #ifdef ANSI
7805 Void rgSCHCmnUeReset
7806 (
7807 RgSchCellCb  *cell,
7808 RgSchUeCb    *ue
7809 )
7810 #else
7811 Void rgSCHCmnUeReset(cell, ue)
7812 RgSchCellCb  *cell;
7813 RgSchUeCb    *ue;
7814 #endif
7815 {
7816    uint8_t idx;
7817    Pst               pst;
7818    RgInfResetHqEnt   hqEntRstInfo;
7819
7820    /* RACHO: remove UE from pdcch, handover and rapId assoc Qs */
7821    rgSCHCmnDelRachInfo(cell, ue);
7822
7823    rgSCHPwrUeReset(cell, ue);
7824
7825    rgSCHCmnUlUeReset(cell, ue);
7826    rgSCHCmnDlUeReset(cell, ue);
7827    
7828 #ifdef LTE_ADV
7829    /* Making allocCmnUlPdcch TRUE to allocate DCI0/1A from Common search space.
7830       As because multiple cells are added hence 2 bits CqiReq is there 
7831       This flag will be set to FALSE once we will get Scell READY */
7832    ue->allocCmnUlPdcch = TRUE;
7833 #endif
7834
7835    /* Fix : syed RESET UL CQI and DL CQI&RI to conservative values
7836     * for a reestablishing UE */
7837    /*Reset Cqi Config for all the configured cells*/
7838    for (idx = 0;idx < CM_LTE_MAX_CELLS; idx++)
7839    {
7840       if (ue->cellInfo[idx] != NULLP) 
7841       {   
7842          rgSCHCmnResetRiCqi(ue->cellInfo[idx]->cell, ue);
7843       }
7844    }
7845    /*After Reset Trigger APCQI for Pcell*/
7846    RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
7847    if(pCellInfo->acqiCb.aCqiCfg.pres)
7848    {
7849       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
7850    }
7851
7852 /* sending HqEnt reset to MAC */
7853    hqEntRstInfo.cellId = cell->cellId;
7854    hqEntRstInfo.crnti  = ue->ueId;
7855
7856    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
7857    RgSchMacRstHqEnt(&pst,&hqEntRstInfo);
7858
7859    return;
7860 }
7861
7862 /**
7863  * @brief UE out of MeasGap or AckNackReptn.
7864  *
7865  * @details
7866  *
7867  *     Function : rgSCHCmnActvtUlUe
7868  *
7869  *     This functions triggers specific scheduler
7870  *     to start considering it for scheduling.
7871  *
7872  *  @param[in]  RgSchCellCb  *cell
7873  *  @param[in]  RgSchUeCb    *ue
7874  *  @return  S16
7875  *      -# ROK
7876  *      -# RFAILED
7877  **/
7878 #ifdef ANSI
7879 Void rgSCHCmnActvtUlUe
7880 (
7881 RgSchCellCb  *cell,
7882 RgSchUeCb    *ue
7883 )
7884 #else
7885 Void rgSCHCmnActvtUlUe(cell, ue)
7886 RgSchCellCb  *cell;
7887 RgSchUeCb    *ue;
7888 #endif
7889 {
7890    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7891
7892    /* : take care of this in UL retransmission */
7893    cellSchd->apisUl->rgSCHUlActvtUe(cell, ue);
7894    return;
7895 }
7896
7897 /**
7898  * @brief UE out of MeasGap or AckNackReptn.
7899  *
7900  * @details
7901  *
7902  *     Function : rgSCHCmnActvtDlUe
7903  *
7904  *     This functions triggers specific scheduler
7905  *     to start considering it for scheduling.
7906  *
7907  *  @param[in]  RgSchCellCb  *cell
7908  *  @param[in]  RgSchUeCb    *ue
7909  *  @return  S16
7910  *      -# ROK
7911  *      -# RFAILED
7912  **/
7913 #ifdef ANSI
7914 Void rgSCHCmnActvtDlUe
7915 (
7916 RgSchCellCb  *cell,
7917 RgSchUeCb    *ue
7918 )
7919 #else
7920 Void rgSCHCmnActvtDlUe(cell, ue)
7921 RgSchCellCb  *cell;
7922 RgSchUeCb    *ue;
7923 #endif
7924 {
7925    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
7926
7927    cellSchd->apisDl->rgSCHDlActvtUe(cell, ue);
7928    return;
7929 }
7930
7931 /**
7932  * @brief This API is invoked to indicate scheduler of a CRC indication.
7933  *
7934  * @details
7935  *
7936  *     Function : rgSCHCmnHdlUlTransInd
7937  *      This API is invoked to indicate scheduler of a CRC indication.
7938  *
7939  *  @param[in]  RgSchCellCb     *cell
7940  *  @param[in]  RgSchUeCb       *ue
7941  *  @param[in]  CmLteTimingInfo timingInfo
7942  *
7943  *  @return Void
7944  **/
7945 #ifdef ANSI
7946 Void rgSCHCmnHdlUlTransInd
7947 (
7948 RgSchCellCb     *cell,
7949 RgSchUeCb       *ue,
7950 CmLteTimingInfo timingInfo
7951 )
7952 #else
7953 Void rgSCHCmnHdlUlTransInd(cell, ue, timingInfo)
7954 RgSchCellCb     *cell;
7955 RgSchUeCb       *ue;
7956 CmLteTimingInfo timingInfo;
7957 #endif
7958 {
7959
7960    /* Update the latest UL dat/sig transmission time */
7961    RGSCHCPYTIMEINFO(timingInfo, ue->ul.ulTransTime);
7962    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
7963    {
7964       /* Some UL Transmission from this UE.
7965        * Activate this UE if it was inactive */
7966       RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7967       RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
7968    }
7969    return;
7970 }
7971
7972 #ifdef TFU_UPGRADE
7973
7974 /**
7975  * @brief Compute the minimum Rank based on Codebook subset
7976  *        restriction configuration for 4 Tx Ports and Tx Mode 4.
7977  *
7978  * @details
7979  *
7980  *     Function : rgSCHCmnComp4TxMode4
7981  *
7982  *     Depending on BitMap set at CBSR during Configuration
7983  *      - return the least possible Rank
7984  *
7985  *
7986  *  @param[in]  uint32_t *pmiBitMap
7987  *  @return  RgSchCmnRank
7988  **/
7989 #ifdef ANSI
7990 static RgSchCmnRank rgSCHCmnComp4TxMode4
7991 (
7992  uint32_t    *pmiBitMap
7993  )
7994 #else
7995 static RgSchCmnRank rgSCHCmnComp4TxMode4(pmiBitMap)
7996    uint32_t  *pmiBitMap;
7997 #endif
7998 {
7999    uint32_t bitMap0, bitMap1;
8000    bitMap0 = pmiBitMap[0];
8001    bitMap1 = pmiBitMap[1];
8002    if((bitMap1) & 0xFFFF)
8003    {
8004       return  (RG_SCH_CMN_RANK_1);
8005    }
8006    else if((bitMap1>>16) & 0xFFFF)
8007    {
8008       return  (RG_SCH_CMN_RANK_2);
8009    }
8010    else if((bitMap0) & 0xFFFF)
8011    {
8012       return  (RG_SCH_CMN_RANK_3);
8013    }
8014    else if((bitMap0>>16) & 0xFFFF)
8015    {
8016       return  (RG_SCH_CMN_RANK_4);
8017    }
8018    else
8019    {
8020       return  (RG_SCH_CMN_RANK_1);
8021    }
8022 }
8023
8024
8025 /**
8026  * @brief Compute the minimum Rank based on Codebook subset
8027  *        restriction configuration for 2 Tx Ports and Tx Mode 4.
8028  *
8029  * @details
8030  *
8031  *     Function : rgSCHCmnComp2TxMode4
8032  *
8033  *     Depending on BitMap set at CBSR during Configuration
8034  *      - return the least possible Rank
8035  *
8036  *
8037  *  @param[in]  uint32_t *pmiBitMap
8038  *  @return  RgSchCmnRank
8039  **/
8040 #ifdef ANSI
8041 static RgSchCmnRank rgSCHCmnComp2TxMode4
8042 (
8043  uint32_t    *pmiBitMap
8044  )
8045 #else
8046 static RgSchCmnRank rgSCHCmnComp2TxMode4(pmiBitMap)
8047    uint32_t  *pmiBitMap;
8048 #endif
8049 {
8050    uint32_t bitMap0;
8051    bitMap0 = pmiBitMap[0];
8052    if((bitMap0>>26)& 0x0F)
8053    {
8054       return  (RG_SCH_CMN_RANK_1);
8055    }
8056    else if((bitMap0>>30) & 3)
8057    {
8058       return  (RG_SCH_CMN_RANK_2);
8059    }
8060    else
8061    {
8062       return  (RG_SCH_CMN_RANK_1);
8063    }
8064 }
8065
8066 /**
8067  * @brief Compute the minimum Rank based on Codebook subset
8068  *        restriction configuration for 4 Tx Ports and Tx Mode 3.
8069  *
8070  * @details
8071  *
8072  *     Function : rgSCHCmnComp4TxMode3
8073  *
8074  *     Depending on BitMap set at CBSR during Configuration
8075  *      - return the least possible Rank
8076  *
8077  *
8078  *  @param[in]  uint32_t *pmiBitMap
8079  *  @return  RgSchCmnRank
8080  **/
8081 #ifdef ANSI
8082 static RgSchCmnRank rgSCHCmnComp4TxMode3
8083 (
8084  uint32_t    *pmiBitMap
8085  )
8086 #else
8087 static RgSchCmnRank rgSCHCmnComp4TxMode3(pmiBitMap)
8088    uint32_t  *pmiBitMap;
8089 #endif
8090 {
8091    uint32_t bitMap0;
8092    bitMap0 = pmiBitMap[0];
8093    if((bitMap0>>28)& 1)
8094    {
8095       return  (RG_SCH_CMN_RANK_1);
8096    }
8097    else if((bitMap0>>29) &1)
8098    {
8099       return  (RG_SCH_CMN_RANK_2);
8100    }
8101    else if((bitMap0>>30) &1)
8102    {
8103       return  (RG_SCH_CMN_RANK_3);
8104    }
8105    else if((bitMap0>>31) &1)
8106    {
8107       return  (RG_SCH_CMN_RANK_4);
8108    }
8109    else
8110    {
8111       return  (RG_SCH_CMN_RANK_1);
8112    }
8113 }
8114
8115 /**
8116  * @brief Compute the minimum Rank based on Codebook subset
8117  *        restriction configuration for 2 Tx Ports and Tx Mode 3.
8118  *
8119  * @details
8120  *
8121  *     Function : rgSCHCmnComp2TxMode3
8122  *
8123  *     Depending on BitMap set at CBSR during Configuration
8124  *      - return the least possible Rank
8125  *
8126  *
8127  *  @param[in]  uint32_t *pmiBitMap
8128  *  @return  RgSchCmnRank
8129  **/
8130 #ifdef ANSI
8131 static RgSchCmnRank rgSCHCmnComp2TxMode3
8132 (
8133  uint32_t *pmiBitMap
8134  )
8135 #else
8136 static RgSchCmnRank rgSCHCmnComp2TxMode3(pmiBitMap)
8137    uint32_t *pmiBitMap;
8138 #endif
8139 {
8140    uint32_t bitMap0;
8141    bitMap0 = pmiBitMap[0];
8142    if((bitMap0>>30)& 1)
8143    {
8144       return  (RG_SCH_CMN_RANK_1);
8145    }
8146    else if((bitMap0>>31) &1)
8147    {
8148       return  (RG_SCH_CMN_RANK_2);
8149    }
8150    else
8151    {
8152       return  (RG_SCH_CMN_RANK_1);
8153    }
8154 }
8155
8156 /**
8157  * @brief Compute the minimum Rank based on Codebook subset
8158  *        restriction configuration.
8159  *
8160  * @details
8161  *
8162  *     Function : rgSCHCmnComputeRank
8163  *
8164  *     Depending on Num Tx Ports and Transmission mode
8165  *      - return the least possible Rank
8166  *
8167  *
8168  *  @param[in]  RgrTxMode txMode
8169  *  @param[in]  uint32_t *pmiBitMap
8170  *  @param[in]  uint8_t numTxPorts
8171  *  @return  RgSchCmnRank
8172  **/
8173 #ifdef ANSI
8174 static RgSchCmnRank rgSCHCmnComputeRank
8175 (
8176  RgrTxMode    txMode,
8177  uint32_t          *pmiBitMap,
8178  uint8_t           numTxPorts
8179  )
8180 #else
8181 static RgSchCmnRank rgSCHCmnComputeRank(txMode, pmiBitMap, numTxPorts)
8182    RgrTxMode    txMode;
8183    uint32_t          *pmiBitMap;
8184    uint8_t           numTxPorts;
8185 #endif
8186 {
8187
8188    if (numTxPorts ==2 && txMode == RGR_UE_TM_3)
8189    {
8190       return  (rgSCHCmnComp2TxMode3(pmiBitMap));
8191    }
8192    else if (numTxPorts ==4 && txMode == RGR_UE_TM_3)
8193    {
8194       return  (rgSCHCmnComp4TxMode3(pmiBitMap));
8195    }
8196    else if (numTxPorts ==2 && txMode == RGR_UE_TM_4)
8197    {
8198       return  (rgSCHCmnComp2TxMode4(pmiBitMap));
8199    }
8200    else if (numTxPorts ==4 && txMode == RGR_UE_TM_4)
8201    {
8202       return  (rgSCHCmnComp4TxMode4(pmiBitMap));
8203    }
8204    else
8205    {
8206       return  (RG_SCH_CMN_RANK_1);
8207    }
8208 }
8209
8210 #endif
8211
8212 /**
8213  * @brief Harq Entity Deinitialization for CMN SCH.
8214  *
8215  * @details
8216  *
8217  *     Function : rgSCHCmnDlDeInitHqEnt 
8218  *
8219  *     Harq Entity Deinitialization for CMN SCH 
8220  *
8221  *  @param[in]  RgSchCellCb  *cell
8222  *  @param[in]  RgSchDlHqEnt *hqE 
8223  *  @return  VOID
8224  **/
8225 /*KWORK_FIX:Changed function return type to void */
8226 #ifdef ANSI
8227 Void rgSCHCmnDlDeInitHqEnt 
8228 (
8229 RgSchCellCb  *cell,
8230 RgSchDlHqEnt *hqE
8231 )
8232 #else
8233 Void rgSCHCmnDlDeInitHqEnt(cell, hqE)
8234 RgSchCellCb  *cell;
8235 RgSchDlHqEnt *hqE;
8236 #endif
8237 {
8238    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8239    RgSchDlHqProcCb      *hqP;
8240    uint8_t                   cnt;
8241    S16                  ret;
8242
8243
8244    ret = cellSchd->apisDl->rgSCHDlUeHqEntDeInit(cell, hqE);
8245    /* Free only If the Harq proc are created*/
8246    if(RFAILED == ret)
8247    {
8248    }
8249
8250    for(cnt = 0; cnt < hqE->numHqPrcs; cnt++)
8251    {
8252       hqP = &hqE->procs[cnt];
8253       if ((RG_SCH_CMN_GET_DL_HQP(hqP)))
8254       {
8255          rgSCHUtlFreeSBuf(cell->instIdx,
8256               (Data**)(&(hqP->sch)), (sizeof(RgSchCmnDlHqProc)));
8257       }
8258    }
8259 #ifdef LTE_ADV
8260    rgSCHLaaDeInitDlHqProcCb (cell, hqE);
8261 #endif
8262
8263    return;
8264 }
8265
8266 /**
8267  * @brief Harq Entity initialization for CMN SCH.
8268  *
8269  * @details
8270  *
8271  *     Function : rgSCHCmnDlInitHqEnt 
8272  *
8273  *     Harq Entity initialization for CMN SCH 
8274  *
8275  *  @param[in]  RgSchCellCb  *cell
8276  *  @param[in]  RgSchUeCb    *ue
8277  *  @return  S16
8278  *      -# ROK
8279  *      -# RFAILED
8280  **/
8281 #ifdef ANSI
8282 S16 rgSCHCmnDlInitHqEnt 
8283 (
8284 RgSchCellCb  *cell,
8285 RgSchDlHqEnt  *hqEnt
8286 )
8287 #else
8288 S16 rgSCHCmnDlInitHqEnt(cell, hqEnt)
8289 RgSchCellCb  *cell;
8290 RgSchDlHqEnt  *hqEnt;
8291 #endif
8292
8293 {
8294    RgSchDlHqProcCb      *hqP;
8295    uint8_t                   cnt;
8296
8297    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8298
8299    for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
8300    {
8301       hqP = &hqEnt->procs[cnt];
8302       if (rgSCHUtlAllocSBuf(cell->instIdx,
8303                (Data**)&(hqP->sch), (sizeof(RgSchCmnDlHqProc))) != ROK)
8304       {
8305          return RFAILED;
8306       }
8307    }
8308 #ifdef EMTC_ENABLE
8309    if((cell->emtcEnable) &&(hqEnt->ue->isEmtcUe))
8310    {
8311       if(ROK != cellSchd->apisEmtcDl->rgSCHDlUeHqEntInit(cell, hqEnt))
8312       {
8313          return RFAILED;
8314       }
8315
8316    }
8317    else
8318 #endif
8319    {
8320       if(ROK != cellSchd->apisDl->rgSCHDlUeHqEntInit(cell, hqEnt))
8321       {
8322          return RFAILED;
8323       }
8324    }
8325
8326    return ROK;
8327 }  /* rgSCHCmnDlInitHqEnt */
8328
8329 /**
8330  * @brief This function computes distribution of refresh period
8331  *
8332  * @details
8333  *
8334  *     Function: rgSCHCmnGetRefreshDist 
8335  *     Purpose: This function computes distribution of refresh period
8336  *              This is required to align set of UEs refresh
8337  *              around the different consecutive subframe.
8338  *               
8339  *     Invoked by: rgSCHCmnGetRefreshPerDist
8340  *
8341  *  @param[in]  RgSchCellCb        *cell
8342  *  @param[in]  RgSchUeCb          *ue
8343  *  @return  Void
8344  *
8345  **/
8346 #ifdef ANSI
8347 static uint8_t rgSCHCmnGetRefreshDist 
8348 (
8349 RgSchCellCb        *cell,
8350 RgSchUeCb          *ue
8351 )
8352 #else
8353 static uint8_t rgSCHCmnGetRefreshDist(cell, ue)
8354 RgSchCellCb        *cell;
8355 RgSchUeCb          *ue;
8356 #endif
8357 {
8358    uint8_t   refOffst;
8359 #ifdef DEBUGP
8360    Inst inst = cell->instIdx;
8361 #endif
8362
8363    for(refOffst = 0; refOffst < RGSCH_MAX_REFRESH_OFFSET; refOffst++)
8364    {
8365       if(cell->refreshUeCnt[refOffst] < RGSCH_MAX_REFRESH_GRPSZ)
8366       {
8367          cell->refreshUeCnt[refOffst]++;
8368          ue->refreshOffset = refOffst;
8369          /* printf("UE[%d] refresh offset[%d]. Cell refresh ue count[%d].\n", ue->ueId, refOffst,  cell->refreshUeCnt[refOffst]); */
8370          return (refOffst);
8371       }
8372    }
8373   
8374    RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Allocation of refresh distribution failed\n"));
8375    /* We should not enter here  normally, but incase of failure, allocating from  last offset*/
8376    cell->refreshUeCnt[refOffst-1]++;
8377    ue->refreshOffset = refOffst-1;
8378
8379    return (refOffst-1);
8380 }
8381 /**
8382  * @brief This function computes initial Refresh Wait Period.
8383  *
8384  * @details
8385  *
8386  *     Function: rgSCHCmnGetRefreshPer 
8387  *     Purpose: This function computes initial Refresh Wait Period.
8388  *              This is required to align multiple UEs refresh
8389  *              around the same time.
8390  *               
8391  *     Invoked by: rgSCHCmnGetRefreshPer 
8392  *
8393  *  @param[in]  RgSchCellCb        *cell
8394  *  @param[in]  RgSchUeCb          *ue
8395  *  @param[in]  uint32_t                *waitPer 
8396  *  @return  Void
8397  *
8398  **/
8399 #ifdef ANSI
8400 static Void rgSCHCmnGetRefreshPer 
8401 (
8402 RgSchCellCb        *cell,
8403 RgSchUeCb          *ue,
8404 uint32_t                *waitPer
8405 )
8406 #else
8407 static Void rgSCHCmnGetRefreshPer(cell, ue, waitPer)
8408 RgSchCellCb        *cell;
8409 RgSchUeCb          *ue;
8410 uint32_t                *waitPer;
8411 #endif
8412 {
8413    uint32_t       refreshPer;      
8414    uint32_t       crntSubFrm;
8415
8416
8417    refreshPer = RG_SCH_CMN_REFRESH_TIME * RG_SCH_CMN_REFRESH_TIMERES;
8418    crntSubFrm = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.slot;
8419    /* Fix: syed align multiple UEs to refresh at same time */
8420    *waitPer = refreshPer - (crntSubFrm % refreshPer);
8421    *waitPer = RGSCH_CEIL(*waitPer, RG_SCH_CMN_REFRESH_TIMERES);
8422    *waitPer = *waitPer + rgSCHCmnGetRefreshDist(cell, ue);
8423
8424    return;
8425 }
8426
8427
8428 #ifdef LTE_ADV
8429 /**
8430  * @brief UE initialisation for scheduler.
8431  *
8432  * @details
8433  *
8434  *     Function : rgSCHCmnRgrSCellUeCfg
8435  *
8436  *     This functions intialises UE specific scheduler 
8437  *     information for SCELL
8438  *     0. Perform basic validations
8439  *     1. Allocate common sched UE cntrl blk
8440  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
8441  *     3. Perform UL cfg
8442  *     4. Perform DLFS cfg
8443  *
8444  *  @param[in]  RgSchCellCb  *cell
8445  *  @param[in]  RgSchUeCb    *ue
8446  *  @param[out] RgSchErrInfo *err
8447  *  @return  S16
8448  *      -# ROK
8449  *      -# RFAILED
8450  **/
8451 #ifdef ANSI
8452 S16 rgSCHCmnRgrSCellUeCfg
8453 (
8454 RgSchCellCb  *sCell,
8455 RgSchUeCb    *ue,
8456 RgrUeSecCellCfg  *sCellInfoCfg,
8457 RgSchErrInfo *err
8458 )
8459 #else
8460 S16 rgSCHCmnRgrSCellUeCfg(sCell, ue, sCellInfoCfg, err)
8461 RgSchCellCb  *sCell;
8462 RgSchUeCb    *ue;
8463 RgrUeSecCellCfg  *sCellInfoCfg;
8464 RgSchErrInfo *err;
8465 #endif
8466 {
8467    uint8_t i;
8468    S16                  ret;
8469    uint8_t                   cnt;
8470    RgSchCmnAllocRecord  *allRcd;
8471    RgSchDlRbAlloc       *allocInfo;
8472    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
8473    RgSchCmnUlUe         *ueUl;
8474    RgSchCmnUlUe         *ueUlPcell;
8475    RgSchCmnUe           *pCellUeSchCmn;
8476    RgSchCmnUe           *ueSchCmn;
8477    RgSchCmnDlUe         *ueDl;
8478    RgSchCmnDlUe         *pCellUeDl;
8479 #ifdef DEBUGP
8480    Inst                 inst = ue->cell->instIdx;
8481 #endif
8482    uint32_t idx = (uint8_t)((sCell->cellId - rgSchCb[sCell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
8483
8484    pCellUeSchCmn = RG_SCH_CMN_GET_UE(ue,ue->cell);
8485    pCellUeDl = &pCellUeSchCmn->dl;
8486
8487    /* 1. Allocate Common sched control block */
8488    if((rgSCHUtlAllocSBuf(sCell->instIdx,
8489                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
8490    {
8491       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Memory allocation FAILED\n"));
8492       err->errCause = RGSCHERR_SCH_CFG;
8493       return RFAILED;
8494    }
8495    ueSchCmn = RG_SCH_CMN_GET_UE(ue,sCell);
8496
8497    /*2.  Perform UEs downlink configuration */
8498    ueDl = &ueSchCmn->dl;
8499
8500    /*CA TODO*/
8501    ueDl->mimoInfo = pCellUeDl->mimoInfo;
8502
8503    if ((ue->mimoInfo.txMode == RGR_UE_TM_4) ||
8504          (ue->mimoInfo.txMode == RGR_UE_TM_6))
8505    {
8506       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_NO_PMI);
8507    }
8508    if (ue->mimoInfo.txMode == RGR_UE_TM_3)
8509    {
8510       RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_RI_1);
8511    }
8512    RGSCH_ARRAY_BOUND_CHECK(sCell->instIdx, rgUeCatTbl, pCellUeSchCmn->cmn.ueCat);
8513    ueDl->maxTbBits = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlTbBits;
8514    /*CA dev-Start*/
8515    uint8_t ri = 0;
8516    ri = RGSCH_MIN(ri, sCell->numTxAntPorts);
8517    if(((CM_LTE_UE_CAT_6 == pCellUeSchCmn->cmn.ueCat )
8518             ||(CM_LTE_UE_CAT_7 == pCellUeSchCmn->cmn.ueCat)) 
8519          && (4 == ri))
8520    {
8521       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[1];
8522    }
8523    else
8524    {
8525       ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[0];
8526    }
8527    /*CA dev-End*/
8528    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
8529 #ifdef LTE_TDD
8530    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
8531          rgSchTddDlNumHarqProcTbl[sCell->ulDlCfgIdx]);
8532 #else
8533    ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/
8534          RGSCH_NUM_DL_HQ_PROC);
8535 #endif
8536 #ifdef EMTC_ENABLE   
8537    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, ue->isEmtcUe);
8538 #else
8539    rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, FALSE);
8540 #endif      
8541
8542    /* DL ambr */
8543    /* ambrCfgd config moved to ueCb.dl, as it's not needed for per cell wise*/
8544
8545    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, sCell);
8546    allocInfo->rnti = ue->ueId;
8547
8548    /* Initializing the lastCfi value to current cfi value */
8549    ueDl->lastCfi = cellSchd->dl.currCfi;
8550
8551    if ((cellSchd->apisDl->rgSCHRgrSCellDlUeCfg(sCell, ue, err)) != ROK)
8552    {
8553       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Spec Sched DL UE CFG FAILED\n"));
8554       return RFAILED;
8555    }
8556
8557    /* TODO: enhance for DLFS RB Allocation for SCELLs in future dev */
8558
8559    /* DLFS UE Config */
8560    if (cellSchd->dl.isDlFreqSel)
8561    {
8562       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeCfg(sCell, ue, sCellInfoCfg, err)) != ROK)
8563       {
8564          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS UE config FAILED\n"));
8565          return RFAILED;
8566       }
8567    }
8568
8569    /* TODO: Do UL SCELL CFG during UL CA dev */
8570    {
8571       ueUl = RG_SCH_CMN_GET_UL_UE(ue, sCell);
8572
8573       /* TODO_ULCA: SRS for SCELL needs to be handled in the below function call */
8574       rgSCHCmnUpdUeUlCqiInfo(sCell, ue, ueUl, ueSchCmn, cellSchd,
8575             sCell->isCpUlExtend);
8576
8577       ret = rgSCHUhmHqEntInit(sCell, ue);
8578       if (ret != ROK)
8579       {
8580          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL UHM HARQ Ent Init "
8581                "Failed for CRNTI:%d", ue->ueId);
8582          return RFAILED;
8583       }
8584
8585       ueUlPcell = RG_SCH_CMN_GET_UL_UE(ue, ue->cell);
8586       /* Initialize uplink HARQ related information for UE */
8587       ueUl->hqEnt.maxHqRetx = ueUlPcell->hqEnt.maxHqRetx;
8588       cmLListInit(&ueUl->hqEnt.free);
8589       cmLListInit(&ueUl->hqEnt.inUse);
8590       for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
8591       {
8592          ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
8593          ueUl->hqEnt.hqProcCb[i].procId = i;
8594          ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
8595          ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
8596 #ifdef LTEMAC_SPS
8597          /* ccpu00139513- Initializing SPS flags*/
8598          ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
8599          ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
8600 #endif
8601          cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
8602          ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
8603       }
8604
8605       /* Allocate UL BSR allocation tracking List */
8606       cmLListInit(&ueUl->ulAllocLst);
8607
8608       for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
8609       {
8610          if((rgSCHUtlAllocSBuf(sCell->instIdx,
8611                      (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
8612          {
8613             RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL Memory allocation FAILED"
8614                   "for CRNTI:%d",ue->ueId);
8615             err->errCause = RGSCHERR_SCH_CFG;
8616             return RFAILED;
8617          }
8618          allRcd->allocTime = sCell->crntTime;
8619          cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
8620          allRcd->lnk.node = (PTR)allRcd;
8621       }
8622
8623       /* After initialising UL part, do power related init */
8624       ret = rgSCHPwrUeSCellCfg(sCell, ue, sCellInfoCfg);
8625       if (ret != ROK)
8626       {
8627          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Could not do "
8628                "power config for UE CRNTI:%d",ue->ueId);
8629          return RFAILED;
8630       }
8631
8632 #ifdef EMTC_ENABLE   
8633       if(TRUE == ue->isEmtcUe)
8634       {
8635          if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
8636          {
8637             RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED"
8638                   "for CRNTI:%d",ue->ueId);
8639             return RFAILED;
8640          }
8641       }
8642       else
8643 #endif
8644       {
8645       if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK)
8646       {
8647          RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED"
8648                "for CRNTI:%d",ue->ueId);
8649          return RFAILED;
8650       }
8651       }
8652    
8653       ue->ul.isUlCaEnabled = TRUE;
8654    }
8655
8656    return ROK;
8657 }  /* rgSCHCmnRgrSCellUeCfg */
8658
8659
8660 /**
8661  * @brief UE initialisation for scheduler.
8662  *
8663  * @details
8664  *
8665  *     Function : rgSCHCmnRgrSCellUeDel 
8666  *
8667  *     This functions Delete UE specific scheduler 
8668  *     information for SCELL
8669  *
8670  *  @param[in]  RgSchCellCb  *cell
8671  *  @param[in]  RgSchUeCb    *ue
8672  *  @return  S16
8673  *      -# ROK
8674  *      -# RFAILED
8675  **/
8676 #ifdef ANSI
8677 S16 rgSCHCmnRgrSCellUeDel
8678 (
8679 RgSchUeCellInfo *sCellInfo,
8680 RgSchUeCb    *ue
8681 )
8682 #else
8683 S16 rgSCHCmnRgrSCellUeDel(sCellInfo, ue)
8684 RgSchUeCellInfo *sCellInfo;
8685 RgSchUeCb    *ue;
8686 #endif
8687 {
8688    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell);
8689    Inst                 inst = ue->cell->instIdx;
8690
8691
8692    cellSchd->apisDl->rgSCHRgrSCellDlUeDel(sCellInfo, ue);
8693
8694    /* UL CA */
8695    rgSCHCmnUlUeDelAllocs(sCellInfo->cell, ue);
8696
8697 #ifdef EMTC_ENABLE   
8698    if(TRUE == ue->isEmtcUe)
8699    {
8700       cellSchd->apisEmtcUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
8701    }
8702    else
8703 #endif
8704    {
8705    cellSchd->apisUl->rgSCHFreeUlUe(sCellInfo->cell, ue);
8706    }
8707
8708    /* DLFS UE Config */
8709    if (cellSchd->dl.isDlFreqSel)
8710    {
8711       if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeDel(sCellInfo->cell, ue)) != ROK)
8712       {
8713          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS Scell del FAILED\n"));
8714          return RFAILED;
8715       }
8716    }
8717
8718    rgSCHUtlFreeSBuf(sCellInfo->cell->instIdx,
8719          (Data**)(&(sCellInfo->sch)), (sizeof(RgSchCmnUe)));
8720
8721
8722    return ROK;
8723 }  /* rgSCHCmnRgrSCellUeDel */
8724  
8725 #endif
8726
8727 #ifdef RG_5GTF
8728 /**
8729  * @brief Handles 5gtf configuration for a UE
8730  *
8731  * @details
8732  *
8733  *     Function : rgSCHCmn5gtfUeCfg
8734  *
8735  *     Processing Steps:
8736  *
8737  *      - Return ROK
8738  *
8739  *  @param[in]  RgSchCellCb  *cell
8740  *  @param[in]  RgSchUeCb    *ue
8741  *  @param[in]  RgrUeCfg     *cfg
8742  *  @return  S16
8743  *      -# ROK
8744  *      -# RFAILED
8745  **/
8746 #ifdef ANSI
8747 S16 rgSCHCmn5gtfUeCfg
8748 (
8749 RgSchCellCb *cell,
8750 RgSchUeCb   *ue,
8751 RgrUeCfg    *cfg
8752 )
8753 #else
8754 S16 rgSCHCmn5gtfUeCfg(cell, ue, cfg)
8755 RgSchCellCb *cell;
8756 RgSchUeCb   *ue;
8757 RgrUeCfg    *cfg;
8758 #endif
8759 {
8760
8761    RgSchUeGrp *ue5gtfGrp;
8762    ue->ue5gtfCb.grpId = cfg->ue5gtfCfg.grpId;
8763    ue->ue5gtfCb.BeamId = cfg->ue5gtfCfg.BeamId;
8764    ue->ue5gtfCb.numCC = cfg->ue5gtfCfg.numCC;   
8765    ue->ue5gtfCb.mcs = cfg->ue5gtfCfg.mcs;
8766    ue->ue5gtfCb.maxPrb = cfg->ue5gtfCfg.maxPrb;
8767
8768    ue->ue5gtfCb.cqiRiPer = 100;
8769    /* 5gtf TODO: CQIs to start from (10,0)*/
8770    ue->ue5gtfCb.nxtCqiRiOccn.sfn = 10;
8771    ue->ue5gtfCb.nxtCqiRiOccn.slot = 0;
8772    ue->ue5gtfCb.rank = 1;
8773
8774    printf("\nschd cfg at mac,%u,%u,%u,%u,%u\n",ue->ue5gtfCb.grpId,ue->ue5gtfCb.BeamId,ue->ue5gtfCb.numCC,
8775          ue->ue5gtfCb.mcs,ue->ue5gtfCb.maxPrb); 
8776
8777    ue5gtfGrp = &(cell->cell5gtfCb.ueGrp5gConf[ue->ue5gtfCb.BeamId]);
8778
8779    /* TODO_5GTF: Currently handling 1 group only. Need to update when multi group 
8780       scheduling comes into picture */
8781    if(ue5gtfGrp->beamBitMask & (1 << ue->ue5gtfCb.BeamId))
8782    {
8783       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8784             "5GTF_ERROR Invalid beam id CRNTI:%d",cfg->crnti);
8785       return RFAILED;
8786    }
8787    ue5gtfGrp->beamBitMask |= (1 << ue->ue5gtfCb.BeamId);
8788
8789    return ROK;
8790 }
8791 #endif
8792
8793 /**
8794  * @brief UE initialisation for scheduler.
8795  *
8796  * @details
8797  *
8798  *     Function : rgSCHCmnRgrUeCfg
8799  *
8800  *     This functions intialises UE specific scheduler
8801  *     information
8802  *     0. Perform basic validations
8803  *     1. Allocate common sched UE cntrl blk
8804  *     2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks)
8805  *     3. Perform UL cfg
8806  *     4. Perform DLFS cfg
8807  *
8808  *  @param[in]  RgSchCellCb  *cell
8809  *  @param[in]  RgSchUeCb    *ue
8810  *  @param[int] RgrUeCfg     *ueCfg
8811  *  @param[out] RgSchErrInfo *err
8812  *  @return  S16
8813  *      -# ROK
8814  *      -# RFAILED
8815  **/
8816 #ifdef ANSI
8817 S16 rgSCHCmnRgrUeCfg
8818 (
8819 RgSchCellCb  *cell,
8820 RgSchUeCb    *ue,
8821 RgrUeCfg     *ueCfg,
8822 RgSchErrInfo *err
8823 )
8824 #else
8825 S16 rgSCHCmnRgrUeCfg(cell, ue, ueCfg, err)
8826 RgSchCellCb  *cell;
8827 RgSchUeCb    *ue;
8828 RgrUeCfg     *ueCfg;
8829 RgSchErrInfo *err;
8830 #endif
8831 {
8832    RgSchDlRbAlloc  *allocInfo;
8833    S16                  ret;
8834    RgSchCmnCell         *cellSchd = RG_SCH_CMN_GET_CELL(cell);
8835    RgSchCmnUe           *ueSchCmn;
8836    RgSchCmnUlUe         *ueUl;
8837    RgSchCmnDlUe         *ueDl;
8838    uint8_t                   cnt;
8839    RgSchCmnAllocRecord  *allRcd;
8840    uint32_t                  waitPer;
8841    uint32_t                  idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
8842    RgSchUeCellInfo      *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
8843
8844
8845    /* 1. Allocate Common sched control block */
8846    if((rgSCHUtlAllocSBuf(cell->instIdx,
8847                (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK))
8848    {
8849       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8850             "Memory allocation FAILED for CRNTI:%d",ueCfg->crnti);
8851       err->errCause = RGSCHERR_SCH_CFG;
8852       return RFAILED;
8853    }
8854    ueSchCmn   = RG_SCH_CMN_GET_UE(ue,cell);
8855    ue->dl.ueDlCqiCfg = ueCfg->ueDlCqiCfg;
8856    pCellInfo->acqiCb.aCqiCfg = ueCfg->ueDlCqiCfg.aprdCqiCfg;
8857    if(ueCfg->ueCatEnum > 0 )
8858    {
8859      /*KWORK_FIX removed NULL chk for ueSchCmn*/
8860       ueSchCmn->cmn.ueCat = ueCfg->ueCatEnum - 1; 
8861    }
8862    else
8863    {
8864       ueSchCmn->cmn.ueCat = 0; /* Assuming enum values correctly set */
8865    }
8866    cmInitTimers(&ueSchCmn->cmn.tmr, 1);
8867
8868    /*2.  Perform UEs downlink configuration */
8869    ueDl = &ueSchCmn->dl;
8870    /* RACHO : store the rapId assigned for HandOver UE.
8871     * Append UE to handover list of cmnCell */
8872    if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
8873    {
8874       rgSCHCmnDelDedPreamble(cell, ueCfg->dedPreambleId.val);
8875       ueDl->rachInfo.hoRapId = ueCfg->dedPreambleId.val;
8876       cmLListAdd2Tail(&cellSchd->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
8877       ueDl->rachInfo.hoLnk.node = (PTR)ue;
8878    }
8879
8880    rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd);
8881
8882    if (ueCfg->txMode.pres == TRUE)
8883    {
8884       if ((ueCfg->txMode.txModeEnum == RGR_UE_TM_4) ||
8885             (ueCfg->txMode.txModeEnum == RGR_UE_TM_6))
8886       {
8887          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
8888       }
8889       if (ueCfg->txMode.txModeEnum == RGR_UE_TM_3)
8890       {
8891          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
8892       }
8893    }
8894    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
8895    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
8896    /*CA dev-Start*/
8897    uint8_t ri = 0;
8898    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
8899    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
8900             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
8901                   && (4 == ri))
8902    {
8903       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
8904    }
8905    else
8906    {
8907       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
8908    }
8909    /*CA dev-End*/
8910    /* Fix : syed Assign hqEnt to UE only if msg4 is done */
8911 #ifdef LTE_TDD
8912    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
8913          rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]);
8914 #else
8915    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
8916          RGSCH_NUM_DL_HQ_PROC);
8917 #endif
8918 #ifdef EMTC_ENABLE   
8919    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe);
8920 #else
8921    rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE);
8922 #endif 
8923      /* if none of the DL and UL AMBR are configured then fail the configuration
8924     */     
8925    if((ueCfg->ueQosCfg.dlAmbr == 0) && (ueCfg->ueQosCfg.ueBr == 0))
8926    {
8927       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"UL Ambr and DL Ambr are"
8928          "configured as 0 for CRNTI:%d",ueCfg->crnti);
8929       err->errCause = RGSCHERR_SCH_CFG;
8930       return RFAILED;
8931    }
8932    /* DL ambr */
8933    ue->dl.ambrCfgd = (ueCfg->ueQosCfg.dlAmbr * RG_SCH_CMN_REFRESH_TIME)/100;
8934
8935    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
8936    allocInfo->rnti = ue->ueId;
8937
8938    /* Initializing the lastCfi value to current cfi value */
8939    ueDl->lastCfi = cellSchd->dl.currCfi;
8940 #ifdef EMTC_ENABLE
8941    if(cell->emtcEnable && ue->isEmtcUe)
8942    {
8943       if ((cellSchd->apisEmtcDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8944       {
8945          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8946                "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8947          return RFAILED;
8948       }
8949
8950    }
8951    else
8952 #endif
8953    {
8954       if ((cellSchd->apisDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK)
8955       {
8956          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
8957                "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti);
8958          return RFAILED;
8959       }
8960    }
8961
8962
8963
8964    /* 3. Initialize ul part */
8965    ueUl     = &ueSchCmn->ul;
8966
8967    rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd,
8968             cell->isCpUlExtend);
8969
8970    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
8971                                RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
8972
8973    ue->ul.cfgdAmbr = (ueCfg->ueQosCfg.ueBr * RG_SCH_CMN_REFRESH_TIME)/100;
8974    ue->ul.effAmbr = ue->ul.cfgdAmbr;
8975    RGSCHCPYTIMEINFO(cell->crntTime, ue->ul.ulTransTime);
8976
8977    /* Allocate UL BSR allocation tracking List */
8978    cmLListInit(&ueUl->ulAllocLst);
8979
8980    for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++)
8981    {
8982       if((rgSCHUtlAllocSBuf(cell->instIdx,
8983                   (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK))
8984       {
8985          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED"
8986                    "for CRNTI:%d",ueCfg->crnti);
8987          err->errCause = RGSCHERR_SCH_CFG;
8988          return RFAILED;
8989       }
8990       allRcd->allocTime = cell->crntTime;
8991       cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk);
8992       allRcd->lnk.node = (PTR)allRcd;
8993    }
8994    /* Allocate common sch cntrl blocks for LCGs */
8995    for (cnt=0; cnt<RGSCH_MAX_LCG_PER_UE; cnt++)
8996    {
8997       ret = rgSCHUtlAllocSBuf(cell->instIdx,
8998             (Data**)&(ue->ul.lcgArr[cnt].sch), (sizeof(RgSchCmnLcg)));
8999       if (ret != ROK)
9000       {
9001          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9002             "SCH struct alloc failed for CRNTI:%d",ueCfg->crnti);
9003          err->errCause = RGSCHERR_SCH_CFG;
9004          return (ret);
9005       }
9006    }
9007    /* After initialising UL part, do power related init */
9008    ret = rgSCHPwrUeCfg(cell, ue, ueCfg);
9009    if (ret != ROK)
9010    {
9011       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do "
9012          "power config for UE CRNTI:%d",ueCfg->crnti);
9013       return RFAILED;
9014    }
9015 #ifdef LTEMAC_SPS
9016    ret = rgSCHCmnSpsUeCfg(cell, ue, ueCfg, err);
9017    if (ret != ROK)
9018    {
9019       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do "
9020          "SPS config for CRNTI:%d",ueCfg->crnti);
9021       return RFAILED;
9022    }
9023 #endif /* LTEMAC_SPS */
9024
9025 #ifdef EMTC_ENABLE   
9026    if(TRUE == ue->isEmtcUe)
9027    {
9028       if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
9029       {
9030          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED"
9031                   "for CRNTI:%d",ueCfg->crnti);
9032          return RFAILED;
9033       }
9034    }
9035    else
9036 #endif
9037    {
9038    if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK)
9039    {
9040       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED"
9041                "for CRNTI:%d",ueCfg->crnti);
9042       return RFAILED;
9043    }
9044    }
9045
9046    /* DLFS UE Config */
9047    if (cellSchd->dl.isDlFreqSel)
9048    {
9049       if ((cellSchd->apisDlfs->rgSCHDlfsUeCfg(cell, ue, ueCfg, err)) != ROK)
9050       {
9051          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "DLFS UE config FAILED"
9052                    "for CRNTI:%d",ueCfg->crnti);
9053          return RFAILED;
9054       }
9055    }
9056
9057    /* Fix: syed align multiple UEs to refresh at same time */
9058    rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
9059    /* Start UE Qos Refresh Timer */
9060    rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
9061 #ifdef RG_5GTF
9062    rgSCHCmn5gtfUeCfg(cell, ue, ueCfg);
9063 #endif
9064
9065    return ROK;
9066 }  /* rgSCHCmnRgrUeCfg */
9067
9068 /**
9069  * @brief UE TX mode reconfiguration handler.
9070  *
9071  * @details
9072  *
9073  *     Function : rgSCHCmnDlHdlTxModeRecfg
9074  *
9075  *     This functions updates UE specific scheduler
9076  *     information upon UE reconfiguration.
9077  *
9078  *  @param[in]  RgSchUeCb    *ue
9079  *  @param[in] RgrUeRecfg   *ueRecfg
9080  *  @return  Void
9081  **/
9082 #ifdef TFU_UPGRADE
9083 #ifdef ANSI
9084 static Void rgSCHCmnDlHdlTxModeRecfg
9085 (
9086 RgSchCellCb *cell,
9087 RgSchUeCb    *ue,
9088 RgrUeRecfg   *ueRecfg,
9089 uint8_t numTxPorts
9090 )
9091 #else
9092 static Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, numTxPorts)
9093 RgSchCellCb *cell;
9094 RgSchUeCb    *ue;
9095 RgrUeRecfg   *ueRecfg;
9096 uint8_t numTxPorts;
9097 #endif
9098 #else
9099 #ifdef ANSI
9100 static Void rgSCHCmnDlHdlTxModeRecfg
9101 (
9102 RgSchCellCb *cell,
9103 RgSchUeCb    *ue,
9104 RgrUeRecfg   *ueRecfg
9105 )
9106 #else
9107 static Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg)
9108 RgSchCellCb *cell;
9109 RgSchUeCb    *ue;
9110 RgrUeRecfg   *ueRecfg;
9111 #endif
9112 #endif
9113 {
9114    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
9115
9116    if (ueRecfg->txMode.pres != PRSNT_NODEF)
9117    {
9118       return;
9119    }
9120    /* ccpu00140894- Starting Timer for TxMode Transition Completion*/
9121    ue->txModeTransCmplt =FALSE;
9122    rgSCHTmrStartTmr (ue->cell, ue, RG_SCH_TMR_TXMODE_TRNSTN, RG_SCH_TXMODE_TRANS_TIMER);
9123    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_CMPLT)
9124    {
9125       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell,
9126                                 RG_SCH_CMN_TD_TXMODE_RECFG);
9127      /* MS_WORKAROUND for ccpu00123186 MIMO Fix Start: need to set FORCE TD bitmap based on TX mode */
9128      ueDl->mimoInfo.ri = 1;
9129      if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
9130           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
9131       {
9132          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
9133       }
9134       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
9135       {
9136          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
9137       }
9138       /* MIMO Fix End: need to set FORCE TD bitmap based on TX mode */
9139       return;
9140    }
9141    if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_START)
9142    {
9143       /* start afresh forceTD masking */
9144       RG_SCH_CMN_INIT_FORCE_TD(ue, cell, 0);
9145       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_TXMODE_RECFG);
9146       /* Intialize MIMO related parameters of UE */
9147
9148 #ifdef TFU_UPGRADE
9149       if(ueRecfg->txMode.pres)
9150       {
9151          if((ueRecfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
9152                (ueRecfg->txMode.txModeEnum ==RGR_UE_TM_4))
9153          {
9154             if(ueRecfg->ueCodeBookRstRecfg.pres)
9155             {
9156                ueDl->mimoInfo.ri =
9157                   rgSCHCmnComputeRank(ueRecfg->txMode.txModeEnum,
9158                     ueRecfg->ueCodeBookRstRecfg.pmiBitMap, numTxPorts);
9159             }
9160             else
9161             {
9162                ueDl->mimoInfo.ri = 1;
9163             }
9164          }
9165          else
9166          {
9167             ueDl->mimoInfo.ri = 1;
9168          }
9169       }
9170       else
9171       {
9172          ueDl->mimoInfo.ri = 1;
9173       }
9174 #else
9175       ueDl->mimoInfo.ri = 1;
9176 #endif /* TFU_UPGRADE */
9177       if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) ||
9178           (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6))
9179       {
9180          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
9181       }
9182       if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3)
9183       {
9184          RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
9185       }
9186       return;
9187    }
9188 }
9189 /***********************************************************
9190  *
9191  *     Func : rgSCHCmnUpdUeMimoInfo
9192  *
9193  *     Desc : Updates UL and DL Ue Information
9194  *
9195  *     Ret  :
9196  *
9197  *     Notes:
9198  *
9199  *     File :
9200  *
9201  **********************************************************/
9202 #ifdef ANSI
9203 static Void rgSCHCmnUpdUeMimoInfo
9204 (
9205 RgrUeCfg     *ueCfg,
9206 RgSchCmnDlUe *ueDl,
9207 RgSchCellCb  *cell,
9208 RgSchCmnCell *cellSchd
9209 )
9210 #else
9211 static Void rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd)
9212 RgrUeCfg     *ueCfg;
9213 RgSchCmnDlUe *ueDl;
9214 RgSchCellCb  *cell;
9215 RgSchCmnCell *cellSchd;
9216 #endif
9217 {
9218 #ifdef TFU_UPGRADE
9219    if(ueCfg->txMode.pres)
9220    {
9221       if((ueCfg->txMode.txModeEnum ==RGR_UE_TM_3) ||
9222             (ueCfg->txMode.txModeEnum ==RGR_UE_TM_4))
9223       {
9224          if(ueCfg->ueCodeBookRstCfg.pres)
9225          {
9226             ueDl->mimoInfo.ri =
9227                rgSCHCmnComputeRank(ueCfg->txMode.txModeEnum,
9228                  ueCfg->ueCodeBookRstCfg.pmiBitMap, cell->numTxAntPorts);
9229          }
9230          else
9231          {
9232             ueDl->mimoInfo.ri = 1;
9233          }
9234       }
9235       else
9236       {
9237          ueDl->mimoInfo.ri = 1;
9238       }
9239    }
9240    else
9241    {
9242       ueDl->mimoInfo.ri = 1;
9243    }
9244
9245 #else
9246    ueDl->mimoInfo.ri = 1;
9247 #endif /*TFU_UPGRADE */
9248    ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi;
9249    ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi;
9250
9251    return;
9252 }
9253 /***********************************************************
9254  *
9255  *     Func : rgSCHCmnUpdUeUlCqiInfo
9256  *
9257  *     Desc : Updates UL and DL Ue Information
9258  *
9259  *     Ret  :
9260  *
9261  *     Notes:
9262  *
9263  *     File :
9264  *
9265  **********************************************************/
9266 #ifdef ANSI
9267 static Void rgSCHCmnUpdUeUlCqiInfo
9268 (
9269 RgSchCellCb   *cell,
9270 RgSchUeCb     *ue,
9271 RgSchCmnUlUe  *ueUl,
9272 RgSchCmnUe    *ueSchCmn,
9273 RgSchCmnCell  *cellSchd,
9274 Bool          isEcp
9275 )
9276 #else
9277 static Void rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, isEcp)
9278 RgSchCellCb  *cell;
9279 RgSchUeCb    *ue;
9280 RgSchCmnUlUe *ueUl;
9281 RgSchCmnUe   *ueSchCmn;
9282 RgSchCmnCell *cellSchd;
9283 Bool          isEcp;
9284 #endif
9285 {
9286
9287
9288 #ifdef TFU_UPGRADE
9289    if(ue->srsCb.srsCfg.type  ==  RGR_SCH_SRS_SETUP)
9290    {
9291      if(ue->ul.ulTxAntSel.pres)
9292      {
9293        ueUl->crntUlCqi[ue->srsCb.selectedAnt] = cellSchd->ul.dfltUlCqi;
9294        ueUl->validUlCqi = ueUl->crntUlCqi[ue->srsCb.selectedAnt];
9295      }
9296      else
9297      {
9298        ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
9299        ueUl->validUlCqi =  ueUl->crntUlCqi[0];
9300      }
9301       ue->validTxAnt = ue->srsCb.selectedAnt;
9302    }
9303    else
9304    {
9305       ueUl->validUlCqi = cellSchd->ul.dfltUlCqi;
9306       ue->validTxAnt = 0;
9307    }
9308 #ifdef UL_LA
9309    ueUl->ulLaCb.cqiBasediTbs = rgSchCmnUlCqiToTbsTbl[isEcp]
9310                                                 [ueUl->validUlCqi] * 100;   
9311    ueUl->ulLaCb.deltaiTbs = 0;
9312 #endif
9313
9314 #else
9315    ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi;
9316 #endif /*TFU_UPGRADE */
9317    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat);
9318    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
9319    {
9320       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
9321    }
9322    else
9323    {
9324       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
9325    }
9326
9327    return;
9328 }
9329 /***********************************************************
9330  *
9331  *     Func : rgSCHCmnUpdUeCatCfg
9332  *
9333  *     Desc : Updates UL and DL Ue Information
9334  *
9335  *     Ret  :
9336  *
9337  *     Notes:
9338  *
9339  *     File :
9340  *
9341  **********************************************************/
9342 #ifdef ANSI
9343 static Void rgSCHCmnUpdUeCatCfg
9344 (
9345 RgSchUeCb    *ue,
9346 RgSchCellCb  *cell
9347 )
9348 #else
9349 static Void rgSCHCmnUpdUeCatCfg(ue, cell)
9350 RgSchUeCb    *ue;
9351 RgSchCellCb  *cell;
9352 #endif
9353 {
9354    RgSchDlHqEnt *hqE = NULLP;
9355    RgSchCmnUlUe *ueUl     = RG_SCH_CMN_GET_UL_UE(ue,cell);
9356    RgSchCmnDlUe *ueDl     = RG_SCH_CMN_GET_DL_UE(ue,cell);
9357    RgSchCmnUe   *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell);
9358    RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell);
9359
9360
9361    ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits;
9362    
9363    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
9364    /*CA dev-Start*/
9365    uint8_t ri = 0;
9366    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
9367    if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat )
9368             ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) 
9369          && (RG_SCH_MAX_TX_LYRS_4 == ri))
9370    {
9371       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1];
9372    }
9373    else
9374    {
9375       ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0];
9376    }
9377    /*CA dev-End*/
9378    ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/
9379                            hqE->numHqPrcs);
9380    if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE)
9381    {
9382       ueUl->maxUlCqi = cellSchd->ul.max16qamCqi;
9383    }
9384    else
9385    {
9386       ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1;
9387    }
9388    ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \
9389                    RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8);
9390    return;
9391 }
9392
9393 /**
9394  * @brief UE reconfiguration for scheduler.
9395  *
9396  * @details
9397  *
9398  *     Function : rgSChCmnRgrUeRecfg
9399  *
9400  *     This functions updates UE specific scheduler
9401  *     information upon UE reconfiguration.
9402  *
9403  *  @param[in]  RgSchCellCb  *cell
9404  *  @param[in]  RgSchUeCb    *ue
9405  *  @param[int] RgrUeRecfg   *ueRecfg
9406  *  @param[out] RgSchErrInfo *err
9407  *  @return  S16
9408  *      -# ROK
9409  *      -# RFAILED
9410  **/
9411 #ifdef ANSI
9412 S16 rgSCHCmnRgrUeRecfg
9413 (
9414 RgSchCellCb  *cell,
9415 RgSchUeCb    *ue,
9416 RgrUeRecfg   *ueRecfg,
9417 RgSchErrInfo *err
9418 )
9419 #else
9420 S16 rgSCHCmnRgrUeRecfg(cell, ue, ueRecfg, err)
9421 RgSchCellCb  *cell;
9422 RgSchUeCb    *ue;
9423 RgrUeRecfg   *ueRecfg;
9424 RgSchErrInfo *err;
9425 #endif
9426 {
9427    RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
9428    uint32_t          waitPer;
9429
9430    /* Basic validations */
9431    if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
9432    {
9433 #ifdef TFU_UPGRADE
9434       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, cell->numTxAntPorts);
9435 #else
9436       rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg);
9437 #endif /* TFU_UPGRADE */
9438    }
9439    if(ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG)
9440    {
9441       ue->csgMmbrSta = ueRecfg->csgMmbrSta;
9442    }
9443    /* Changes for UE Category reconfiguration feature */
9444    if(ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
9445    {
9446        rgSCHCmnUpdUeCatCfg(ue, cell);
9447    }
9448    if (ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG)
9449    {
9450       RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue);
9451       pCellInfo->acqiCb.aCqiCfg = ueRecfg->aprdDlCqiRecfg;
9452    }
9453 #ifndef TFU_UPGRADE
9454    if (ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG)
9455    {
9456       if ((ueRecfg->prdDlCqiRecfg.pres == TRUE)
9457             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD10)
9458             && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD20))
9459       {
9460          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unsupported periodic CQI "
9461             "reporting mode %d for old CRNIT:%d", 
9462             (int)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->oldCrnti);
9463          err->errCause = RGSCHERR_SCH_CFG;
9464          return RFAILED;
9465       }
9466      ue->dl.ueDlCqiCfg.prdCqiCfg = ueRecfg->prdDlCqiRecfg;
9467    }
9468 #endif
9469
9470    if (ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG)
9471    {
9472       if (rgSCHPwrUeRecfg(cell, ue, ueRecfg) != ROK)
9473       {
9474          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
9475                "Power Reconfiguration Failed for OLD CRNTI:%d",ueRecfg->oldCrnti);
9476          return RFAILED;
9477       }
9478    }
9479
9480    if (ueRecfg->ueRecfgTypes & RGR_UE_QOS_RECFG)
9481    {
9482       /* Uplink Sched related Initialization */
9483       if ((ueRecfg->ueQosRecfg.dlAmbr == 0) && (ueRecfg->ueQosRecfg.ueBr == 0))
9484       {
9485          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Ul Ambr and DL Ambr "
9486             "configured as 0 for OLD CRNTI:%d",ueRecfg->oldCrnti);
9487          err->errCause = RGSCHERR_SCH_CFG;
9488          return RFAILED;
9489       }
9490       ue->ul.cfgdAmbr = (ueRecfg->ueQosRecfg.ueBr * \
9491       RG_SCH_CMN_REFRESH_TIME)/100;
9492       /* Downlink Sched related Initialization */
9493       ue->dl.ambrCfgd = (ueRecfg->ueQosRecfg.dlAmbr * \
9494       RG_SCH_CMN_REFRESH_TIME)/100;
9495       /* Fix: syed Update the effAmbr and effUeBR fields w.r.t the
9496        * new QOS configuration */
9497       rgSCHCmnDelUeFrmRefreshQ(cell, ue);
9498       /* Fix: syed align multiple UEs to refresh at same time */
9499       rgSCHCmnGetRefreshPer(cell, ue, &waitPer);
9500       rgSCHCmnApplyUeRefresh(cell, ue);
9501       rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer);
9502    }
9503 #ifdef EMTC_ENABLE   
9504    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
9505    {
9506       if ((cellSchCmn->apisEmtcUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9507       {
9508          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9509                "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9510          return RFAILED;
9511       }
9512       if ((cellSchCmn->apisEmtcDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9513       {
9514          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9515                "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9516          return RFAILED;
9517       }
9518    }
9519    else
9520 #endif
9521    {
9522       if ((cellSchCmn->apisUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9523       {
9524          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9525             "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9526          return RFAILED;
9527       }
9528       if ((cellSchCmn->apisDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK)
9529       {
9530          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9531             "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId);
9532          return RFAILED;
9533       }
9534    }
9535    /* DLFS UE Config */
9536    if (cellSchCmn->dl.isDlFreqSel)
9537    {
9538       if ((cellSchCmn->apisDlfs->rgSCHDlfsUeRecfg(cell, ue, \
9539          ueRecfg, err)) != ROK)
9540       {
9541          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9542                "DLFS UE re-config FAILED for CRNTI:%d",ue->ueId);
9543          return RFAILED;
9544       }
9545    }
9546
9547 #ifdef LTEMAC_SPS
9548    /* Invoke re-configuration on SPS module */
9549    if (rgSCHCmnSpsUeRecfg(cell, ue, ueRecfg, err) != ROK)
9550    {
9551       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
9552               "DL SPS ReCFG FAILED for UE CRNTI:%d", ue->ueId);
9553       return RFAILED;
9554    }
9555 #endif
9556
9557    return ROK;
9558 }  /* rgSCHCmnRgrUeRecfg*/
9559
9560 /***********************************************************
9561  *
9562  *     Func : rgSCHCmnUlUeDelAllocs
9563  *
9564  *     Desc : Deletion of all UE allocations.
9565  *
9566  *     Ret  :
9567  *
9568  *     Notes:
9569  *
9570  *     File :
9571  *
9572  **********************************************************/
9573 #ifdef ANSI
9574 static Void rgSCHCmnUlUeDelAllocs
9575 (
9576 RgSchCellCb  *cell,
9577 RgSchUeCb   *ue
9578 )
9579 #else
9580 static Void rgSCHCmnUlUeDelAllocs(cell, ue)
9581 RgSchCellCb  *cell;
9582 RgSchUeCb   *ue;
9583 #endif
9584 {
9585    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
9586    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
9587    uint8_t i;
9588 #ifdef LTEMAC_SPS
9589    RgSchCmnUlUeSpsInfo   *ulSpsUe   = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
9590 #endif
9591
9592    for (i = 0; i < ueUl->hqEnt.numHqPrcs; ++i)
9593    {
9594       RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, i);
9595
9596 #ifdef ERRCLS_KW
9597       /* proc can't be NULL here */
9598       if (proc)
9599 #endif
9600       {
9601          /* R8 Upgrade */
9602          proc->ndi = 0;
9603          if (proc->alloc)
9604          {
9605             /* Added Insure Fixes Of reading Dangling memory.NULLed crntAlloc */
9606 #ifdef LTEMAC_SPS
9607             if(proc->alloc == ulSpsUe->ulSpsSchdInfo.crntAlloc)
9608             {
9609                ulSpsUe->ulSpsSchdInfo.crntAlloc = NULLP;
9610                ulSpsUe->ulSpsSchdInfo.crntAllocSf = NULLP;
9611             }
9612 #endif
9613 #ifdef EMTC_ENABLE
9614             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
9615                   proc->alloc,ue->isEmtcUe);
9616 #else
9617             rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx],
9618                   proc->alloc);
9619 #endif
9620             /* PHY probably needn't be intimated since
9621              * whatever intimation it needs happens at the last minute
9622              */
9623          }
9624          /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
9625           * from adaptive retx List. */
9626          if (proc->reTxLnk.node)
9627          {
9628             {
9629                //TODO_SID: Need to take care
9630                cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); 
9631                proc->reTxLnk.node = (PTR)NULLP;
9632             }
9633          }
9634       }
9635    }
9636    return;
9637 }
9638
9639 /***********************************************************
9640  *
9641  *     Func : rgSCHCmnDelUeFrmRefreshQ
9642  *
9643  *     Desc : Adds a UE to refresh queue, so that the UE is
9644  *            periodically triggered to refresh it's GBR and
9645  *            AMBR values.
9646  *
9647  *     Ret  :
9648  *
9649  *     Notes:
9650  *
9651  *     File :
9652  *
9653  **********************************************************/
9654 #ifdef ANSI
9655 static Void rgSCHCmnDelUeFrmRefreshQ
9656 (
9657 RgSchCellCb     *cell,
9658 RgSchUeCb       *ue
9659 )
9660 #else
9661 static Void rgSCHCmnDelUeFrmRefreshQ(cell, ue)
9662 RgSchCellCb     *cell;
9663 RgSchUeCb       *ue;
9664 #endif
9665 {
9666    RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
9667    CmTmrArg       arg;
9668    RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue);
9669
9670
9671 #ifdef RGL_SPECIFIC_CHANGES
9672    if(ue->refreshOffset < RGSCH_MAX_REFRESH_GRPSZ)
9673    {
9674       if(cell->refreshUeCnt[ue->refreshOffset])
9675       {
9676          cell->refreshUeCnt[ue->refreshOffset]--;
9677       }
9678    }
9679 #endif
9680
9681
9682    memset(&arg, 0, sizeof(arg));
9683    arg.tqCp   = &sched->tmrTqCp;
9684    arg.tq     = sched->tmrTq;
9685    arg.timers = &ueSchd->tmr;
9686    arg.cb     = (PTR)ue;
9687    arg.tNum   = 0;
9688    arg.max    = 1;
9689    arg.evnt   = RG_SCH_CMN_EVNT_UE_REFRESH;
9690
9691    cmRmvCbTq(&arg);
9692    return;
9693 }
9694
9695 /***********************************************************
9696  *
9697  *     Func : rgSCHCmnUeCcchSduDel
9698  *
9699  *     Desc : Clear CCCH SDU scheduling context.
9700  *
9701  *     Ret  :
9702  *
9703  *     Notes:
9704  *
9705  *     File :
9706  *
9707  **********************************************************/
9708 #ifdef ANSI
9709 static Void rgSCHCmnUeCcchSduDel
9710 (
9711 RgSchCellCb  *cell,
9712 RgSchUeCb    *ueCb
9713 )
9714 #else
9715 static Void rgSCHCmnUeCcchSduDel(cell, ueCb)
9716 RgSchCellCb  *cell;
9717 RgSchUeCb    *ueCb;
9718 #endif
9719 {
9720    RgSchDlHqEnt      *hqE = NULLP;
9721    RgSchDlHqProcCb   *ccchSduHqP = NULLP;
9722    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
9723
9724
9725    hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell);
9726    if (hqE == NULLP)
9727    {
9728       return;
9729    }
9730    ccchSduHqP = hqE->ccchSduProc;
9731    if(ueCb->ccchSduLnk.node != NULLP)
9732    {
9733       /* Remove the ccchSduProc if it is in the Tx list */
9734       cmLListDelFrm(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
9735       ueCb->ccchSduLnk.node = NULLP;   
9736    }
9737    else if(ccchSduHqP != NULLP)
9738    {
9739       /* Fix for crash due to stale pdcch. Release ccch pdcch*/
9740       if(ccchSduHqP->pdcch)
9741       {
9742          cmLListDelFrm(&ccchSduHqP->subFrm->pdcchInfo.pdcchs,
9743                &ccchSduHqP->pdcch->lnk);
9744          cmLListAdd2Tail(&cell->pdcchLst, &ccchSduHqP->pdcch->lnk);
9745          ccchSduHqP->pdcch = NULLP;
9746       }
9747       if(ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node != NULLP)
9748       {
9749          /* Remove the ccchSduProc if it is in the retx list */
9750          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
9751           &ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk);
9752          /* ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node = NULLP; */
9753          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
9754       }
9755       else if ((ccchSduHqP->subFrm != NULLP) &&
9756        (ccchSduHqP->hqPSfLnk.node != NULLP))
9757       {
9758          rgSCHUtlDlHqPTbRmvFrmTx(ccchSduHqP->subFrm, 
9759                ccchSduHqP, 0, FALSE);
9760          rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE);
9761       }
9762    }   
9763    return;
9764 }
9765
9766
9767
9768
9769 /**
9770  * @brief UE deletion for scheduler.
9771  *
9772  * @details
9773  *
9774  *     Function : rgSCHCmnUeDel
9775  *
9776  *     This functions deletes all scheduler information
9777  *     pertaining to an UE.
9778  *
9779  *  @param[in]  RgSchCellCb  *cell
9780  *  @param[in]  RgSchUeCb    *ue
9781  *  @return  Void
9782  **/
9783 #ifdef ANSI
9784 Void rgSCHCmnUeDel
9785 (
9786 RgSchCellCb  *cell,
9787 RgSchUeCb    *ue
9788 )
9789 #else
9790 Void rgSCHCmnUeDel(cell, ue)
9791 RgSchCellCb  *cell;
9792 RgSchUeCb    *ue;
9793 #endif
9794 {
9795    RgSchDlHqEnt         *hqE = NULLP;
9796    RgSchCmnUlUe         *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
9797    CmLList              *node;
9798    RgSchCmnAllocRecord  *allRcd;
9799    uint8_t              cnt;
9800    RgSchCmnCell         *cellSchCmn = RG_SCH_CMN_GET_CELL(cell);
9801    uint32_t             idx = 0;
9802
9803    if (RG_SCH_CMN_GET_UE(ue,cell) == NULLP)
9804    {
9805       /* Common scheduler config has not happened yet */
9806       return;
9807    }
9808    hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell);
9809    if(hqE)
9810    {
9811       /* UE Free can be triggered before MSG4 done when dlHqE is not updated */
9812 #ifdef EMTC_ENABLE
9813       if(ue->isEmtcUe)
9814       {
9815          rgSCHEmtcCmnUeCcchSduDel(cell, ue);
9816       }
9817       else
9818 #endif
9819      {    
9820          rgSCHCmnUeCcchSduDel(cell, ue);
9821      }
9822    }
9823    rgSCHCmnDelUeFrmRefreshQ(cell, ue);
9824
9825    rgSCHCmnUlUeDelAllocs(cell, ue);
9826
9827    rgSCHCmnDelRachInfo(cell, ue);
9828
9829 #ifdef EMTC_ENABLE   
9830    if(TRUE == ue->isEmtcUe)
9831    {
9832       cellSchCmn->apisEmtcUl->rgSCHFreeUlUe(cell, ue);
9833    }
9834    else
9835 #endif
9836    {
9837    cellSchCmn->apisUl->rgSCHFreeUlUe(cell, ue);
9838    }
9839 #ifdef LTE_ADV
9840    if (ue->numSCells)
9841    {
9842       for(idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
9843       {
9844          if(ue->cellInfo[idx] != NULLP) 
9845          {
9846             rgSCHSCellDelUeSCell(cell,ue,idx);
9847          }
9848       }
9849
9850    }
9851 #endif
9852 #ifdef EMTC_ENABLE
9853    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
9854    {
9855       cellSchCmn->apisEmtcDl->rgSCHFreeDlUe(cell, ue);
9856    }
9857    else
9858 #endif
9859    {
9860       cellSchCmn->apisDl->rgSCHFreeDlUe(cell, ue);
9861    }
9862    rgSCHPwrUeDel(cell, ue);
9863
9864 #ifdef LTEMAC_SPS
9865    rgSCHCmnSpsUeDel(cell, ue);
9866 #endif /* LTEMAC_SPS*/
9867
9868    /* CA Dev Start*/
9869    rgSchCmnDlSfHqDel(ue, cell);
9870    /* CA Dev End*/
9871    /* DLFS UE delete */
9872    if (cellSchCmn->dl.isDlFreqSel)
9873    {
9874       cellSchCmn->apisDlfs->rgSCHDlfsUeDel(cell, ue);
9875    }
9876    node = ueUl->ulAllocLst.first;
9877
9878 /* ccpu00117052 - MOD - Passing double pointer in all the places of
9879    rgSCHUtlFreeSBuf function call for proper NULLP assignment*/
9880    while(node)
9881    {
9882       allRcd = (RgSchCmnAllocRecord *)node->node;
9883       node = node->next;
9884       cmLListDelFrm(&ueUl->ulAllocLst, &allRcd->lnk);
9885       rgSCHUtlFreeSBuf(cell->instIdx,
9886          (Data**)(&allRcd), (sizeof(RgSchCmnAllocRecord)));
9887    }
9888
9889    for(cnt = 0; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
9890    {
9891       if (ue->ul.lcgArr[cnt].sch != NULLP)
9892       {
9893          rgSCHUtlFreeSBuf(cell->instIdx,
9894             (Data**)(&(ue->ul.lcgArr[cnt].sch)), (sizeof(RgSchCmnLcg)));
9895       }
9896    }
9897
9898    /* Fix : syed Moved hqEnt deinit to rgSCHCmnDlDeInitHqEnt */
9899    idx = (uint8_t)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId) & (CM_LTE_MAX_CELLS - 1));
9900    rgSCHUtlFreeSBuf(cell->instIdx,
9901          (Data**)(&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch))), (sizeof(RgSchCmnUe)));
9902    return;
9903 }  /* rgSCHCmnUeDel */
9904
9905 \f
9906 /**
9907  * @brief This function handles the common code rate configurations
9908  *        done as part of RgrCellCfg/RgrCellRecfg.
9909  *
9910  * @details
9911  *
9912  *     Function: rgSCHCmnDlCnsdrCmnRt
9913  *     Purpose:  This function handles the common code rate configurations
9914  *        done as part of RgrCellCfg/RgrCellRecfg.
9915  *
9916  *     Invoked by: Scheduler
9917  *
9918  *  @param[in]  RgSchCellCb                *cell
9919  *  @param[in]  RgrDlCmnCodeRateCfg     *dlCmnCodeRate
9920  *  @return     S16
9921  *
9922  **/
9923 #ifdef ANSI
9924 static S16 rgSCHCmnDlCnsdrCmnRt
9925 (
9926 RgSchCellCb             *cell,
9927 RgrDlCmnCodeRateCfg     *dlCmnCodeRate
9928 )
9929 #else
9930 static S16 rgSCHCmnDlCnsdrCmnRt(cell, dlCmnCodeRate)
9931 RgSchCellCb             *cell;
9932 RgrDlCmnCodeRateCfg     *dlCmnCodeRate;
9933 #endif
9934 {
9935    RgSchCmnCell         *cellDl = RG_SCH_CMN_GET_CELL(cell);
9936    uint32_t                  bitsPerRb;
9937    uint32_t                  bitsPer2Rb;
9938    uint32_t                  bitsPer3Rb;
9939    uint8_t                   i, rbNum;
9940    uint32_t                  pdcchBits;
9941
9942
9943    /* code rate is bits per 1024 phy bits, since modl'n scheme is 2. it is
9944     * bits per 1024/2 REs */
9945    if (dlCmnCodeRate->bcchPchRaCodeRate != 0)
9946    {
9947       bitsPerRb = ((dlCmnCodeRate->bcchPchRaCodeRate * 2) *
9948             cellDl->dl.noResPerRb[3])/1024;
9949    }
9950    else
9951    {
9952       bitsPerRb = ((RG_SCH_CMN_DEF_BCCHPCCH_CODERATE * 2) *
9953             cellDl->dl.noResPerRb[3])/1024;
9954    }
9955    /* Store bitsPerRb in cellDl->dl to use later to determine
9956     * Number of RBs for UEs with SI-RNTI, P-RNTI and RA-RNTI */
9957    cellDl->dl.bitsPerRb = bitsPerRb;
9958    /* ccpu00115595 end*/
9959    /* calculate the ITbs for 2 RBs. Initialize ITbs to MAX value */
9960    i = 0;
9961    rbNum = 2;
9962    bitsPer2Rb = bitsPerRb * rbNum;
9963    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer2Rb))
9964       i++;
9965
9966    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs2Rbs = 0) :
9967       (cellDl->dl.cmnChITbs.iTbs2Rbs = i-1);
9968
9969    /* calculate the ITbs for 3 RBs. Initialize ITbs to MAX value */
9970    i = 0;
9971    rbNum = 3;
9972    bitsPer3Rb = bitsPerRb * rbNum;
9973    while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer3Rb))
9974          i++;
9975
9976    (i <= 1)? (cellDl->dl.cmnChITbs.iTbs3Rbs = 0) :
9977       (cellDl->dl.cmnChITbs.iTbs3Rbs = i-1);
9978
9979
9980    pdcchBits = 1 + /* Flag for format0/format1a differentiation */
9981       1 + /* Localized/distributed VRB assignment flag */
9982       5 + /* For mcs */
9983 #ifndef LTE_TDD
9984       3 + /* Harq process Id */
9985 #else
9986       4 + /* Harq process Id */
9987       2 + /* UL Index or DAI */
9988 #endif
9989       1 + /* New Data Indicator */
9990       2 + /* For RV */
9991       2 + /* For tpc */
9992       1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \
9993                (cell->bwCfg.dlTotalBw + 1))/2);
9994    /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \
9995       Since VRB is local */
9996    /* For TDD consider DAI */
9997
9998    /* Convert the pdcchBits to actual pdcchBits required for transmission */
9999    if (dlCmnCodeRate->pdcchCodeRate != 0)
10000    {
10001       pdcchBits = (pdcchBits * 1024)/dlCmnCodeRate->pdcchCodeRate;
10002       if (pdcchBits <= 288) /* 288 : Num of pdcch bits for aggrLvl=4 */
10003       {
10004          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
10005       }
10006       else                  /* 576 : Num of pdcch bits for aggrLvl=8 */
10007       {
10008          cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL8;
10009       }
10010    }
10011    else
10012    {
10013       cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4;
10014    }
10015    if (dlCmnCodeRate->ccchCqi == 0)
10016    {
10017       return RFAILED;
10018    }
10019    else
10020    {
10021       cellDl->dl.ccchCqi = dlCmnCodeRate->ccchCqi;
10022    }
10023    return ROK;
10024 }
10025
10026 #ifdef LTE_TDD
10027 /**
10028  * @brief This function handles the configuration of cell for the first
10029  *        time by the scheduler.
10030  *
10031  * @details
10032  *
10033  *     Function: rgSCHCmnDlRgrCellCfg
10034  *     Purpose:  Configuration received is stored into the data structures
10035  *               Also, update the scheduler with the number of frames of
10036  *               RACH preamble transmission.
10037  *
10038  *     Invoked by: BO and Scheduler
10039  *
10040  *  @param[in]  RgSchCellCb*     cell
10041  *  @param[in]  RgrCellCfg*      cfg
10042  *  @return     S16
10043  *
10044  **/
10045 #ifdef ANSI
10046 static S16 rgSCHCmnDlRgrCellCfg
10047 (
10048 RgSchCellCb    *cell,
10049 RgrCellCfg     *cfg,
10050 RgSchErrInfo   *err
10051 )
10052 #else
10053 static S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err)
10054 RgSchCellCb    *cell;
10055 RgrCellCfg     *cfg;
10056 RgSchErrInfo   *err;
10057 #endif
10058 {
10059    RgSchCmnCell         *cellSch;
10060    uint8_t                   cp;
10061    uint8_t                   sfCount;
10062    uint8_t                   numPdcchSym;
10063    uint8_t                   noSymPerSlot;
10064    uint8_t                   maxDlSubfrms = cell->numDlSubfrms;
10065    uint8_t                   splSubfrmIdx = cfg->spclSfCfgIdx;
10066    uint8_t                   swPtCnt = 0;
10067    Bool                 isSplfrm;
10068    RgSchTddSubfrmInfo   subfrmInfo = rgSchTddMaxUlSubfrmTbl[cell->ulDlCfgIdx];
10069    S16                  ret;
10070    uint8_t                   splSfIdx;
10071    uint8_t                   antPortIdx;
10072    uint8_t                   numCrs;
10073    uint8_t                   cfi;  
10074    uint8_t                   cfiIdx;
10075    RgSchDlSf            *sf;
10076    uint8_t                   splSfCfi;
10077    uint8_t                   mPhich;
10078
10079    
10080
10081    cellSch = RG_SCH_CMN_GET_CELL(cell);
10082    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->\
10083                                                   rachCfg.preambleFormat];
10084    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
10085    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
10086    
10087    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
10088                        3 TTI (MAX L1+L2 processing delay at the UE) */
10089    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
10090                                  rgSchCmnHarqRtt[cell->ulDlCfgIdx] + 3; 
10091    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10092    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10093    if (cfg->maxUePerDlSf == 0)
10094    {
10095       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10096    }
10097    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
10098    {
10099       return RFAILED;
10100    }
10101
10102
10103    if (cell->bwCfg.dlTotalBw <= 10)
10104    {
10105       cfiIdx = 1;
10106       numPdcchSym = 2;
10107    }
10108    else
10109    {
10110       cfiIdx = 0;
10111       numPdcchSym = 1;
10112    }
10113    /* DwPTS Scheduling Changes Start */
10114    cellSch->dl.splSfCfg  = splSubfrmIdx;
10115  
10116    if (cfg->isCpDlExtend == TRUE)
10117    {
10118       if((0 == splSubfrmIdx) || (4 == splSubfrmIdx) ||
10119          (7 == splSubfrmIdx) || (8 == splSubfrmIdx)
10120         )
10121       {
10122          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
10123       }
10124       else
10125       {
10126          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
10127       }
10128    }
10129    else
10130    {
10131       /* Refer to 36.213 Section 7.1.7 */
10132       if((0 == splSubfrmIdx) || (5 == splSubfrmIdx))
10133       {
10134          cell->splSubfrmCfg.isDlDataAllowed = FALSE; 
10135       }
10136       else
10137       {
10138          cell->splSubfrmCfg.isDlDataAllowed = TRUE; 
10139       }
10140    }
10141    /* DwPTS Scheduling Changes End */  
10142
10143    splSfCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
10144    RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
10145    
10146    for (sfCount = 0; sfCount < maxDlSubfrms; sfCount++)
10147    {
10148       sf = cell->subFrms[sfCount];
10149       /* Sfcount matches the first special subframe occurs at Index 0
10150             * or subsequent special subframes */
10151       if(subfrmInfo.switchPoints == 1)
10152       {
10153          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
10154                                  RG_SCH_CMN_10_MS_PRD, &subfrmInfo);
10155       }
10156       else
10157       {
10158          isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount,
10159                                  RG_SCH_CMN_5_MS_PRD, &subfrmInfo);
10160       }
10161       if(isSplfrm == TRUE)
10162       {
10163          swPtCnt++;
10164          /* DwPTS Scheduling Changes Start */        
10165          if (cell->splSubfrmCfg.isDlDataAllowed == TRUE)
10166          {
10167             sf->sfType = RG_SCH_SPL_SF_DATA;
10168          }
10169          else
10170          {
10171             sf->sfType = RG_SCH_SPL_SF_NO_DATA;
10172          }
10173          /* DwPTS Scheduling Changes End */
10174       }
10175       else
10176       {
10177          /* DwPTS Scheduling Changes Start */
10178          if (sf->sfNum != 0)
10179          {
10180             sf->sfType = RG_SCH_DL_SF;
10181          }
10182          else
10183          {
10184             sf->sfType = RG_SCH_DL_SF_0;
10185          }
10186          /* DwPTS Scheduling Changes End */
10187       }
10188       
10189       /* Calculate the number of CCEs per subframe in the cell */
10190       mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][sf->sfNum];
10191       if(cell->dynCfiCb.isDynCfiEnb == TRUE)
10192       {   
10193          /* In case if Dynamic CFI feature is enabled, default CFI 
10194           * value 1 is used  */
10195          sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][1];
10196       }
10197       else
10198       {
10199          if (sf->sfType == RG_SCH_SPL_SF_DATA)
10200          {
10201             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
10202          }
10203          else
10204          {
10205             sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi)];
10206          }
10207       }   
10208    }
10209
10210    /* Intialize the RACH response scheduling related infromation */
10211    if(rgSCHCmnDlRachInfoInit(cell) != ROK)
10212    {
10213      return RFAILED;
10214    }
10215
10216    /* Allocate PRACH preamble list */
10217    rgSCHCmnDlCreateRachPrmLst(cell);
10218
10219    /* Initialize PHICH offset information */
10220    rgSCHCmnDlPhichOffsetInit(cell);
10221
10222    /* Update the size of HARQ ACK/NACK feedback table */
10223    /* The array size is increased by 2 to have enough free indices, where other
10224     * indices are busy waiting for HARQ feedback */
10225    cell->ackNackFdbkArrSize = rgSchTddANFdbkMapTbl[cell->ulDlCfgIdx] + 2; 
10226
10227    /* Initialize expected HARQ ACK/NACK feedback time */
10228    rgSCHCmnDlANFdbkInit(cell);
10229
10230    /* Initialize UL association set index */
10231    if(cell->ulDlCfgIdx != 0)
10232    {
10233       rgSCHCmnDlKdashUlAscInit(cell);
10234    }
10235
10236    if (cfg->isCpDlExtend == TRUE)
10237    {
10238       cp = RG_SCH_CMN_EXT_CP;
10239       noSymPerSlot = 6;
10240       cell->splSubfrmCfg.dwPts =
10241           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlDwPts;
10242    
10243       if ( cell->splSubfrmCfg.dwPts == 0 )
10244       {
10245          cell->isDwPtsCnted = FALSE;
10246       }
10247       else
10248       {
10249          cell->isDwPtsCnted = TRUE;
10250       }
10251
10252       if(cfg->isCpUlExtend == TRUE)
10253       {
10254          cell->splSubfrmCfg.upPts =
10255             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlExtUpPts;
10256       }
10257       else
10258       {
10259          cell->splSubfrmCfg.upPts =
10260             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlNorUpPts;
10261       }
10262    }
10263    else
10264    {
10265       cp = RG_SCH_CMN_NOR_CP;
10266       noSymPerSlot = 7;
10267       cell->splSubfrmCfg.dwPts =
10268           rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlDwPts;
10269       cell->isDwPtsCnted = TRUE;
10270
10271       if(cfg->isCpUlExtend == TRUE)
10272       {
10273          cell->splSubfrmCfg.upPts =
10274             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlExtUpPts;
10275       }
10276       else
10277       {
10278          cell->splSubfrmCfg.upPts =
10279             rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlNorUpPts;
10280       }
10281    }
10282
10283    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
10284    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++,cfiIdx++)
10285    {   
10286       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
10287       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
10288                                                  [cell->numTxAntPorts]][cfiIdx];
10289       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
10290       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
10291                                                  [cell->numTxAntPorts]][cfiIdx];
10292    }
10293
10294    /* Initializing the values of CFI parameters */
10295    if(cell->dynCfiCb.isDynCfiEnb)
10296    {   
10297       /* If DCFI is enabled, current CFI value will start from 1 */
10298       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
10299    }
10300    else
10301    {
10302       /* If DCFI is disabled, current CFI value is set as default max allowed CFI value */
10303       cellSch->dl.currCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi);
10304       cellSch->dl.newCfi = cellSch->dl.currCfi;
10305    }   
10306
10307    /* Include CRS REs while calculating Efficiency
10308     * The number of Resource Elements occupied by CRS depends on Number of
10309     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
10310     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
10311     * details of the same. Please note that PDCCH overlap symbols would not
10312     * considered in CRS REs deduction */
10313    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
10314    {
10315       cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
10316             - numPdcchSym) *RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
10317    }
10318
10319    /* DwPTS Scheduling Changes Start */
10320    antPortIdx = (cell->numTxAntPorts == 1)? 0: 
10321       ((cell->numTxAntPorts == 2)? 1: 2);     
10322
10323    if (cp == RG_SCH_CMN_NOR_CP)
10324    {
10325       splSfIdx = (splSubfrmIdx == 4)? 1: 0;   
10326    }
10327    else
10328    {
10329       splSfIdx = (splSubfrmIdx == 3)? 1: 0;
10330    }
10331
10332    numCrs = rgSchCmnDwptsCrs[splSfIdx][antPortIdx];
10333
10334    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI-1; cfi++)
10335    { 
10336       /* If CFI is 2 and Ant Port is 4, don't consider the sym 1 CRS REs */  
10337       if (antPortIdx == 2 && cfi == 2)
10338       {
10339          numCrs -= 4;      
10340       }
10341       cellSch->dl.numReDwPts[cfi]  =  ((cell->splSubfrmCfg.dwPts - cfi)*
10342                                   RB_SCH_CMN_NUM_SCS_PER_RB) - numCrs;
10343    }
10344    /* DwPTS Scheduling Changes End */
10345
10346    if (cfg->maxDlBwPerUe == 0)
10347    {
10348       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
10349    }
10350    else
10351    {
10352       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
10353    }
10354    if (cfg->maxDlRetxBw == 0)
10355    {
10356       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
10357    }
10358    else
10359    {
10360       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
10361    }
10362    /* Fix: MUE_PERTTI_DL*/
10363    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10364    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10365    if (cfg->maxUePerDlSf == 0)
10366    {
10367       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10368    }
10369    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
10370    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
10371    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
10372    {
10373       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
10374                       "Invalid configuration !: "
10375                       "maxCcchPerDlSf %u > maxUePerDlSf %u",
10376                    cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
10377
10378       return RFAILED;
10379    }
10380    else if (!cfg->maxCcchPerDlSf)
10381    {
10382       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
10383        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
10384        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
10385        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
10386        * FLE crash in PHY as PHY has limit of 16 max*/
10387       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
10388    }
10389    else
10390    {
10391       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
10392    }
10393    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
10394    {
10395       return RFAILED;
10396    }
10397
10398    /*ccpu00118273 - ADD - start */
10399    cmLListInit(&cellSch->dl.msg4RetxLst);
10400 #ifdef RGR_V1
10401    cmLListInit(&cellSch->dl.ccchSduRetxLst);
10402 #endif
10403
10404 #ifdef RG_PHASE2_SCHED
10405    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
10406    {
10407       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
10408    }
10409    if (cfg->dlfsCfg.isDlFreqSel)
10410    {
10411       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
10412       if (ret != ROK)
10413       {
10414          return RFAILED;
10415       }
10416    }
10417    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
10418 #endif
10419
10420    /* Power related configuration */
10421    ret = rgSCHPwrCellCfg(cell, cfg);
10422    if (ret != ROK)
10423    {
10424       return RFAILED;
10425    }
10426
10427    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
10428    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
10429    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
10430    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
10431    cellSch->dl.msg4pAVal        = cfg->msg4pAVal;
10432    return ROK;
10433 }
10434 #else /* LTE_TDD */
10435 /**
10436  * @brief This function handles the configuration of cell for the first
10437  *        time by the scheduler.
10438  *
10439  * @details
10440  *
10441  *     Function: rgSCHCmnDlRgrCellCfg
10442  *     Purpose:  Configuration received is stored into the data structures
10443  *               Also, update the scheduler with the number of frames of
10444  *               RACH preamble transmission.
10445  *
10446  *     Invoked by: BO and Scheduler
10447  *
10448  *  @param[in]  RgSchCellCb*   cell
10449  *  @param[in]  RgrCellCfg*    cfg
10450  *  @param[in]  RgSchErrInfo*  err
10451  *  @return     S16
10452  *
10453  **/
10454 #ifdef ANSI
10455 static S16 rgSCHCmnDlRgrCellCfg
10456 (
10457 RgSchCellCb             *cell,
10458 RgrCellCfg              *cfg,
10459 RgSchErrInfo            *err
10460 )
10461 #else
10462 static S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err)
10463 RgSchCellCb             *cell;
10464 RgrCellCfg              *cfg;
10465 RgSchErrInfo            *err;
10466 #endif
10467 {
10468    S16                 ret;
10469    RgSchCmnCell        *cellSch;
10470    uint8_t                   cp;
10471    uint8_t                   numPdcchSym;
10472    uint8_t                   noSymPerSlot;
10473    uint8_t                   cfi;  
10474    uint8_t                   cfiIdx;
10475
10476
10477    cellSch = RG_SCH_CMN_GET_CELL(cell);
10478
10479    /* Initialize the parameters with the ones received in the */
10480    /* configuration.                                          */
10481
10482    /* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA
10483     * sub-frames from preamble format */
10484    cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat];
10485
10486    /*[ccpu00138532]-ADD-fill the Msg4 Harq data */
10487    cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx;                                                
10488    
10489    /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX)  + 
10490                        3 TTI (MAX L1+L2 processing delay at the UE) */
10491    cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) *
10492                                  rgSchCmnHarqRtt[7] + 3; 
10493
10494    if (cell->bwCfg.dlTotalBw <= 10)
10495    {
10496       cfiIdx = 1;
10497       numPdcchSym = 2;
10498    }
10499    else
10500    {
10501       cfiIdx = 0;
10502       numPdcchSym = 1;
10503    }
10504
10505    if (cell->isCpDlExtend == TRUE)
10506    {
10507       cp = RG_SCH_CMN_EXT_CP;
10508       noSymPerSlot = 6;
10509    }
10510    else
10511    {
10512       cp = RG_SCH_CMN_NOR_CP;
10513       noSymPerSlot = 7;
10514    }
10515
10516    /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */
10517    for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, cfiIdx++)
10518    {   
10519       cellSch->dl.cqiToTbsTbl[0][cfi]   = rgSchCmnCqiToTbs[0][cp][cfiIdx];
10520 #ifdef EMTC_ENABLE      
10521       cellSch->dl.emtcCqiToTbsTbl[0][cfi]   = rgSchEmtcCmnCqiToTbs[0][cp][cfiIdx];
10522 #endif      
10523       cellSch->dl.cqiToEffTbl[0][cfi]   = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\
10524                                                  [cell->numTxAntPorts]][cfiIdx];
10525       cellSch->dl.cqiToTbsTbl[1][cfi]   = rgSchCmnCqiToTbs[1][cp][cfiIdx];
10526 #ifdef EMTC_ENABLE      
10527       cellSch->dl.emtcCqiToTbsTbl[1][cfi]   = rgSchEmtcCmnCqiToTbs[1][cp][cfiIdx];
10528 #endif      
10529       cellSch->dl.cqiToEffTbl[1][cfi]   = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\
10530                                                  [cell->numTxAntPorts]][cfiIdx];
10531    }
10532
10533    /* Initializing the values of CFI parameters */
10534    if(cell->dynCfiCb.isDynCfiEnb)
10535    {   
10536       /* If DCFI is enabled, current CFI value will start from 1 */
10537       cellSch->dl.currCfi = cellSch->dl.newCfi = 1;
10538    }
10539    else
10540    {
10541       /* If DCFI is disabled, current CFI value is set as default CFI value */
10542       cellSch->dl.currCfi = cellSch->cfiCfg.cfi;
10543       cellSch->dl.newCfi = cellSch->dl.currCfi;
10544    }   
10545
10546    /* Include CRS REs while calculating Efficiency
10547     * The number of Resource Elements occupied by CRS depends on Number of
10548     * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0.
10549     * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic
10550     * details of the same. Please note that PDCCH overlap symbols would not
10551     * considered in CRS REs deduction */
10552    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++)
10553    {
10554        cellSch->dl.noResPerRb[cfi]    = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF)
10555             - numPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts];
10556    }           
10557
10558    if (cfg->maxDlBwPerUe == 0)
10559    {
10560       cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE;
10561    }
10562    else
10563    {
10564       cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe;
10565    }
10566    if (cfg->maxDlRetxBw == 0)
10567    {
10568       cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW;
10569    }
10570    else
10571    {
10572       cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw;
10573    }
10574    
10575    /* Fix: MUE_PERTTI_DL*/
10576    cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf;
10577    cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti;
10578    if (cfg->maxUePerDlSf == 0)
10579    {
10580       cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF;
10581    }
10582    /* Fix: MUE_PERTTI_DL syed validating Cell Configuration */
10583    if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti)
10584    {
10585       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
10586             "FAILED MaxUePerDlSf(%u) < MaxDlUeNewTxPerTti(%u)",
10587             cellSch->dl.maxUePerDlSf,
10588             cellSch->dl.maxUeNewTxPerTti);
10589       return RFAILED;
10590    }
10591    /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */
10592    if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf)
10593    {
10594       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid configuration !: "
10595             "maxCcchPerDlSf %u > maxUePerDlSf %u",
10596             cfg->maxCcchPerDlSf, cfg->maxUePerDlSf );
10597
10598       return RFAILED;
10599    }
10600    else if (!cfg->maxCcchPerDlSf)
10601    {
10602       /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application
10603        * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler
10604        * does't consider CCCH allocation in MaxUePerTti cap. Hence more than
10605        * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes
10606        * FLE crash in PHY as PHY has limit of 16 max*/
10607       cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf;
10608    }
10609    else
10610    {
10611       cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf;
10612    }
10613
10614
10615    if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK)
10616    {
10617       return RFAILED;
10618    }
10619    cmLListInit(&cellSch->dl.msg4RetxLst);
10620 #ifdef RGR_V1
10621    cmLListInit(&cellSch->dl.ccchSduRetxLst);
10622 #endif
10623
10624 #ifdef RG_PHASE2_SCHED
10625    if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */
10626    {
10627       cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType];
10628    }
10629    if (cfg->dlfsCfg.isDlFreqSel)
10630    {
10631       ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err);
10632       if (ret != ROK)
10633       {
10634          return RFAILED;
10635       }
10636    }
10637    cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel;
10638 #endif
10639
10640    /* Power related configuration */
10641    ret = rgSCHPwrCellCfg(cell, cfg);
10642    if (ret != ROK)
10643    {
10644       return RFAILED;
10645    }
10646
10647    cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; 
10648    cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; 
10649    cellSch->dl.rarTxPwrOffset  = cfg->rarTxPwrOffset; 
10650    cellSch->dl.phichTxPwrOffset  = cfg->phichTxPwrOffset; 
10651    RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl);
10652    return ROK;
10653 }
10654 #endif /* LTE_TDD */
10655
10656 /***********************************************************
10657  *
10658  *     Func : rgSCHCmnUlCalcReqRbCeil
10659  *
10660  *     Desc : Calculate RB required to satisfy 'bytes' for
10661  *            a given CQI.
10662  *            Returns number of RBs such that requirement
10663  *            is necessarily satisfied (does a 'ceiling'
10664  *            computation).
10665  *
10666  *     Ret  : Required RBs (uint8_t)
10667  *
10668  *     Notes:
10669  *
10670  *     File :
10671  *
10672  **********************************************************/
10673 #ifdef ANSI
10674 uint8_t rgSCHCmnUlCalcReqRbCeil
10675 (
10676 uint32_t            bytes,
10677 uint8_t             cqi,
10678 RgSchCmnUlCell *cellUl
10679 )
10680 #else
10681 uint8_t rgSCHCmnUlCalcReqRbCeil(bytes, cqi, cellUl)
10682 uint32_t            bytes;
10683 uint8_t             cqi;
10684 RgSchCmnUlCell *cellUl;
10685 #endif
10686 {
10687    uint32_t numRe = RGSCH_CEIL((bytes * 8) * 1024, rgSchCmnUlCqiTbl[cqi].eff);
10688    return ((uint8_t)RGSCH_CEIL(numRe, RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl)));
10689 }
10690
10691 /***********************************************************
10692  *
10693  *     Func : rgSCHCmnPrecompMsg3Vars
10694  *
10695  *     Desc : Precomputes the following for msg3 allocation:
10696  *            1. numSb and Imcs for msg size A
10697  *            2. numSb and Imcs otherwise
10698  *
10699  *     Ret  :
10700  *
10701  *     Notes: The corresponding vars in cellUl struct is filled
10702  *            up
10703  *
10704  *     File :
10705  *
10706  **********************************************************/
10707 #ifdef ANSI
10708 static S16 rgSCHCmnPrecompMsg3Vars
10709 (
10710 RgSchCmnUlCell *cellUl,
10711 uint8_t           ccchCqi,
10712 uint16_t          msgSzA,
10713 uint8_t           sbSize,
10714 Bool         isEcp
10715 )
10716 #else
10717 static S16 rgSCHCmnPrecompMsg3Vars(cellUl, ccchCqi, msgSzA, sbSize, isEcp)
10718 RgSchCmnUlCell *cellUl;
10719 uint8_t           ccchCqi;
10720 uint16_t          msgSzA;
10721 uint8_t           sbSize;
10722 Bool         isEcp;
10723 #endif
10724 {
10725    uint8_t numSb;
10726    uint8_t ccchTbs;
10727    uint8_t ccchMcs;
10728    uint8_t   numRb = 0;
10729    uint8_t   iTbs = 0;
10730    uint16_t  msg3GrntSz = 0;
10731
10732
10733    if (ccchCqi > cellUl->max16qamCqi)
10734    {
10735       ccchCqi = cellUl->max16qamCqi;
10736    }
10737 /* #ifndef RG_SCH_CMN_EXP_CP_SUP For ECP Pick the index 1 */
10738    /* Fix */
10739    ccchTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
10740    ccchMcs = rgSCHCmnUlGetIMcsFrmITbs(ccchTbs, CM_LTE_UE_CAT_1);
10741    
10742    /* MCS should fit in 4 bits in RAR */
10743    if (ccchMcs >= 15)
10744    {
10745       ccchMcs = 15;
10746    }
10747    
10748    /* Limit the ccchMcs to 15 as it
10749     * can be inferred from 36.213, section 6.2 that msg3 imcs
10750     * field is 4 bits.
10751     * Since, UE doesn't exist right now, we use CAT_1 for ue
10752     * category*/
10753    while((ccchMcs = (rgSCHCmnUlGetIMcsFrmITbs(
10754                       rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi],CM_LTE_UE_CAT_1))
10755                     ) >
10756                  RG_SCH_CMN_MAX_MSG3_IMCS)
10757    {
10758       ccchCqi--;
10759    }
10760    
10761    iTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ccchCqi];
10762    
10763    if (msgSzA < RGSCH_MIN_MSG3_GRNT_SZ)
10764    {
10765       return RFAILED;
10766    }
10767    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(msgSzA, ccchCqi, cellUl), sbSize);
10768    
10769    numRb   = numSb * sbSize;
10770    msg3GrntSz = 8 * msgSzA;
10771
10772    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
10773    {
10774       ++numSb;
10775       numRb   = numSb * sbSize;
10776    }
10777    while (rgSchCmnMult235Tbl[numSb].match != numSb)
10778    {
10779       ++numSb;
10780    }
10781    /* Reversed(Corrected) the assignment for preamble-GrpA
10782     * Refer- TG36.321- section- 5.1.2*/
10783    cellUl->ra.prmblBNumSb = numSb;
10784    cellUl->ra.prmblBIMcs  = ccchMcs;
10785    numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(RGSCH_MIN_MSG3_GRNT_SZ, \
10786                       ccchCqi, cellUl),
10787          sbSize);
10788
10789    numRb   = numSb * sbSize;
10790    msg3GrntSz = 8 * RGSCH_MIN_MSG3_GRNT_SZ;
10791    while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz)
10792    {
10793       ++numSb;
10794       numRb   = numSb * sbSize;
10795    }
10796    while (rgSchCmnMult235Tbl[numSb].match != numSb)
10797    {
10798       ++numSb;
10799    }
10800    /* Reversed(Corrected) the assignment for preamble-GrpA
10801     * Refer- TG36.321- section- 5.1.2*/
10802    cellUl->ra.prmblANumSb = numSb;
10803    cellUl->ra.prmblAIMcs  = ccchMcs;
10804    return ROK;
10805 }
10806
10807 uint32_t gPrntPucchDet=0;
10808
10809 #ifdef LTE_TDD
10810 /***********************************************************
10811  *
10812  *     Func : rgSCHCmnUlCalcAvailBw
10813  *
10814  *     Desc : Calculates bandwidth available for PUSCH scheduling.
10815  *
10816  *     Ret  : S16 (ROK/RFAILED)
10817  *
10818  *     Notes:
10819  *
10820  *     File :
10821  *
10822  **********************************************************/
10823 #ifdef ANSI
10824 static S16 rgSCHCmnUlCalcAvailBw
10825 (
10826 RgSchCellCb    *cell,
10827 RgrCellCfg     *cellCfg,
10828 uint8_t              cfi,
10829 uint8_t             *rbStartRef,
10830 uint8_t             *bwAvailRef
10831 )
10832 #else
10833 static S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef)
10834 RgSchCellCb   *cell;
10835 RgrCellCfg    *cellCfg;
10836 uint8_t             cfi;  
10837 uint8_t            *rbStartRef;
10838 uint8_t            *bwAvailRef;
10839 #endif
10840 {
10841    uint8_t  c        = 3;
10842    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
10843    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
10844    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
10845    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
10846    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
10847
10848    uint8_t  n1PerRb;
10849    uint8_t  totalCce;
10850    uint16_t n1Max;
10851    uint8_t  n1Rb;
10852    uint32_t mixedRb;
10853    uint8_t  exclRb; /* RBs to exclude */
10854    uint8_t  n1RbPart;
10855    uint8_t  puschRbStart;
10856    /* To avoid PUCCH and PUSCH collision issue */
10857    uint8_t  P;
10858    uint8_t  n1PlusOne;
10859    uint8_t  mi;
10860    /* Maximum value of M as per Table 10.1-1 */
10861    uint8_t  M[RGSCH_MAX_TDD_UL_DL_CFG] = {1, 2, 4, 3, 4, 9, 1};
10862
10863
10864    if (cell->isCpUlExtend)
10865    {
10866       c = 2;
10867    }
10868
10869    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
10870
10871    /* Considering the max no. of CCEs for PUSCH BW calculation 
10872     * based on min mi value */
10873    if (cell->ulDlCfgIdx == 0 || cell->ulDlCfgIdx == 6)
10874    {
10875       mi = 1;
10876    }
10877    else
10878    { 
10879       mi = 0;
10880    }
10881    
10882    totalCce = cell->dynCfiCb.cfi2NCceTbl[mi][cfi];
10883
10884    P        = rgSCHCmnGetPValFrmCCE(cell, totalCce-1);
10885    n1PlusOne = cell->rgSchTddNpValTbl[P + 1];
10886    n1Max    = (M[cell->ulDlCfgIdx] - 1)*n1PlusOne + (totalCce-1) + n1Pucch;
10887
10888    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
10889     * TS 36.211  */
10890    n1RbPart = (c*n1Cs)/pucchDeltaShft;
10891    n1Rb = (n1Max - n1RbPart)/ n1PerRb;
10892    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
10893
10894    /* get the total Number of RB's to be excluded for PUSCH */
10895    /* ccpu00137339 */
10896    if(n1Pucch < n1RbPart)
10897    {
10898       exclRb = n2Rb;
10899    }
10900    else
10901    {
10902       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
10903    }
10904    puschRbStart = exclRb/2 + 1; 
10905
10906    /* Num of PUCCH RBs = puschRbStart*2 */
10907    if (puschRbStart * 2 >= ulBw)
10908    {
10909       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH");
10910       return RFAILED;
10911    }
10912
10913    *rbStartRef = puschRbStart;
10914    *bwAvailRef = ulBw -  puschRbStart * 2;
10915  
10916    if(cell->pucchCfg.maxPucchRb !=0 && 
10917          (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
10918    {
10919       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
10920    }
10921     
10922    return ROK;
10923 }
10924 #else
10925
10926 /***********************************************************
10927  *
10928  *     Func : rgSCHCmnUlCalcAvailBw
10929  *
10930  *     Desc : Calculates bandwidth available for PUSCH scheduling.
10931  *
10932  *     Ret  : S16 (ROK/RFAILED)
10933  *
10934  *     Notes:
10935  *
10936  *     File :
10937  *
10938  **********************************************************/
10939 #ifdef ANSI
10940 static S16 rgSCHCmnUlCalcAvailBw
10941 (
10942 RgSchCellCb    *cell,
10943 RgrCellCfg     *cellCfg,
10944 uint8_t              cfi,
10945 uint8_t             *rbStartRef,
10946 uint8_t             *bwAvailRef
10947 )
10948 #else
10949 static S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef)
10950 RgSchCellCb   *cell;
10951 RgrCellCfg    *cellCfg;
10952 uint8_t             cfi;
10953 uint8_t            *rbStartRef;
10954 uint8_t            *bwAvailRef;
10955 #endif
10956 {
10957    uint8_t  c        = 3;
10958    uint8_t  ulBw     = cell->bwCfg.ulTotalBw;
10959    uint8_t  n2Rb     = cell->pucchCfg.resourceSize;
10960    uint8_t  pucchDeltaShft = cell->pucchCfg.deltaShift;
10961    uint16_t n1Pucch  = cell->pucchCfg.n1PucchAn;
10962    uint8_t  n1Cs     = cell->pucchCfg.cyclicShift;
10963    uint8_t  n1PerRb;
10964    uint8_t  totalCce;
10965    uint16_t n1Max;
10966    uint8_t  n1Rb;
10967    uint32_t mixedRb;
10968    uint8_t  exclRb; /* RBs to exclude */
10969    uint8_t  n1RbPart;
10970    uint8_t  puschRbStart;
10971 #ifdef LTE_ADV
10972    uint16_t numOfN3PucchRb;
10973    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);  
10974 #endif
10975    
10976
10977    if (cell->isCpUlExtend)
10978    {
10979       c = 2;
10980    }
10981
10982    n1PerRb  = c * 12 / pucchDeltaShft; /* 12/18/36 */
10983
10984    totalCce = cell->dynCfiCb.cfi2NCceTbl[0][cfi];
10985
10986    n1Max    = n1Pucch + totalCce-1;
10987
10988    /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in 
10989     * TS 36.211  */
10990    n1RbPart = (c*n1Cs)/pucchDeltaShft;
10991    n1Rb = (uint8_t)((n1Max - n1RbPart) / n1PerRb);
10992    mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */
10993
10994    /* get the total Number of RB's to be excluded for PUSCH */
10995    /* ccpu00137339 */
10996    if(n1Pucch < n1RbPart)
10997    {
10998       exclRb = n2Rb;
10999    }
11000    else
11001    {
11002       exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */
11003    }
11004    /*Support for PUCCH Format 3*/
11005 #ifdef LTE_ADV
11006    if (cell->isPucchFormat3Sptd)
11007    {
11008       numOfN3PucchRb = RGSCH_CEIL(cellSch->dl.maxUePerDlSf,5); 
11009       exclRb = exclRb + numOfN3PucchRb;
11010    }
11011 #endif
11012    puschRbStart = exclRb/2 + 1;
11013
11014    if(gPrntPucchDet)
11015    {
11016 #ifndef ALIGN_64BIT
11017            printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%ld:%d:%d:%d:%d:%d]\n",
11018         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
11019 #else
11020            printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%d:%d:%d:%d:%d:%d]\n",
11021         cell->crntTime.sfn, cell->crntTime.slot, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb);
11022 #endif
11023    }
11024
11025    if (puschRbStart*2 >= ulBw)
11026    {
11027       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH");
11028       return RFAILED;
11029    }
11030
11031    *rbStartRef = puschRbStart;
11032    *bwAvailRef = ulBw - puschRbStart * 2;
11033
11034    if(cell->pucchCfg.maxPucchRb !=0 && 
11035       (puschRbStart * 2 > cell->pucchCfg.maxPucchRb))
11036    {
11037       cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi);
11038    }
11039    
11040    return ROK;
11041 }
11042 #endif
11043
11044
11045
11046 /***********************************************************
11047  *
11048  *     Func : rgSCHCmnUlCellInit
11049  *
11050  *     Desc : Uplink scheduler initialisation for cell.
11051  *
11052  *     Ret  : S16
11053  *
11054  *     Notes:
11055  *
11056  *     File :
11057  *
11058  **********************************************************/
11059 #ifdef ANSI
11060 static S16 rgSCHCmnUlCellInit
11061 (
11062  RgSchCellCb  *cell,
11063  RgrCellCfg   *cellCfg
11064  )
11065 #else
11066 static S16 rgSCHCmnUlCellInit(cell, cellCfg)
11067    RgSchCellCb *cell;
11068    RgrCellCfg  *cellCfg;
11069 #endif
11070 {
11071    S16            ret;
11072    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
11073    uint8_t             maxUePerUlSf = cellCfg->maxUePerUlSf;
11074 #ifdef RGR_V1
11075    /* Added configuration for maximum number of MSG3s */
11076    uint8_t             maxMsg3PerUlSf = cellCfg->maxMsg3PerUlSf;
11077 #endif
11078    uint8_t             maxUlBwPerUe = cellCfg->maxUlBwPerUe;
11079    uint8_t             sbSize       = cellCfg->puschSubBand.size;
11080    uint8_t             i;
11081    uint8_t             rbStart;
11082    uint8_t             bwAvail;
11083    uint8_t             cfi;  
11084    uint8_t             maxSbPerUe;
11085    uint8_t             numSb;
11086 #ifdef LTE_TDD
11087    uint16_t            ulDlCfgIdx = cell->ulDlCfgIdx;
11088    /* [ccpu00127294]-MOD-Change the max Ul subfrms size in TDD */
11089    uint8_t             maxSubfrms = 2 * rgSchTddNumUlSf[ulDlCfgIdx]; 
11090    uint8_t             ulToDlMap[12] = {0}; /* maximum 6 Subframes in UL  * 2 */
11091    uint8_t             maxUlsubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
11092                                            [RGSCH_NUM_SUB_FRAMES-1];
11093    uint16_t             subfrm;
11094    S8             dlIdx;
11095 #else
11096    uint8_t             maxSubfrms = RG_SCH_CMN_UL_NUM_SF;
11097 #endif
11098 #ifdef LTE_L2_MEAS
11099    uint8_t             idx;
11100 #endif
11101    uint8_t  iTbs;
11102 #if (defined(LTE_L2_MEAS) )
11103    Inst           inst         = cell->instIdx;
11104 #endif /* #if (defined(LTE_L2_MEAS) || defined(DEBUGP) */
11105    RgSchCmnCell      *cellSch =  (RgSchCmnCell *)(cell->sc.sch);
11106    
11107
11108    cellUl->maxUeNewTxPerTti = cellCfg->maxUlUeNewTxPerTti;
11109    if (maxUePerUlSf == 0)
11110    {
11111       maxUePerUlSf = RG_SCH_CMN_MAX_UE_PER_UL_SF;
11112    }
11113 #ifdef RGR_V1
11114    if (maxMsg3PerUlSf == 0)
11115    {
11116       maxMsg3PerUlSf = RG_SCH_CMN_MAX_MSG3_PER_UL_SF;
11117    }
11118    /*  fixed the problem while sending raRsp 
11119     * if maxMsg3PerUlSf is greater than 
11120     * RGSCH_MAX_RNTI_PER_RARNTI 
11121     * */
11122    if(maxMsg3PerUlSf > RGSCH_MAX_RNTI_PER_RARNTI)
11123    {
11124       maxMsg3PerUlSf = RGSCH_MAX_RNTI_PER_RARNTI; 
11125    } 
11126
11127    if(maxMsg3PerUlSf > maxUePerUlSf)
11128    {
11129       maxMsg3PerUlSf =  maxUePerUlSf;   
11130    }
11131    
11132    /*cellUl->maxAllocPerUlSf = maxUePerUlSf + maxMsg3PerUlSf;*/
11133    /*Max MSG3 should be a subset of Max UEs*/
11134    cellUl->maxAllocPerUlSf = maxUePerUlSf;
11135    cellUl->maxMsg3PerUlSf = maxMsg3PerUlSf;
11136 #else
11137    cellUl->maxAllocPerUlSf = maxUePerUlSf;
11138 #endif
11139    /* Fix: MUE_PERTTI_UL syed validating Cell Configuration */
11140    if (cellUl->maxAllocPerUlSf < cellUl->maxUeNewTxPerTti)
11141    {
11142       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
11143             "FAILED: MaxUePerUlSf(%u) < MaxUlUeNewTxPerTti(%u)",
11144             cellUl->maxAllocPerUlSf,
11145             cellUl->maxUeNewTxPerTti);
11146       return RFAILED;
11147    }
11148
11149 #ifdef LTE_L2_MEAS
11150 #ifdef LTE_TDD
11151    for(idx = 0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
11152 #else
11153    for(idx = 0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
11154 #endif
11155    {
11156
11157       ret = rgSCHUtlAllocSBuf(inst,  (Data **)&(cell->sfAllocArr[idx].
11158               ulUeInfo.ulAllocInfo), (cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)));
11159       if (ret != ROK)
11160       {
11161             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation failed ");
11162             return (ret);
11163       }
11164    }
11165 #endif
11166    if (maxUlBwPerUe == 0)
11167    {
11168       /* ccpu00139362- Setting to configured UL BW instead of MAX BW(100)*/
11169       maxUlBwPerUe = cell->bwCfg.ulTotalBw;
11170    }
11171    cellUl->maxUlBwPerUe = maxUlBwPerUe;
11172
11173    /* FOR RG_SCH_CMN_EXT_CP_SUP */
11174    if (!cellCfg->isCpUlExtend)
11175    {
11176       cellUl->ulNumRePerRb = 12 * (14 - RGSCH_UL_SYM_DMRS_SRS);
11177    }
11178    else
11179    {
11180       cellUl->ulNumRePerRb = 12 * (12 - RGSCH_UL_SYM_DMRS_SRS);
11181    }
11182
11183    if (sbSize != rgSchCmnMult235Tbl[sbSize].match)
11184    {
11185       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid subband size %d", sbSize);
11186       return RFAILED;
11187    }
11188         //Setting the subband size to 4 which is size of VRBG in 5GTF
11189 #ifdef RG_5GTF
11190         sbSize = MAX_5GTF_VRBG_SIZE;
11191 #endif
11192         
11193    maxSbPerUe = maxUlBwPerUe / sbSize;
11194    if (maxSbPerUe == 0)
11195    {
11196       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnUlCellInit(): "
11197          "maxUlBwPerUe/sbSize is zero");
11198       return RFAILED;
11199    }
11200    cellUl->maxSbPerUe = rgSchCmnMult235Tbl[maxSbPerUe].prvMatch;
11201
11202    /* CQI related updations */
11203    if ((!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->ulCmnCodeRate.ccchCqi))
11204          || (!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->trgUlCqi.trgCqi)))
11205    {
11206       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnUlCellInit(): "
11207          "Invalid cqi");
11208       return RFAILED;
11209    }
11210    cellUl->dfltUlCqi = cellCfg->ulCmnCodeRate.ccchCqi;
11211
11212    /* Changed the logic to determine maxUlCqi.
11213     * For a 16qam UE, maxUlCqi is the CQI Index at which
11214     * efficiency is as close as possible to RG_SCH_MAX_CODE_RATE_16QAM
11215     * Refer to 36.213-8.6.1 */
11216     for (i = RG_SCH_CMN_UL_NUM_CQI - 1;i > 0; --i)
11217    {
11218       RLOG_ARG2(L_INFO,DBG_CELLID,cell->cellId,
11219             "CQI %u:iTbs %u",
11220             i, 
11221             rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]);
11222 #ifdef MAC_SCH_STATS
11223       /* ccpu00128489 ADD Update mcs in hqFailStats here instead of at CRC 
11224        * since CQI to MCS mapping does not change. The only exception is for 
11225        * ITBS = 19 where the MCS can be 20 or 21 based on the UE cat. We 
11226        * choose 20, instead of 21, ie UE_CAT_3 */
11227       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
11228       RG_SCH_CMN_UL_TBS_TO_MCS(iTbs, hqFailStats.ulCqiStat[i - 1].mcs);
11229 #endif
11230    }
11231    for (i = RG_SCH_CMN_UL_NUM_CQI - 1; i != 0; --i)
11232    {
11233       /* Fix for ccpu00123912*/
11234       iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i];
11235       if (iTbs <= RGSCH_UL_16QAM_MAX_ITBS) /* corresponds to 16QAM */
11236       {
11237          RLOG_ARG1(L_INFO,DBG_CELLID,cell->cellId,
11238                          "16 QAM CQI %u", i);
11239          cellUl->max16qamCqi = i;
11240          break;
11241       }
11242    }
11243
11244 #ifdef EMTC_ENABLE
11245    /* Precompute useful values for RA msg3 */
11246    ret = rgSCHCmnPrecompEmtcMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
11247          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
11248    if (ret != ROK)
11249    {
11250       return (ret);
11251    }
11252 #endif   
11253
11254    /* Precompute useful values for RA msg3 */
11255    ret = rgSCHCmnPrecompMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi,
11256          cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend);
11257    if (ret != ROK)
11258    {
11259       return (ret);
11260    }
11261
11262    cellUl->sbSize  = sbSize;
11263    
11264 #ifdef LTE_TDD  
11265    cellUl->numUlSubfrms = maxSubfrms;
11266
11267    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->ulSfArr,
11268             cellUl->numUlSubfrms * sizeof(RgSchUlSf));
11269
11270    if (ret != ROK)
11271    {
11272       cellUl->numUlSubfrms = 0;
11273       return (ret);
11274    }
11275
11276    /* store the DL subframe corresponding to the PUSCH offset
11277     * in their respective UL subframe */
11278    for(i=0; i < RGSCH_NUM_SUB_FRAMES; i++)
11279    {
11280       if(rgSchTddPuschTxKTbl[ulDlCfgIdx][i] != 0)
11281       {
11282          subfrm = (i + rgSchTddPuschTxKTbl[ulDlCfgIdx][i]) % \
11283                                  RGSCH_NUM_SUB_FRAMES;
11284          subfrm = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subfrm]-1;
11285          dlIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][i]-1;
11286          RGSCH_ARRAY_BOUND_CHECK( cell->instIdx, ulToDlMap, subfrm);
11287          ulToDlMap[subfrm] = dlIdx;
11288       }
11289    }
11290    /* Copy the information in the remaining UL subframes based
11291     * on number of HARQ processes */
11292    for(i=maxUlsubfrms; i < maxSubfrms; i++)
11293    {
11294       subfrm = i-maxUlsubfrms;
11295       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, i);
11296       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, subfrm)
11297       ulToDlMap[i] = ulToDlMap[subfrm];
11298    }
11299 #endif
11300
11301    for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++)
11302    {
11303 #ifdef LTE_TDD        
11304       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
11305 #else
11306       ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); 
11307 #endif
11308       if (ret != ROK)
11309       {
11310          return (ret);
11311       }
11312
11313       if (cfi == 1)
11314       {
11315          cell->ulAvailBw = bwAvail;
11316       }
11317
11318       numSb = bwAvail/sbSize; 
11319
11320       cell->dynCfiCb.bwInfo[cfi].startRb  = rbStart;
11321       cell->dynCfiCb.bwInfo[cfi].numSb    = numSb;
11322    }
11323
11324    if(0 == cell->dynCfiCb.maxCfi)
11325    {
11326       RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, 
11327                "Incorrect Default CFI(%u), maxCfi(%u), maxPucchRb(%d)",
11328                cellSch->cfiCfg.cfi, cell->dynCfiCb.maxCfi, 
11329                cell->pucchCfg.maxPucchRb);
11330             
11331       return RFAILED;
11332    }
11333
11334    /* DMRS values */
11335    cellUl->dmrsArrSize = cell->dynCfiCb.bwInfo[1].numSb;
11336    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->dmrsArr,
11337          cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11338    if (ret != ROK)
11339    {
11340       return (ret);
11341    }
11342    for (i = 0; i < cellUl->dmrsArrSize; ++i)
11343    {
11344       cellUl->dmrsArr[i] = cellCfg->puschSubBand.dmrs[i];
11345    }
11346  
11347    /* Init subframes */
11348    for (i = 0; i < maxSubfrms; ++i)
11349    {
11350       ret = rgSCHUtlUlSfInit(cell, &cellUl->ulSfArr[i], i,
11351                              cellUl->maxAllocPerUlSf);
11352       if (ret != ROK)
11353       {
11354          for (; i != 0; --i)
11355          {
11356             rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[i-1]);
11357          }
11358          /* ccpu00117052 - MOD - Passing double pointer
11359             for proper NULLP assignment*/
11360          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(cellUl->dmrsArr)),
11361                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11362 #ifdef LTE_TDD
11363          /* ccpu00117052 - MOD - Passing double pointer
11364             for proper NULLP assignment*/
11365          rgSCHUtlFreeSBuf(cell->instIdx,
11366             (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
11367 #endif
11368          return (ret);
11369       }
11370    }
11371    RG_SCH_RESET_HCSG_UL_PRB_CNTR(cellUl);
11372    return ROK;
11373 }
11374
11375 /**
11376  * @brief Scheduler processing on cell configuration.
11377  *
11378  * @details
11379  *
11380  *     Function : rgSCHCmnRgrCellCfg
11381  *
11382  *     This function does requisite initialisation
11383  *     and setup for scheduler1 when a cell is
11384  *     configured.
11385  *
11386  *  @param[in]  RgSchCellCb   *cell
11387  *  @param[in]  RgrCellCfg    *cellCfg
11388  *  @param[out] RgSchErrInfo  *err
11389  *  @return  S16
11390  *      -# ROK
11391  *      -# RFAILED
11392  **/
11393 #ifdef ANSI
11394 S16 rgSCHCmnRgrCellCfg
11395 (
11396 RgSchCellCb   *cell,
11397 RgrCellCfg    *cellCfg,
11398 RgSchErrInfo  *err
11399 )
11400 #else
11401 S16 rgSCHCmnRgrCellCfg(cell, cellCfg, err)
11402 RgSchCellCb   *cell;
11403 RgrCellCfg    *cellCfg;
11404 RgSchErrInfo  *err;
11405 #endif
11406 {
11407    S16       ret;
11408    RgSchCmnCell *cellSch;
11409
11410    /* As part of RGR cell configuration, validate the CRGCellCfg
11411     * There is no trigger for crgCellCfg from SC1 */
11412    /* Removed failure check for Extended CP */
11413
11414    if (((ret = rgSCHUtlAllocSBuf(cell->instIdx,
11415       (Data**)&(cell->sc.sch), (sizeof(RgSchCmnCell)))) != ROK))
11416    {
11417       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,  
11418          "Memory allocation FAILED");
11419       err->errCause = RGSCHERR_SCH_CFG;
11420       return (ret);
11421    }
11422    cellSch = (RgSchCmnCell *)(cell->sc.sch);
11423    cellSch->cfiCfg = cellCfg->cfiCfg;
11424    cellSch->trgUlCqi.trgCqi = cellCfg->trgUlCqi.trgCqi;
11425    /* Initialize the scheduler refresh timer queues */
11426    cellSch->tmrTqCp.nxtEnt = 0;
11427    cellSch->tmrTqCp.tmrLen = RG_SCH_CMN_NUM_REFRESH_Q;
11428
11429    /* RACHO Intialize the RACH ded Preamble Information */
11430    rgSCHCmnCfgRachDedPrm(cell);
11431 #ifdef LTE_TDD
11432    /* Initialize 'Np' value for each 'p' used for
11433     * HARQ ACK/NACK reception */
11434    rgSCHCmnDlNpValInit(cell);
11435 #endif
11436
11437    /* Initialize 'Np' value for each 'p' used for
11438     * HARQ ACK/NACK reception */
11439 #ifdef LTE_TDD
11440    rgSCHCmnDlNpValInit(cell);
11441 #endif
11442
11443    /* Now perform uplink related initializations  */
11444    ret = rgSCHCmnUlCellInit(cell, cellCfg);
11445    if (ret != ROK)
11446    {
11447       /* There is no downlink deinit to be performed */
11448       err->errCause = RGSCHERR_SCH_CFG;
11449       return (ret);
11450    }
11451    ret = rgSCHCmnDlRgrCellCfg(cell, cellCfg, err);
11452    if (ret != ROK)
11453    {
11454       err->errCause = RGSCHERR_SCH_CFG;
11455       return (ret);
11456    }
11457    /* DL scheduler has no initializations to make */
11458    /* As of now DL scheduler always returns ROK   */
11459
11460    rgSCHCmnGetDciFrmtSizes(cell);
11461    rgSCHCmnGetCqiDciFrmt2AggrLvl(cell);
11462 #ifdef EMTC_ENABLE 
11463    rgSCHCmnGetEmtcDciFrmtSizes(cell);
11464    rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl(cell);
11465 #endif /* EMTC_ENABLE  */
11466
11467 #ifdef EMTC_ENABLE   
11468    if(TRUE == cellCfg->emtcEnable)
11469    {
11470       cellSch->apisEmtcUl = &rgSchEmtcUlSchdTbl[0];
11471       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
11472       if (ret != ROK)
11473       {
11474          return (ret);
11475       }
11476    }
11477 #endif
11478    cellSch->apisUl = &rgSchUlSchdTbl[RG_SCH_CMN_GET_UL_SCHED_TYPE(cell)];
11479    ret = cellSch->apisUl->rgSCHRgrUlCellCfg(cell, cellCfg, err);
11480    if (ret != ROK)
11481    {
11482       return (ret);
11483    }
11484 #ifdef EMTC_ENABLE   
11485    if(TRUE == cellCfg->emtcEnable)
11486    {
11487       cellSch->apisEmtcDl = &rgSchEmtcDlSchdTbl[0];
11488       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
11489       if (ret != ROK)
11490       {
11491          return (ret);
11492       }
11493    }
11494 #endif
11495    cellSch->apisDl = &rgSchDlSchdTbl[RG_SCH_CMN_GET_DL_SCHED_TYPE(cell)];
11496 #ifdef LTEMAC_SPS
11497    /* Perform SPS specific initialization for the cell */
11498    ret = rgSCHCmnSpsCellCfg(cell, cellCfg, err);
11499    if (ret != ROK)
11500    {
11501       return (ret);
11502    }
11503 #endif
11504    ret = cellSch->apisDl->rgSCHRgrDlCellCfg(cell, cellCfg, err);
11505    if (ret != ROK)
11506    {
11507       return (ret);
11508    }
11509    rgSCHCmnInitVars(cell);
11510
11511    return ROK;
11512 }  /* rgSCHCmnRgrCellCfg*/
11513
11514 \f
11515 /**
11516  * @brief This function handles the reconfiguration of cell.
11517  *
11518  * @details
11519  *
11520  *     Function: rgSCHCmnRgrCellRecfg
11521  *     Purpose:  Update the reconfiguration parameters.
11522  *
11523  *     Invoked by: Scheduler
11524  *
11525  *  @param[in]  RgSchCellCb*  cell
11526  *  @return  Void
11527  *
11528  **/
11529 #ifdef ANSI
11530 S16 rgSCHCmnRgrCellRecfg
11531 (
11532 RgSchCellCb             *cell,
11533 RgrCellRecfg            *recfg,
11534 RgSchErrInfo            *err
11535 )
11536 #else
11537 S16 rgSCHCmnRgrCellRecfg(cell, recfg, err)
11538 RgSchCellCb             *cell;
11539 RgrCellRecfg            *recfg;
11540 RgSchErrInfo            *err;
11541 #endif
11542 {
11543    S16                  ret;
11544    RgSchCmnCell         *cellSch = RG_SCH_CMN_GET_CELL(cell);
11545    RgSchCmnUlCell       *cellUl  = RG_SCH_CMN_GET_UL_CELL(cell);
11546
11547
11548    if (recfg->recfgTypes & RGR_CELL_UL_CMNRATE_RECFG)
11549    {
11550       uint8_t   oldCqi = cellUl->dfltUlCqi;
11551       if (!RG_SCH_CMN_UL_IS_CQI_VALID(recfg->ulCmnCodeRate.ccchCqi))
11552       {
11553          err->errCause = RGSCHERR_SCH_CFG;
11554          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnRgrCellRecfg(): "
11555             "Invalid cqi");
11556          return RFAILED;
11557       }
11558       cellUl->dfltUlCqi = recfg->ulCmnCodeRate.ccchCqi;
11559       ret = rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
11560             cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
11561       if (ret != ROK)
11562       {
11563          cellUl->dfltUlCqi = oldCqi;
11564          rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi,
11565                cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend);
11566          return (ret);
11567       }
11568    }
11569
11570    if (recfg->recfgTypes & RGR_CELL_DL_CMNRATE_RECFG)
11571    {
11572       if (rgSCHCmnDlCnsdrCmnRt(cell, &recfg->dlCmnCodeRate) != ROK)
11573       {
11574          err->errCause = RGSCHERR_SCH_CFG;
11575          return RFAILED;
11576       }
11577    }
11578  
11579 #ifdef EMTC_ENABLE  
11580    if(TRUE == cell->emtcEnable) 
11581    {
11582       /* Invoke UL sched for cell Recfg */
11583       ret = cellSch->apisEmtcUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
11584       if (ret != ROK)
11585       {
11586          return RFAILED;
11587       }
11588
11589       /* Invoke DL sched for cell Recfg */
11590       ret = cellSch->apisEmtcDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
11591       if (ret != ROK)
11592       {
11593          return RFAILED;
11594       }
11595    }
11596    else
11597 #endif
11598    {
11599    /* Invoke UL sched for cell Recfg */
11600    ret = cellSch->apisUl->rgSCHRgrUlCellRecfg(cell, recfg, err);
11601    if (ret != ROK)
11602    {
11603       return RFAILED;
11604    }
11605
11606    /* Invoke DL sched for cell Recfg */
11607    ret = cellSch->apisDl->rgSCHRgrDlCellRecfg(cell, recfg, err);
11608    if (ret != ROK)
11609    {
11610       return RFAILED;
11611    }
11612    }
11613
11614    if (recfg->recfgTypes & RGR_CELL_DLFS_RECFG)
11615    {
11616       ret = cellSch->apisDlfs->rgSCHDlfsCellRecfg(cell, recfg, err);
11617       if (ret != ROK)
11618       {
11619          return RFAILED;
11620       }
11621       cellSch->dl.isDlFreqSel = recfg->dlfsRecfg.isDlFreqSel;
11622    }
11623
11624    if (recfg->recfgTypes & RGR_CELL_PWR_RECFG)
11625    {
11626       ret = rgSCHPwrCellRecfg(cell, recfg);
11627       if (ret != ROK)
11628       {
11629          return RFAILED;
11630       }
11631    }
11632
11633    return ROK;
11634 }
11635
11636 /***********************************************************
11637  *
11638  *     Func : rgSCHCmnUlCellDeinit
11639  *
11640  *     Desc : Uplink scheduler de-initialisation for cell.
11641  *
11642  *     Ret  : S16
11643  *
11644  *     Notes:
11645  *
11646  *     File :
11647  *
11648  **********************************************************/
11649 #ifdef ANSI
11650 static Void rgSCHCmnUlCellDeinit
11651 (
11652 RgSchCellCb *cell
11653 )
11654 #else
11655 static Void rgSCHCmnUlCellDeinit(cell)
11656 RgSchCellCb *cell;
11657 #endif
11658 {
11659    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11660    uint8_t               ulSfIdx;
11661 #ifdef LTE_TDD
11662    uint8_t        maxSubfrms = cellUl->numUlSubfrms;
11663 #endif
11664 #ifdef LTE_L2_MEAS
11665    CmLList       *lnk = NULLP;
11666    RgSchL2MeasCb *measCb;
11667 #endif
11668 #ifdef LTE_L2_MEAS
11669 #ifdef LTE_TDD
11670    for(ulSfIdx = 0; ulSfIdx < RGSCH_SF_ALLOC_SIZE; ulSfIdx++)
11671 #else
11672    for(ulSfIdx = 0; ulSfIdx < RGSCH_NUM_SUB_FRAMES; ulSfIdx++)
11673 #endif
11674    {
11675       if(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo != NULLP)
11676       {
11677          /* ccpu00117052 - MOD - Passing double pointer
11678             for proper NULLP assignment*/
11679          rgSCHUtlFreeSBuf(cell->instIdx,
11680          (Data **)(&(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo)),
11681          cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc));
11682
11683          /* ccpu00117052 - DEL - removed explicit NULLP assignment
11684             as it is done in above utility function */
11685       }
11686    }
11687    /* Free the memory allocated to measCb */
11688    lnk = cell->l2mList.first;
11689    while(lnk != NULLP)
11690    {
11691       measCb = (RgSchL2MeasCb *)lnk->node;
11692       cmLListDelFrm(&cell->l2mList, lnk);
11693       lnk = lnk->next;
11694    /* ccpu00117052 - MOD - Passing double pointer
11695    for proper NULLP assignment*/
11696       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\
11697                           sizeof(RgSchL2MeasCb));
11698    }
11699 #endif
11700    if (cellUl->dmrsArr != NULLP)
11701    {
11702       /* ccpu00117052 - MOD - Passing double pointer
11703       for proper NULLP assignment*/
11704       rgSCHUtlFreeSBuf(cell->instIdx,(Data **)(&(cellUl->dmrsArr)),
11705                cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr));
11706    }
11707    /* De-init subframes */
11708 #ifdef LTE_TDD
11709    for (ulSfIdx = 0; ulSfIdx < maxSubfrms; ++ulSfIdx)
11710 #else
11711    for (ulSfIdx = 0; ulSfIdx < RG_SCH_CMN_UL_NUM_SF; ++ulSfIdx)
11712 #endif
11713    {
11714       rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[ulSfIdx]);
11715    }
11716
11717 #ifdef LTE_TDD
11718    if (cellUl->ulSfArr != NULLP)
11719    {
11720       /* ccpu00117052 - MOD - Passing double pointer
11721       for proper NULLP assignment*/
11722       rgSCHUtlFreeSBuf(cell->instIdx,
11723          (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf));
11724    }
11725 #endif
11726
11727    return;
11728 }
11729
11730 /**
11731  * @brief Scheduler processing for cell delete.
11732  *
11733  * @details
11734  *
11735  *     Function : rgSCHCmnCellDel
11736  *
11737  *     This functions de-initialises and frees memory
11738  *     taken up by scheduler1 for the entire cell.
11739  *
11740  *  @param[in]  RgSchCellCb  *cell
11741  *  @return  Void
11742  **/
11743 #ifdef ANSI
11744 Void rgSCHCmnCellDel
11745 (
11746 RgSchCellCb  *cell
11747 )
11748 #else
11749 Void rgSCHCmnCellDel(cell)
11750 RgSchCellCb  *cell;
11751 #endif
11752 {
11753    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11754
11755 #ifdef LTE_L2_MEAS
11756    glblTtiCnt = 0;
11757 #endif
11758    if (cellSch == NULLP)
11759    {
11760       return;
11761    }
11762    /* Perform the deinit for the UL scheduler */
11763    rgSCHCmnUlCellDeinit(cell);
11764 #ifdef EMTC_ENABLE
11765    if(TRUE == cell->emtcEnable)
11766    {
11767       if (cellSch->apisEmtcUl)
11768       {
11769          cellSch->apisEmtcUl->rgSCHFreeUlCell(cell);
11770       }
11771    }
11772 #endif 
11773    if (cellSch->apisUl)
11774    {
11775       /* api pointer checks added (here and below in
11776        * this function). pl check. - antriksh */
11777       cellSch->apisUl->rgSCHFreeUlCell(cell);
11778    }
11779
11780    /* Perform the deinit for the DL scheduler */
11781    cmLListInit(&cellSch->dl.taLst);
11782    if (cellSch->apisDl)
11783    {
11784       cellSch->apisDl->rgSCHFreeDlCell(cell);
11785    }
11786 #ifdef EMTC_ENABLE
11787    if (cellSch->apisEmtcDl)
11788    {
11789       rgSCHEmtcInitTaLst(&cellSch->dl);
11790
11791       cellSch->apisEmtcDl->rgSCHFreeDlCell(cell);
11792    }
11793 #endif
11794
11795    /* DLFS de-initialization */
11796    if (cellSch->dl.isDlFreqSel && cellSch->apisDlfs)
11797    {
11798       cellSch->apisDlfs->rgSCHDlfsCellDel(cell);
11799    }
11800
11801    rgSCHPwrCellDel(cell);
11802 #ifdef LTEMAC_SPS
11803    rgSCHCmnSpsCellDel(cell);
11804 #endif
11805
11806    /* ccpu00117052 - MOD - Passing double pointer
11807    for proper NULLP assignment*/
11808    rgSCHUtlFreeSBuf(cell->instIdx,
11809       (Data**)(&(cell->sc.sch)), (sizeof(RgSchCmnCell)));
11810    return;
11811 }  /* rgSCHCmnCellDel */
11812
11813 \f
11814 /**
11815  * @brief This function validates QOS parameters for DL.
11816  *
11817  * @details
11818  *
11819  *     Function: rgSCHCmnValidateDlQos
11820  *     Purpose:  This function validates QOS parameters for DL.
11821  *
11822  *     Invoked by: Scheduler
11823  *
11824  *  @param[in] CrgLchQosCfg    *dlQos
11825  *  @return                    S16
11826  *
11827  **/
11828 #ifdef ANSI
11829 static S16 rgSCHCmnValidateDlQos
11830 (
11831 RgrLchQosCfg            *dlQos
11832 )
11833 #else
11834 static S16 rgSCHCmnValidateDlQos(dlQos)
11835 RgrLchQosCfg            *dlQos;
11836 #endif
11837 {
11838    uint8_t qci = dlQos->qci;
11839
11840
11841    if ( qci < RG_SCH_CMN_MIN_QCI || qci > RG_SCH_CMN_MAX_QCI )
11842    {
11843       return RFAILED;
11844    }
11845
11846    if ((qci >= RG_SCH_CMN_GBR_QCI_START) &&
11847        (qci <= RG_SCH_CMN_GBR_QCI_END))
11848    {
11849       if ((dlQos->mbr == 0) || (dlQos->mbr < dlQos->gbr))
11850       {
11851          return RFAILED;
11852       }
11853    }
11854    return ROK;
11855 }
11856
11857 /**
11858  * @brief Scheduler invocation on logical channel addition.
11859  *
11860  * @details
11861  *
11862  *     Function : rgSCHCmnRgrLchCfg
11863  *
11864  *     This functions does required processing when a new
11865  *     (dedicated) logical channel is added. Assumes lcg
11866  *     pointer in ulLc is set.
11867  *
11868  *  @param[in]  RgSchCellCb  *cell
11869  *  @param[in]  RgSchUeCb    *ue
11870  *  @param[in]  RgSchDlLcCb  *dlLc
11871  *  @param[int] RgrLchCfg    *lcCfg
11872  *  @param[out] RgSchErrInfo *err
11873  *  @return  S16
11874  *      -# ROK
11875  *      -# RFAILED
11876  **/
11877 #ifdef ANSI
11878 S16 rgSCHCmnRgrLchCfg
11879 (
11880 RgSchCellCb  *cell,
11881 RgSchUeCb    *ue,
11882 RgSchDlLcCb  *dlLc,
11883 RgrLchCfg *lcCfg,
11884 RgSchErrInfo *err
11885 )
11886 #else
11887 S16 rgSCHCmnRgrLchCfg(cell, ue, dlLc, lcCfg, err)
11888 RgSchCellCb  *cell;
11889 RgSchUeCb    *ue;
11890 RgSchDlLcCb  *dlLc;
11891 RgrLchCfg *lcCfg;
11892 RgSchErrInfo *err;
11893 #endif
11894 {
11895    S16 ret;
11896
11897    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
11898
11899
11900    ret = rgSCHUtlAllocSBuf(cell->instIdx,
11901       (Data**)&((dlLc)->sch), (sizeof(RgSchCmnDlSvc)));
11902    if (ret != ROK)
11903    {
11904       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRgrLchCfg(): "
11905          "SCH struct alloc failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
11906       err->errCause = RGSCHERR_SCH_CFG;
11907       return (ret);
11908    }
11909    if(lcCfg->lcType != CM_LTE_LCH_DCCH)
11910    {
11911       ret = rgSCHCmnValidateDlQos(&lcCfg->dlInfo.dlQos);
11912       if (ret != ROK)
11913       {
11914          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSchCmnCrgLcCfg(): "
11915             "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
11916          err->errCause = RGSCHERR_SCH_CFG;
11917          return (ret);
11918       }
11919       /* Perform DL service activation in the scheduler */
11920       ((RgSchCmnDlSvc *)(dlLc->sch))->qci = lcCfg->dlInfo.dlQos.qci;
11921       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = rgSchCmnDlQciPrio[lcCfg->dlInfo.dlQos.qci - 1];
11922       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcCfg->dlInfo.dlQos.gbr * \
11923       RG_SCH_CMN_REFRESH_TIME)/100;
11924       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcCfg->dlInfo.dlQos.mbr * \
11925       RG_SCH_CMN_REFRESH_TIME)/100;
11926    }
11927    else
11928    {
11929      /*assigning highest priority to DCCH */
11930     ((RgSchCmnDlSvc *)(dlLc->sch))->prio=RG_SCH_CMN_DCCH_PRIO; 
11931    }   
11932    dlLc->ue = ue;
11933    dlLc->lcType=lcCfg->lcType;
11934
11935 #ifdef EMTC_ENABLE
11936    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
11937    {
11938       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcCfg(cell, ue,dlLc ,lcCfg, err);
11939       if (ret != ROK)
11940       {
11941          return RFAILED;
11942       }
11943    }
11944    else
11945 #endif 
11946    {
11947       ret = cellSch->apisDl->rgSCHRgrDlLcCfg(cell, ue, dlLc, lcCfg, err);
11948       if (ret != ROK)
11949       {
11950          return RFAILED;
11951       }
11952    }
11953    
11954 #ifdef EMTC_ENABLE
11955    if(TRUE == ue->isEmtcUe)
11956    {
11957       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
11958       if (ret != ROK)
11959       {
11960          return RFAILED;
11961       }
11962    }
11963    else
11964 #endif 
11965    {
11966    ret = cellSch->apisUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err);
11967    if (ret != ROK)
11968    {
11969       return RFAILED;
11970    }
11971    }
11972    
11973 #ifdef LTE_ADV
11974    if (ue->numSCells)
11975    {
11976       rgSCHSCellDlLcCfg(cell, ue, dlLc);
11977    }
11978 #endif
11979
11980
11981 #ifdef LTEMAC_SPS
11982    if(lcCfg->dlInfo.dlSpsCfg.isSpsEnabled)
11983    {
11984       /* Invoke SPS module if SPS is enabled for the service */
11985       ret = rgSCHCmnSpsDlLcCfg(cell, ue, dlLc, lcCfg, err);
11986       if (ret != ROK)
11987       {
11988          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "rgSchCmnRgrLchCfg(): "
11989             "SPS configuration failed for DL LC for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
11990          err->errCause = RGSCHERR_SCH_CFG;
11991          return RFAILED;
11992       }
11993    }
11994 #endif
11995
11996    return ROK;
11997 }
11998
11999 /**
12000  * @brief Scheduler invocation on logical channel addition.
12001  *
12002  * @details
12003  *
12004  *     Function : rgSCHCmnRgrLchRecfg
12005  *
12006  *     This functions does required processing when an existing
12007  *     (dedicated) logical channel is reconfigured. Assumes lcg
12008  *     pointer in ulLc is set to the old value.
12009  *     Independent of whether new LCG is meant to be configured,
12010  *     the new LCG scheduler information is accessed and possibly modified.
12011  *
12012  *  @param[in]  RgSchCellCb  *cell
12013  *  @param[in]  RgSchUeCb    *ue
12014  *  @param[in]  RgSchDlLcCb  *dlLc
12015  *  @param[int] RgrLchRecfg  *lcRecfg
12016  *  @param[out] RgSchErrInfo *err
12017  *  @return  S16
12018  *      -# ROK
12019  *      -# RFAILED
12020  **/
12021 #ifdef ANSI
12022 S16 rgSCHCmnRgrLchRecfg
12023 (
12024 RgSchCellCb  *cell,
12025 RgSchUeCb    *ue,
12026 RgSchDlLcCb  *dlLc,
12027 RgrLchRecfg  *lcRecfg,
12028 RgSchErrInfo *err
12029 )
12030 #else
12031 S16 rgSCHCmnRgrLchRecfg(cell, ue, dlLc, lcRecfg, err)
12032 RgSchCellCb  *cell;
12033 RgSchUeCb    *ue;
12034 RgSchDlLcCb  *dlLc;
12035 RgrLchRecfg  *lcRecfg;
12036 RgSchErrInfo *err;
12037 #endif
12038 {
12039    S16   ret;
12040    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12041
12042
12043    if(dlLc->lcType != CM_LTE_LCH_DCCH)
12044    {
12045       ret = rgSCHCmnValidateDlQos(&lcRecfg->dlRecfg.dlQos);
12046    
12047       if (ret != ROK)
12048       {
12049          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
12050                "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12051          err->errCause = RGSCHERR_SCH_CFG;
12052          return (ret);
12053       }
12054       if (((RgSchCmnDlSvc *)(dlLc->sch))->qci != lcRecfg->dlRecfg.dlQos.qci)
12055       {
12056          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Qci, hence lc Priority change "
12057             "not supported for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12058          err->errCause = RGSCHERR_SCH_CFG;
12059          return (ret);
12060       }
12061       ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcRecfg->dlRecfg.dlQos.gbr * \
12062       RG_SCH_CMN_REFRESH_TIME)/100;
12063       ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcRecfg->dlRecfg.dlQos.mbr * \
12064       RG_SCH_CMN_REFRESH_TIME)/100;
12065    }
12066    else
12067    {
12068       /*assigning highest priority to DCCH */
12069       ((RgSchCmnDlSvc *)(dlLc->sch))->prio = RG_SCH_CMN_DCCH_PRIO; 
12070    }
12071    
12072 #ifdef EMTC_ENABLE
12073    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
12074    {
12075       ret = cellSch->apisEmtcDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12076       if (ret != ROK)
12077       {
12078          return RFAILED;
12079       }
12080       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
12081       if (ret != ROK)
12082       {
12083          return RFAILED;
12084       }
12085    }
12086    else
12087 #endif 
12088    {
12089    ret = cellSch->apisDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12090    if (ret != ROK)
12091    {
12092       return RFAILED;
12093    }
12094    ret = cellSch->apisUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err);
12095    if (ret != ROK)
12096    {
12097       return RFAILED;
12098    }
12099    }
12100     
12101 #ifdef LTEMAC_SPS
12102    if (lcRecfg->recfgTypes & RGR_DL_LC_SPS_RECFG)
12103    {
12104       /* Invoke SPS module if SPS is enabled for the service */
12105       if(lcRecfg->dlRecfg.dlSpsRecfg.isSpsEnabled)
12106       {
12107          ret = rgSCHCmnSpsDlLcRecfg(cell, ue, dlLc, lcRecfg, err);
12108          if (ret != ROK)
12109          {
12110             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"SPS re-configuration not "
12111                   "supported for dlLC Ignore this CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId);
12112          }
12113       }
12114       return ROK;
12115    }
12116 #endif
12117
12118    return ROK;
12119 }
12120
12121 /**
12122  * @brief Scheduler invocation on logical channel addition.
12123  *
12124  * @details
12125  *
12126  *     Function : rgSCHCmnRgrLcgCfg
12127  *
12128  *     This functions does required processing when a new
12129  *     (dedicated) logical channel is added. Assumes lcg
12130  *     pointer in ulLc is set.
12131  *
12132  *  @param[in]  RgSchCellCb  *cell,
12133  *  @param[in]  RgSchUeCb    *ue,
12134  *  @param[in]  RgSchLcgCb   *lcg,
12135  *  @param[in]  RgrLcgCfg    *lcgCfg,
12136  *  @param[out] RgSchErrInfo *err
12137  *  @return  S16
12138  *      -# ROK
12139  *      -# RFAILED
12140  **/
12141 #ifdef ANSI
12142 S16 rgSCHCmnRgrLcgCfg
12143 (
12144 RgSchCellCb  *cell,
12145 RgSchUeCb    *ue,
12146 RgSchLcgCb   *lcg,
12147 RgrLcgCfg    *lcgCfg,
12148 RgSchErrInfo *err
12149 )
12150 #else
12151 S16 rgSCHCmnRgrLcgCfg(cell, ue, lcg, lcgCfg, err)
12152 RgSchCellCb  *cell;
12153 RgSchUeCb    *ue;
12154 RgSchLcgCb   *lcg;
12155 RgrLcgCfg    *lcgCfg;
12156 RgSchErrInfo *err;
12157 #endif
12158 {
12159    S16 ret;
12160    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12161    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].sch));
12162
12163
12164    ulLcg->cfgdGbr = (lcgCfg->ulInfo.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
12165    ulLcg->effGbr  = ulLcg->cfgdGbr;
12166    ulLcg->deltaMbr = ((lcgCfg->ulInfo.mbr - lcgCfg->ulInfo.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
12167    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
12168
12169 #ifdef EMTC_ENABLE
12170    if(TRUE == ue->isEmtcUe)
12171    {
12172       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
12173       if (ret != ROK)
12174       {
12175          return RFAILED;
12176       }
12177    }
12178    else
12179 #endif
12180    {
12181    ret = cellSch->apisUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err);
12182    if (ret != ROK)
12183    {
12184       return RFAILED;
12185    }
12186    }
12187    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
12188    {
12189       /* Indicate MAC that this LCG is GBR LCG */
12190       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcgCfg->ulInfo.lcgId, TRUE);
12191    }
12192    return ROK;
12193 }
12194
12195 /**
12196  * @brief Scheduler invocation on logical channel addition.
12197  *
12198  * @details
12199  *
12200  *     Function : rgSCHCmnRgrLcgRecfg
12201  *
12202  *     This functions does required processing when a new
12203  *     (dedicated) logical channel is added. Assumes lcg
12204  *     pointer in ulLc is set.
12205  *
12206  *  @param[in]  RgSchCellCb  *cell,
12207  *  @param[in]  RgSchUeCb    *ue,
12208  *  @param[in]  RgSchLcgCb   *lcg,
12209  *  @param[in]  RgrLcgRecfg  *reCfg,
12210  *  @param[out] RgSchErrInfo *err
12211  *  @return  S16
12212  *      -# ROK
12213  *      -# RFAILED
12214  **/
12215 #ifdef ANSI
12216 S16 rgSCHCmnRgrLcgRecfg
12217 (
12218 RgSchCellCb  *cell,
12219 RgSchUeCb    *ue,
12220 RgSchLcgCb   *lcg,
12221 RgrLcgRecfg  *reCfg,
12222 RgSchErrInfo *err
12223 )
12224 #else
12225 S16 rgSCHCmnRgrLcgRecfg(cell, ue, lcg, reCfg, err)
12226 RgSchCellCb  *cell;
12227 RgSchUeCb    *ue;
12228 RgSchLcgCb   *lcg;
12229 RgrLcgRecfg  *reCfg;
12230 RgSchErrInfo *err;
12231 #endif
12232 {
12233    S16 ret;
12234    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12235    RgSchCmnLcg  *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[reCfg->ulRecfg.lcgId].sch));
12236    
12237
12238    ulLcg->cfgdGbr = (reCfg->ulRecfg.gbr * RG_SCH_CMN_REFRESH_TIME)/100;
12239    ulLcg->effGbr  = ulLcg->cfgdGbr;
12240    ulLcg->deltaMbr = ((reCfg->ulRecfg.mbr - reCfg->ulRecfg.gbr) * RG_SCH_CMN_REFRESH_TIME)/100;
12241    ulLcg->effDeltaMbr = ulLcg->deltaMbr;
12242  
12243 #ifdef EMTC_ENABLE
12244    if(TRUE == ue->isEmtcUe)
12245    {
12246       ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
12247       if (ret != ROK)
12248       {
12249          return RFAILED;
12250       }
12251    }
12252    else
12253 #endif
12254    {
12255    ret = cellSch->apisUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err);
12256    if (ret != ROK)
12257    {
12258       return RFAILED;
12259    }
12260    }
12261    if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr))
12262    {
12263       /* Indicate MAC that this LCG is GBR LCG */
12264       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, TRUE);
12265    }
12266    else
12267    {
12268       /* In case of RAB modification */
12269       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, FALSE);
12270    }
12271    return ROK;
12272 }
12273
12274 /***********************************************************
12275  *
12276  *     Func : rgSCHCmnRgrLchDel
12277  *
12278  *     Desc : Scheduler handling for a (dedicated)
12279  *             uplink logical channel being deleted.
12280  *
12281  *     Ret  :
12282  *
12283  *     Notes:
12284  *
12285  *     File :
12286  **********************************************************/
12287 #ifdef ANSI
12288 S16 rgSCHCmnRgrLchDel 
12289 (
12290 RgSchCellCb   *cell,
12291 RgSchUeCb     *ue,
12292 CmLteLcId     lcId,
12293 uint8_t            lcgId
12294 )
12295 #else
12296 S16 rgSCHCmnRgrLchDel(cell, ue, lcId, lcgId)
12297 RgSchCellCb   *cell;
12298 RgSchUeCb     *ue;
12299 CmLteLcId     lcId;
12300 uint8_t            lcgId;
12301 #endif
12302 {
12303    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12304 #ifdef EMTC_ENABLE
12305    if(TRUE == ue->isEmtcUe)
12306    {
12307       cellSch->apisEmtcUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
12308    }
12309    else
12310 #endif
12311    {
12312    cellSch->apisUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId);
12313    }
12314    return ROK;
12315 }
12316
12317 /***********************************************************
12318  *
12319  *     Func : rgSCHCmnLcgDel
12320  *
12321  *     Desc : Scheduler handling for a (dedicated)
12322  *             uplink logical channel being deleted.
12323  *
12324  *     Ret  :
12325  *
12326  *     Notes:
12327  *
12328  *     File :
12329  *
12330  **********************************************************/
12331 #ifdef ANSI
12332 Void rgSCHCmnLcgDel
12333 (
12334 RgSchCellCb   *cell,
12335 RgSchUeCb     *ue,
12336 RgSchLcgCb    *lcg
12337 )
12338 #else
12339 Void rgSCHCmnLcgDel(cell, ue, lcg)
12340 RgSchCellCb   *cell;
12341 RgSchUeCb     *ue;
12342 RgSchLcgCb    *lcg;
12343 #endif
12344 {
12345    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12346    RgSchCmnLcg  *lcgCmn = RG_SCH_CMN_GET_UL_LCG(lcg);
12347
12348    if (lcgCmn == NULLP)
12349    {
12350       return;
12351    }
12352
12353    if (RGSCH_IS_GBR_BEARER(lcgCmn->cfgdGbr))
12354    {
12355       /* Indicate MAC that this LCG is GBR LCG */
12356       rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcg->lcgId, FALSE);
12357    }
12358
12359 #ifdef LTEMAC_SPS
12360    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
12361    {
12362       rgSCHCmnSpsUlLcgDel(cell, ue, lcg);
12363    }
12364 #endif /* LTEMAC_SPS */
12365
12366    lcgCmn->effGbr     = 0;
12367    lcgCmn->reportedBs = 0;
12368    lcgCmn->cfgdGbr    = 0;
12369    /* set lcg bs to 0. Deletion of control block happens
12370     * at the time of UE deletion. */
12371    lcgCmn->bs = 0;
12372 #ifdef EMTC_ENABLE
12373    if(TRUE == ue->isEmtcUe)
12374    {
12375       cellSch->apisEmtcUl->rgSCHFreeUlLcg(cell, ue, lcg);
12376    }
12377    else
12378 #endif
12379    {
12380    cellSch->apisUl->rgSCHFreeUlLcg(cell, ue, lcg);
12381    }
12382    return;
12383 }
12384
12385 \f
12386 /**
12387  * @brief This function deletes a service from scheduler.
12388  *
12389  * @details
12390  *
12391  *     Function: rgSCHCmnFreeDlLc
12392  *     Purpose:  This function is made available through a FP for
12393  *               making scheduler aware of a service being deleted from UE.
12394  *
12395  *     Invoked by: BO and Scheduler
12396  *
12397  *  @param[in]  RgSchCellCb*  cell
12398  *  @param[in]  RgSchUeCb*    ue
12399  *  @param[in]  RgSchDlLcCb*  svc
12400  *  @return  Void
12401  *
12402  **/
12403 #ifdef ANSI
12404 Void rgSCHCmnFreeDlLc
12405 (
12406 RgSchCellCb                *cell,
12407 RgSchUeCb                  *ue,
12408 RgSchDlLcCb                *svc
12409 )
12410 #else
12411 Void rgSCHCmnFreeDlLc(cell, ue, svc)
12412 RgSchCellCb                *cell;
12413 RgSchUeCb                  *ue;
12414 RgSchDlLcCb                *svc;
12415 #endif
12416 {
12417    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
12418    if (svc->sch == NULLP)
12419    {
12420       return;
12421    }
12422 #ifdef EMTC_ENABLE
12423     if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
12424     {
12425       cellSch->apisEmtcDl->rgSCHFreeDlLc(cell, ue, svc);
12426     }
12427     else
12428 #endif
12429    {
12430       cellSch->apisDl->rgSCHFreeDlLc(cell, ue, svc);
12431    }
12432
12433 #ifdef LTE_ADV
12434    if (ue->numSCells)
12435    {
12436       rgSCHSCellDlLcDel(cell, ue, svc);
12437    }
12438 #endif
12439
12440 #ifdef LTEMAC_SPS
12441    /* If SPS service, invoke SPS module */
12442    if (svc->dlLcSpsCfg.isSpsEnabled)
12443    {
12444       rgSCHCmnSpsDlLcDel(cell, ue, svc);
12445    }
12446 #endif
12447
12448    /* ccpu00117052 - MOD - Passing double pointer
12449    for proper NULLP assignment*/
12450    rgSCHUtlFreeSBuf(cell->instIdx,
12451          (Data**)(&(svc->sch)), (sizeof(RgSchCmnDlSvc)));
12452
12453 #ifdef LTE_ADV
12454    rgSCHLaaDeInitDlLchCb(cell, svc);
12455 #endif
12456
12457    return;
12458 }
12459
12460 #ifdef RGR_V1
12461
12462 /**
12463  * @brief This function Processes the Final Allocations
12464  *        made by the RB Allocator against the requested
12465  *        CCCH SDURetx Allocations.
12466  *
12467  * @details
12468  *
12469  *     Function: rgSCHCmnDlCcchSduRetxFnlz
12470  *     Purpose:  This function Processes the Final Allocations
12471  *               made by the RB Allocator against the requested
12472  *               CCCH Retx Allocations.
12473  *               Scans through the scheduled list of ccchSdu retrans
12474  *               fills the corresponding pdcch, adds the hqProc to
12475  *               the corresponding SubFrm and removes the hqP from
12476  *               cells retx List.
12477  *
12478  *     Invoked by: Common Scheduler
12479  *
12480  *  @param[in]  RgSchCellCb           *cell
12481  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12482  *  @return  Void
12483  *
12484  **/
12485 #ifdef ANSI
12486 static Void rgSCHCmnDlCcchSduRetxFnlz
12487 (
12488 RgSchCellCb           *cell,
12489 RgSchCmnDlRbAllocInfo *allocInfo
12490 )
12491 #else
12492 static Void rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo)
12493 RgSchCellCb           *cell;
12494 RgSchCmnDlRbAllocInfo *allocInfo;
12495 #endif
12496 {
12497    CmLList           *node;
12498    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12499    RgSchDlRbAlloc    *rbAllocInfo;
12500    RgSchDlHqProcCb   *hqP;
12501    RgSchUeCb         *ue;
12502
12503    /* Traverse through the Scheduled Retx List */
12504    node = allocInfo->ccchSduAlloc.schdCcchSduRetxLst.first;
12505    while (node)
12506    {
12507       hqP = (RgSchDlHqProcCb *)(node->node);
12508       ue = hqP->hqE->ue;
12509       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
12510       node = node->next;
12511       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12512
12513       /* Remove the HqP from cell's ccchSduRetxLst */
12514       cmLListDelFrm(&cmnCellDl->ccchSduRetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
12515       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
12516
12517       /* Fix: syed dlAllocCb reset should be performed.
12518        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12519       rgSCHCmnDlUeResetTemp(ue, hqP);
12520    }
12521    /* Fix: syed dlAllocCb reset should be performed.
12522     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12523    node = allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst.first;
12524    while(node)
12525    {
12526       hqP = (RgSchDlHqProcCb *)(node->node);
12527       ue = hqP->hqE->ue;
12528       node = node->next;
12529       /* reset the UE allocation Information */
12530       rgSCHCmnDlUeResetTemp(ue, hqP);
12531    }
12532    return;
12533 }
12534 #endif
12535 /**
12536  * @brief This function Processes the Final Allocations
12537  *        made by the RB Allocator against the requested
12538  *        CCCH Retx Allocations.
12539  *
12540  * @details
12541  *
12542  *     Function: rgSCHCmnDlCcchRetxFnlz
12543  *     Purpose:  This function Processes the Final Allocations
12544  *               made by the RB Allocator against the requested
12545  *               CCCH Retx Allocations.
12546  *               Scans through the scheduled list of msg4 retrans
12547  *               fills the corresponding pdcch, adds the hqProc to
12548  *               the corresponding SubFrm and removes the hqP from
12549  *               cells retx List.
12550  *
12551  *     Invoked by: Common Scheduler
12552  *
12553  *  @param[in]  RgSchCellCb           *cell
12554  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12555  *  @return  Void
12556  *
12557  **/
12558 #ifdef ANSI
12559 static Void rgSCHCmnDlCcchRetxFnlz
12560 (
12561 RgSchCellCb           *cell,
12562 RgSchCmnDlRbAllocInfo *allocInfo
12563 )
12564 #else
12565 static Void rgSCHCmnDlCcchRetxFnlz(cell, allocInfo)
12566 RgSchCellCb           *cell;
12567 RgSchCmnDlRbAllocInfo *allocInfo;
12568 #endif
12569 {
12570    CmLList           *node;
12571    RgSchCmnDlCell    *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12572    RgSchDlRbAlloc    *rbAllocInfo;
12573    RgSchDlHqProcCb   *hqP;
12574    RgSchRaCb         *raCb;
12575
12576    /* Traverse through the Scheduled Retx List */
12577    node = allocInfo->msg4Alloc.schdMsg4RetxLst.first;
12578    while (node)
12579    {
12580       hqP = (RgSchDlHqProcCb *)(node->node);
12581       raCb = hqP->hqE->raCb;
12582       rbAllocInfo = &raCb->rbAllocInfo;
12583       node = node->next;
12584       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12585
12586       /* Remove the HqP from cell's msg4RetxLst */
12587       cmLListDelFrm(&cmnCellDl->msg4RetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
12588       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
12589       /* Fix: syed dlAllocCb reset should be performed.
12590        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12591       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
12592       rgSCHCmnDlHqPResetTemp(hqP);
12593    }
12594    /* Fix: syed dlAllocCb reset should be performed.
12595     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12596    node = allocInfo->msg4Alloc.nonSchdMsg4RetxLst.first;
12597    while(node)
12598    {
12599       hqP = (RgSchDlHqProcCb *)(node->node);
12600       raCb = hqP->hqE->raCb;
12601       node = node->next;
12602       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
12603       rgSCHCmnDlHqPResetTemp(hqP);
12604    }
12605    return;
12606 }
12607
12608 #ifdef RGR_V1
12609 /**
12610  * @brief This function Processes the Final Allocations
12611  *        made by the RB Allocator against the requested
12612  *        CCCH SDU tx Allocations.
12613  *
12614  * @details
12615  *
12616  *     Function: rgSCHCmnDlCcchSduTxFnlz
12617  *     Purpose:  This function Processes the Final Allocations
12618  *               made by the RB Allocator against the requested
12619  *               CCCH tx Allocations.
12620  *               Scans through the scheduled list of CCCH SDU trans
12621  *               fills the corresponding pdcch, adds the hqProc to
12622  *               the corresponding SubFrm and removes the hqP from
12623  *               cells tx List.
12624  *
12625  *     Invoked by: Common Scheduler
12626  *
12627  *  @param[in]  RgSchCellCb           *cell
12628  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12629  *  @return  Void
12630  *
12631  **/
12632 #ifdef ANSI
12633 static Void rgSCHCmnDlCcchSduTxFnlz
12634 (
12635 RgSchCellCb           *cell,
12636 RgSchCmnDlRbAllocInfo *allocInfo
12637 )
12638 #else
12639 static Void rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo)
12640 RgSchCellCb           *cell;
12641 RgSchCmnDlRbAllocInfo *allocInfo;
12642 #endif
12643 {
12644    CmLList           *node;
12645    RgSchUeCb         *ueCb;
12646    RgSchDlRbAlloc    *rbAllocInfo;
12647    RgSchDlHqProcCb   *hqP;
12648    RgSchLchAllocInfo  lchSchdData;
12649
12650    /* Traverse through the Scheduled Retx List */
12651    node = allocInfo->ccchSduAlloc.schdCcchSduTxLst.first;
12652    while (node)
12653    {
12654       hqP = (RgSchDlHqProcCb *)(node->node);
12655       ueCb = hqP->hqE->ue;
12656       node = node->next;
12657       rbAllocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell);
12658
12659       /* fill the pdcch and HqProc */
12660       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12661
12662       /* Remove the raCb from cell's toBeSchdLst */
12663       cmLListDelFrm(&cell->ccchSduUeLst, &ueCb->ccchSduLnk);
12664       ueCb->ccchSduLnk.node = (PTR)NULLP;
12665
12666       /* Fix : Resetting this required to avoid complication
12667        * in reestablishment case */
12668       ueCb->dlCcchInfo.bo = 0;
12669
12670       /* Indicate DHM of the CCCH LC scheduling */
12671       hqP->tbInfo[0].contResCe = NOTPRSNT;
12672       lchSchdData.lcId     = 0;
12673       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
12674                              (RGSCH_MSG4_HDRSIZE);
12675       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
12676
12677       /* Fix: syed dlAllocCb reset should be performed.
12678        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12679       rgSCHCmnDlUeResetTemp(ueCb, hqP);
12680    }
12681    /* Fix: syed dlAllocCb reset should be performed.
12682     * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12683    node = allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst.first;
12684    while(node)
12685    {
12686       hqP = (RgSchDlHqProcCb *)(node->node);
12687       ueCb = hqP->hqE->ue;
12688       node = node->next;
12689       /* Release HqProc */
12690       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
12691       /*Fix: Removing releasing of TB1 as it will not exist for CCCH SDU and hence caused a crash*/
12692       /*rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
12693       /* reset the UE allocation Information */
12694       rgSCHCmnDlUeResetTemp(ueCb, hqP);
12695    }
12696    return;
12697 }
12698
12699 #endif
12700 /**
12701  * @brief This function Processes the Final Allocations
12702  *        made by the RB Allocator against the requested
12703  *        CCCH tx Allocations.
12704  *
12705  * @details
12706  *
12707  *     Function: rgSCHCmnDlCcchTxFnlz
12708  *     Purpose:  This function Processes the Final Allocations
12709  *               made by the RB Allocator against the requested
12710  *               CCCH tx Allocations.
12711  *               Scans through the scheduled list of msg4 trans
12712  *               fills the corresponding pdcch, adds the hqProc to
12713  *               the corresponding SubFrm and removes the hqP from
12714  *               cells tx List.
12715  *
12716  *     Invoked by: Common Scheduler
12717  *
12718  *  @param[in]  RgSchCellCb           *cell
12719  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12720  *  @return  Void
12721  *
12722  **/
12723 #ifdef ANSI
12724 static Void rgSCHCmnDlCcchTxFnlz
12725 (
12726 RgSchCellCb           *cell,
12727 RgSchCmnDlRbAllocInfo *allocInfo
12728 )
12729 #else
12730 static Void rgSCHCmnDlCcchTxFnlz(cell, allocInfo)
12731 RgSchCellCb           *cell;
12732 RgSchCmnDlRbAllocInfo *allocInfo;
12733 #endif
12734 {
12735    CmLList           *node;
12736    RgSchRaCb         *raCb;
12737    RgSchDlRbAlloc    *rbAllocInfo;
12738    RgSchDlHqProcCb   *hqP;
12739    RgSchLchAllocInfo  lchSchdData;
12740
12741    /* Traverse through the Scheduled Retx List */
12742    node = allocInfo->msg4Alloc.schdMsg4TxLst.first;
12743    while (node)
12744    {
12745       hqP = (RgSchDlHqProcCb *)(node->node);
12746       raCb = hqP->hqE->raCb;
12747       node = node->next;
12748       rbAllocInfo = &raCb->rbAllocInfo;
12749
12750       /* fill the pdcch and HqProc */
12751       rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP);
12752       /* MSG4 Fix Start */
12753      
12754       rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
12755       /* MSG4 Fix End */     
12756
12757       /* Indicate DHM of the CCCH LC scheduling */
12758       lchSchdData.lcId     = 0;
12759       lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes -
12760          (RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE);
12761       /* TRansmitting presence of cont Res CE across MAC-SCH interface to
12762        * identify CCCH SDU transmissions which need to be done
12763        * without the
12764        * contention resolution CE*/
12765       hqP->tbInfo[0].contResCe = PRSNT_NODEF;
12766       /*Dont add lc if only cont res CE is being transmitted*/
12767       if(raCb->dlCcchInfo.bo)
12768       {
12769          rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]);
12770       }
12771       else
12772       {
12773       }
12774       /* Fix: syed dlAllocCb reset should be performed.
12775        * zombie info in dlAllocCb leading to crash rbNum wraparound */ 
12776       memset(&raCb->rbAllocInfo, 0, sizeof(raCb->rbAllocInfo));
12777       rgSCHCmnDlHqPResetTemp(hqP);
12778    }
12779    node = allocInfo->msg4Alloc.nonSchdMsg4TxLst.first;
12780    while(node)
12781    {
12782       hqP = (RgSchDlHqProcCb *)(node->node);
12783       raCb = hqP->hqE->raCb;
12784       node = node->next;
12785       rbAllocInfo = &raCb->rbAllocInfo;
12786       /* Release HqProc */
12787       rgSCHDhmRlsHqpTb(hqP, 0, FALSE);
12788       /*Fix: Removing releasing of TB1 as it will not exist for MSG4 and hence caused a crash*/
12789       /*      rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/
12790       /* reset the UE allocation Information */
12791       memset(rbAllocInfo, 0, sizeof(*rbAllocInfo));
12792       rgSCHCmnDlHqPResetTemp(hqP);
12793    }
12794
12795    return;
12796 }
12797 /* R8 Upgrade */
12798 /**
12799  * @brief This function calculates the BI Index to be sent in the Bi header
12800  * field.
12801  *
12802  * @details
12803  *     Function: rgSCHCmnGetBiIndex
12804  *     Purpose:  This function Processes utilizes the previous BI time value
12805  *     calculated and the difference last BI sent time and current time. To
12806  *     calculate the latest BI Index. It also considers the how many UE's
12807  *     Unserved in this subframe.
12808  *
12809  *     Invoked by: Common Scheduler
12810  *
12811  *  @param[in]  RgSchCellCb           *cell
12812  *  @param[in]  uint32_t                   ueCount
12813  *  @return  uint8_t
12814  *
12815  **/
12816 #ifdef ANSI
12817 uint8_t rgSCHCmnGetBiIndex
12818 (
12819 RgSchCellCb   *cell,
12820 uint32_t           ueCount
12821 )
12822 #else
12823 uint8_t rgSCHCmnGetBiIndex(cell, ueCount)
12824 RgSchCellCb   *cell;
12825 uint32_t           ueCount;
12826 #endif
12827 {
12828    S16  prevVal = 0;      /* To Store Intermediate Value */
12829    uint16_t  newBiVal = 0;     /* To store Bi Value in millisecond */
12830    uint8_t   idx = 0;
12831    uint16_t  timeDiff = 0;
12832
12833
12834    if (cell->biInfo.prevBiTime != 0)
12835    {
12836 #ifdef EMTC_ENABLE
12837       if(cell->emtcEnable == TRUE)
12838       {
12839          timeDiff =(RGSCH_CALC_SF_DIFF_EMTC(cell->crntTime, cell->biInfo.biTime));
12840       }
12841       else
12842 #endif
12843       {
12844          timeDiff =(RGSCH_CALC_SF_DIFF(cell->crntTime, cell->biInfo.biTime));
12845       }
12846
12847       prevVal = cell->biInfo.prevBiTime - timeDiff;
12848    }
12849    if (prevVal < 0)
12850    {
12851       prevVal = 0;
12852    }
12853    newBiVal = RG_SCH_CMN_GET_BI_VAL(prevVal,ueCount);
12854    /* To be used next time when BI is calculated */
12855 #ifdef EMTC_ENABLE
12856    if(cell->emtcEnable == TRUE)
12857    {
12858       RGSCHCPYTIMEINFO_EMTC(cell->crntTime, cell->biInfo.biTime)
12859    }
12860    else
12861 #endif
12862    {
12863       RGSCHCPYTIMEINFO(cell->crntTime, cell->biInfo.biTime)
12864    }
12865
12866   /* Search the actual BI Index from table Backoff Parameters Value  and
12867    * return that Index */
12868    do
12869    {
12870       if (rgSchCmnBiTbl[idx] > newBiVal)
12871       {
12872          break;
12873       }
12874       idx++;
12875    }while(idx < RG_SCH_CMN_NUM_BI_VAL-1);
12876    cell->biInfo.prevBiTime = rgSchCmnBiTbl[idx];
12877    /* For 16 Entries in Table 7.2.1 36.321.880 - 3 reserved so total 13 Entries */
12878    return (idx); /* Returning reserved value from table UE treats it has 960 ms */
12879 } /* rgSCHCmnGetBiIndex */
12880
12881
12882 /**
12883  * @brief This function Processes the Final Allocations
12884  *        made by the RB Allocator against the requested
12885  *        RAR allocations. Assumption: The reuqested
12886  *        allocations are always satisfied completely.
12887  *        Hence no roll back.
12888  *
12889  * @details
12890  *
12891  *     Function: rgSCHCmnDlRaRspFnlz
12892  *     Purpose:  This function Processes the Final Allocations
12893  *               made by the RB Allocator against the requested.
12894  *               Takes care of PDCCH filling.
12895  *
12896  *     Invoked by: Common Scheduler
12897  *
12898  *  @param[in]  RgSchCellCb           *cell
12899  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
12900  *  @return  Void
12901  *
12902  **/
12903 #ifdef ANSI
12904 static Void rgSCHCmnDlRaRspFnlz
12905 (
12906 RgSchCellCb           *cell,
12907 RgSchCmnDlRbAllocInfo *allocInfo
12908 )
12909 #else
12910 static Void rgSCHCmnDlRaRspFnlz(cell, allocInfo)
12911 RgSchCellCb           *cell;
12912 RgSchCmnDlRbAllocInfo *allocInfo;
12913 #endif
12914 {
12915    uint32_t            rarCnt = 0;
12916    RgSchDlRbAlloc *raRspAlloc;
12917    RgSchDlSf      *subFrm = NULLP;
12918    RgSchRaCb      *raCb;
12919    RgSchErrInfo   err;
12920    CmLListCp      *reqLst;
12921    RgSchRaReqInfo *raReq;
12922    Bool           preamGrpA;
12923    RgSchUlAlloc   *ulAllocRef=NULLP;
12924    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
12925    uint8_t              allocRapidCnt = 0;
12926 #ifdef LTE_TDD
12927    uint32_t            msg3SchdIdx = 0;
12928    uint8_t             ulDlCfgIdx = cell->ulDlCfgIdx;
12929    uint8_t             msg3Subfrm;
12930 #endif
12931
12932
12933    for (rarCnt=0; rarCnt<RG_SCH_CMN_MAX_CMN_PDCCH; rarCnt++)
12934    {
12935       raRspAlloc = &allocInfo->raRspAlloc[rarCnt];
12936       /* Having likely condition first for optimization */
12937       if (!raRspAlloc->pdcch)
12938       {
12939          continue;
12940       }
12941       else
12942       {
12943          subFrm = raRspAlloc->dlSf;
12944          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
12945          /* Corrected RACH handling for multiple RAPIDs per RARNTI */
12946          allocRapidCnt = raRspAlloc->numRapids;
12947          while (allocRapidCnt)
12948          {
12949             raReq = (RgSchRaReqInfo *)(reqLst->first->node);
12950             /* RACHO: If dedicated preamble, then allocate UL Grant
12951              * (consequence of handover/pdcchOrder) and continue */
12952             if (RGSCH_IS_DEDPRM(cell, raReq->raReq.rapId))
12953             {
12954                rgSCHCmnHdlHoPo(cell, &subFrm->raRsp[rarCnt].contFreeUeLst,
12955                      raReq);
12956                cmLListDelFrm(reqLst, reqLst->first);
12957                allocRapidCnt--;
12958                /* ccpu00117052 - MOD - Passing double pointer
12959                for proper NULLP assignment*/
12960                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
12961                      sizeof(RgSchRaReqInfo));
12962                continue;
12963             }
12964             /* ccpu00139815 */
12965             if(cell->overLoadBackOffEnab)
12966             {/* rach Overlaod conrol is triggerd, Skipping this rach */
12967                cmLListDelFrm(reqLst, reqLst->first);
12968                allocRapidCnt--;
12969                rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
12970                      sizeof(RgSchRaReqInfo));
12971                continue;
12972             }
12973             /* Attempt to include each RA request into the RSP */
12974             /* Any failure in the procedure is considered to   */
12975             /* affect futher allocations in the same TTI. When */
12976             /* a failure happens, we break out and complete    */
12977             /* the processing for random access                */
12978             if (rgSCHRamCreateRaCb(cell, &raCb, &err) != ROK)
12979             {
12980                break;
12981             }
12982             /* Msg3 allocation request to USM */
12983             if (raReq->raReq.rapId < cell->rachCfg.sizeRaPreambleGrpA)
12984                preamGrpA = TRUE;
12985             else
12986                preamGrpA = FALSE;
12987             /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
12988             rgSCHCmnMsg3GrntReq(cell, raCb->tmpCrnti, preamGrpA, \
12989                   &(raCb->msg3HqProc), &ulAllocRef, &raCb->msg3HqProcId);
12990             if (ulAllocRef == NULLP)
12991             {
12992                rgSCHRamDelRaCb(cell, raCb, TRUE);
12993                break;
12994             }
12995             if (raReq->raReq.cqiPres)
12996             {
12997                raCb->ccchCqi = raReq->raReq.cqiIdx;
12998             }
12999             else
13000             {
13001                raCb->ccchCqi = cellDl->ccchCqi;
13002             }
13003             raCb->rapId = raReq->raReq.rapId;
13004             raCb->ta.pres    = TRUE;
13005             raCb->ta.val = raReq->raReq.ta;
13006             raCb->msg3Grnt = ulAllocRef->grnt;
13007             /* Populating the tpc value received */
13008             raCb->msg3Grnt.tpc = raReq->raReq.tpc;
13009             /* PHR handling for MSG3 */
13010             ulAllocRef->raCb = raCb;
13011 #ifndef LTE_TDD
13012             /* To the crntTime, add the MIN time at which UE will
13013              * actually send MSG3 i.e DL_DELTA+6 */
13014             raCb->msg3AllocTime = cell->crntTime;
13015             RGSCH_INCR_SUB_FRAME(raCb->msg3AllocTime, RG_SCH_CMN_MIN_MSG3_RECP_INTRVL);
13016 #else
13017             msg3SchdIdx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % 
13018                                  RGSCH_NUM_SUB_FRAMES;
13019             /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
13020               special subframe */                       
13021             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][msg3SchdIdx] != 
13022                         RG_SCH_TDD_UL_SUBFRAME)
13023             {
13024                RGSCHCMNADDTOCRNTTIME(cell->crntTime,raCb->msg3AllocTime,
13025                                        RG_SCH_CMN_DL_DELTA)
13026                msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][
13027                                        raCb->msg3AllocTime.slot];
13028                RGSCHCMNADDTOCRNTTIME(raCb->msg3AllocTime, raCb->msg3AllocTime, 
13029                                  msg3Subfrm);
13030             }
13031 #endif
13032             cmLListAdd2Tail(&subFrm->raRsp[rarCnt].raRspLst, &raCb->rspLnk);
13033             raCb->rspLnk.node = (PTR)raCb;
13034             cmLListDelFrm(reqLst, reqLst->first);
13035             allocRapidCnt--;
13036             /* ccpu00117052 - MOD - Passing double pointer
13037             for proper NULLP assignment*/
13038             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq,
13039                   sizeof(RgSchRaReqInfo));
13040
13041             /* SR_RACH_STATS : RAR scheduled */
13042             rgNumRarSched++;
13043
13044          }
13045          /* R8 Upgrade */
13046          /* Fill subframe data members */
13047          subFrm->raRsp[rarCnt].raRnti = raRspAlloc->rnti;
13048          subFrm->raRsp[rarCnt].pdcch  = raRspAlloc->pdcch;
13049          subFrm->raRsp[rarCnt].tbSz   = raRspAlloc->tbInfo[0].bytesAlloc;
13050          /* Fill PDCCH data members */
13051          rgSCHCmnFillPdcch(cell, subFrm->raRsp[rarCnt].pdcch, raRspAlloc);
13052
13053          /* ccpu00139815 */
13054          if(cell->overLoadBackOffEnab)
13055          {/* rach Overlaod conrol is triggerd, Skipping this rach */
13056             subFrm->raRsp[rarCnt].backOffInd.pres = PRSNT_NODEF;
13057             subFrm->raRsp[rarCnt].backOffInd.val  = cell->overLoadBackOffval;
13058             continue;
13059          }
13060          else
13061          {
13062             subFrm->raRsp[rarCnt].backOffInd.pres = NOTPRSNT;
13063          }
13064
13065          /*[ccpu00125212] Avoiding sending of empty RAR in case of RAR window
13066            is short and UE is sending unauthorised preamble.*/
13067          reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex];
13068          if ((raRspAlloc->biEstmt) && (reqLst->count))
13069          {
13070             subFrm->raRsp[0].backOffInd.pres = PRSNT_NODEF;
13071             /* Added as part of Upgrade */
13072             subFrm->raRsp[0].backOffInd.val =
13073             rgSCHCmnGetBiIndex(cell, reqLst->count);
13074
13075             /* SR_RACH_STATS : Back Off Inds */
13076             rgNumBI++;
13077
13078          }
13079          else if ((subFrm->raRsp[rarCnt].raRspLst.first == NULLP) &&
13080                (subFrm->raRsp[rarCnt].contFreeUeLst.first == NULLP))
13081          {
13082             /* Return the grabbed PDCCH */
13083             rgSCHUtlPdcchPut(cell, &subFrm->pdcchInfo, raRspAlloc->pdcch);
13084             subFrm->raRsp[rarCnt].pdcch = NULLP;
13085             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRaRspAlloc(): "
13086                   "Not even one RaReq.");
13087             return;
13088          }
13089       }
13090       RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, 
13091             "RNTI:%d Scheduled RAR @ (%u,%u) ",
13092             raRspAlloc->rnti, 
13093             cell->crntTime.sfn,
13094             cell->crntTime.slot);
13095    }
13096    return;
13097 }
13098
13099 /**
13100  * @brief This function computes rv.
13101  *
13102  * @details
13103  *
13104  *     Function: rgSCHCmnDlCalcRvForBcch
13105  *     Purpose:  This function computes rv.
13106  *
13107  *     Invoked by: Common Scheduler
13108  *
13109  *  @param[in]   RgSchCellCb     *cell
13110  *  @param[in]   Bool            si
13111  *  @param[in]   uint16_t             i
13112  *  @return  uint8_t
13113  *
13114  **/
13115 #ifdef ANSI
13116 static uint8_t rgSCHCmnDlCalcRvForBcch
13117 (
13118 RgSchCellCb          *cell,
13119 Bool                 si,
13120 uint16_t             i
13121 )
13122 #else
13123 static uint8_t rgSCHCmnDlCalcRvForBcch(cell, si, i)
13124 RgSchCellCb          *cell;
13125 Bool                 si;
13126 uint16_t             i;
13127 #endif
13128 {
13129    uint8_t k, rv;
13130    CmLteTimingInfo   frm;
13131
13132    frm   = cell->crntTime;
13133    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
13134
13135    if(si)
13136    {
13137       k = i % 4;
13138    }
13139    else
13140    {
13141       k = (frm.sfn/2) % 4;
13142    }
13143    rv = RGSCH_CEIL(3*k, 2) % 4;
13144    return (rv);
13145 }
13146
13147 /**
13148  * @brief This function Processes the Final Allocations
13149  *        made by the RB Allocator against the requested
13150  *        BCCH/PCCH allocations. Assumption: The reuqested
13151  *        allocations are always satisfied completely.
13152  *        Hence no roll back.
13153  *
13154  * @details
13155  *
13156  *     Function: rgSCHCmnDlBcchPcchFnlz
13157  *     Purpose:  This function Processes the Final Allocations
13158  *               made by the RB Allocator against the requested.
13159  *               Takes care of PDCCH filling.
13160  *
13161  *     Invoked by: Common Scheduler
13162  *
13163  *  @param[in]  RgSchCellCb           *cell
13164  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
13165  *  @return  Void
13166  *
13167  **/
13168 #ifdef ANSI
13169 static Void rgSCHCmnDlBcchPcchFnlz
13170 (
13171 RgSchCellCb           *cell,
13172 RgSchCmnDlRbAllocInfo *allocInfo
13173 )
13174 #else
13175 static Void rgSCHCmnDlBcchPcchFnlz(cell, allocInfo)
13176 RgSchCellCb           *cell;
13177 RgSchCmnDlRbAllocInfo *allocInfo;
13178 #endif
13179 {
13180    RgSchDlRbAlloc *rbAllocInfo;
13181    RgSchDlSf      *subFrm;
13182
13183 #ifdef LTE_TDD
13184    uint8_t             nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
13185 #else
13186 #ifdef LTEMAC_HDFDD
13187    uint8_t             nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13188 #else
13189    uint8_t             nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13190 #endif
13191 #endif
13192
13193    /*  Moving variables to available scope for optimization */
13194    RgSchClcDlLcCb *pcch;
13195    RgSchClcBoRpt  *bo;
13196 #ifndef RGR_SI_SCH
13197    RgSchClcDlLcCb  *bcch;
13198    Bool           sendInd=TRUE;
13199 #endif
13200    RgSchCmnDlCell       *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
13201
13202
13203    /* handle PCCH */
13204    rbAllocInfo = &allocInfo->pcchAlloc;
13205    if (rbAllocInfo->pdcch)
13206    {
13207       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
13208
13209       /* Added sfIdx calculation for TDD as well */
13210 #ifndef LTE_TDD
13211 #ifdef LTEMAC_HDFDD
13212       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13213 #else
13214       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13215 #endif
13216 #endif
13217       subFrm = rbAllocInfo->dlSf;
13218       pcch = rgSCHDbmGetPcch(cell);
13219       if(pcch == NULLP)
13220       {
13221          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnDlBcchPcchFnlz( ): "
13222                "No Pcch Present");
13223          return;
13224       }
13225
13226       /* Added Dl TB count for paging message transmission*/
13227 #ifdef LTE_L2_MEAS
13228       cell->dlUlTbCnt.tbTransDlTotalCnt++;
13229 #endif      
13230       bo = (RgSchClcBoRpt *)pcch->boLst.first->node;
13231       cmLListDelFrm(&pcch->boLst, &bo->boLstEnt);
13232       /* ccpu00117052 - MOD - Passing double pointer
13233          for proper NULLP assignment*/
13234       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
13235       /* Fill subframe data members */
13236       subFrm->pcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
13237       subFrm->pcch.pdcch  = rbAllocInfo->pdcch;
13238       /* Fill PDCCH data members */
13239       rgSCHCmnFillPdcch(cell, subFrm->pcch.pdcch, rbAllocInfo);
13240       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, pcch->lcId, TRUE);
13241       /* ccpu00132314-ADD-Update the tx power allocation info  
13242          TODO-Need to add a check for max tx power per symbol */ 
13243       subfrmAlloc->cmnLcInfo.pcchInfo.txPwrOffset = cellDl->pcchTxPwrOffset;   
13244    }
13245
13246    /* handle BCCH */
13247    rbAllocInfo = &allocInfo->bcchAlloc;
13248    if (rbAllocInfo->pdcch)
13249    {
13250       RgInfSfAlloc   *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]);
13251 #ifndef LTE_TDD
13252 #ifdef LTEMAC_HDFDD
13253       nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
13254 #else
13255       nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
13256 #endif
13257 #endif
13258       subFrm = rbAllocInfo->dlSf;
13259
13260       /* Fill subframe data members */
13261       subFrm->bcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc;
13262       subFrm->bcch.pdcch  = rbAllocInfo->pdcch;
13263       /* Fill PDCCH data members */
13264       rgSCHCmnFillPdcch(cell, subFrm->bcch.pdcch, rbAllocInfo);
13265
13266       if(rbAllocInfo->schdFirst)
13267       {
13268 #ifndef RGR_SI_SCH
13269          bcch = rgSCHDbmGetFirstBcchOnDlsch(cell);
13270          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
13271 #else
13272          /*Copy the SIB1 msg buff into interface buffer */
13273          SCpyMsgMsg(cell->siCb.crntSiInfo.sib1Info.sib1,
13274                rgSchCb[cell->instIdx].rgSchInit.region,
13275                rgSchCb[cell->instIdx].rgSchInit.pool,
13276                &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13277 #endif/*RGR_SI_SCH*/
13278          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
13279             rgSCHCmnDlCalcRvForBcch(cell, FALSE, 0);
13280       }
13281       else
13282       {
13283          uint16_t   i;
13284 #ifdef RGR_SI_SCH
13285          Buffer    *pdu;
13286
13287          i = cell->siCb.siCtx.i;
13288          /*Decrement the retransmission count */
13289          cell->siCb.siCtx.retxCntRem--;
13290
13291          /*Copy the SI msg buff into interface buffer */
13292          if(cell->siCb.siCtx.warningSiFlag == FALSE)
13293          {
13294             SCpyMsgMsg(cell->siCb.siArray[cell->siCb.siCtx.siId-1].si,
13295                   rgSchCb[cell->instIdx].rgSchInit.region,
13296                   rgSchCb[cell->instIdx].rgSchInit.pool,
13297                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13298          }
13299          else
13300          {
13301             pdu = rgSCHUtlGetWarningSiPdu(cell);
13302             RGSCH_NULL_CHECK(cell->instIdx, pdu);
13303             SCpyMsgMsg(pdu,
13304                   rgSchCb[cell->instIdx].rgSchInit.region,
13305                   rgSchCb[cell->instIdx].rgSchInit.pool,
13306                   &subfrmAlloc->cmnLcInfo.bcchInfo.pdu);
13307             if(cell->siCb.siCtx.retxCntRem == 0)
13308             {  
13309                rgSCHUtlFreeWarningSiPdu(cell);
13310                cell->siCb.siCtx.warningSiFlag  = FALSE;
13311
13312             }
13313          }
13314 #else
13315          bcch = rgSCHDbmGetSecondBcchOnDlsch(cell);
13316          bo = (RgSchClcBoRpt *)bcch->boLst.first->node;
13317          bo->retxCnt--;
13318          if(bo->retxCnt != cell->siCfg.retxCnt-1)
13319          {
13320             sendInd=FALSE;
13321          }
13322          i = bo->i;
13323 #endif/*RGR_SI_SCH*/
13324          subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv =
13325             rgSCHCmnDlCalcRvForBcch(cell, TRUE, i);
13326       }
13327
13328       /* Added Dl TB count for SIB1 and SI messages transmission.
13329        * This counter will be incremented only for the first transmission
13330        * (with RV 0) of these messages*/
13331 #ifdef LTE_L2_MEAS
13332       if(subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv == 0)
13333       {   
13334          cell->dlUlTbCnt.tbTransDlTotalCnt++;
13335       }
13336 #endif      
13337 #ifndef RGR_SI_SCH
13338       if(bo->retxCnt == 0)
13339       {
13340          cmLListDelFrm(&bcch->boLst, &bo->boLstEnt);
13341          /* ccpu00117052 - MOD - Passing double pointer
13342             for proper NULLP assignment*/
13343          rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
13344       }
13345       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, bcch->lcId, sendInd);
13346 #else
13347       /*Fill the interface info */
13348       rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, NULLD, NULLD);
13349
13350       /* ccpu00132314-ADD-Update the tx power allocation info  
13351          TODO-Need to add a check for max tx power per symbol */ 
13352       subfrmAlloc->cmnLcInfo.bcchInfo.txPwrOffset = cellDl->bcchTxPwrOffset;   
13353
13354       /*mBuf has been already copied above */
13355 #endif/*RGR_SI_SCH*/
13356    }
13357
13358    return;
13359 }
13360
13361
13362 #if RG_UNUSED
13363 /**
13364  * @brief
13365  *
13366  * @details
13367  *
13368  *     Function: rgSCHCmnUlSetAllUnSched
13369  *     Purpose:
13370  *
13371  *     Invoked by: Common Scheduler
13372  *
13373  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13374  *  @return  Void
13375  *
13376  **/
13377 #ifdef ANSI
13378 static Void rgSCHCmnUlSetAllUnSched
13379 (
13380 RgSchCmnUlRbAllocInfo *allocInfo
13381 )
13382 #else
13383 static Void rgSCHCmnUlSetAllUnSched(allocInfo)
13384 RgSchCmnUlRbAllocInfo *allocInfo;
13385 #endif
13386 {
13387    CmLList            *node;
13388
13389
13390    node = allocInfo->contResLst.first;
13391    while (node)
13392    {
13393       rgSCHCmnUlMov2NonSchdCntResLst(allocInfo, (RgSchUeCb *)node->node);
13394       node = allocInfo->contResLst.first;
13395    }
13396
13397    node = allocInfo->retxUeLst.first;
13398    while (node)
13399    {
13400       rgSCHCmnUlMov2NonSchdRetxUeLst(allocInfo, (RgSchUeCb *)node->node);
13401       node = allocInfo->retxUeLst.first;
13402    }
13403
13404    node = allocInfo->ueLst.first;
13405    while (node)
13406    {
13407       rgSCHCmnUlMov2NonSchdUeLst(allocInfo, (RgSchUeCb *)node->node);
13408       node = allocInfo->ueLst.first;
13409    }
13410
13411    return;
13412 }
13413 #endif
13414
13415 /**
13416  * @brief
13417  *
13418  * @details
13419  *
13420  *     Function: rgSCHCmnUlAdd2CntResLst
13421  *     Purpose:
13422  *
13423  *     Invoked by: Common Scheduler
13424  *
13425  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13426  *  @param[in]  RgSchUeCb             *ue
13427  *  @return  Void
13428  *
13429  **/
13430 #ifdef ANSI
13431 Void rgSCHCmnUlAdd2CntResLst
13432 (
13433 RgSchCmnUlRbAllocInfo *allocInfo,
13434 RgSchUeCb             *ue
13435 )
13436 #else
13437 Void rgSCHCmnUlAdd2CntResLst(allocInfo, ue)
13438 RgSchCmnUlRbAllocInfo *allocInfo;
13439 RgSchUeCb             *ue;
13440 #endif
13441 {
13442    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,ue->cell))->alloc);
13443    cmLListAdd2Tail(&allocInfo->contResLst, &ulAllocInfo->reqLnk);
13444    ulAllocInfo->reqLnk.node = (PTR)ue;
13445    return;
13446 }
13447
13448 /**
13449  * @brief
13450  *
13451  * @details
13452  *
13453  *     Function: rgSCHCmnUlAdd2UeLst
13454  *     Purpose:
13455  *
13456  *     Invoked by: Common Scheduler
13457  *
13458  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo
13459  *  @param[in]  RgSchUeCb             *ue
13460  *  @return  Void
13461  *
13462  **/
13463 #ifdef ANSI
13464 Void rgSCHCmnUlAdd2UeLst
13465 (
13466 RgSchCellCb           *cell,
13467 RgSchCmnUlRbAllocInfo *allocInfo,
13468 RgSchUeCb             *ue
13469 )
13470 #else
13471 Void rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue)
13472 RgSchCellCb           *cell;
13473 RgSchCmnUlRbAllocInfo *allocInfo;
13474 RgSchUeCb             *ue;
13475 #endif
13476 {
13477    RgSchCmnUeUlAlloc  *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,cell))->alloc);
13478    if (ulAllocInfo->reqLnk.node == NULLP)
13479    {
13480       cmLListAdd2Tail(&allocInfo->ueLst, &ulAllocInfo->reqLnk);
13481       ulAllocInfo->reqLnk.node = (PTR)ue;
13482    }
13483    return;
13484 }
13485
13486 /**
13487  * @brief
13488  *
13489  * @details
13490  *
13491  *     Function: rgSCHCmnAllocUlRb
13492  *     Purpose:  To do RB allocations for uplink
13493  *
13494  *     Invoked by: Common Scheduler
13495  *
13496  *  @param[in]  RgSchCellCb           *cell
13497  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
13498  *  @return  Void
13499  **/
13500 #ifdef ANSI
13501 Void rgSCHCmnAllocUlRb
13502 (
13503 RgSchCellCb           *cell,
13504 RgSchCmnUlRbAllocInfo *allocInfo
13505 )
13506 #else
13507 Void rgSCHCmnAllocUlRb(cell, allocInfo)
13508 RgSchCellCb           *cell;
13509 RgSchCmnUlRbAllocInfo *allocInfo;
13510 #endif
13511 {
13512    RgSchUlSf         *sf = allocInfo->sf;
13513
13514    /* Schedule for new transmissions */
13515    rgSCHCmnUlRbAllocForLst(cell, sf, allocInfo->ueLst.count,
13516          &allocInfo->ueLst, &allocInfo->schdUeLst,
13517          &allocInfo->nonSchdUeLst, (Bool)TRUE);
13518    return;
13519 }
13520
13521 /***********************************************************
13522  *
13523  *     Func : rgSCHCmnUlRbAllocForLst
13524  *
13525  *     Desc : Allocate for a list in cmn rb alloc information passed
13526  *            in a subframe.
13527  *
13528  *     Ret  :
13529  *
13530  *     Notes:
13531  *
13532  *     File :
13533  *
13534  **********************************************************/
13535 #ifdef ANSI
13536 static Void rgSCHCmnUlRbAllocForLst
13537 (
13538 RgSchCellCb           *cell,
13539 RgSchUlSf             *sf,
13540 uint32_t                   count,
13541 CmLListCp             *reqLst,
13542 CmLListCp             *schdLst,
13543 CmLListCp             *nonSchdLst,
13544 Bool                  isNewTx
13545 )
13546 #else
13547 static Void rgSCHCmnUlRbAllocForLst(cell, sf, count, reqLst, schdLst,
13548                                      nonSchdLst, isNewTx)
13549 RgSchCellCb           *cell;
13550 RgSchUlSf             *sf;
13551 uint32_t                   count;
13552 CmLListCp             *reqLst;
13553 CmLListCp             *schdLst;
13554 CmLListCp             *nonSchdLst;
13555 Bool                  isNewTx;
13556 #endif
13557 {
13558    CmLList          *lnk;
13559    RgSchUlHole      *hole;
13560 #ifdef LTE_L2_MEAS
13561 #ifdef LTE_TDD
13562    uint8_t               k;
13563    CmLteTimingInfo  timeInfo;
13564 #endif    
13565 #endif    
13566
13567    if(schdLst->count == 0)
13568    {
13569       cmLListInit(schdLst);
13570    }
13571
13572    cmLListInit(nonSchdLst);
13573 #ifdef LTE_L2_MEAS
13574    if(isNewTx == TRUE)
13575    {
13576       cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.numUes = (uint8_t) count;
13577 #ifdef LTE_TDD
13578       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timeInfo, TFU_ULCNTRL_DLDELTA);
13579       k = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][timeInfo.subframe];
13580       RG_SCH_ADD_TO_CRNT_TIME(timeInfo,
13581           cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, k);
13582 #else
13583       RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime,cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo,
13584                             (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
13585 #endif
13586    }
13587 #endif
13588
13589    for (lnk = reqLst->first; count; lnk = lnk->next, --count)
13590    {
13591       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
13592       RgSchCmnUlUe          *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
13593       S16                   ret;
13594       uint8_t                    maxRb;
13595
13596
13597       if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
13598       {
13599          break;
13600       }
13601
13602       ueUl->subbandShare = ueUl->subbandRequired;
13603       if(isNewTx == TRUE)
13604       {
13605          maxRb = RGSCH_MIN((ueUl->subbandRequired * MAX_5GTF_VRBG_SIZE), ue->ue5gtfCb.maxPrb);
13606       } 
13607       ret = rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole);
13608       if (ret == ROK)
13609       {
13610          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, schdLst);
13611          rgSCHCmnUlUeFillAllocInfo(cell, ue);
13612       }
13613       else
13614       {
13615          gUl5gtfRbAllocFail++;
13616 #if defined (TENB_STATS) && defined (RG_5GTF)
13617          cell->tenbStats->sch.ul5gtfRbAllocFail++;
13618 #endif
13619          rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
13620          ue->isMsg4PdcchWithCrnti = FALSE;
13621          ue->isSrGrant = FALSE;
13622       }
13623 #ifdef LTE_L2_MEAS
13624       if(isNewTx == TRUE)
13625       {
13626          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
13627          ulAllocInfo[count - 1].rnti   = ue->ueId;
13628          cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.
13629          ulAllocInfo[count - 1].numPrb = ue->ul.nPrb;
13630       }
13631 #endif
13632       ueUl->subbandShare = 0; /* This reset will take care of
13633                                   * all scheduler types */
13634    }
13635    for (; count; lnk = lnk->next, --count)
13636    {
13637       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
13638       rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst);
13639       ue->isMsg4PdcchWithCrnti = FALSE;
13640    }
13641    return;
13642 }
13643
13644 #ifdef UNUSED_FUNC
13645 #ifdef TFU_UPGRADE
13646 /***********************************************************
13647  *
13648  *     Func : rgSCHCmnUlMdfyGrntForCqi
13649  *
13650  *     Desc : Modify UL Grant to consider presence of 
13651  *            CQI along with PUSCH Data.
13652  *
13653  *     Ret  :
13654  *
13655  *     Notes: 
13656  *          -  Scale down iTbs based on betaOffset and
13657  *             size of Acqi Size.
13658  *          -  Optionally attempt to increase numSb by 1
13659  *             if input payload size does not fit in due 
13660  *             to reduced tbSz as a result of iTbsNew.
13661  *
13662  *     File :
13663  *
13664  **********************************************************/
13665 #ifdef ANSI
13666 static S16 rgSCHCmnUlMdfyGrntForCqi
13667 (
13668 RgSchCellCb  *cell,
13669 RgSchUeCb    *ue,
13670 uint32_t          maxRb,
13671 uint32_t          *numSb,
13672 uint8_t           *iTbs,
13673 uint32_t          hqSz,
13674 uint32_t          stepDownItbs,
13675 uint32_t          effTgt
13676 )
13677 #else
13678 static S16 rgSCHCmnUlMdfyGrntForCqi(cell, ue, maxRb, numSb, iTbs, hqSz, stepDownItbs, effTgt)
13679 RgSchCellCb  *cell;
13680 RgSchUeCb    *ue;
13681 uint32_t          maxRb;
13682 uint32_t          *numSb;
13683 uint8_t           *iTbs;
13684 uint32_t          hqSz;
13685 uint32_t          stepDownItbs;
13686 uint32_t          effTgt;
13687 #endif
13688 {
13689    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(ue->cell);
13690    uint32_t  nPrb;
13691    uint32_t  totREs;
13692    uint32_t  cqiRiREs;
13693    uint32_t  hqREs;
13694    uint32_t  remREsForPusch;
13695    uint32_t  bitsPerRe;
13696    uint32_t  tbSz;
13697    uint32_t  betaOffVal = ue->ul.betaOffstVal;
13698    uint32_t  cqiRiRptSz = ue->ul.cqiRiSz;
13699    uint32_t  betaOffHqVal = rgSchCmnBetaHqOffstTbl[ue->ul.betaHqOffst];
13700    uint32_t  resNumSb = *numSb;
13701    uint32_t  puschEff = 1000;
13702    uint8_t   modOdr;
13703    uint8_t   iMcs;
13704    Bool mdfyiTbsFlg = FALSE;
13705    uint8_t   resiTbs = *iTbs;
13706
13707
13708    
13709    do
13710    {
13711       iMcs  = rgSCHCmnUlGetIMcsFrmITbs(resiTbs, RG_SCH_CMN_GET_UE_CTGY(ue));
13712       RG_SCH_UL_MCS_TO_MODODR(iMcs, modOdr);
13713       if (RG_SCH_CMN_GET_UE_CTGY(ue) != CM_LTE_UE_CAT_5)
13714       {
13715          modOdr = RGSCH_MIN(RGSCH_QM_QPSK, modOdr);
13716       }
13717       else
13718       {
13719          modOdr = RGSCH_MIN(RGSCH_QM_64QAM, modOdr);
13720       }
13721       nPrb = resNumSb * cellUl->sbSize;
13722       /* Restricting the minumum iTbs requried to modify to 10 */
13723       if ((nPrb >= maxRb) && (resiTbs <= 10))
13724       {
13725          /* Could not accomodate ACQI */
13726          return RFAILED;
13727       }
13728       totREs = nPrb * RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
13729       tbSz = rgTbSzTbl[0][resiTbs][nPrb-1];
13730       /*  totalREs/tbSz = num of bits perRE.  */
13731       cqiRiREs = (totREs * betaOffVal * cqiRiRptSz)/(1000 * tbSz); /* betaOffVal is represented 
13732                                                                    as parts per 1000 */
13733       hqREs = (totREs * betaOffHqVal * hqSz)/(1000 * tbSz);
13734       if ((cqiRiREs + hqREs) < totREs)
13735       {
13736          remREsForPusch = totREs - cqiRiREs - hqREs;
13737          bitsPerRe = (tbSz * 1000)/remREsForPusch; /* Multiplying by 1000 for Interger Oper */
13738          puschEff = bitsPerRe/modOdr;
13739       }
13740       if (puschEff < effTgt)
13741       {
13742           /* ensure resultant efficiency for PUSCH Data is within 0.93*/
13743           break;
13744       }
13745       else
13746       {
13747          /* Alternate between increasing SB or decreasing iTbs until eff is met */
13748          if (mdfyiTbsFlg == FALSE)
13749          {
13750             if (nPrb < maxRb)
13751             {
13752               resNumSb = resNumSb + 1;
13753             }
13754             mdfyiTbsFlg = TRUE;
13755          }
13756          else
13757          {
13758             if (resiTbs > 10)
13759             {
13760                resiTbs-= stepDownItbs;
13761             }
13762             mdfyiTbsFlg = FALSE;
13763          }
13764       }
13765    }while (1); /* Loop breaks if efficency is met 
13766                   or returns RFAILED if not able to meet the efficiency */
13767               
13768    *numSb = resNumSb;
13769    *iTbs = resiTbs;
13770
13771    return ROK;
13772 }
13773 #endif
13774 #endif
13775 /***********************************************************
13776  *
13777  *     Func : rgSCHCmnUlRbAllocForUe
13778  *
13779  *     Desc : Do uplink RB allocation for an UE.
13780  *
13781  *     Ret  :
13782  *
13783  *     Notes: Note that as of now, for retx, maxRb
13784  *            is not considered. Alternatives, such
13785  *            as dropping retx if it crosses maxRb
13786  *            could be considered.
13787  *
13788  *     File :
13789  *
13790  **********************************************************/
13791 #ifdef ANSI
13792 static S16 rgSCHCmnUlRbAllocForUe
13793 (
13794 RgSchCellCb           *cell,
13795 RgSchUlSf             *sf,
13796 RgSchUeCb             *ue,
13797 uint8_t                    maxRb,
13798 RgSchUlHole           *hole
13799 )
13800 #else
13801 static S16 rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole)
13802 RgSchCellCb           *cell;
13803 RgSchUlSf             *sf;
13804 RgSchUeCb             *ue;
13805 uint8_t                    maxRb;
13806 RgSchUlHole           *hole;
13807 #endif
13808 {
13809    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
13810    RgSchCmnUlUe    *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
13811    RgSchUlAlloc     *alloc = NULLP;
13812    uint32_t              nPrb = 0;
13813    uint8_t               numVrbg;
13814    uint8_t               iMcs;
13815    uint8_t               iMcsCrnt;
13816 #ifndef RG_5GTF
13817    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->schdHqProcIdx];
13818 #else
13819    RgSchUlHqProcCb  *proc = NULLP;
13820 #endif
13821    RgSchPdcch       *pdcch;
13822    uint32_t              reqVrbg;
13823    uint8_t               numVrbgTemp;
13824 #ifdef RG_5GTF
13825    TfuDciFormat     dciFrmt;
13826    uint8_t               numLyr;
13827 #endif
13828
13829 #ifdef RG_5GTF
13830    rgSCHUhmGetAvlHqProc(cell, ue, &proc);
13831    if (proc == NULLP)
13832    {
13833       //printf("UE [%d] HQ Proc unavailable\n", ue->ueId);
13834       return RFAILED;
13835    }
13836 #endif
13837
13838    if (ue->ue5gtfCb.rank == 2)
13839    {
13840       dciFrmt = TFU_DCI_FORMAT_A2;
13841       numLyr = 2;
13842    }
13843    else
13844    {
13845       dciFrmt = TFU_DCI_FORMAT_A1;
13846       numLyr = 1;
13847    }
13848    /* 5gtf TODO : To pass dci frmt to this function */
13849    pdcch = rgSCHCmnPdcchAllocCrntSf(cell, ue);
13850    if(pdcch == NULLP)
13851    {
13852       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, 
13853          "rgSCHCmnUlRbAllocForUe(): Could not get PDCCH for CRNTI:%d",ue->ueId);
13854       return RFAILED;
13855    }
13856         gUl5gtfPdcchSchd++;
13857 #if defined (TENB_STATS) && defined (RG_5GTF)
13858    cell->tenbStats->sch.ul5gtfPdcchSchd++;
13859 #endif
13860
13861    //TODO_SID using configured prb as of now
13862    nPrb = ue->ue5gtfCb.maxPrb;
13863    reqVrbg = nPrb/MAX_5GTF_VRBG_SIZE;
13864    iMcs  = ue->ue5gtfCb.mcs; //gSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
13865    iMcsCrnt = iMcs;
13866    numVrbg = reqVrbg;
13867
13868    if((sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart > MAX_5GTF_VRBG)
13869          || (sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated > MAX_5GTF_VRBG))
13870    {
13871       printf("5GTF_ERROR vrbg > 25 valstart = %d valalloc %d\n", sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart
13872             , sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated);
13873       int *p=NULLP;
13874       *p = 10;
13875    }
13876
13877    /*TODO_SID: Workaround for alloc. Currently alloc is ulsf based. To handle multiple beams, we need a different
13878      design. Now alloc are formed based on MAX_5GTF_UE_SCH macro. */
13879    numVrbgTemp = MAX_5GTF_VRBG/MAX_5GTF_UE_SCH;
13880    if(numVrbg)
13881    {
13882       alloc = rgSCHCmnUlSbAlloc(sf, numVrbgTemp,\
13883                                 hole);
13884    }
13885    if (alloc == NULLP)
13886    {
13887       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
13888          "rgSCHCmnUlRbAllocForUe(): Could not get UlAlloc %d CRNTI:%d",numVrbg,ue->ueId);
13889       rgSCHCmnPdcchRlsCrntSf(cell, pdcch);
13890       return RFAILED;
13891    }
13892    gUl5gtfAllocAllocated++;
13893 #if defined (TENB_STATS) && defined (RG_5GTF)
13894    cell->tenbStats->sch.ul5gtfAllocAllocated++;
13895 #endif
13896    alloc->grnt.vrbgStart = sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart;
13897    alloc->grnt.numVrbg = numVrbg;
13898    alloc->grnt.numLyr = numLyr;
13899    alloc->grnt.dciFrmt = dciFrmt;
13900
13901    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart += numVrbg;
13902    sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated += numVrbg;
13903
13904    //rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
13905 #ifdef LTE_L2_MEAS
13906    sf->totPrb  += alloc->grnt.numRb;
13907    ue->ul.nPrb = alloc->grnt.numRb;
13908 #endif
13909    if (ue->csgMmbrSta != TRUE)
13910    {
13911       cellUl->ncsgPrbCnt += alloc->grnt.numRb;
13912    }
13913    cellUl->totPrbCnt += (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
13914    alloc->pdcch = pdcch;
13915    alloc->grnt.iMcs = iMcs;
13916    alloc->grnt.iMcsCrnt = iMcsCrnt;
13917    alloc->grnt.hop = 0;
13918    /* Initial Num RBs support for UCI on PUSCH */
13919 #ifdef TFU_UPGRADE
13920    ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
13921 #endif
13922    alloc->forMsg3 = FALSE;
13923    //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTb5gtfSzTbl[0], (iTbs)); 
13924
13925    //ueUl->alloc.allocdBytes = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
13926    /* TODO_SID Allocating based on configured MCS as of now.
13927          Currently for format A2. When doing multi grp per tti, need to update this. */
13928    ueUl->alloc.allocdBytes = (rgSch5gtfTbSzTbl[iMcs]/8) * ue->ue5gtfCb.rank;
13929
13930    alloc->grnt.datSz = ueUl->alloc.allocdBytes;
13931    //TODO_SID Need to check mod order.
13932    RG_SCH_CMN_TBS_TO_MODODR(iMcs, alloc->grnt.modOdr);
13933         //alloc->grnt.modOdr = 6;
13934    alloc->grnt.isRtx = FALSE;
13935
13936    alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
13937    alloc->grnt.SCID = 0;
13938    alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
13939    alloc->grnt.PMI = 0;
13940    alloc->grnt.uciOnxPUSCH = 0;
13941    alloc->grnt.hqProcId = proc->procId;
13942
13943    alloc->hqProc = proc;
13944    alloc->hqProc->ulSfIdx = cellUl->schdIdx;
13945    alloc->ue = ue;
13946    /*commenting to retain the rnti used for transmission SPS/c-rnti */
13947    alloc->rnti = ue->ueId;
13948    ueUl->alloc.alloc = alloc;
13949    /*rntiwari-Adding the debug for generating the graph.*/
13950    /* No grant attr recorded now */
13951    return ROK;
13952 }
13953
13954 /***********************************************************
13955  *
13956  *     Func : rgSCHCmnUlRbAllocAddUeToLst
13957  *
13958  *     Desc : Add UE to list (scheduled/non-scheduled list)
13959  *            for UL RB allocation information.
13960  *
13961  *     Ret  :
13962  *
13963  *     Notes:
13964  *
13965  *     File :
13966  *
13967  **********************************************************/
13968 #ifdef ANSI
13969 Void rgSCHCmnUlRbAllocAddUeToLst
13970 (
13971 RgSchCellCb           *cell,
13972 RgSchUeCb             *ue,
13973 CmLListCp             *lst
13974 )
13975 #else
13976 Void rgSCHCmnUlRbAllocAddUeToLst(cell, ue, lst)
13977 RgSchCellCb           *cell;
13978 RgSchUeCb             *ue;
13979 CmLListCp             *lst;
13980 #endif
13981 {
13982    RgSchCmnUlUe   *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
13983    UNUSED(cell);
13984
13985    gUl5gtfUeRbAllocDone++;
13986 #if defined (TENB_STATS) && defined (RG_5GTF)
13987    cell->tenbStats->sch.ul5gtfUeRbAllocDone++;
13988 #endif
13989    cmLListAdd2Tail(lst, &ueUl->alloc.schdLstLnk);
13990    ueUl->alloc.schdLstLnk.node = (PTR)ue;
13991 }
13992
13993
13994 /**
13995  * @brief This function Processes the Final Allocations
13996  *        made by the RB Allocator against the requested.
13997  *
13998  * @details
13999  *
14000  *     Function: rgSCHCmnUlAllocFnlz
14001  *     Purpose:  This function Processes the Final Allocations
14002  *               made by the RB Allocator against the requested.
14003  *
14004  *     Invoked by: Common Scheduler
14005  *
14006  *  @param[in]  RgSchCellCb           *cell
14007  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
14008  *  @return  Void
14009  *
14010  **/
14011 #ifdef ANSI
14012 static Void rgSCHCmnUlAllocFnlz
14013 (
14014 RgSchCellCb           *cell,
14015 RgSchCmnUlRbAllocInfo *allocInfo
14016 )
14017 #else
14018 static Void rgSCHCmnUlAllocFnlz(cell, allocInfo)
14019 RgSchCellCb           *cell;
14020 RgSchCmnUlRbAllocInfo *allocInfo;
14021 #endif
14022 {
14023    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
14024
14025    /* call scheduler specific Finalization */
14026    cellSch->apisUl->rgSCHUlAllocFnlz(cell, allocInfo);
14027
14028    return;
14029 }
14030
14031 /**
14032  * @brief This function Processes the Final Allocations
14033  *        made by the RB Allocator against the requested.
14034  *
14035  * @details
14036  *
14037  *     Function: rgSCHCmnDlAllocFnlz
14038  *     Purpose:  This function Processes the Final Allocations
14039  *               made by the RB Allocator against the requested.
14040  *
14041  *     Invoked by: Common Scheduler
14042  *
14043  *  @param[in]  RgSchCellCb           *cell
14044  *  @return  Void
14045  *
14046  **/
14047 #ifdef ANSI
14048 Void rgSCHCmnDlAllocFnlz
14049 (
14050 RgSchCellCb           *cell
14051 )
14052 #else
14053 Void rgSCHCmnDlAllocFnlz(cell)
14054 RgSchCellCb           *cell;
14055 #endif
14056 {
14057    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14058    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo; 
14059
14060
14061    rgSCHCmnDlCcchRetxFnlz(cell, allocInfo);
14062    rgSCHCmnDlCcchTxFnlz(cell, allocInfo);
14063 #ifdef RGR_V1
14064    /* Added below functions for handling CCCH SDU transmission received
14065     * after
14066     *     * guard timer expiry*/
14067    rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo);
14068    rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo);
14069 #endif
14070    rgSCHCmnDlRaRspFnlz(cell, allocInfo);
14071       /* call scheduler specific Finalization */
14072    cellSch->apisDl->rgSCHDlAllocFnlz(cell, allocInfo);
14073
14074    /* Stack Crash problem for TRACE5 Changes. Added the return below */
14075    return;
14076
14077 }
14078
14079 #ifdef RG_UNUSED
14080 /**
14081  * @brief Update an uplink subframe.
14082  *
14083  * @details
14084  *
14085  *     Function : rgSCHCmnUlUpdSf
14086  *
14087  *     For each allocation
14088  *      - if no more tx needed
14089  *         - Release allocation
14090  *      - else
14091  *         - Perform retransmission
14092  *
14093  *  @param[in]  RgSchUlSf *sf
14094  *  @return  Void
14095  **/
14096 #ifdef ANSI
14097 static Void rgSCHCmnUlUpdSf
14098 (
14099 RgSchCellCb           *cell,
14100 RgSchCmnUlRbAllocInfo *allocInfo,
14101 RgSchUlSf *sf
14102 )
14103 #else
14104 static Void rgSCHCmnUlUpdSf(cell, allocInfo, sf)
14105 RgSchCellCb           *cell;
14106 RgSchCmnUlRbAllocInfo *allocInfo;
14107 RgSchUlSf *sf;
14108 #endif
14109 {
14110    CmLList        *lnk;
14111
14112    while ((lnk = sf->allocs.first))
14113    {
14114       RgSchUlAlloc  *alloc = (RgSchUlAlloc *)lnk->node;
14115       lnk = lnk->next;
14116
14117       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
14118       {
14119       }
14120       else
14121       {
14122          /* If need to handle all retx together, run another loop separately */
14123          rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc);
14124       }
14125       rgSCHCmnUlRlsUlAlloc(cell, sf, alloc);
14126    }
14127
14128    /* By this time, all allocs would have been cleared and
14129     * SF is reset to be made ready for new allocations. */
14130    rgSCHCmnUlSfReset(cell, sf);
14131    /* In case there are timing problems due to msg3
14132     * allocations being done in advance, (which will
14133     * probably happen with the current FDD code that
14134     * handles 8 subframes) one solution
14135     * could be to hold the (recent) msg3 allocs in a separate
14136     * list, and then possibly add that to the actual
14137     * list later. So at this time while allocations are
14138     * traversed, the recent msg3 ones are not seen. Anytime after
14139     * this (a good time is when the usual allocations
14140     * are made), msg3 allocations could be transferred to the
14141     * normal list. Not doing this now as it is assumed
14142     * that incorporation of TDD shall take care of this.
14143     */
14144
14145
14146    return;
14147 }
14148
14149 /**
14150  * @brief Handle uplink allocation for retransmission.
14151  *
14152  * @details
14153  *
14154  *     Function : rgSCHCmnUlHndlAllocRetx
14155  *
14156  *     Processing Steps:
14157  *     - Add to queue for retx.
14158  *     - Do not release here, release happends as part
14159  *       of the loop that calls this function.
14160  *
14161  *  @param[in]  RgSchCellCb           *cell
14162  *  @param[in]  RgSchCmnUlRbAllocInfo *allocInfo
14163  *  @param[in]  RgSchUlSf *sf
14164  *  @param[in]  RgSchUlAlloc  *alloc
14165  *  @return  Void
14166  **/
14167 #ifdef ANSI
14168 static Void rgSCHCmnUlHndlAllocRetx
14169 (
14170 RgSchCellCb           *cell,
14171 RgSchCmnUlRbAllocInfo *allocInfo,
14172 RgSchUlSf     *sf,
14173 RgSchUlAlloc  *alloc
14174 )
14175 #else
14176 static Void rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc)
14177 RgSchCellCb           *cell;
14178 RgSchCmnUlRbAllocInfo *allocInfo;
14179 RgSchUlSf     *sf;
14180 RgSchUlAlloc  *alloc;
14181 #endif
14182 {
14183    uint32_t            bytes;
14184    RgSchCmnUlUe   *ueUl;
14185    bytes = \
14186       rgTbSzTbl[0][rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs)]\
14187                                      [alloc->grnt.numRb-1]/8;
14188    if (!alloc->forMsg3)
14189    {
14190       ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue);
14191       ueUl->alloc.reqBytes = bytes;
14192       rgSCHUhmRetx(alloc->hqProc);
14193       rgSCHCmnUlAdd2RetxUeLst(allocInfo, alloc->ue);
14194    }
14195    else
14196    {
14197       /* RACHO msg3 retx handling. Part of RACH procedure changes. */
14198       retxAlloc = rgSCHCmnUlGetUlAlloc(cell, sf, alloc->numSb);
14199       if (retxAlloc == NULLP)
14200       {
14201          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
14202                "rgSCHCmnUlRbAllocForUe():Could not get UlAlloc for msg3Retx RNTI:%d",
14203                alloc->rnti);
14204          return;
14205       }
14206       retxAlloc->grnt.iMcs = alloc->grnt.iMcs;
14207       retxAlloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl\
14208                                  [alloc->hqProc->rvIdx];
14209       retxAlloc->grnt.nDmrs    = 0;
14210       retxAlloc->grnt.hop      = 0;
14211       retxAlloc->grnt.delayBit = 0;
14212       retxAlloc->rnti          = alloc->rnti;
14213       retxAlloc->ue            = NULLP;
14214       retxAlloc->pdcch         = FALSE;
14215       retxAlloc->forMsg3       = TRUE;
14216       retxAlloc->raCb          = alloc->raCb;
14217       retxAlloc->hqProc        = alloc->hqProc;
14218       rgSCHUhmRetx(retxAlloc->hqProc);
14219    }
14220    return;
14221 }
14222 #endif
14223
14224 /**
14225  * @brief Uplink Scheduling Handler.
14226  *
14227  * @details
14228  *
14229  *     Function: rgSCHCmnUlAlloc
14230  *     Purpose:  This function Handles Uplink Scheduling.
14231  *
14232  *     Invoked by: Common Scheduler
14233  *
14234  *  @param[in]  RgSchCellCb *cell
14235  *  @return  Void
14236  **/
14237 /* ccpu00132653- The definition of this function made common for TDD and FDD*/
14238 #ifdef ANSI
14239 static Void rgSCHCmnUlAlloc
14240 (
14241 RgSchCellCb  *cell
14242 )
14243 #else
14244 static Void rgSCHCmnUlAlloc(cell)
14245 RgSchCellCb  *cell;
14246 #endif
14247 {
14248    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14249    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
14250    RgSchCmnDlCell         *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
14251    RgSchCmnUlRbAllocInfo  allocInfo;
14252    RgSchCmnUlRbAllocInfo  *allocInfoRef = &allocInfo;
14253 #ifdef RG_5GTF
14254    uint8_t idx;
14255
14256 #endif
14257
14258
14259    /* Initializing RgSchCmnUlRbAllocInfo structure */
14260    rgSCHCmnInitUlRbAllocInfo(allocInfoRef);
14261
14262    /* Get Uplink Subframe */
14263    allocInfoRef->sf = &cellUl->ulSfArr[cellUl->schdIdx];
14264 #ifdef LTE_L2_MEAS
14265    /* initializing the UL PRB count */
14266    allocInfoRef->sf->totPrb = 0;
14267 #endif
14268
14269 #ifdef LTEMAC_SPS
14270    rgSCHCmnSpsUlTti(cell, allocInfoRef);
14271 #endif
14272
14273    if(*allocInfoRef->sf->allocCountRef == 0)
14274    {            
14275       RgSchUlHole     *hole;
14276
14277       if ((hole = rgSCHUtlUlHoleFirst(allocInfoRef->sf)) != NULLP)
14278       {
14279          /* Sanity check of holeDb */
14280          if (allocInfoRef->sf->holeDb->count == 1 && hole->start == 0) 
14281          {
14282             hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb;   
14283             /* Re-Initialize available subbands because of CFI change*/
14284             allocInfoRef->sf->availSubbands = cell->dynCfiCb.\
14285                                               bwInfo[cellDl->currCfi].numSb;
14286             /*Currently initializing 5gtf ulsf specific initialization here.
14287               need to do at proper place */
14288 #ifdef RG_5GTF
14289        allocInfoRef->sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
14290        allocInfoRef->sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
14291             for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
14292             {
14293                allocInfoRef->sf->sfBeamInfo[idx].totVrbgAllocated = 0;
14294                allocInfoRef->sf->sfBeamInfo[idx].totVrbgRequired = 0;
14295                allocInfoRef->sf->sfBeamInfo[idx].vrbgStart = 0;
14296             }    
14297 #endif
14298          }
14299          else
14300          {
14301             RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
14302                   "Error! holeDb sanity check failed");
14303          }
14304       }
14305    }
14306
14307    /* Fix: Adaptive re-transmissions prioritised over other transmissions */
14308    /* perform adaptive retransmissions */
14309    rgSCHCmnUlSfReTxAllocs(cell, allocInfoRef->sf);
14310
14311         g5gtfTtiCnt++;
14312
14313    /* Fix: syed Adaptive Msg3 Retx crash. Release all
14314     Harq processes for which adap Retx failed, to avoid 
14315     blocking. This step should be done before New TX 
14316     scheduling to make hqProc available. Right now we
14317     dont check if proc is in adap Retx list for considering
14318     it to be available. But now with this release that 
14319     functionality would be correct. */
14320 #ifndef RG_5GTF
14321    rgSCHCmnUlSfRlsRetxProcs(cell, allocInfoRef->sf);  
14322 #endif
14323
14324    /* Specific UL scheduler to perform UE scheduling */
14325    cellSch->apisUl->rgSCHUlSched(cell, allocInfoRef);
14326
14327    /* Call UL RB allocator module */
14328    rgSCHCmnAllocUlRb(cell, allocInfoRef);
14329
14330    /* Do group power control for PUSCH */
14331    rgSCHCmnGrpPwrCntrlPusch(cell, allocInfoRef->sf);
14332
14333    cell->sc.apis->rgSCHDrxStrtInActvTmrInUl(cell);
14334
14335    rgSCHCmnUlAllocFnlz(cell, allocInfoRef);
14336         if(5000 == g5gtfTtiCnt)
14337         {
14338       ul5gtfsidDlAlreadyMarkUl = 0;
14339                 ul5gtfsidDlSchdPass = 0;
14340                 ul5gtfsidUlMarkUl = 0;
14341       ul5gtfTotSchdCnt = 0;
14342                 g5gtfTtiCnt = 0;
14343         }
14344
14345    return;
14346 }
14347
14348 /**
14349  * @brief send Subframe Allocations.
14350  *
14351  * @details
14352  *
14353  *     Function: rgSCHCmnSndCnsldtInfo
14354  *     Purpose:  Send the scheduled
14355  *     allocations to MAC for StaInd generation to Higher layers and
14356  *     for MUXing. PST's RgInfSfAlloc to MAC instance.
14357  *
14358  *     Invoked by: Common Scheduler
14359  *
14360  *  @param[in]  RgSchCellCb *cell
14361  *  @return  Void
14362  **/
14363 #ifdef ANSI
14364 Void rgSCHCmnSndCnsldtInfo
14365 (
14366 RgSchCellCb  *cell
14367 )
14368 #else
14369 Void rgSCHCmnSndCnsldtInfo(cell)
14370 RgSchCellCb  *cell;
14371 #endif
14372 {
14373    RgInfSfAlloc           *subfrmAlloc;
14374    Pst                    pst;
14375    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
14376
14377
14378    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
14379
14380    /* Send the allocations to MAC for MUXing */
14381    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
14382    subfrmAlloc->cellId = cell->cellId;
14383    /* Populate the List of UEs needing PDB-based Flow control */
14384    cellSch->apisDl->rgSCHDlFillFlwCtrlInfo(cell, subfrmAlloc);
14385 #ifdef LTE_L2_MEAS
14386    if((subfrmAlloc->rarInfo.numRaRntis) ||
14387 #ifdef EMTC_ENABLE
14388       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
14389       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
14390       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
14391 #endif
14392       (subfrmAlloc->ueInfo.numUes)      ||
14393       (subfrmAlloc->cmnLcInfo.bitMask)  ||
14394          (subfrmAlloc->ulUeInfo.numUes)    ||
14395          (subfrmAlloc->flowCntrlInfo.numUes))
14396 #else
14397    if((subfrmAlloc->rarInfo.numRaRntis) ||
14398 #ifdef EMTC_ENABLE
14399       (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) ||
14400       (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask)  ||
14401       (subfrmAlloc->emtcInfo.ueInfo.numUes) ||
14402 #endif
14403       (subfrmAlloc->ueInfo.numUes)      ||
14404             (subfrmAlloc->cmnLcInfo.bitMask)  ||
14405             (subfrmAlloc->flowCntrlInfo.numUes))
14406 #endif
14407    {
14408       RgSchMacSfAlloc(&pst, subfrmAlloc);
14409    }
14410 #ifndef LTE_TDD
14411    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
14412 #else
14413    cell->crntSfIdx  = (cell->crntSfIdx + 1) % RGSCH_SF_ALLOC_SIZE;
14414 #endif
14415    
14416    return;
14417 }
14418 /**
14419  * @brief Consolidate Subframe Allocations.
14420  *
14421  * @details
14422  *
14423  *     Function: rgSCHCmnCnsldtSfAlloc
14424  *     Purpose:  Consolidate Subframe Allocations.
14425  *
14426  *     Invoked by: Common Scheduler
14427  *
14428  *  @param[in]  RgSchCellCb *cell
14429  *  @return  Void
14430  **/
14431 #ifdef ANSI
14432 Void rgSCHCmnCnsldtSfAlloc
14433 (
14434 RgSchCellCb  *cell
14435 )
14436 #else
14437 Void rgSCHCmnCnsldtSfAlloc(cell)
14438 RgSchCellCb  *cell;
14439 #endif
14440 {
14441    RgInfSfAlloc           *subfrmAlloc;
14442    CmLteTimingInfo        frm;
14443    RgSchDlSf              *dlSf;
14444    CmLListCp              dlDrxInactvTmrLst;
14445    CmLListCp              dlInActvLst;
14446    CmLListCp              ulInActvLst;
14447    RgSchCmnCell           *cellSch = NULLP;
14448
14449
14450    cmLListInit(&dlDrxInactvTmrLst);
14451    cmLListInit(&dlInActvLst);
14452    cmLListInit(&ulInActvLst);
14453
14454    subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
14455
14456    /* Get Downlink Subframe */
14457    frm   = cell->crntTime;
14458    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
14459    dlSf = rgSCHUtlSubFrmGet(cell, frm);
14460
14461    /* Fill the allocation Info */
14462    rgSCHUtlFillRgInfRarInfo(dlSf, subfrmAlloc, cell);
14463
14464   /* CA dev Start */
14465    rgSCHUtlFillRgInfUeInfo(dlSf, cell, &dlDrxInactvTmrLst, 
14466                            &dlInActvLst, &ulInActvLst);
14467 #ifdef RG_PFS_STATS
14468    cell->totalPrb += dlSf->bwAssigned;
14469 #endif
14470    /* Mark the following Ues inactive for UL*/
14471    cellSch = RG_SCH_CMN_GET_CELL(cell);
14472
14473    /* Calling Scheduler specific function with DRX inactive UE list*/
14474    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInActvLst);
14475    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInActvLst);
14476     
14477   /* CA dev End */
14478    /*re/start DRX inactivity timer for the UEs*/
14479    (Void)rgSCHDrxStrtInActvTmr(cell,&dlDrxInactvTmrLst,RG_SCH_DRX_DL);
14480
14481    return;
14482 }
14483
14484 /**
14485  * @brief Initialize the DL Allocation Information Structure.
14486  *
14487  * @details
14488  *
14489  *     Function: rgSCHCmnInitDlRbAllocInfo
14490  *     Purpose:  Initialize the DL Allocation Information Structure.
14491  *
14492  *     Invoked by: Common Scheduler
14493  *
14494  *  @param[out]  RgSchCmnDlRbAllocInfo  *allocInfo
14495  *  @return  Void
14496  **/
14497 #ifdef ANSI
14498 static Void rgSCHCmnInitDlRbAllocInfo
14499 (
14500 RgSchCmnDlRbAllocInfo  *allocInfo
14501 )
14502 #else
14503 static Void rgSCHCmnInitDlRbAllocInfo(allocInfo)
14504 RgSchCmnDlRbAllocInfo  *allocInfo;
14505 #endif
14506 {
14507    memset(&allocInfo->pcchAlloc, 0, sizeof(RgSchDlRbAlloc));
14508    memset(&allocInfo->bcchAlloc, 0, sizeof(RgSchDlRbAlloc));
14509    memset(allocInfo->raRspAlloc, 0, RG_SCH_CMN_MAX_CMN_PDCCH*sizeof(RgSchDlRbAlloc));
14510
14511    allocInfo->msg4Alloc.msg4DlSf = NULLP;
14512    cmLListInit(&allocInfo->msg4Alloc.msg4TxLst);
14513    cmLListInit(&allocInfo->msg4Alloc.msg4RetxLst);
14514    cmLListInit(&allocInfo->msg4Alloc.schdMsg4TxLst);
14515    cmLListInit(&allocInfo->msg4Alloc.schdMsg4RetxLst);
14516    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4TxLst);
14517    cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4RetxLst);
14518 #ifdef RGR_V1
14519    allocInfo->ccchSduAlloc.ccchSduDlSf = NULLP;
14520    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduTxLst);
14521    cmLListInit(&allocInfo->ccchSduAlloc.ccchSduRetxLst);
14522    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduTxLst);
14523    cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduRetxLst);
14524    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst);
14525    cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst);
14526 #endif
14527
14528    allocInfo->dedAlloc.dedDlSf = NULLP;
14529    cmLListInit(&allocInfo->dedAlloc.txHqPLst);
14530    cmLListInit(&allocInfo->dedAlloc.retxHqPLst);
14531    cmLListInit(&allocInfo->dedAlloc.schdTxHqPLst);
14532    cmLListInit(&allocInfo->dedAlloc.schdRetxHqPLst);
14533    cmLListInit(&allocInfo->dedAlloc.nonSchdTxHqPLst);
14534    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxHqPLst);
14535
14536    cmLListInit(&allocInfo->dedAlloc.txRetxHqPLst);
14537    cmLListInit(&allocInfo->dedAlloc.schdTxRetxHqPLst);
14538    cmLListInit(&allocInfo->dedAlloc.nonSchdTxRetxHqPLst);
14539 #ifdef LTEMAC_SPS
14540    cmLListInit(&allocInfo->dedAlloc.txSpsHqPLst);
14541    cmLListInit(&allocInfo->dedAlloc.retxSpsHqPLst);
14542    cmLListInit(&allocInfo->dedAlloc.schdTxSpsHqPLst);
14543    cmLListInit(&allocInfo->dedAlloc.schdRetxSpsHqPLst);
14544    cmLListInit(&allocInfo->dedAlloc.nonSchdTxSpsHqPLst);
14545    cmLListInit(&allocInfo->dedAlloc.nonSchdRetxSpsHqPLst);
14546 #endif
14547
14548 #ifdef LTE_ADV
14549    rgSCHLaaCmnInitDlRbAllocInfo (allocInfo);
14550 #endif
14551
14552    cmLListInit(&allocInfo->dedAlloc.errIndTxHqPLst);
14553    cmLListInit(&allocInfo->dedAlloc.schdErrIndTxHqPLst);
14554    cmLListInit(&allocInfo->dedAlloc.nonSchdErrIndTxHqPLst);
14555    return;
14556 }
14557
14558 /**
14559  * @brief Initialize the UL Allocation Information Structure.
14560  *
14561  * @details
14562  *
14563  *     Function: rgSCHCmnInitUlRbAllocInfo
14564  *     Purpose:  Initialize the UL Allocation Information Structure.
14565  *
14566  *     Invoked by: Common Scheduler
14567  *
14568  *  @param[out]  RgSchCmnUlRbAllocInfo  *allocInfo
14569  *  @return  Void
14570  **/
14571 #ifdef ANSI
14572 Void rgSCHCmnInitUlRbAllocInfo
14573 (
14574 RgSchCmnUlRbAllocInfo  *allocInfo
14575 )
14576 #else
14577 Void rgSCHCmnInitUlRbAllocInfo(allocInfo)
14578 RgSchCmnUlRbAllocInfo  *allocInfo;
14579 #endif
14580 {
14581    allocInfo->sf = NULLP;
14582    cmLListInit(&allocInfo->contResLst);
14583    cmLListInit(&allocInfo->schdContResLst);
14584    cmLListInit(&allocInfo->nonSchdContResLst);
14585    cmLListInit(&allocInfo->ueLst);
14586    cmLListInit(&allocInfo->schdUeLst);
14587    cmLListInit(&allocInfo->nonSchdUeLst);
14588
14589    return;
14590 }
14591
14592 /**
14593  * @brief Scheduling for PUCCH group power control.
14594  *
14595  * @details
14596  *
14597  *     Function: rgSCHCmnGrpPwrCntrlPucch
14598  *     Purpose: This function does group power control for PUCCH
14599  *     corresponding to the subframe for which DL UE allocations
14600  *     have happended.
14601  *
14602  *     Invoked by: Common Scheduler
14603  *
14604  *  @param[in]  RgSchCellCb *cell
14605  *  @return  Void
14606  **/
14607 #ifdef ANSI
14608 static Void rgSCHCmnGrpPwrCntrlPucch
14609 (
14610 RgSchCellCb            *cell,
14611 RgSchDlSf              *dlSf
14612 )
14613 #else
14614 static Void rgSCHCmnGrpPwrCntrlPucch(cell, dlSf)
14615 RgSchCellCb            *cell;
14616 RgSchDlSf              *dlSf;
14617 #endif
14618 {
14619
14620    rgSCHPwrGrpCntrlPucch(cell, dlSf);
14621
14622    return;
14623 }
14624
14625 /**
14626  * @brief Scheduling for PUSCH group power control.
14627  *
14628  * @details
14629  *
14630  *     Function: rgSCHCmnGrpPwrCntrlPusch
14631  *     Purpose: This function does group power control, for
14632  *     the subframe for which UL allocation has (just) happened.
14633  *
14634  *     Invoked by: Common Scheduler
14635  *
14636  *  @param[in]  RgSchCellCb *cell
14637  *  @param[in]  RgSchUlSf   *ulSf
14638  *  @return  Void
14639  **/
14640 #ifdef ANSI
14641 static Void rgSCHCmnGrpPwrCntrlPusch
14642 (
14643 RgSchCellCb            *cell,
14644 RgSchUlSf              *ulSf
14645 )
14646 #else
14647 static Void rgSCHCmnGrpPwrCntrlPusch(cell, ulSf)
14648 RgSchCellCb            *cell;
14649 RgSchUlSf              *ulSf;
14650 #endif
14651 {
14652    /*removed unused variable *cellSch*/
14653    CmLteTimingInfo        frm;
14654    RgSchDlSf              *dlSf;
14655
14656
14657    /* Got to pass DL SF corresponding to UL SF, so get that first.
14658     * There is no easy way of getting dlSf by having the RgSchUlSf*,
14659     * so use the UL delta from current time to get the DL SF. */
14660    frm   = cell->crntTime;
14661
14662 #ifdef EMTC_ENABLE
14663    if(cell->emtcEnable == TRUE)
14664    {
14665       RGSCH_INCR_SUB_FRAME_EMTC(frm, TFU_DLCNTRL_DLDELTA);
14666    }
14667    else
14668 #endif
14669    {
14670       RGSCH_INCR_SUB_FRAME(frm, TFU_DLCNTRL_DLDELTA);
14671    }
14672    /* Del filling of dl.time */
14673    dlSf = rgSCHUtlSubFrmGet(cell, frm);
14674
14675    rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf);
14676
14677    return;
14678 }
14679
14680 /* Fix: syed align multiple UEs to refresh at same time */
14681 /***********************************************************
14682  *
14683  *     Func : rgSCHCmnApplyUeRefresh 
14684  *
14685  *     Desc : Apply UE refresh in CMN and Specific 
14686  *     schedulers. Data rates and corresponding 
14687  *     scratchpad variables are updated.
14688  *
14689  *     Ret  :
14690  *
14691  *     Notes:
14692  *
14693  *     File :
14694  *
14695  **********************************************************/
14696 #ifdef ANSI
14697 static S16 rgSCHCmnApplyUeRefresh 
14698 (
14699 RgSchCellCb     *cell,
14700 RgSchUeCb       *ue
14701 )
14702 #else
14703 static S16 rgSCHCmnApplyUeRefresh(cell, ue)
14704 RgSchCellCb     *cell;
14705 RgSchUeCb       *ue;
14706 #endif
14707 {
14708    RgSchCmnCell    *cellSch     = RG_SCH_CMN_GET_CELL(cell);
14709    uint32_t             effGbrBsr    = 0;
14710    uint32_t             effNonGbrBsr = 0;
14711    uint32_t             lcgId;
14712
14713
14714    /* Reset the refresh cycle variableCAP */
14715    ue->ul.effAmbr = ue->ul.cfgdAmbr;
14716
14717    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
14718    {
14719       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
14720       {
14721          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
14722
14723          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
14724          {
14725             cmnLcg->effGbr = cmnLcg->cfgdGbr;
14726             cmnLcg->effDeltaMbr = cmnLcg->deltaMbr;
14727             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
14728             /* Considering GBR LCG will be prioritised by UE */
14729             effGbrBsr += cmnLcg->bs;
14730          }/* Else no remaing BS so nonLcg0 will be updated when BSR will be received */
14731          else
14732          {
14733             effNonGbrBsr += cmnLcg->reportedBs;
14734             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
14735          }
14736       }
14737    }
14738    effNonGbrBsr = RGSCH_MIN(effNonGbrBsr,ue->ul.effAmbr);
14739    ue->ul.nonGbrLcgBs = effNonGbrBsr;
14740
14741    ue->ul.nonLcg0Bs = effGbrBsr + effNonGbrBsr;
14742    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
14743                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
14744
14745
14746    /* call scheduler specific event handlers
14747     * for refresh timer expiry */
14748    cellSch->apisUl->rgSCHUlUeRefresh(cell, ue);
14749    cellSch->apisDl->rgSCHDlUeRefresh(cell, ue);
14750
14751    return ROK;
14752 }
14753
14754 /***********************************************************
14755  *
14756  *     Func : rgSCHCmnTmrExpiry
14757  *
14758  *     Desc : Adds an UE to refresh queue, so that the UE is
14759  *            periodically triggered to refresh it's GBR and
14760  *            AMBR values.
14761  *
14762  *     Ret  :
14763  *
14764  *     Notes:
14765  *
14766  *     File :
14767  *
14768  **********************************************************/
14769 #ifdef ANSI
14770 static S16 rgSCHCmnTmrExpiry
14771 (
14772 PTR cb,               /* Pointer to timer control block */
14773 S16 tmrEvnt           /* Timer Event */
14774 )
14775 #else
14776 static S16 rgSCHCmnTmrExpiry(cb, tmrEvnt)
14777 PTR cb;               /* Pointer to timer control block */
14778 S16 tmrEvnt;           /* Timer Event */
14779 #endif
14780 {
14781    RgSchUeCb       *ue = (RgSchUeCb *)cb;
14782    RgSchCellCb     *cell = ue->cell;
14783 #if (ERRCLASS & ERRCLS_DEBUG)
14784 #endif
14785
14786
14787 #if (ERRCLASS & ERRCLS_DEBUG)
14788    if (tmrEvnt != RG_SCH_CMN_EVNT_UE_REFRESH)
14789    {
14790       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnTmrExpiry(): Invalid "
14791          "timer event CRNTI:%d",ue->ueId);
14792       return RFAILED;
14793    }
14794 #else
14795    UNUSED(tmrEvnt);
14796 #endif
14797
14798    rgSCHCmnApplyUeRefresh(cell, ue);
14799
14800    rgSCHCmnAddUeToRefreshQ(cell, ue, RG_SCH_CMN_REFRESH_TIME);
14801
14802    return ROK;
14803 }
14804
14805 /***********************************************************
14806  *
14807  *     Func : rgSCHCmnTmrProc
14808  *
14809  *     Desc : Timer entry point per cell. Timer
14810  *            processing is triggered at every frame boundary
14811  *            (every 10 ms).
14812  *
14813  *     Ret  :
14814  *
14815  *     Notes:
14816  *
14817  *     File :
14818  *
14819  **********************************************************/
14820 #ifdef ANSI
14821 static S16 rgSCHCmnTmrProc
14822 (
14823 RgSchCellCb *cell
14824 )
14825 #else
14826 static S16 rgSCHCmnTmrProc(cell)
14827 RgSchCellCb *cell;
14828 #endif
14829 {
14830    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
14831    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
14832    /* Moving the assignment of scheduler pointer
14833      to available scope for optimization */
14834
14835    if ((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES_5G) == 0)
14836    {
14837       /* Reset the counters periodically */
14838       if ((cell->crntTime.sfn % RG_SCH_CMN_CSG_REFRESH_TIME) == 0)
14839       {
14840          RG_SCH_RESET_HCSG_DL_PRB_CNTR(cmnDlCell);
14841          RG_SCH_RESET_HCSG_UL_PRB_CNTR(cmnUlCell);
14842       }
14843       if ((cell->crntTime.sfn % RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME) == 0)
14844       {
14845
14846          cell->measurements.ulTpt =  ((cell->measurements.ulTpt * 95) + ( cell->measurements.ulBytesCnt * 5))/100;
14847          cell->measurements.dlTpt =  ((cell->measurements.dlTpt * 95) + ( cell->measurements.dlBytesCnt * 5))/100;
14848
14849          rgSCHUtlCpuOvrLdAdjItbsCap(cell);
14850          /* reset cell level tpt measurements for next cycle */
14851          cell->measurements.ulBytesCnt = 0;
14852          cell->measurements.dlBytesCnt = 0;
14853       }
14854       /* Comparing with Zero instead of % is being done for efficiency.
14855        * If Timer resolution changes then accordingly update the
14856        * macro RG_SCH_CMN_REFRESH_TIMERES */    
14857       RgSchCmnCell   *sched  = RG_SCH_CMN_GET_CELL(cell);
14858       cmPrcTmr(&sched->tmrTqCp, sched->tmrTq, (PFV)rgSCHCmnTmrExpiry);
14859    }
14860
14861    return ROK;
14862 }
14863
14864
14865 /***********************************************************
14866  *
14867  *     Func : rgSchCmnUpdCfiVal 
14868  *
14869  *     Desc : Update the CFI value if CFI switch was done 
14870  *
14871  *     Ret  :
14872  *
14873  *     Notes:
14874  *
14875  *     File :
14876  *
14877  **********************************************************/
14878 #ifdef ANSI
14879 static Void rgSchCmnUpdCfiVal
14880 (
14881 RgSchCellCb     *cell,
14882 uint8_t              delta
14883 )
14884 #else
14885 static Void rgSchCmnUpdCfiVal(cell, delta)
14886 RgSchCellCb     *cell;
14887 uint8_t              delta;
14888 #endif  
14889 {
14890    RgSchDlSf        *dlSf;
14891    CmLteTimingInfo  pdsch;
14892    RgSchCmnDlCell  *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); 
14893    uint8_t               dlIdx;
14894 #ifdef LTE_TDD
14895    uint8_t               mPhich;
14896    RgSchDlSf        *tddSf;
14897    uint8_t               idx;
14898    uint8_t               splSfCfi = 0;
14899 #endif    
14900
14901
14902    pdsch  = cell->crntTime;
14903    RGSCH_INCR_SUB_FRAME(pdsch, delta);
14904    dlSf = rgSCHUtlSubFrmGet(cell, pdsch);
14905    /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
14906     *change happens in that SF then UL PDCCH allocation happens with old CFI
14907     *but CFI in control Req goes updated one since it was stored in the CELL
14908     */
14909    dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
14910    if(cell->dynCfiCb.pdcchSfIdx != 0xFF) 
14911    {
14912 #ifdef LTE_TDD
14913       dlIdx = rgSCHUtlGetDlSfIdx(cell, &pdsch);
14914 #else
14915       dlIdx = (((pdsch.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (pdsch.slot % RGSCH_NUM_SUB_FRAMES));
14916       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
14917 #endif  
14918       /* If current downlink subframe index is same as pdcch SF index,
14919        * perform the switching of CFI in this subframe */
14920       if(cell->dynCfiCb.pdcchSfIdx == dlIdx)
14921       {
14922          cellCmnDl->currCfi  = cellCmnDl->newCfi;
14923          cell->dynCfiCb.pdcchSfIdx = 0xFF;
14924
14925          /* Updating the nCce value based on the new CFI */
14926 #ifdef LTE_TDD
14927          splSfCfi = cellCmnDl->newCfi;
14928          for(idx = 0; idx < cell->numDlSubfrms; idx++)
14929          {   
14930             tddSf = cell->subFrms[idx];
14931
14932             mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][tddSf->sfNum];
14933
14934             if(tddSf->sfType == RG_SCH_SPL_SF_DATA)
14935             {
14936                RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi);
14937
14938                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi];
14939             }
14940             else
14941             {   
14942                tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][cellCmnDl->currCfi];
14943             }
14944          }
14945          /* Setting the switch over window length based on config index.
14946           * During switch over period all the UL trnsmissions are Acked 
14947           * to UEs */
14948          cell->dynCfiCb.switchOvrWinLen = 
14949                rgSchCfiSwitchOvrWinLen[cell->ulDlCfgIdx];
14950 #else
14951          cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCmnDl->currCfi];
14952          /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI
14953           *change happens in that SF then UL PDCCH allocation happens with old CFI
14954           *but CFI in control Req goes updated one since it was stored in the CELL
14955           */
14956          dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi;
14957          cell->dynCfiCb.switchOvrWinLen = rgSchCfiSwitchOvrWinLen[7];
14958 #endif
14959       }   
14960    }   
14961
14962    return;
14963 }
14964
14965 /***********************************************************
14966  *
14967  *     Func : rgSchCmnUpdtPdcchSfIdx 
14968  *
14969  *     Desc : Update the switch over window length
14970  *
14971  *     Ret  : void
14972  *
14973  *     Notes:
14974  *
14975  *     File :
14976  *
14977  **********************************************************/
14978 #ifdef LTE_TDD
14979 #ifdef ANSI
14980 static Void rgSchCmnUpdtPdcchSfIdx 
14981 (
14982 RgSchCellCb     *cell,
14983 uint8_t              dlIdx,
14984 uint8_t              sfNum
14985 )
14986 #else
14987 static Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, sfNum)
14988 RgSchCellCb     *cell;
14989 uint8_t              dlIdx;
14990 uint8_t              sfNum;
14991 #endif   
14992 #else
14993 #ifdef ANSI
14994 static Void rgSchCmnUpdtPdcchSfIdx 
14995 (
14996 RgSchCellCb     *cell,
14997 uint8_t              dlIdx
14998 )
14999 #else
15000 static Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx)
15001 RgSchCellCb     *cell;
15002 uint8_t              dlIdx;
15003 #endif    
15004 #endif
15005 {
15006    uint8_t         idx;
15007
15008
15009    /* Resetting the parameters on CFI switching */
15010    cell->dynCfiCb.cceUsed = 0;
15011    cell->dynCfiCb.lowCceCnt = 0;
15012
15013    cell->dynCfiCb.cceFailSum = 0;
15014    cell->dynCfiCb.cceFailCnt = 0;
15015    cell->dynCfiCb.prevCceFailIdx = 0;
15016
15017    cell->dynCfiCb.switchOvrInProgress = TRUE;
15018
15019    for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++)
15020    {
15021       cell->dynCfiCb.cceFailSamples[idx] = 0;
15022    }   
15023
15024    cell->dynCfiCb.ttiCnt = 0;
15025
15026    cell->dynCfiCb.cfiSwitches++;
15027    cfiSwitchCnt = cell->dynCfiCb.cfiSwitches;
15028
15029 #ifdef LTE_TDD 
15030    cell->dynCfiCb.pdcchSfIdx = (dlIdx + 
15031       rgSchTddPdcchSfIncTbl[cell->ulDlCfgIdx][sfNum]) % cell->numDlSubfrms;
15032 #else
15033    cell->dynCfiCb.pdcchSfIdx = (dlIdx + RG_SCH_CFI_APPLY_DELTA) % \
15034         RGSCH_NUM_DL_slotS;
15035 #endif
15036 }
15037
15038 /***********************************************************
15039  *
15040  *     Func : rgSchCmnUpdCfiDb 
15041  *
15042  *     Desc : Update the counters related to dynamic
15043  *            CFI feature in cellCb. 
15044  *
15045  *     Ret  :
15046  *
15047  *     Notes:
15048  *
15049  *     File :
15050  *
15051  **********************************************************/
15052 #ifdef ANSI
15053 Void rgSchCmnUpdCfiDb 
15054 (
15055 RgSchCellCb     *cell,
15056 uint8_t              delta 
15057 )
15058 #else
15059 Void rgSchCmnUpdCfiDb(cell, delta)
15060 RgSchCellCb     *cell;
15061 uint8_t              delta;
15062 #endif 
15063 {
15064    CmLteTimingInfo        frm;
15065    RgSchDlSf              *dlSf;
15066 #ifdef LTE_TDD
15067    uint8_t                     mPhich;
15068    Bool                   isHiDci0; 
15069 #endif      
15070    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell); 
15071    uint8_t                     nCceLowerCfi = 0;
15072    uint8_t                     currCfi;
15073    uint8_t                     cceFailIdx;
15074    uint32_t                    totalCce;
15075    uint8_t                     dlIdx;
15076    uint16_t                    ttiMod;
15077
15078
15079    /* Get Downlink Subframe */   
15080    frm   = cell->crntTime;
15081    RGSCH_INCR_SUB_FRAME(frm, delta);
15082
15083 #ifdef LTE_TDD
15084    dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
15085    dlSf = cell->subFrms[dlIdx];
15086    isHiDci0 = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][dlSf->sfNum];
15087 #else
15088    /* Changing the idexing
15089       so that proper subframe is selected */
15090    dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
15091    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
15092    dlSf = cell->subFrms[dlIdx];
15093 #endif 
15094
15095    currCfi = cellSch->dl.currCfi;
15096
15097    if(!cell->dynCfiCb.switchOvrInProgress)
15098    {   
15099       do{
15100          if(!cell->dynCfiCb.isDynCfiEnb)
15101          {
15102             if(currCfi != cellSch->cfiCfg.cfi)
15103             {
15104                if(currCfi < cellSch->cfiCfg.cfi)
15105                {
15106                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
15107                   cfiIncr = cell->dynCfiCb.cfiIncr;   
15108                }
15109                else
15110                {
15111                   RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
15112                   cfiDecr = cell->dynCfiCb.cfiDecr;
15113                }
15114             }
15115             break;
15116          }
15117
15118 #ifdef LTE_TDD         
15119          /* Setting ttiMod to 0 for ttiCnt > 1000 in case if this 
15120           * function was not called in UL subframe*/
15121          if(cell->dynCfiCb.ttiCnt > RGSCH_CFI_TTI_MON_INTRVL)
15122          {   
15123             ttiMod = 0;
15124          }
15125          else
15126 #endif
15127          {   
15128             ttiMod = cell->dynCfiCb.ttiCnt % RGSCH_CFI_TTI_MON_INTRVL;
15129          }
15130
15131          dlSf->dlUlBothCmplt++;
15132 #ifdef LTE_TDD      
15133          if((dlSf->dlUlBothCmplt == 2) || (!isHiDci0))
15134 #else
15135          if(dlSf->dlUlBothCmplt == 2)
15136 #endif         
15137          {
15138             /********************STEP UP CRITERIA********************/
15139             /* Updating the CCE failure count parameter */
15140             cell->dynCfiCb.cceFailCnt += dlSf->isCceFailure;
15141             cell->dynCfiCb.cceFailSum += dlSf->isCceFailure;
15142
15143             /* Check if cfi step up can be performed */
15144             if(currCfi < cell->dynCfiCb.maxCfi)
15145             {
15146                if(cell->dynCfiCb.cceFailSum >= cell->dynCfiCb.cfiStepUpTtiCnt) 
15147                {
15148                   RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi)
15149                   cfiIncr = cell->dynCfiCb.cfiIncr;   
15150                   break;
15151                }
15152             } 
15153
15154             /********************STEP DOWN CRITERIA********************/
15155
15156             /* Updating the no. of CCE used in this dl subframe */
15157             cell->dynCfiCb.cceUsed += dlSf->cceCnt;
15158
15159             if(currCfi > RGSCH_MIN_CFI_VAL)
15160             {   
15161                /* calculating the number of CCE for next lower CFI */
15162 #ifdef LTE_TDD      
15163                mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][dlSf->sfNum];
15164                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[mPhich][currCfi-1];
15165 #else
15166                nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[0][currCfi-1];
15167 #endif     
15168                if(dlSf->cceCnt < nCceLowerCfi)
15169                {
15170                   /* Updating the count of TTIs in which no. of CCEs
15171                    * used were less than the CCEs of next lower CFI */
15172                   cell->dynCfiCb.lowCceCnt++;
15173                }   
15174
15175                if(ttiMod == 0)
15176                {
15177                   totalCce = (nCceLowerCfi * cell->dynCfiCb.cfiStepDownTtiCnt * 
15178                         RGSCH_CFI_CCE_PERCNTG)/100;
15179
15180                   if((!cell->dynCfiCb.cceFailSum) && 
15181                         (cell->dynCfiCb.lowCceCnt >= 
15182                          cell->dynCfiCb.cfiStepDownTtiCnt) && 
15183                         (cell->dynCfiCb.cceUsed < totalCce))  
15184                   {
15185                      RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi)
15186                      cfiDecr = cell->dynCfiCb.cfiDecr; 
15187                      break;
15188                   }
15189                }   
15190             }
15191
15192             cceFailIdx = ttiMod/cell->dynCfiCb.failSamplePrd;
15193
15194             if(cceFailIdx != cell->dynCfiCb.prevCceFailIdx)
15195             {   
15196                /* New sample period has started. Subtract the old count  
15197                 * from the new sample period */
15198                cell->dynCfiCb.cceFailSum -= cell->dynCfiCb.cceFailSamples[cceFailIdx];
15199
15200                /* Store the previous sample period data */
15201                cell->dynCfiCb.cceFailSamples[cell->dynCfiCb.prevCceFailIdx]
15202                   = cell->dynCfiCb.cceFailCnt;
15203
15204                cell->dynCfiCb.prevCceFailIdx = cceFailIdx;
15205
15206                /* Resetting the CCE failure count as zero for next sample period */
15207                cell->dynCfiCb.cceFailCnt = 0;  
15208             }
15209
15210             if(ttiMod == 0)
15211             {   
15212                /* Restting the parametrs after Monitoring Interval expired */
15213                cell->dynCfiCb.cceUsed = 0;
15214                cell->dynCfiCb.lowCceCnt = 0;
15215                cell->dynCfiCb.ttiCnt = 0;
15216             }
15217
15218             cell->dynCfiCb.ttiCnt++;
15219          }
15220       }while(0);
15221
15222       if(cellSch->dl.newCfi != cellSch->dl.currCfi)
15223       {
15224 #ifdef LTE_TDD      
15225          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, dlSf->sfNum);
15226 #else
15227          rgSchCmnUpdtPdcchSfIdx(cell, dlIdx);
15228 #endif      
15229       }  
15230    }
15231 }   
15232
15233 /**
15234  * @brief Dl Scheduler for Broadcast and Common channel scheduling.
15235  *
15236  * @details
15237  *
15238  *     Function: rgSCHCmnDlCommonChSch
15239  *     Purpose:  This function schedules DL Common channels for LTE. 
15240  *               Invoked by TTI processing in TOM. Scheduling is done for 
15241  *               BCCH, PCCH, Msg4, CCCH SDU, RAR in that order 
15242  *
15243  *     Invoked by: TOM (TTI processing)
15244  *
15245  *  @param[in]  RgSchCellCb *cell
15246  *  @return  Void
15247  **/
15248 #ifdef ANSI
15249 Void rgSCHCmnDlCommonChSch
15250 (
15251 RgSchCellCb  *cell
15252 )
15253 #else
15254 Void rgSCHCmnDlCommonChSch(cell)
15255 RgSchCellCb  *cell;
15256 #endif
15257 {
15258    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
15259
15260
15261    cellSch->apisDl->rgSCHDlTickForPdbTrkng(cell);
15262    rgSchCmnUpdCfiVal(cell, RG_SCH_CMN_DL_DELTA);
15263
15264    /* handle Inactive UEs for DL */
15265    rgSCHCmnHdlDlInactUes(cell);
15266
15267    /* Send a Tick to Refresh Timer */
15268    rgSCHCmnTmrProc(cell);
15269
15270    if (cell->isDlDataAllwd && (cell->stopSiSch == FALSE)) 
15271    {
15272       rgSCHCmnInitRbAlloc(cell); 
15273       /* Perform DL scheduling of BCCH, PCCH */
15274       rgSCHCmnDlBcchPcchAlloc(cell);
15275    }
15276    else
15277    {
15278       if(cell->siCb.inWindow != 0)
15279       {
15280          cell->siCb.inWindow--;
15281       }
15282    }
15283    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
15284    {
15285       rgSCHCmnDlCcchRarAlloc(cell);
15286    }
15287    return;
15288 }
15289
15290 /**
15291  * @brief Scheduler invocation per TTI.
15292  *
15293  * @details
15294  *
15295  *     Function: rgSCHCmnUlSch
15296  *     Purpose:  This function implements UL scheduler alone. This is to
15297  *               be able to perform scheduling with more flexibility.
15298  *
15299  *     Invoked by: TOM (TTI processing)
15300  *
15301  *  @param[in]  RgSchCellCb *cell
15302  *  @return  Void
15303  **/
15304 #ifdef ANSI
15305 Void rgSCHCmnUlSch
15306 (
15307 RgSchCellCb  *cell
15308 )
15309 #else
15310 Void  rgSCHCmnUlSch(cell)
15311 RgSchCellCb  *cell;
15312 #endif
15313 {
15314    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
15315    
15316
15317 #ifdef LTE_ADV
15318    /* LAA_SCELL: */
15319    if(TRUE == rgSCHLaaSCellEnabled(cell))
15320    {
15321       return;   
15322    }
15323 #endif
15324    
15325    if(cellSch->ul.schdIdx != RGSCH_INVALID_INFO)
15326    {   
15327       rgSchCmnUpdCfiVal(cell, TFU_ULCNTRL_DLDELTA);
15328
15329       /* Handle Inactive UEs for UL */
15330       rgSCHCmnHdlUlInactUes(cell);
15331       /* Perform UL Scheduling EVERY TTI */
15332       rgSCHCmnUlAlloc(cell);
15333
15334       /* Calling function to update CFI parameters*/
15335       rgSchCmnUpdCfiDb(cell, TFU_ULCNTRL_DLDELTA);   
15336
15337       if(cell->dynCfiCb.switchOvrWinLen > 0)
15338       {
15339          /* Decrementing the switchover window length */
15340          cell->dynCfiCb.switchOvrWinLen--;
15341
15342          if(!cell->dynCfiCb.switchOvrWinLen)
15343          {   
15344             if(cell->dynCfiCb.dynCfiRecfgPend)
15345             {  
15346                /* Toggling the Dynamic CFI enabling */
15347                cell->dynCfiCb.isDynCfiEnb ^= 1;
15348                rgSCHDynCfiReCfg(cell, cell->dynCfiCb.isDynCfiEnb); 
15349                cell->dynCfiCb.dynCfiRecfgPend = FALSE;
15350             }   
15351             cell->dynCfiCb.switchOvrInProgress = FALSE;
15352          }
15353       }
15354    }
15355 #ifdef LTE_TDD
15356 #ifdef LTEMAC_SPS
15357    else
15358    {
15359       rgSCHCmnSpsUlTti(cell, NULLP); 
15360    }
15361 #endif
15362 #endif
15363
15364    return;
15365 }
15366
15367 \f
15368 /**
15369  * @brief This function updates the scheduler with service for an UE.
15370  *
15371  * @details
15372  *
15373  *     Function: rgSCHCmnDlDedBoUpd
15374  *     Purpose:  This function should be called whenever there is a
15375  *               change BO for a service.
15376  *
15377  *     Invoked by: BO and Scheduler
15378  *
15379  *  @param[in]  RgSchCellCb*  cell
15380  *  @param[in]  RgSchUeCb*    ue
15381  *  @param[in]  RgSchDlLcCb*  svc
15382  *  @return  Void
15383  *
15384  **/
15385 #ifdef ANSI
15386 Void rgSCHCmnDlDedBoUpd
15387 (
15388 RgSchCellCb                *cell,
15389 RgSchUeCb                  *ue,
15390 RgSchDlLcCb                *svc
15391 )
15392 #else
15393 Void rgSCHCmnDlDedBoUpd(cell, ue, svc)
15394 RgSchCellCb                *cell;
15395 RgSchUeCb                  *ue;
15396 RgSchDlLcCb                *svc;
15397 #endif
15398 {
15399    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15400
15401    /* RACHO : if UEs idle time exceeded and a BO update
15402     * is received, then add UE to the pdcch Order Q */
15403    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
15404    {
15405       RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
15406       /* If PDCCH order is already triggered and we are waiting for
15407        * RACH from UE then do not add to PdcchOdrQ. */
15408       if (ueDl->rachInfo.rapIdLnk.node == NULLP)
15409       {
15410          rgSCHCmnDlAdd2PdcchOdrQ(cell, ue);
15411       }
15412    }
15413
15414 #ifdef LTEMAC_SPS
15415
15416    /* If SPS service, invoke SPS module */
15417    if (svc->dlLcSpsCfg.isSpsEnabled)
15418    {
15419       rgSCHCmnSpsDlDedBoUpd(cell, ue, svc);
15420       /* Note: Retrun from here, no update needed in other schedulers */
15421       return;
15422    }
15423 #endif
15424 #ifdef EMTC_ENABLE
15425    if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe))
15426    {
15427       cellSch->apisEmtcDl->rgSCHDlDedBoUpd(cell, ue, svc);
15428       //printf("rgSCHEMTCDlDedBoUpd\n");
15429    }
15430    else
15431 #endif
15432    {
15433       cellSch->apisDl->rgSCHDlDedBoUpd(cell, ue, svc);
15434    }
15435 #ifdef LTE_ADV
15436    if (ue->numSCells)
15437    {
15438       rgSCHSCellDlDedBoUpd(cell, ue, svc);
15439    }
15440 #endif
15441    return;
15442 }
15443
15444 \f
15445 /**
15446  * @brief Removes an UE from Cell's TA List.
15447  *
15448  * @details
15449  *
15450  *     Function: rgSCHCmnRmvFrmTaLst
15451  *     Purpose:  Removes an UE from Cell's TA List.
15452  *
15453  *     Invoked by: Specific Scheduler
15454  *
15455  *  @param[in]  RgSchCellCb*     cell
15456  *  @param[in]  RgSchUeCb*       ue
15457  *  @return  Void
15458  *
15459  **/
15460 #ifdef ANSI
15461 Void rgSCHCmnRmvFrmTaLst
15462 (
15463 RgSchCellCb                *cell,
15464 RgSchUeCb                  *ue
15465 )
15466 #else
15467 Void rgSCHCmnRmvFrmTaLst(cell, ue)
15468 RgSchCellCb                *cell;
15469 RgSchUeCb                  *ue;
15470 #endif
15471 {
15472    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
15473
15474 #ifdef EMTC_ENABLE
15475    if(cell->emtcEnable && ue->isEmtcUe)
15476    {
15477       rgSCHEmtcRmvFrmTaLst(cellCmnDl,ue);
15478    }
15479    else
15480 #endif
15481    {
15482       cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk);
15483       ue->dlTaLnk.node = (PTR)NULLP;
15484    }
15485    return;
15486 }
15487
15488 /* Fix: syed Remove the msg4Proc from cell
15489  * msg4Retx Queue. I have used CMN scheduler function
15490  * directly. Please define a new API and call this
15491  * function through that. */        
15492 \f
15493 /**
15494  * @brief This function removes MSG4 HARQ process from cell RETX Queues.
15495  *
15496  * @details
15497  *
15498  *     Function: rgSCHCmnDlMsg4ProcRmvFrmRetx
15499  *     Purpose:  This function removes MSG4 HARQ process from cell RETX Queues.
15500  *
15501  *     Invoked by: UE/RACB deletion. 
15502  *
15503  *  @param[in]  RgSchCellCb*     cell
15504  *  @param[in]  RgSchDlHqProc*   hqP
15505  *  @return  Void
15506  *
15507  **/
15508 #ifdef ANSI
15509 Void rgSCHCmnDlMsg4ProcRmvFrmRetx 
15510 (
15511 RgSchCellCb                *cell,
15512 RgSchDlHqProcCb            *hqP
15513 )
15514 #else
15515 Void rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, hqP)
15516 RgSchCellCb                *cell;
15517 RgSchDlHqProcCb            *hqP;
15518 #endif
15519 {
15520    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15521
15522    if (hqP->tbInfo[0].ccchSchdInfo.retxLnk.node)
15523    {
15524       if (hqP->hqE->msg4Proc == hqP)
15525       {
15526          cmLListDelFrm(&cellSch->dl.msg4RetxLst, \
15527                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15528          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
15529       }
15530 #ifdef RGR_V1
15531       else if(hqP->hqE->ccchSduProc == hqP)
15532       {
15533          cmLListDelFrm(&cellSch->dl.ccchSduRetxLst,
15534                &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15535          hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP;
15536       }
15537 #endif
15538    }
15539    return;
15540 }
15541
15542 \f
15543 /**
15544  * @brief This function adds a HARQ process for retx.
15545  *
15546  * @details
15547  *
15548  *     Function: rgSCHCmnDlProcAddToRetx
15549  *     Purpose:  This function adds a HARQ process to retransmission
15550  *               queue. This may be performed when a HARQ ack is
15551  *               unsuccessful.
15552  *
15553  *     Invoked by: HARQ feedback processing
15554  *
15555  *  @param[in]  RgSchCellCb*     cell
15556  *  @param[in]  RgSchDlHqProc*   hqP
15557  *  @return  Void
15558  *
15559  **/
15560 #ifdef ANSI
15561 Void rgSCHCmnDlProcAddToRetx
15562 (
15563 RgSchCellCb                *cell,
15564 RgSchDlHqProcCb            *hqP
15565 )
15566 #else
15567 Void rgSCHCmnDlProcAddToRetx(cell, hqP)
15568 RgSchCellCb                *cell;
15569 RgSchDlHqProcCb            *hqP;
15570 #endif
15571 {
15572    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
15573
15574    if (hqP->hqE->msg4Proc == hqP) /* indicating msg4 transmission */
15575    {
15576       cmLListAdd2Tail(&cellSch->dl.msg4RetxLst, \
15577             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15578       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
15579    }
15580 #ifdef RGR_V1
15581    else if(hqP->hqE->ccchSduProc == hqP)
15582    {
15583       /*If CCCH SDU being transmitted without cont res CE*/
15584       cmLListAdd2Tail(&cellSch->dl.ccchSduRetxLst,
15585             &hqP->tbInfo[0].ccchSchdInfo.retxLnk);
15586       hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP;
15587    }
15588 #endif
15589    else
15590    {
15591 #ifdef LTEMAC_SPS
15592       if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
15593       {
15594          /* Invoke SPS module for SPS HARQ proc re-transmission handling */
15595          rgSCHCmnSpsDlProcAddToRetx(cell, hqP);
15596          return;
15597       }
15598 #endif /* LTEMAC_SPS */
15599 #ifdef EMTC_ENABLE      
15600       if((TRUE == cell->emtcEnable)
15601          && (TRUE == hqP->hqE->ue->isEmtcUe))
15602       {
15603          cellSch->apisEmtcDl->rgSCHDlProcAddToRetx(cell, hqP);
15604       }
15605       else
15606 #endif         
15607       {
15608          cellSch->apisDl->rgSCHDlProcAddToRetx(cell, hqP);
15609       }
15610    }
15611    return;
15612 }
15613
15614 \f
15615 /**
15616  * @brief This function performs RI validation and
15617  *        updates it to the ueCb.
15618  *
15619  * @details
15620  *
15621  *     Function: rgSCHCmnDlSetUeRi
15622  *     Purpose:  This function performs RI validation and
15623  *        updates it to the ueCb.
15624  *
15625  *     Invoked by: rgSCHCmnDlCqiInd
15626  *
15627  *  @param[in]  RgSchCellCb        *cell
15628  *  @param[in]  RgSchUeCb          *ue
15629  *  @param[in]  uint8_t                 ri
15630  *  @param[in]  Bool               isPeriodic
15631  *  @return  Void
15632  *
15633  **/
15634 #ifdef ANSI
15635 static Void rgSCHCmnDlSetUeRi
15636 (
15637 RgSchCellCb        *cell,
15638 RgSchUeCb          *ue,
15639 uint8_t                 ri,
15640 Bool               isPer
15641 )
15642 #else
15643 static Void rgSCHCmnDlSetUeRi(cell, ue, ri, isPer)
15644 RgSchCellCb        *cell;
15645 RgSchUeCb          *ue;
15646 uint8_t                 ri;
15647 Bool               isPer;
15648 #endif
15649 {
15650    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15651    RgSchCmnUeInfo    *ueSchCmn = RG_SCH_CMN_GET_CMN_UE(ue);
15652    
15653 #ifdef TFU_UPGRADE
15654    RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell);
15655    UNUSED(isPer);
15656 #endif
15657
15658
15659    /* FIX for RRC Reconfiguration issue */
15660    /* ccpu00140894- During Tx Mode transition RI report will not entertained for 
15661     * specific during which SCH expecting UE can complete TX mode transition*/
15662    if (ue->txModeTransCmplt == FALSE)
15663    {
15664       return;
15665    }
15666
15667    /* Restrict the Number of TX layers to cell->numTxAntPorts.
15668     * Protection from invalid RI values. */
15669    ri = RGSCH_MIN(ri, cell->numTxAntPorts);
15670    
15671    /* Special case of converting PMI to sane value when
15672     * there is a switch in RI from 1 to 2 and PMI reported 
15673     * for RI=1 is invalid for RI=2 */
15674    if ((cell->numTxAntPorts == 2) && (ue->mimoInfo.txMode == RGR_UE_TM_4))
15675    {
15676       if ((ri == 2) && ( ueDl->mimoInfo.ri == 1))
15677       {
15678          ueDl->mimoInfo.pmi = (ueDl->mimoInfo.pmi < 2)? 1:2;
15679       }
15680    }
15681
15682    /* Restrict the Number of TX layers according to the UE Category */
15683    ueDl->mimoInfo.ri = RGSCH_MIN(ri, rgUeCatTbl[ueSchCmn->ueCat].maxTxLyrs);
15684 #ifdef TENB_STATS
15685    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].riCnt[ueDl->mimoInfo.ri-1]++;
15686    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
15687 #endif
15688
15689 #ifdef TENB_STATS
15690    ue->tenbStats->stats.nonPersistent.sch[0].riCnt[ueDl->mimoInfo.ri-1]++;
15691    cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++;
15692 #endif
15693
15694 #ifdef TFU_UPGRADE
15695    if (isPer)
15696    {
15697       /* If RI is from Periodic CQI report */
15698       cqiCb->perRiVal = ueDl->mimoInfo.ri;
15699       /* Reset at every Periodic RI Reception */ 
15700       cqiCb->invalidateCqi = FALSE;
15701    }
15702    else
15703    {
15704       /* If RI is from Aperiodic CQI report */
15705       if (cqiCb->perRiVal != ueDl->mimoInfo.ri)
15706       {
15707          /* if this aperRI is different from last reported
15708           * perRI then invalidate all CQI reports till next
15709           * perRI */
15710          cqiCb->invalidateCqi = TRUE;
15711       }
15712       else
15713       {
15714          cqiCb->invalidateCqi = FALSE;
15715       }
15716    }
15717 #endif   
15718
15719    if (ueDl->mimoInfo.ri > 1)
15720    {
15721       RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
15722    }
15723    else if (ue->mimoInfo.txMode == RGR_UE_TM_3) /* ri == 1 */
15724    {
15725       RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1);
15726    }
15727
15728    return;
15729 }
15730
15731 \f
15732 /**
15733  * @brief This function performs PMI validation and
15734  *        updates it to the ueCb.
15735  *
15736  * @details
15737  *
15738  *     Function: rgSCHCmnDlSetUePmi
15739  *     Purpose:  This function performs PMI validation and
15740  *        updates it to the ueCb.
15741  *
15742  *     Invoked by: rgSCHCmnDlCqiInd
15743  *
15744  *  @param[in]  RgSchCellCb        *cell
15745  *  @param[in]  RgSchUeCb          *ue
15746  *  @param[in]  uint8_t                 pmi
15747  *  @return  Void
15748  *
15749  **/
15750 #ifdef ANSI
15751 static S16 rgSCHCmnDlSetUePmi
15752 (
15753 RgSchCellCb        *cell,
15754 RgSchUeCb          *ue,
15755 uint8_t                 pmi
15756 )
15757 #else
15758 static S16 rgSCHCmnDlSetUePmi(cell, ue, pmi)
15759 RgSchCellCb        *cell;
15760 RgSchUeCb          *ue;
15761 uint8_t                 pmi;
15762 #endif
15763 {
15764    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15765
15766    if (ue->txModeTransCmplt == FALSE)
15767    {
15768        return RFAILED;
15769    }
15770  
15771    if (cell->numTxAntPorts == 2)
15772    {
15773       if (pmi > 3)
15774       {
15775          return RFAILED;
15776       }
15777       if (ueDl->mimoInfo.ri == 2)
15778       {
15779          /*ccpu00118150 - MOD - changed pmi value validation from 0 to 2*/
15780          /* PMI 2 and 3 are invalid incase of 2 TxAnt and 2 Layered SM */
15781          if (pmi == 2 || pmi == 3)
15782          {
15783             return RFAILED;
15784          }
15785          ueDl->mimoInfo.pmi = pmi+1;
15786       }
15787       else
15788       {
15789          ueDl->mimoInfo.pmi = pmi;
15790       }
15791    }
15792    else if (cell->numTxAntPorts == 4)
15793    {
15794       if (pmi > 15)
15795       {
15796          return RFAILED;
15797       }
15798       ueDl->mimoInfo.pmi = pmi;
15799    }
15800    /* Reset the No PMI Flag in forceTD */
15801    RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI);
15802    return ROK;
15803 }
15804
15805 /**
15806  * @brief This function Updates the DL CQI on PUCCH for the UE.
15807  *
15808  * @details
15809  *
15810  *     Function: rgSCHCmnDlProcCqiMode10
15811  *
15812  *     This function updates the DL CQI on PUCCH for the UE.
15813  *
15814  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
15815  *
15816  *     Processing Steps:
15817  *
15818  *  @param[in] RgSchCellCb     *cell
15819  *  @param[in] RgSchUeCb       *ue
15820  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
15821  *  @return  S16
15822  *      -# ROK
15823  *      -# RFAILED
15824  **/
15825 #ifdef RGR_CQI_REPT
15826 #ifdef ANSI
15827 static inline Void rgSCHCmnDlProcCqiMode10
15828 (
15829  RgSchCellCb        *cell,
15830  RgSchUeCb          *ue,
15831  TfuDlCqiPucch      *pucchCqi,
15832  Bool               *isCqiAvail
15833  )
15834 #else
15835 static inline Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail)
15836  RgSchCellCb        *cell;
15837  RgSchUeCb          *ue;
15838  TfuDlCqiPucch      *pucchCqi;
15839  Bool               *isCqiAvail;
15840 #endif
15841 #else
15842 #ifdef ANSI
15843 static inline Void rgSCHCmnDlProcCqiMode10
15844 (
15845  RgSchCellCb        *cell,
15846  RgSchUeCb          *ue,
15847  TfuDlCqiPucch      *pucchCqi
15848  )
15849 #else
15850 static inline Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi)
15851  RgSchCellCb        *cell;
15852  RgSchUeCb          *ue;
15853  TfuDlCqiPucch      *pucchCqi;
15854 #endif
15855 #endif
15856 {
15857    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15858
15859    if (pucchCqi->u.mode10Info.type == TFU_RPT_CQI)
15860    {
15861       /*ccpu00109787 - ADD - Check for non-zero CQI*/
15862       /* Checking whether the decoded CQI is a value between 1 and 15*/
15863       if((pucchCqi->u.mode10Info.u.cqi) && (pucchCqi->u.mode10Info.u.cqi
15864                < RG_SCH_CMN_MAX_CQI))
15865       {
15866          ueDl->cqiFlag = TRUE;
15867          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode10Info.u.cqi;
15868          ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
15869          /* ccpu00117452 - MOD - Changed macro name from
15870             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
15871 #ifdef RGR_CQI_REPT
15872          *isCqiAvail = TRUE;
15873 #endif
15874       }
15875       else
15876       {
15877          return;
15878       }
15879    }
15880    else if (pucchCqi->u.mode10Info.type == TFU_RPT_RI)
15881    {
15882       if ( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode10Info.u.ri) )
15883       {
15884          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode10Info.u.ri,
15885                            TRUE);
15886       }
15887       else
15888       {
15889          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
15890             pucchCqi->u.mode10Info.u.ri,ue->ueId);
15891          return;
15892       }
15893    }
15894 }
15895
15896 /**
15897  * @brief This function Updates the DL CQI on PUCCH for the UE.
15898  *
15899  * @details
15900  *
15901  *     Function: rgSCHCmnDlProcCqiMode11
15902  *
15903  *     This function updates the DL CQI on PUCCH for the UE.
15904  *
15905  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
15906  *
15907  *     Processing Steps:
15908  *       Process CQI MODE 11
15909  *  @param[in] RgSchCellCb     *cell
15910  *  @param[in] RgSchUeCb       *ue
15911  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
15912  *  @return  S16
15913  *      -# ROK
15914  *      -# RFAILED
15915  **/
15916 #ifdef RGR_CQI_REPT
15917 #ifdef ANSI
15918 static inline Void rgSCHCmnDlProcCqiMode11
15919 (
15920  RgSchCellCb        *cell,
15921  RgSchUeCb          *ue,
15922  TfuDlCqiPucch      *pucchCqi,
15923  Bool               *isCqiAvail,
15924  Bool               *is2ndCwCqiAvail
15925  )
15926 #else
15927 static inline Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail)
15928  RgSchCellCb        *cell;
15929  RgSchUeCb          *ue;
15930  TfuDlCqiPucch      *pucchCqi;
15931  Bool               *isCqiAvail;
15932  Bool               *is2ndCwCqiAvail;
15933 #endif
15934 #else
15935 #ifdef ANSI
15936 static inline Void rgSCHCmnDlProcCqiMode11
15937 (
15938  RgSchCellCb        *cell,
15939  RgSchUeCb          *ue,
15940  TfuDlCqiPucch      *pucchCqi
15941  )
15942 #else
15943 static inline Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi)
15944  RgSchCellCb        *cell;
15945  RgSchUeCb          *ue;
15946  TfuDlCqiPucch      *pucchCqi;
15947 #endif
15948 #endif
15949 {
15950    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
15951
15952    if (pucchCqi->u.mode11Info.type == TFU_RPT_CQI)
15953    {
15954       ue->mimoInfo.puschFdbkVld  = FALSE;
15955       /*ccpu00109787 - ADD - Check for non-zero CQI*/
15956       if((pucchCqi->u.mode11Info.u.cqi.cqi) &&
15957             (pucchCqi->u.mode11Info.u.cqi.cqi < RG_SCH_CMN_MAX_CQI))
15958       {
15959          ueDl->cqiFlag = TRUE;
15960          /* ccpu00117452 - MOD - Changed macro name from
15961             RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
15962 #ifdef RGR_CQI_REPT
15963          *isCqiAvail = TRUE;
15964 #endif
15965          ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode11Info.u.cqi.cqi;
15966          if (pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.pres)
15967          {
15968             RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
15969                                      ueDl->mimoInfo.cwInfo[1].cqi, \
15970                                      pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.val);
15971 #ifdef RGR_CQI_REPT
15972             /* ccpu00117259 - ADD - Considering second codeword CQI info
15973                incase of MIMO for CQI Reporting */
15974             *is2ndCwCqiAvail = TRUE;
15975 #endif
15976          }
15977       }
15978       else
15979       {
15980          return;
15981       }
15982       rgSCHCmnDlSetUePmi(cell, ue, \
15983             pucchCqi->u.mode11Info.u.cqi.pmi);
15984    }
15985    else if (pucchCqi->u.mode11Info.type == TFU_RPT_RI)
15986    {
15987       if( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode11Info.u.ri))
15988       {
15989          rgSCHCmnDlSetUeRi(cell, ue,  pucchCqi->u.mode11Info.u.ri,
15990                            TRUE);
15991       }
15992       else
15993       {
15994          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Invalid RI value(%x) CRNTI:%d",
15995             pucchCqi->u.mode11Info.u.ri,ue->ueId);
15996          return;
15997       }
15998    }
15999 }
16000
16001 /**
16002  * @brief This function Updates the DL CQI on PUCCH for the UE.
16003  *
16004  * @details
16005  *
16006  *     Function: rgSCHCmnDlProcCqiMode20
16007  *
16008  *     This function updates the DL CQI on PUCCH for the UE.
16009  *
16010  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
16011  *
16012  *     Processing Steps:
16013  *       Process CQI MODE 20
16014  *  @param[in] RgSchCellCb     *cell
16015  *  @param[in] RgSchUeCb       *ue
16016  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16017  *  @return  S16
16018  *      -# ROK
16019  *      -# RFAILED
16020  **/
16021 #ifdef RGR_CQI_REPT
16022 #ifdef ANSI
16023 static inline Void rgSCHCmnDlProcCqiMode20
16024 (
16025  RgSchCellCb        *cell,
16026  RgSchUeCb          *ue,
16027  TfuDlCqiPucch      *pucchCqi,
16028  Bool               *isCqiAvail
16029  )
16030 #else
16031 static inline Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail )
16032  RgSchCellCb        *cell;
16033  RgSchUeCb          *ue;
16034  TfuDlCqiPucch      *pucchCqi;
16035  Bool               *isCqiAvail;
16036 #endif
16037 #else
16038 #ifdef ANSI
16039 static inline Void rgSCHCmnDlProcCqiMode20
16040 (
16041  RgSchCellCb        *cell,
16042  RgSchUeCb          *ue,
16043  TfuDlCqiPucch      *pucchCqi
16044  )
16045 #else
16046 static inline Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi)
16047  RgSchCellCb        *cell;
16048  RgSchUeCb          *ue;
16049  TfuDlCqiPucch      *pucchCqi;
16050 #endif
16051 #endif
16052 {
16053    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16054
16055    if (pucchCqi->u.mode20Info.type == TFU_RPT_CQI)
16056    {
16057       if (pucchCqi->u.mode20Info.u.cqi.isWideband)
16058       {
16059          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16060          if((pucchCqi->u.mode20Info.u.cqi.u.wideCqi) &&
16061                (pucchCqi->u.mode20Info.u.cqi.u.wideCqi < RG_SCH_CMN_MAX_CQI))
16062          {
16063             ueDl->cqiFlag = TRUE;
16064             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode20Info.u.cqi.\
16065                                            u.wideCqi;
16066             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16067             /* ccpu00117452 - MOD - Changed macro name from
16068                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16069 #ifdef RGR_CQI_REPT
16070             *isCqiAvail = TRUE;
16071 #endif
16072          }
16073          else
16074          {
16075             return;
16076          }
16077       }
16078    }
16079    else if (pucchCqi->u.mode20Info.type == TFU_RPT_RI)
16080    {
16081       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode20Info.u.ri))
16082       {
16083          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode20Info.u.ri, 
16084                            TRUE);
16085       }
16086       else
16087       {
16088          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
16089             pucchCqi->u.mode20Info.u.ri,ue->ueId);
16090          return;
16091       }
16092    }
16093 }
16094
16095
16096 /**
16097  * @brief This function Updates the DL CQI on PUCCH for the UE.
16098  *
16099  * @details
16100  *
16101  *     Function: rgSCHCmnDlProcCqiMode21
16102  *
16103  *     This function updates the DL CQI on PUCCH for the UE.
16104  *
16105  *     Invoked by: rgSCHCmnDlCqiOnPucchInd
16106  *
16107  *     Processing Steps:
16108  *       Process CQI MODE 21
16109  *  @param[in] RgSchCellCb     *cell
16110  *  @param[in] RgSchUeCb       *ue
16111  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16112  *  @return  S16
16113  *      -# ROK
16114  *      -# RFAILED
16115  **/
16116 #ifdef RGR_CQI_REPT
16117 #ifdef ANSI
16118 static inline Void rgSCHCmnDlProcCqiMode21
16119 (
16120  RgSchCellCb        *cell,
16121  RgSchUeCb          *ue,
16122  TfuDlCqiPucch      *pucchCqi,
16123  Bool               *isCqiAvail,
16124  Bool               *is2ndCwCqiAvail
16125  )
16126 #else
16127 static inline Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail)
16128    RgSchCellCb        *cell;
16129    RgSchUeCb          *ue;
16130  TfuDlCqiPucch        *pucchCqi;
16131    TfuDlCqiRpt        *dlCqiRpt;
16132    Bool               *isCqiAvail;
16133    Bool               *is2ndCwCqiAvail;
16134 #endif
16135 #else
16136 #ifdef ANSI
16137 static inline Void rgSCHCmnDlProcCqiMode21
16138 (
16139  RgSchCellCb        *cell,
16140  RgSchUeCb          *ue,
16141  TfuDlCqiPucch      *pucchCqi
16142  )
16143 #else
16144 static inline Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi)
16145  RgSchCellCb        *cell;
16146  RgSchUeCb          *ue;
16147  TfuDlCqiPucch      *pucchCqi;
16148 #endif
16149 #endif
16150 {
16151    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16152
16153    if (pucchCqi->u.mode21Info.type == TFU_RPT_CQI)
16154    {
16155       ue->mimoInfo.puschFdbkVld  = FALSE;
16156       if (pucchCqi->u.mode21Info.u.cqi.isWideband)
16157       {
16158          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16159          if((pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi) &&
16160                (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi < RG_SCH_CMN_MAX_CQI))
16161          {
16162             ueDl->cqiFlag = TRUE;
16163             ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode21Info.u.cqi.\
16164                                            u.wideCqi.cqi;
16165             if (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.pres)
16166             {
16167                RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \
16168                                      ueDl->mimoInfo.cwInfo[1].cqi, \
16169                                      pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.val);
16170 #ifdef RGR_CQI_REPT
16171                /* ccpu00117259 - ADD - Considering second codeword CQI info
16172                   incase of MIMO for CQI Reporting */
16173                *is2ndCwCqiAvail = TRUE;
16174 #endif
16175             }
16176             /* ccpu00117452 - MOD - Changed macro name from
16177                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16178 #ifdef RGR_CQI_REPT
16179             *isCqiAvail = TRUE;
16180 #endif
16181          }
16182          else
16183          {
16184             return;
16185          }
16186          rgSCHCmnDlSetUePmi(cell, ue, \
16187                pucchCqi->u.mode21Info.u.cqi.u.wideCqi.pmi);
16188       }
16189    }
16190    else if (pucchCqi->u.mode21Info.type == TFU_RPT_RI)
16191    {
16192       if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode21Info.u.ri))
16193       {
16194          rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode21Info.u.ri,
16195                            TRUE);
16196       }
16197       else
16198       {
16199          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Invalid RI value(%x) CRNTI:%d",
16200             pucchCqi->u.mode21Info.u.ri,ue->ueId);
16201          return;
16202       }
16203    }
16204 }
16205
16206
16207 /**
16208  * @brief This function Updates the DL CQI on PUCCH for the UE.
16209  *
16210  * @details
16211  *
16212  *     Function: rgSCHCmnDlCqiOnPucchInd
16213  *
16214  *     This function updates the DL CQI on PUCCH for the UE.
16215  *
16216  *     Invoked by: rgSCHCmnDlCqiInd
16217  *
16218  *     Processing Steps:
16219  *     - Depending on the reporting mode of the PUCCH, the CQI/PMI/RI values
16220  *       are updated and stored for each UE
16221  *
16222  *  @param[in] RgSchCellCb     *cell
16223  *  @param[in] RgSchUeCb       *ue
16224  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16225  *  @return  S16
16226  *      -# ROK
16227  *      -# RFAILED
16228  **/
16229 #ifdef RGR_CQI_REPT
16230 #ifdef ANSI
16231 static Void rgSCHCmnDlCqiOnPucchInd
16232 (
16233  RgSchCellCb        *cell,
16234  RgSchUeCb          *ue,
16235  TfuDlCqiPucch      *pucchCqi,
16236  RgrUeCqiRept       *ueCqiRept,
16237  Bool               *isCqiAvail,
16238  Bool               *is2ndCwCqiAvail
16239  )
16240 #else
16241 static Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail)
16242  RgSchCellCb        *cell;
16243  RgSchUeCb          *ue;
16244  TfuDlCqiPucch      *pucchCqi;
16245  RgrUeCqiRept       *ueCqiRept;
16246  Bool               *isCqiAvail;
16247  Bool               *is2ndCwCqiAvail;
16248 #endif
16249 #else
16250 #ifdef ANSI
16251 static Void rgSCHCmnDlCqiOnPucchInd
16252 (
16253  RgSchCellCb        *cell,
16254  RgSchUeCb          *ue,
16255  TfuDlCqiPucch      *pucchCqi
16256  )
16257 #else
16258 static Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi)
16259  RgSchCellCb        *cell;
16260  RgSchUeCb          *ue;
16261  TfuDlCqiPucch      *pucchCqi;
16262 #endif
16263 #endif
16264 {
16265    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16266
16267    /* ccpu00117452 - MOD - Changed
16268       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16269 #ifdef RGR_CQI_REPT
16270    /* Save CQI mode information in the report */
16271    ueCqiRept->cqiMode = pucchCqi->mode;
16272 #endif
16273
16274    switch(pucchCqi->mode)
16275    {
16276       case TFU_PUCCH_CQI_MODE10:
16277 #ifdef RGR_CQI_REPT
16278          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail);
16279 #else
16280          rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi);
16281 #endif
16282          ueDl->cqiFlag = TRUE;
16283          break;
16284       case TFU_PUCCH_CQI_MODE11:
16285 #ifdef RGR_CQI_REPT
16286          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail,
16287                 is2ndCwCqiAvail);
16288 #else
16289          rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi);
16290 #endif
16291          ueDl->cqiFlag = TRUE;
16292          break;
16293       case TFU_PUCCH_CQI_MODE20:
16294 #ifdef RGR_CQI_REPT
16295          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail);
16296 #else
16297          rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi);
16298 #endif
16299          ueDl->cqiFlag = TRUE;
16300          break;
16301       case TFU_PUCCH_CQI_MODE21:
16302 #ifdef RGR_CQI_REPT
16303          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail,
16304                 is2ndCwCqiAvail);
16305 #else
16306          rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi);
16307 #endif
16308          ueDl->cqiFlag = TRUE;
16309          break;
16310       default:
16311          {
16312             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unknown CQI Mode %d",
16313                pucchCqi->mode,ue->ueId);
16314             /* ccpu00117452 - MOD - Changed macro name from
16315                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16316 #ifdef RGR_CQI_REPT
16317             *isCqiAvail = FALSE;
16318 #endif
16319          }
16320          break;
16321    }
16322
16323   return;
16324 }  /* rgSCHCmnDlCqiOnPucchInd */
16325
16326
16327 /**
16328  * @brief This function Updates the DL CQI on PUSCH for the UE.
16329  *
16330  * @details
16331  *
16332  *     Function: rgSCHCmnDlCqiOnPuschInd
16333  *
16334  *     This function updates the DL CQI on PUSCH for the UE.
16335  *
16336  *     Invoked by: rgSCHCmnDlCqiInd
16337  *
16338  *     Processing Steps:
16339  *     - Depending on the reporting mode of the PUSCH, the CQI/PMI/RI values
16340  *       are updated and stored for each UE
16341  *
16342  *  @param[in] RgSchCellCb     *cell
16343  *  @param[in] RgSchUeCb       *ue
16344  *  @param[in] TfuDlCqiRpt     *dlCqiRpt
16345  *  @return  S16
16346  *      -# ROK
16347  *      -# RFAILED
16348  **/
16349 #ifdef RGR_CQI_REPT
16350 #ifdef ANSI
16351 static Void rgSCHCmnDlCqiOnPuschInd
16352 (
16353  RgSchCellCb        *cell,
16354  RgSchUeCb          *ue,
16355  TfuDlCqiPusch      *puschCqi,
16356  RgrUeCqiRept       *ueCqiRept,
16357  Bool               *isCqiAvail,
16358  Bool               *is2ndCwCqiAvail
16359  )
16360 #else
16361 static Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail)
16362  RgSchCellCb        *cell;
16363  RgSchUeCb          *ue;
16364  TfuDlCqiPusch      *puschCqi;
16365  RgrUeCqiRept       *ueCqiRept;
16366  Bool               *isCqiAvail;
16367  Bool               *is2ndCwCqiAvail;
16368 #endif
16369 #else
16370 #ifdef ANSI
16371 static Void rgSCHCmnDlCqiOnPuschInd
16372 (
16373  RgSchCellCb        *cell,
16374  RgSchUeCb          *ue,
16375  TfuDlCqiPusch      *puschCqi
16376  )
16377 #else
16378 static Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi)
16379    RgSchCellCb        *cell;
16380    RgSchUeCb          *ue;
16381    TfuDlCqiPusch      *puschCqi;
16382 #endif
16383 #endif
16384 {
16385    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16386    uint32_t prevRiVal = 0; 
16387    if (puschCqi->ri.pres == PRSNT_NODEF)
16388    {
16389       if (RG_SCH_CMN_IS_RI_VALID(puschCqi->ri.val))
16390       {
16391          /* Saving the previous ri value to revert back
16392             in  case PMI update failed */
16393          if (RGR_UE_TM_4 == ue->mimoInfo.txMode ) /* Cheking for TM4. TM8 check later */
16394          {
16395             prevRiVal = ueDl->mimoInfo.ri;
16396          }
16397          rgSCHCmnDlSetUeRi(cell, ue, puschCqi->ri.val, FALSE);
16398       }
16399       else
16400       {
16401          RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d",
16402             puschCqi->ri.val,ue->ueId);
16403          return;
16404       }
16405    }
16406    ue->mimoInfo.puschFdbkVld  = FALSE;
16407    /* ccpu00117452 - MOD - Changed macro name from
16408       RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16409 #ifdef RGR_CQI_REPT
16410    /* Save CQI mode information in the report */
16411    ueCqiRept->cqiMode = puschCqi->mode;
16412    /* ccpu00117259 - DEL - removed default setting of isCqiAvail to TRUE */
16413 #endif
16414
16415    switch(puschCqi->mode)
16416    {
16417       case TFU_PUSCH_CQI_MODE_20:
16418          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16419          /* Checking whether the decoded CQI is a value between 1 and 15*/
16420          if((puschCqi->u.mode20Info.wideBandCqi) &&
16421                (puschCqi->u.mode20Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
16422          {
16423             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode20Info.wideBandCqi;
16424             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16425             /* ccpu00117452 - MOD - Changed macro name from
16426                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16427 #ifdef RGR_CQI_REPT
16428            *isCqiAvail = TRUE;
16429 #endif
16430          }
16431          else
16432          {
16433             return;
16434          }
16435          break;
16436       case TFU_PUSCH_CQI_MODE_30:
16437          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16438          if((puschCqi->u.mode30Info.wideBandCqi) &&
16439                (puschCqi->u.mode30Info.wideBandCqi < RG_SCH_CMN_MAX_CQI))
16440          {
16441             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode30Info.wideBandCqi;
16442             ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi;
16443             /* ccpu00117452 - MOD - Changed macro name from
16444                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16445 #ifdef RGR_CQI_REPT
16446             *isCqiAvail = TRUE;
16447 #endif
16448 #ifdef CA_DBG
16449             {
16450                uint32_t gACqiRcvdCount;
16451                gACqiRcvdCount++;
16452             
16453             }
16454 #endif
16455          }
16456          else
16457          {
16458             return;
16459          }
16460          break;
16461       case TFU_PUSCH_CQI_MODE_12:
16462          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16463          if((puschCqi->u.mode12Info.cqiIdx[0]) &&
16464                (puschCqi->u.mode12Info.cqiIdx[0] < RG_SCH_CMN_MAX_CQI))
16465          {
16466             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode12Info.cqiIdx[0];
16467             /* ccpu00117452 - MOD - Changed macro name from
16468                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16469 #ifdef RGR_CQI_REPT
16470             *isCqiAvail = TRUE;
16471 #endif
16472          }
16473          else
16474          {
16475             return;
16476          }
16477          if((puschCqi->u.mode12Info.cqiIdx[1]) &&
16478                (puschCqi->u.mode12Info.cqiIdx[1] < RG_SCH_CMN_MAX_CQI))
16479          {
16480             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode12Info.cqiIdx[1];
16481             /* ccpu00117452 - MOD - Changed macro name from
16482                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16483 #ifdef RGR_CQI_REPT
16484             /* ccpu00117259 - ADD - Considering second codeword CQI info
16485                incase of MIMO for CQI Reporting */
16486             *is2ndCwCqiAvail = TRUE;
16487 #endif
16488          }
16489          else
16490          {
16491             return;
16492          }
16493          ue->mimoInfo.puschFdbkVld  = TRUE;
16494          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_12;
16495          ue->mimoInfo.puschPmiInfo.u.mode12Info = puschCqi->u.mode12Info;
16496          /*  : resetting this is time based. Make use of CQI reporting
16497           * periodicity, DELTA's in determining the exact time at which this
16498           * need to be reset. */
16499          break;
16500       case TFU_PUSCH_CQI_MODE_22:
16501          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16502          if((puschCqi->u.mode22Info.wideBandCqi[0]) &&
16503                (puschCqi->u.mode22Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
16504          {
16505             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode22Info.wideBandCqi[0];
16506             /* ccpu00117452 - MOD - Changed macro name from
16507                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16508 #ifdef RGR_CQI_REPT
16509             *isCqiAvail = TRUE;
16510 #endif
16511          }
16512          else
16513          {
16514             return;
16515          }
16516          if((puschCqi->u.mode22Info.wideBandCqi[1]) &&
16517                (puschCqi->u.mode22Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
16518          {
16519             ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode22Info.wideBandCqi[1];
16520             /* ccpu00117452 - MOD - Changed macro name from
16521                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16522 #ifdef RGR_CQI_REPT
16523             /* ccpu00117259 - ADD - Considering second codeword CQI info
16524                incase of MIMO for CQI Reporting */
16525             *is2ndCwCqiAvail = TRUE;
16526 #endif
16527          }
16528          else
16529          {
16530             return;
16531          }
16532          rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode22Info.wideBandPmi);
16533          ue->mimoInfo.puschFdbkVld  = TRUE;
16534          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_22;
16535          ue->mimoInfo.puschPmiInfo.u.mode22Info = puschCqi->u.mode22Info;
16536          break;
16537       case TFU_PUSCH_CQI_MODE_31:
16538          /*ccpu00109787 - ADD - Check for non-zero CQI*/
16539          if((puschCqi->u.mode31Info.wideBandCqi[0]) &&
16540                (puschCqi->u.mode31Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI))
16541          {
16542             ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode31Info.wideBandCqi[0];
16543             /* ccpu00117452 - MOD - Changed macro name from
16544                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16545 #ifdef RGR_CQI_REPT
16546             *isCqiAvail = TRUE;
16547 #endif
16548          }
16549          if (ueDl->mimoInfo.ri > 1)
16550          {
16551            if((puschCqi->u.mode31Info.wideBandCqi[1]) &&
16552                (puschCqi->u.mode31Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI))
16553            {
16554              ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode31Info.wideBandCqi[1];
16555             /* ccpu00117452 - MOD - Changed macro name from
16556                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16557 #ifdef RGR_CQI_REPT
16558             /* ccpu00117259 - ADD - Considering second codeword CQI info
16559                incase of MIMO for CQI Reporting */
16560              *is2ndCwCqiAvail = TRUE;
16561 #endif
16562            }
16563          }
16564          if (rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode31Info.pmi) != ROK)
16565          {
16566             /* To avoid Rank and PMI inconsistency */
16567             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
16568                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
16569             {
16570                ueDl->mimoInfo.ri = prevRiVal;
16571             }
16572          }
16573          ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_31;
16574          ue->mimoInfo.puschPmiInfo.u.mode31Info = puschCqi->u.mode31Info;
16575          break;
16576       default:
16577          {
16578             RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,  "Unknown CQI Mode %d CRNTI:%d",
16579                puschCqi->mode,ue->ueId);
16580             /*  CQI decoding failed revert the RI to previous value */
16581             if ((puschCqi->ri.pres == PRSNT_NODEF) &&
16582                 (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */
16583             {
16584                ueDl->mimoInfo.ri = prevRiVal;
16585             }
16586             /* ccpu00117452 - MOD - Changed macro name from
16587                RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16588 #ifdef RGR_CQI_REPT
16589            *isCqiAvail = FALSE;
16590             /* ccpu00117259 - ADD - Considering second codeword CQI info
16591                incase of MIMO for CQI Reporting */
16592             *is2ndCwCqiAvail = FALSE;
16593 #endif
16594          }
16595          break;
16596    }
16597
16598    return;
16599 }  /* rgSCHCmnDlCqiOnPuschInd */
16600
16601 \f
16602 /**
16603  * @brief This function Updates the DL CQI for the UE.
16604  *
16605  * @details
16606  *
16607  *     Function: rgSCHCmnDlCqiInd
16608  *     Purpose:  Updates the DL CQI for the UE
16609  *
16610  *     Invoked by: TOM
16611  *
16612  *  @param[in]  RgSchCellCb        *cell
16613  *  @param[in]  RgSchUeCb          *ue
16614  *  @param[in]  TfuDlCqiRpt        *dlCqi
16615  *  @return  Void
16616  *
16617  **/
16618 #ifdef ANSI
16619 Void rgSCHCmnDlCqiInd
16620 (
16621 RgSchCellCb        *cell,
16622 RgSchUeCb          *ue,
16623 Bool               isPucchInfo,
16624 Void               *dlCqi,
16625 CmLteTimingInfo    timingInfo
16626 )
16627 #else
16628 Void rgSCHCmnDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo)
16629 RgSchCellCb        *cell;
16630 RgSchUeCb          *ue;
16631 Bool               isPucchInfo;
16632 Void               *dlCqi;
16633 CmLteTimingInfo    timingInfo;
16634 #endif
16635 {
16636    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
16637 /* ccpu00117452 - MOD - Changed macro name from
16638    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16639 #ifdef RGR_CQI_REPT
16640    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16641    RgrUeCqiRept   ueCqiRept = {{0}};
16642    Bool           isCqiAvail = FALSE;
16643    /* ccpu00117259 - ADD - Considering second codeword CQI info
16644       incase of MIMO for CQI Reporting */
16645    Bool           is2ndCwCqiAvail = FALSE;
16646 #endif
16647
16648
16649 #ifdef RGR_CQI_REPT
16650    if (isPucchInfo)
16651    {
16652       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail);
16653    }
16654    else
16655    {
16656       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi, &ueCqiRept,  &isCqiAvail, &is2ndCwCqiAvail);
16657    }
16658 #else
16659    if (isPucchInfo)
16660    {
16661       rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi);
16662    }
16663    else
16664    {
16665       rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi);
16666    }
16667 #endif
16668
16669 #ifdef CQI_CONFBITMASK_DROP
16670    if(!ue->cqiConfBitMask)
16671    {
16672       if (ueDl->mimoInfo.cwInfo[0].cqi >15)
16673       {
16674          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
16675          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
16676       }
16677       else if ( ueDl->mimoInfo.cwInfo[0].cqi >= ue->prevCqi)
16678       {
16679          ue->prevCqi = ueDl->mimoInfo.cwInfo[0].cqi;
16680       }
16681       else
16682       {
16683          uint8_t dlCqiDeltaPrev = 0;
16684          dlCqiDeltaPrev = ue->prevCqi - ueDl->mimoInfo.cwInfo[0].cqi;
16685          if (dlCqiDeltaPrev > 3)
16686             dlCqiDeltaPrev = 3;
16687          if ((ue->prevCqi - dlCqiDeltaPrev) < 6)
16688          {
16689             ue->prevCqi = 6;
16690          }
16691          else 
16692          {
16693             ue->prevCqi = ue->prevCqi - dlCqiDeltaPrev;
16694          }
16695          ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi;
16696          ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi;
16697
16698       }
16699    }
16700 #endif
16701
16702 /* ccpu00117452 - MOD - Changed macro name from
16703    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
16704 #ifdef RGR_CQI_REPT
16705    /* ccpu00117259 - ADD - Considering second codeword CQI info
16706       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail\
16707       in 'if' condition*/
16708    if (RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(ue) && (isCqiAvail || is2ndCwCqiAvail))
16709    {
16710       ueCqiRept.cqi[0] = ueDl->mimoInfo.cwInfo[0].cqi;
16711
16712    /* ccpu00117259 - ADD - Considering second codeword CQI info
16713       incase of MIMO for CQI Reporting - added is2ndCwCqiAvail
16714       in 'if' condition*/
16715       ueCqiRept.cqi[1] = 0;
16716       if(is2ndCwCqiAvail)
16717       {
16718          ueCqiRept.cqi[1] = ueDl->mimoInfo.cwInfo[1].cqi;
16719       }
16720       rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, &ueCqiRept);
16721
16722    }
16723 #endif
16724 #ifdef DL_LA
16725    rgSCHCmnDlSetUeAllocLmtLa(cell, ue);
16726    rgSCHCheckAndSetTxScheme(cell, ue);
16727 #else
16728 #ifdef EMTC_ENABLE   
16729    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), ue->isEmtcUe);
16730 #else 
16731    rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), FALSE);
16732 #endif   
16733 #endif
16734
16735    if (cellSch->dl.isDlFreqSel)
16736    {
16737       cellSch->apisDlfs->rgSCHDlfsDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo);
16738    }
16739 #ifdef LTEMAC_SPS
16740    /* Call SPS module to update CQI indication */
16741    rgSCHCmnSpsDlCqiIndHndlr(cell, ue, timingInfo);
16742 #endif
16743    /* Call Specific scheduler to process on dlCqiInd */
16744 #ifdef EMTC_ENABLE
16745    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
16746    {
16747       cellSch->apisEmtcDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
16748    }
16749    else
16750 #endif
16751    {
16752       cellSch->apisDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi);
16753    }
16754
16755 #ifdef RG_PFS_STATS
16756    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].avgCqi += 
16757       ueDl->mimoInfo.cwInfo[0].cqi;
16758    ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].totalCqiOcc++; 
16759 #endif
16760
16761 #ifdef SCH_STATS
16762    ueDl->avgCqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16763    ueDl->numCqiOccns++;
16764    if (ueDl->mimoInfo.ri == 1)
16765    {
16766       ueDl->numRi1++;
16767    }
16768    else
16769    {
16770       ueDl->numRi2++;
16771    }
16772 #endif
16773
16774 #ifdef TENB_STATS
16775    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16776    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
16777    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw0Cqi ++;
16778    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw1Cqi ++;
16779    cell->tenbStats->sch.dlSumCw0Cqi +=  ueDl->mimoInfo.cwInfo[0].cqi;
16780    cell->tenbStats->sch.dlSumCw1Cqi +=  ueDl->mimoInfo.cwInfo[1].cqi;
16781    cell->tenbStats->sch.dlNumCw0Cqi ++;
16782    cell->tenbStats->sch.dlNumCw1Cqi ++;
16783 #endif
16784    return;
16785 }
16786
16787 #ifdef TFU_UPGRADE
16788 /**
16789  * @brief This function calculates the wideband CQI from SNR
16790  *            reported for each RB.
16791  *
16792  * @details
16793  *
16794  *     Function: rgSCHCmnCalcWcqiFrmSnr
16795  *     Purpose:  Wideband CQI calculation from SNR
16796  *
16797  *     Invoked by: RG SCH
16798  *
16799  *  @param[in]  RgSchCellCb        *cell
16800  *  @param[in]  TfuSrsRpt        *srsRpt,
16801  *  @return  Wideband CQI
16802  *
16803  **/
16804 #ifdef ANSI
16805 static uint8_t rgSCHCmnCalcWcqiFrmSnr
16806 (
16807  RgSchCellCb        *cell,
16808  TfuSrsRpt        *srsRpt
16809  )
16810 #else
16811 static uint8_t rgSCHCmnCalcWcqiFrmSnr(cell,srsRpt)
16812    RgSchCellCb        *cell;
16813    TfuSrsRpt            *srsRpt;
16814 #endif
16815 {
16816    uint8_t wideCqi=1; /*Calculated value from SNR*/
16817    /*Need to map a certain SNR with a WideCQI value.
16818     * The CQI calculation is still primitive. Further, need to
16819     * use a improvized method for calculating WideCQI from SNR*/
16820        if (srsRpt->snr[0] <=50)
16821        {
16822            wideCqi=3;
16823        }
16824        else if (srsRpt->snr[0]>=51 && srsRpt->snr[0] <=100)
16825        {
16826            wideCqi=6;
16827        }
16828        else if (srsRpt->snr[0]>=101 && srsRpt->snr[0] <=150)
16829        {
16830            wideCqi=9;
16831        }
16832        else if (srsRpt->snr[0]>=151 && srsRpt->snr[0] <=200)
16833        {
16834            wideCqi=12;
16835        }
16836        else if (srsRpt->snr[0]>=201 && srsRpt->snr[0] <=250)
16837        {
16838            wideCqi=14;
16839        }
16840        else
16841        {
16842            wideCqi=15;
16843        }
16844    return (wideCqi);
16845 }/*rgSCHCmnCalcWcqiFrmSnr*/
16846
16847
16848 /**
16849  * @brief This function Updates the SRS for the UE.
16850  *
16851  * @details
16852  *
16853  *     Function: rgSCHCmnSrsInd
16854  *     Purpose:  Updates the UL SRS for the UE
16855  *
16856  *     Invoked by: TOM
16857  *
16858  *  @param[in]  RgSchCellCb        *cell
16859  *  @param[in]  RgSchUeCb          *ue
16860  *  @param[in]  TfuSrsRpt        *srsRpt,
16861  *  @return  Void
16862  *
16863  **/
16864 #ifdef ANSI
16865 Void rgSCHCmnSrsInd
16866 (
16867  RgSchCellCb        *cell,
16868  RgSchUeCb          *ue,
16869  TfuSrsRpt        *srsRpt,
16870  CmLteTimingInfo    timingInfo
16871  )
16872 #else
16873 Void rgSCHCmnSrsInd(cell, ue, srsRpt, timingInfo)
16874     RgSchCellCb        *cell;
16875     RgSchUeCb          *ue;
16876     TfuSrsRpt            *srsRpt;
16877     CmLteTimingInfo    timingInfo;
16878 #endif
16879 {
16880     uint8_t wideCqi; /*Calculated value from SNR*/
16881     uint32_t recReqTime; /*Received Time in TTI*/
16882
16883     recReqTime = (timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + timingInfo.slot;
16884     ue->srsCb.selectedAnt = (recReqTime/ue->srsCb.peri)%2;
16885     if(srsRpt->wideCqiPres)
16886     {
16887         wideCqi = srsRpt->wideCqi;
16888     }
16889     else
16890     {
16891         wideCqi = rgSCHCmnCalcWcqiFrmSnr(cell, srsRpt);
16892     }
16893     rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi);
16894     return;
16895 }/*rgSCHCmnSrsInd*/
16896 #endif
16897
16898 \f
16899 /**
16900  * @brief This function is a handler for TA report for an UE.
16901  *
16902  * @details
16903  *
16904  *     Function: rgSCHCmnDlTARpt
16905  *     Purpose:  Determine based on UE_IDLE_TIME threshold,
16906  *     whether UE needs to be Linked to the scheduler's TA list OR
16907  *     if it needs a PDCCH Order.
16908  *
16909  *
16910  *     Invoked by: TOM
16911  *
16912  *  @param[in]  RgSchCellCb        *cell
16913  *  @param[in]  RgSchUeCb          *ue
16914  *  @return  Void
16915  *
16916  **/
16917 #ifdef ANSI
16918 Void rgSCHCmnDlTARpt
16919 (
16920 RgSchCellCb        *cell,
16921 RgSchUeCb          *ue
16922 )
16923 #else
16924 Void rgSCHCmnDlTARpt(cell, ue)
16925 RgSchCellCb        *cell;
16926 RgSchUeCb          *ue;
16927 #endif
16928 {
16929    RgSchCmnCell    *cellSch = RG_SCH_CMN_GET_CELL(cell);
16930    RgSchCmnDlCell  *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
16931    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
16932    CmLListCp       poInactvLst;
16933
16934
16935    /* RACHO: If UE idle time is more than threshold, then
16936     * set its poInactv pdcch order inactivity  */
16937    /* Fix : syed Ignore if TaTmr is not configured */
16938    if ((ue->dl.taCb.cfgTaTmr) && (rgSCHCmnUeIdleExdThrsld(cell, ue) == ROK))
16939    {
16940       uint32_t prevDlMsk = ue->dl.dlInactvMask;
16941       uint32_t prevUlMsk = ue->ul.ulInactvMask;
16942       ue->dl.dlInactvMask |= RG_PDCCHODR_INACTIVE;
16943       ue->ul.ulInactvMask |= RG_PDCCHODR_INACTIVE;
16944       /* Indicate Specific scheduler for this UEs inactivity */
16945       cmLListInit(&poInactvLst);
16946       cmLListAdd2Tail(&poInactvLst, &ueDl->rachInfo.inActUeLnk);
16947       ueDl->rachInfo.inActUeLnk.node = (PTR)ue;
16948       /* Send inactivate ind only if not already sent */
16949       if (prevDlMsk == 0)
16950       {
16951          cellSch->apisDl->rgSCHDlInactvtUes(cell, &poInactvLst);
16952       }
16953       if (prevUlMsk == 0)
16954       {
16955          cellSch->apisUl->rgSCHUlInactvtUes(cell, &poInactvLst);
16956       }
16957    }
16958    else
16959    {
16960       /* Fix: ccpu00124009 Fix for loop in the linked list "cellDl->taLst" */
16961       if (!ue->dlTaLnk.node)
16962       {
16963 #ifdef EMTC_ENABLE
16964          if(cell->emtcEnable)
16965          {
16966             if(ue->isEmtcUe)
16967             {
16968                rgSCHEmtcAddToTaLst(cellDl,ue);
16969             }
16970          }
16971          else
16972 #endif
16973          {
16974
16975             cmLListAdd2Tail(&cellDl->taLst, &ue->dlTaLnk);
16976             ue->dlTaLnk.node = (PTR)ue;
16977          }
16978       }
16979       else
16980       {
16981          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
16982                "<TA>TA duplicate entry attempt failed: UEID:%u", 
16983                ue->ueId);
16984       }
16985    }
16986    return;
16987 }
16988
16989 #ifdef TFU_UPGRADE
16990 /**
16991  * @brief Indication of UL CQI.
16992  *
16993  * @details
16994  *
16995  *     Function : rgSCHCmnFindUlCqiUlTxAnt
16996  *
16997  *     - Finds the Best Tx Antenna amongst the CQIs received
16998  *         from Two Tx Antennas.
16999  *
17000  *  @param[in]  RgSchCellCb         *cell
17001  *  @param[in]  RgSchUeCb           *ue
17002  *  @param[in]   uint8_t                 wideCqi
17003  *  @return  Void
17004  **/
17005 #ifdef ANSI
17006 static Void rgSCHCmnFindUlCqiUlTxAnt
17007 (
17008 RgSchCellCb     *cell,
17009 RgSchUeCb       *ue,
17010 uint8_t              wideCqi
17011 )
17012 #else
17013 static Void rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi)
17014 RgSchCellCb     *cell;
17015 RgSchUeCb       *ue;
17016 uint8_t              wideCqi;
17017 #endif
17018 {
17019    ue->validTxAnt = 1;
17020    return;
17021 }  /* rgSCHCmnFindUlCqiUlTxAnt */
17022 #endif
17023
17024 /**
17025  * @brief Indication of UL CQI.
17026  *
17027  * @details
17028  *
17029  *     Function : rgSCHCmnUlCqiInd
17030  *
17031  *     - Updates uplink CQI information for the UE. Computes and
17032  *       stores the lowest CQI of CQIs reported in all subbands.
17033  *
17034  *  @param[in]  RgSchCellCb         *cell
17035  *  @param[in]  RgSchUeCb           *ue
17036  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
17037  *  @return  Void
17038  **/
17039 #ifdef ANSI
17040 Void rgSCHCmnUlCqiInd
17041 (
17042 RgSchCellCb          *cell,
17043 RgSchUeCb            *ue,
17044 TfuUlCqiRpt          *ulCqiInfo
17045 )
17046 #else
17047 Void rgSCHCmnUlCqiInd(cell, ue, ulCqiInfo)
17048 RgSchCellCb          *cell;
17049 RgSchUeCb            *ue;
17050 TfuUlCqiRpt          *ulCqiInfo;
17051 #endif
17052 {
17053    RgSchCmnUlUe  *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17054    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
17055 #ifdef UL_LA
17056    uint8_t            iTbsNew;
17057    S32           previTbs;
17058 #endif
17059 #if (defined(SCH_STATS) || defined(TENB_STATS))
17060      CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
17061 #endif   
17062                   
17063    /*  consider inputs from SRS handlers about SRS occassions
17064     * in determining the UL TX Antenna selection */
17065    ueUl->crntUlCqi[0] = ulCqiInfo->wideCqi;
17066 #ifdef TFU_UPGRADE
17067    ueUl->validUlCqi = ueUl->crntUlCqi[0];
17068    ue->validTxAnt = 0;
17069 #ifdef UL_LA
17070    iTbsNew  =  rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][ueUl->validUlCqi];
17071    previTbs =  (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
17072
17073    if (RG_ITBS_DIFF(iTbsNew, previTbs) > 5)
17074    {
17075       /* Ignore this iTBS report and mark that last iTBS report was */
17076       /* ignored so that subsequently we reset the LA algorithm     */
17077       ueUl->ulLaCb.lastiTbsIgnored = TRUE;
17078    }
17079    else
17080    {
17081       if (ueUl->ulLaCb.lastiTbsIgnored != TRUE)
17082       {
17083          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
17084                                        (80 * ueUl->ulLaCb.cqiBasediTbs))/100;
17085       }
17086       else
17087       {
17088          /* Reset the LA as iTbs in use caught up with the value   */
17089          /* reported by UE.                                        */
17090          ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) +
17091                                         (80 * previTbs * 100))/100;
17092          ueUl->ulLaCb.deltaiTbs = 0;
17093          ueUl->ulLaCb.lastiTbsIgnored = FALSE;
17094       }
17095    }
17096 #endif 
17097 #endif
17098    rgSCHPwrUlCqiInd(cell, ue);
17099 #ifdef LTEMAC_SPS
17100    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
17101    {
17102       rgSCHCmnSpsUlCqiInd(cell, ue);
17103    }
17104 #endif
17105    /* Applicable to only some schedulers */
17106 #ifdef EMTC_ENABLE
17107    if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe))
17108    {
17109       cellSch->apisEmtcUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
17110    }
17111    else
17112 #endif
17113    {
17114       cellSch->apisUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
17115    }
17116
17117 #ifdef SCH_STATS
17118    ueUl->numCqiOccns++;
17119    ueUl->avgCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17120 #endif
17121
17122 #ifdef TENB_STATS
17123    {
17124       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17125       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNumCqi ++;
17126       cell->tenbStats->sch.ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg);
17127       cell->tenbStats->sch.ulNumCqi ++;
17128    }
17129 #endif
17130
17131    return;
17132 }  /* rgSCHCmnUlCqiInd */
17133
17134 /**
17135  * @brief Returns HARQ proc for which data expected now.
17136  *
17137  * @details
17138  *
17139  *     Function: rgSCHCmnUlHqProcForUe
17140  *     Purpose:  This function returns the harq process for
17141  *               which data is expected in the current subframe.
17142  *               It does not validate that the HARQ process
17143  *               has an allocation.
17144  *
17145  *     Invoked by: TOM
17146  *
17147  *  @param[in]  RgSchCellCb        *cell
17148  *  @param[in]  CmLteTimingInfo    frm
17149  *  @param[in]  RgSchUeCb          *ue
17150  *  @param[out] RgSchUlHqProcCb    **procRef
17151  *  @return  Void
17152  **/
17153 #ifdef ANSI
17154 Void rgSCHCmnUlHqProcForUe
17155 (
17156 RgSchCellCb         *cell,
17157 CmLteTimingInfo     frm,
17158 RgSchUeCb           *ue,
17159 RgSchUlHqProcCb     **procRef
17160 )
17161 #else
17162 Void rgSCHCmnUlHqProcForUe(cell, frm, ue, procRef)
17163 RgSchCellCb         *cell;
17164 CmLteTimingInfo     frm;
17165 RgSchUeCb           *ue;
17166 RgSchUlHqProcCb     **procRef;
17167 #endif
17168 {
17169 #ifndef RG_5GTF
17170    uint8_t procId = rgSCHCmnGetUlHqProcIdx(&frm, cell);
17171 #endif
17172 #ifndef RG_5GTF
17173    *procRef = rgSCHUhmGetUlHqProc(cell, ue, procId);
17174 #else
17175    *procRef = rgSCHUhmGetUlProcByTime(cell, ue, frm);
17176 #endif
17177    return;
17178 }
17179
17180 #ifdef RG_UNUSED
17181 /**
17182  * @brief Update harq process for allocation.
17183  *
17184  * @details
17185  *
17186  *     Function : rgSCHCmnUpdUlHqProc
17187  *
17188  *     This function is invoked when harq process
17189  *     control block is now in a new memory location
17190  *     thus requiring a pointer/reference update.
17191  *
17192  *  @param[in] RgSchCellCb      *cell
17193  *  @param[in] RgSchUlHqProcCb  *curProc
17194  *  @param[in] RgSchUlHqProcCb  *oldProc
17195  *  @return  S16
17196  *      -# ROK
17197  *      -# RFAILED
17198  **/
17199 #ifdef ANSI
17200 S16 rgSCHCmnUpdUlHqProc
17201 (
17202 RgSchCellCb      *cell,
17203 RgSchUlHqProcCb  *curProc,
17204 RgSchUlHqProcCb  *oldProc
17205 )
17206 #else
17207 S16 rgSCHCmnUpdUlHqProc(cell, curProc, oldProc)
17208 RgSchCellCb      *cell;
17209 RgSchUlHqProcCb  *curProc;
17210 RgSchUlHqProcCb  *oldProc;
17211 #endif
17212 {
17213
17214    UNUSED(cell);
17215    UNUSED(oldProc);
17216 #if (ERRCLASS & ERRCLS_DEBUG)
17217    if (curProc->alloc == NULLP)
17218    {
17219       return RFAILED;
17220    }
17221 #endif
17222    curProc->alloc->hqProc = curProc;
17223    return ROK;
17224 }  /* rgSCHCmnUpdUlHqProc */
17225 #endif
17226
17227 /*MS_WORKAROUND for CR FIXME */
17228 /**
17229  * @brief Hsndles BSR timer expiry
17230  *
17231  * @details
17232  *
17233  *     Function : rgSCHCmnBsrTmrExpry
17234  *
17235  *     This function is invoked when periodic BSR timer expires for a UE.
17236  *
17237  *  @param[in] RgSchUeCb        *ue
17238  *  @return  S16
17239  *      -# ROK
17240  *      -# RFAILED
17241  **/
17242 #ifdef ANSI
17243 S16 rgSCHCmnBsrTmrExpry
17244 (
17245 RgSchUeCb  *ueCb
17246 )
17247 #else
17248 S16 rgSCHCmnBsrTmrExpry(ueCb)
17249 RgSchUeCb  *ueCb;
17250 #endif
17251 {
17252    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ueCb->cell);
17253
17254
17255    ueCb->isSrGrant = TRUE;
17256
17257 #ifdef EMTC_ENABLE
17258    emtcStatsUlBsrTmrTxp++;
17259 #endif
17260
17261 #ifdef EMTC_ENABLE
17262    if(ueCb->cell->emtcEnable)
17263    {
17264       if(ueCb->isEmtcUe)
17265       {
17266          cellSch->apisEmtcUl->rgSCHSrRcvd(ueCb->cell, ueCb);
17267          return ROK;
17268       }
17269    }
17270    else
17271 #endif
17272    {
17273       cellSch->apisUl->rgSCHSrRcvd(ueCb->cell, ueCb);
17274    }
17275
17276    return  (ROK);
17277 }
17278
17279 /**
17280  * @brief Short BSR update.
17281  *
17282  * @details
17283  *
17284  *     Function : rgSCHCmnUpdBsrShort
17285  *
17286  *     This functions does requisite updates to handle short BSR reporting.
17287  *
17288  *  @param[in]  RgSchCellCb  *cell
17289  *  @param[in]  RgSchUeCb    *ue
17290  *  @param[in]  RgSchLcgCb *ulLcg
17291  *  @param[in]  uint8_t           bsr
17292  *  @param[out] RgSchErrInfo *err
17293  *  @return  S16
17294  *      -# ROK
17295  *      -# RFAILED
17296  **/
17297 #ifdef ANSI
17298 S16 rgSCHCmnUpdBsrShort
17299 (
17300 RgSchCellCb  *cell,
17301 RgSchUeCb    *ue,
17302 RgSchLcgCb *ulLcg,
17303 uint8_t           bsr,
17304 RgSchErrInfo *err
17305 )
17306 #else
17307 S16 rgSCHCmnUpdBsrShort(cell, ue, ulLcg, bsr, err)
17308 RgSchCellCb  *cell;
17309 RgSchUeCb    *ue;
17310 RgSchLcgCb *ulLcg;
17311 uint8_t           bsr;
17312 RgSchErrInfo *err;
17313 #endif
17314 {
17315    uint8_t  lcgCnt;
17316 #ifdef LTE_L2_MEAS
17317    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17318 #endif
17319    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17320    RgSchCmnLcg  *cmnLcg  = NULLP;
17321
17322 #ifdef LTE_L2_MEAS
17323    uint8_t             idx;
17324 #endif
17325
17326    if (!RGSCH_LCG_ISCFGD(ulLcg))
17327    {
17328       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
17329       return RFAILED;
17330    }
17331    for (lcgCnt=0; lcgCnt<4; lcgCnt++)
17332    {
17333 #ifdef LTE_L2_MEAS
17334       /* Set BS of all other LCGs to Zero.
17335          If Zero BSR is reported in Short BSR include this LCG too */
17336       if ((lcgCnt != ulLcg->lcgId) ||
17337             (!bsr && !ueUl->hqEnt.numBusyHqProcs))
17338       {
17339          /* If old BO is zero do nothing */
17340          if(((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs != 0)
17341          {
17342             for(idx = 0; idx < ue->ul.lcgArr[lcgCnt].numLch; idx++)
17343             {
17344                if((ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount) &&
17345                  (ue->ulActiveLCs & (1 << 
17346                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1))))
17347                {
17348           /* L2_COUNTER */
17349                  ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount--;
17350                  ue->ulActiveLCs &= ~(1 << 
17351                   (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1));
17352                }
17353             }
17354          }
17355       }
17356 #endif
17357       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgCnt]))
17358       {
17359          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs = 0;
17360          ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->reportedBs = 0;
17361       }
17362    }
17363
17364 #ifdef LTE_L2_MEAS
17365    if(ulLcg->lcgId && bsr && (((RgSchCmnLcg *)(ulLcg->sch))->bs == 0))
17366    {
17367       for(idx = 0; idx < ulLcg->numLch; idx++)
17368       {
17369           /* L2_COUNTER */
17370           if (!(ue->ulActiveLCs & (1 << (ulLcg->lcArray[idx]->qciCb->qci -1))))
17371           {
17372              ulLcg->lcArray[idx]->qciCb->ulUeCount++;
17373              ue->ulActiveLCs |= (1 << (ulLcg->lcArray[idx]->qciCb->qci -1));
17374           }
17375       }
17376    }
17377 #endif
17378    /* Resetting the nonGbrLcgBs info here */
17379    ue->ul.nonGbrLcgBs = 0;
17380    ue->ul.nonLcg0Bs = 0;
17381
17382    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
17383    
17384    if (TRUE == ue->ul.useExtBSRSizes)
17385    {
17386       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
17387    }
17388    else
17389    {
17390       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
17391    }
17392    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17393    {
17394       /* TBD check for effGbr != 0 */    
17395       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17396    }
17397    else if (0 == ulLcg->lcgId) 
17398    {
17399       /* This is added for handling LCG0 */
17400       cmnLcg->bs = cmnLcg->reportedBs;
17401    }
17402    else 
17403    {
17404       /* Update non GBR LCG's BS*/
17405       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
17406       cmnLcg->bs     = ue->ul.nonGbrLcgBs;
17407    }
17408    ue->ul.totalBsr = cmnLcg->bs;
17409
17410 #ifdef RGR_V1
17411    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (bsr == 0))
17412    {
17413       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
17414    }
17415 #endif
17416 #ifdef LTEMAC_SPS
17417    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
17418    {
17419       rgSCHCmnSpsBsrRpt(cell, ue, ulLcg);
17420    }
17421 #endif
17422    rgSCHCmnUpdUlCompEffBsr(ue);
17423
17424 #ifdef EMTC_ENABLE
17425    if(cell->emtcEnable)
17426    {
17427       if(ue->isEmtcUe)
17428       {
17429          cellSch->apisEmtcUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
17430          return ROK;
17431       }
17432    }
17433    else
17434 #endif
17435    {
17436    cellSch->apisUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr);
17437    }
17438
17439 #ifdef LTE_ADV
17440    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17441    {
17442       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
17443       {
17444 #ifndef PAL_ENABLE_UL_CA
17445          if((ue->cellInfo[sCellIdx] != NULLP) &&
17446                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
17447 #else
17448          if(ue->cellInfo[sCellIdx] != NULLP)
17449 #endif
17450          {
17451             cellSch->apisUl->rgSCHUpdBsrShort(ue->cellInfo[sCellIdx]->cell, 
17452                   ue, ulLcg, bsr);
17453          }
17454       }
17455    }
17456 #endif 
17457
17458    return ROK;
17459 }
17460
17461 /**
17462  * @brief Truncated BSR update.
17463  *
17464  * @details
17465  *
17466  *     Function : rgSCHCmnUpdBsrTrunc
17467  *
17468  *     This functions does required updates to handle truncated BSR report.
17469  *
17470  *
17471  *  @param[in]  RgSchCellCb  *cell
17472  *  @param[in]  RgSchUeCb    *ue
17473  *  @param[in]  RgSchLcgCb *ulLcg
17474  *  @param[in]  uint8_t           bsr
17475  *  @param[out] RgSchErrInfo *err
17476  *  @return  S16
17477  *      -# ROK
17478  *      -# RFAILED
17479  **/
17480 #ifdef ANSI
17481 S16 rgSCHCmnUpdBsrTrunc
17482 (
17483 RgSchCellCb  *cell,
17484 RgSchUeCb    *ue,
17485 RgSchLcgCb *ulLcg,
17486 uint8_t           bsr,
17487 RgSchErrInfo *err
17488 )
17489 #else
17490 S16 rgSCHCmnUpdBsrTrunc(cell, ue, ulLcg, bsr, err)
17491 RgSchCellCb  *cell;
17492 RgSchUeCb    *ue;
17493 RgSchLcgCb *ulLcg;
17494 uint8_t           bsr;
17495 RgSchErrInfo *err;
17496 #endif
17497 {
17498    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17499    RgSchCmnLcg  *cmnLcg = NULLP;
17500    S32          cnt;
17501 #ifdef LTE_L2_MEAS
17502    uint8_t     idx;
17503 #endif
17504
17505
17506    if (!RGSCH_LCG_ISCFGD(ulLcg))
17507    {
17508       err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD;
17509       return RFAILED;
17510    }
17511    /* set all higher prio lcgs bs to 0 and update this lcgs bs and
17512       total bsr= sumofall lcgs bs */
17513    if (ulLcg->lcgId)
17514    {
17515       for (cnt = ulLcg->lcgId-1; cnt >= 0; cnt--)
17516       {
17517 #ifdef LTE_L2_MEAS
17518          /* If Existing BO is zero the don't do anything */
17519          if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs != 0)
17520          {
17521             for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
17522             {
17523                /* L2_COUNTERS */
17524                if((ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount) &&
17525                      (ue->ulActiveLCs & (1 << 
17526                                          (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
17527                {
17528                   ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount--;
17529                   ue->ulActiveLCs &= ~(1 << 
17530                         (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
17531                }
17532             }
17533          }
17534 #endif
17535          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs = 0;
17536          ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->reportedBs = 0;
17537       }
17538    }
17539
17540 #ifdef LTE_L2_MEAS
17541    for (cnt = ulLcg->lcgId; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
17542    {
17543       if (ulLcg->lcgId == 0)
17544       {
17545          continue;
17546       }
17547       /* If Existing BO is zero the don't do anything */
17548       if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs == 0)
17549       {
17550          for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++)
17551          {
17552             /* L2_COUNTERS */
17553             if (!(ue->ulActiveLCs & (1 << 
17554                (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1))))
17555             {
17556                ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount++;
17557                ue->ulActiveLCs |= (1 << 
17558                      (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1));
17559             }
17560          }
17561       }
17562    }
17563 #endif
17564    ue->ul.nonGbrLcgBs = 0;
17565    ue->ul.nonLcg0Bs = 0;
17566    cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch));
17567    if (TRUE == ue->ul.useExtBSRSizes)
17568    {
17569       cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr];
17570    }
17571    else
17572    {
17573       cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr];
17574    }
17575    if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17576    {
17577       cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17578    }
17579    else if(ulLcg->lcgId == 0)
17580    {
17581       /* This is for handeling LCG0 */
17582       cmnLcg->bs = cmnLcg->reportedBs;
17583    }
17584    else
17585    {
17586       ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
17587       cmnLcg->bs = ue->ul.nonGbrLcgBs;
17588    }
17589    ue->ul.totalBsr = cmnLcg->bs;
17590
17591    for (cnt = ulLcg->lcgId+1; cnt < RGSCH_MAX_LCG_PER_UE; cnt++)
17592    {
17593       /* TODO: The bs for the other LCGs may be stale because some or all of
17594        * the part of bs may have been already scheduled/data received. Please 
17595        * consider this when truncated BSR is tested/implemented */
17596       ue->ul.totalBsr += ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs;
17597    }
17598
17599    rgSCHCmnUpdUlCompEffBsr(ue);
17600
17601 #ifdef EMTC_ENABLE
17602    if(cell->emtcEnable)
17603    {
17604       if(ue->isEmtcUe)
17605       {
17606          cellSch->apisEmtcUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
17607          return ROK;
17608       }
17609    }
17610    else
17611 #endif
17612    {
17613       cellSch->apisUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr);
17614    }
17615
17616 #ifdef LTE_ADV
17617    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17618    {
17619       for(uint8_t sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++)
17620       {
17621 #ifndef PAL_ENABLE_UL_CA
17622          if((ue->cellInfo[sCellIdx] != NULLP) &&
17623                (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE))
17624 #else
17625          if(ue->cellInfo[sCellIdx] != NULLP)
17626 #endif
17627          {
17628             cellSch->apisUl->rgSCHUpdBsrTrunc(ue->cellInfo[sCellIdx]->cell, ue, ulLcg, bsr);
17629          }
17630       }
17631    }
17632 #endif 
17633
17634    return ROK;
17635 }
17636
17637 /**
17638  * @brief Long BSR update.
17639  *
17640  * @details
17641  *
17642  *     Function : rgSCHCmnUpdBsrLong
17643  *
17644  *     - Update BSRs for all configured LCGs.
17645  *     - Update priority of LCGs if needed.
17646  *     - Update UE's position within/across uplink scheduling queues.
17647  *
17648  *
17649  *  @param[in]  RgSchCellCb  *cell
17650  *  @param[in]  RgSchUeCb    *ue
17651  *  @param[in]  uint8_t bsArr[]
17652  *  @param[out] RgSchErrInfo *err
17653  *  @return  S16
17654  *      -# ROK
17655  *      -# RFAILED
17656  **/
17657 #ifdef ANSI
17658 S16 rgSCHCmnUpdBsrLong
17659 (
17660 RgSchCellCb  *cell,
17661 RgSchUeCb    *ue,
17662 uint8_t           *bsArr,
17663 RgSchErrInfo *err
17664 )
17665 #else
17666 S16 rgSCHCmnUpdBsrLong(cell, ue, bsArr, err)
17667 RgSchCellCb  *cell;
17668 RgSchUeCb    *ue;
17669 uint8_t           *bsArr;
17670 RgSchErrInfo *err;
17671 #endif
17672 {
17673    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17674    uint32_t           tmpBsArr[4] = {0, 0, 0, 0};
17675    uint32_t           nonGbrBs = 0;
17676 #ifdef LTE_L2_MEAS
17677    uint8_t            idx1;
17678    uint8_t            idx2;
17679 #endif
17680    uint32_t           lcgId;
17681
17682
17683 #ifdef LTE_L2_MEAS
17684    for(idx1 = 1; idx1 < RGSCH_MAX_LCG_PER_UE; idx1++)
17685    {
17686      /* If Old BO is non zero then do nothing */
17687      if ((((RgSchCmnLcg *)(ue->ul.lcgArr[idx1].sch))->bs == 0)
17688         && bsArr[idx1] )
17689      {
17690        for(idx2 = 0; idx2 < ue->ul.lcgArr[idx1].numLch; idx2++)
17691        {
17692           /* L2_COUNTERS */
17693           if (!(ue->ulActiveLCs & (1 << 
17694              (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1))))
17695           {
17696              ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->ulUeCount++;
17697              ue->ulActiveLCs |= (1 << 
17698                (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1));
17699           }
17700        }
17701      }
17702    }
17703 #endif
17704    ue->ul.nonGbrLcgBs = 0;
17705    ue->ul.nonLcg0Bs = 0;
17706
17707    if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[0]))
17708    {
17709       if (TRUE == ue->ul.useExtBSRSizes)
17710       {
17711          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnExtBsrTbl[bsArr[0]];
17712          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnExtBsrTbl[bsArr[0]];
17713          tmpBsArr[0] = rgSchCmnExtBsrTbl[bsArr[0]];
17714       }
17715       else
17716       {
17717          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnBsrTbl[bsArr[0]];
17718          ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnBsrTbl[bsArr[0]];
17719          tmpBsArr[0] = rgSchCmnBsrTbl[bsArr[0]];
17720       }
17721    }
17722    for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
17723    {
17724       if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
17725       {
17726          RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
17727
17728          if (TRUE == ue->ul.useExtBSRSizes)
17729          {
17730             cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsArr[lcgId]];
17731          }
17732          else
17733          {
17734             cmnLcg->reportedBs = rgSchCmnBsrTbl[bsArr[lcgId]];
17735          }
17736          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
17737          {
17738             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr);
17739             tmpBsArr[lcgId] = cmnLcg->bs;
17740          }
17741          else
17742          {
17743             nonGbrBs += cmnLcg->reportedBs;
17744             tmpBsArr[lcgId] = cmnLcg->reportedBs;
17745             cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr);
17746          }
17747       }
17748    }
17749    ue->ul.nonGbrLcgBs = RGSCH_MIN(nonGbrBs,ue->ul.effAmbr);
17750
17751    ue->ul.totalBsr = tmpBsArr[0] + tmpBsArr[1] + tmpBsArr[2] + tmpBsArr[3];
17752 #ifdef RGR_V1
17753    if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (ue->ul.totalBsr == 0))
17754    {
17755       rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
17756    }
17757 #endif
17758
17759 #ifdef LTEMAC_SPS
17760    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) /* SPS_FIX */
17761    {
17762      if(ue->ul.totalBsr - tmpBsArr[1] == 0)
17763      {/* Updaing the BSR to SPS only if LCG1 BS is present in sps active state */
17764         rgSCHCmnSpsBsrRpt(cell, ue, &ue->ul.lcgArr[1]);
17765      }
17766    }
17767 #endif
17768    rgSCHCmnUpdUlCompEffBsr(ue);
17769
17770 #ifdef EMTC_ENABLE
17771    if(cell->emtcEnable)
17772    {
17773       if(ue->isEmtcUe)
17774       {
17775          cellSch->apisEmtcUl->rgSCHUpdBsrLong(cell, ue, bsArr);
17776          return ROK;
17777       }
17778    }
17779    else
17780 #endif
17781    {
17782    cellSch->apisUl->rgSCHUpdBsrLong(cell, ue, bsArr);
17783    }
17784
17785 #ifdef LTE_ADV
17786    if (ue->ul.isUlCaEnabled  && ue->numSCells)
17787    {
17788       for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
17789       {
17790 #ifndef PAL_ENABLE_UL_CA
17791          if((ue->cellInfo[idx] != NULLP) &&
17792                (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE))
17793 #else
17794          if(ue->cellInfo[idx] != NULLP)
17795 #endif
17796          {
17797             cellSch->apisUl->rgSCHUpdBsrLong(ue->cellInfo[idx]->cell, ue, bsArr);
17798          }
17799       }
17800    }
17801 #endif 
17802
17803    return ROK;
17804 }
17805
17806 /**
17807  * @brief PHR update.
17808  *
17809  * @details
17810  *
17811  *     Function : rgSCHCmnUpdExtPhr
17812  *
17813  *     Updates extended power headroom information for an UE.
17814  *
17815  *  @param[in]  RgSchCellCb  *cell
17816  *  @param[in]  RgSchUeCb    *ue
17817  *  @param[in]  uint8_t           phr
17818  *  @param[out] RgSchErrInfo *err
17819  *  @return  S16
17820  *      -# ROK
17821  *      -# RFAILED
17822  **/
17823 #ifdef ANSI
17824 S16 rgSCHCmnUpdExtPhr
17825 (
17826 RgSchCellCb    *cell,
17827 RgSchUeCb      *ue,
17828 RgInfExtPhrCEInfo *extPhr,
17829 RgSchErrInfo   *err
17830 )
17831 #else
17832 S16 rgSCHCmnUpdExtPhr(cell, ue, extPhr, err)
17833 RgSchCellCb    *cell;
17834 RgSchUeCb      *ue;
17835 RgInfExtPhrCEInfo *extPhr;
17836 RgSchErrInfo   *err;
17837 #endif
17838 {
17839    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17840    RgSchCmnAllocRecord *allRcd;
17841    CmLList             *node = ueUl->ulAllocLst.last;
17842
17843 #ifdef LTEMAC_SPS
17844    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
17845 #endif
17846
17847    UNUSED(err);
17848
17849    while (node)
17850    {
17851       allRcd = (RgSchCmnAllocRecord *)node->node;
17852       node = node->prev;
17853       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
17854       {
17855          rgSCHPwrUpdExtPhr(cell, ue, extPhr, allRcd);
17856          break;
17857       }
17858    }
17859 #ifdef LTEMAC_SPS
17860    if(ulSpsUe->isUlSpsActv)
17861    {
17862       rgSCHCmnSpsPhrInd(cell,ue);
17863    }
17864 #endif
17865
17866    return ROK;
17867 }  /* rgSCHCmnUpdExtPhr */
17868
17869
17870
17871
17872 /**
17873  * @brief PHR update.
17874  *
17875  * @details
17876  *
17877  *     Function : rgSCHCmnUpdPhr
17878  *
17879  *     Updates power headroom information for an UE.
17880  *
17881  *  @param[in]  RgSchCellCb  *cell
17882  *  @param[in]  RgSchUeCb    *ue
17883  *  @param[in]  uint8_t           phr
17884  *  @param[out] RgSchErrInfo *err
17885  *  @return  S16
17886  *      -# ROK
17887  *      -# RFAILED
17888  **/
17889 #ifdef ANSI
17890 S16 rgSCHCmnUpdPhr
17891 (
17892 RgSchCellCb    *cell,
17893 RgSchUeCb      *ue,
17894 uint8_t             phr,
17895 RgSchErrInfo   *err
17896 )
17897 #else
17898 S16 rgSCHCmnUpdPhr(cell, ue, phr, err)
17899 RgSchCellCb    *cell;
17900 RgSchUeCb      *ue;
17901 uint8_t             phr;
17902 RgSchErrInfo   *err;
17903 #endif
17904 {
17905    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
17906    RgSchCmnAllocRecord *allRcd;
17907    CmLList             *node = ueUl->ulAllocLst.last;
17908
17909 #ifdef LTEMAC_SPS
17910    RgSchCmnUlUeSpsInfo   *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell);
17911 #endif
17912
17913    UNUSED(err);
17914
17915    while (node)
17916    {
17917       allRcd = (RgSchCmnAllocRecord *)node->node;
17918       node = node->prev;
17919       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
17920       {
17921          rgSCHPwrUpdPhr(cell, ue, phr, allRcd, RG_SCH_CMN_PWR_USE_CFG_MAX_PWR);
17922          break;
17923       }
17924    }
17925 #ifdef LTEMAC_SPS
17926    if(ulSpsUe->isUlSpsActv)
17927    {
17928       rgSCHCmnSpsPhrInd(cell,ue);
17929    }
17930 #endif
17931
17932    return ROK;
17933 }  /* rgSCHCmnUpdPhr */
17934
17935 /**
17936  * @brief UL grant for contention resolution.
17937  *
17938  * @details
17939  *
17940  *     Function : rgSCHCmnContResUlGrant
17941  *
17942  *     Add UE to another queue specifically for CRNTI based contention
17943  *     resolution.
17944  *
17945  *
17946  *  @param[in]  RgSchUeCb    *ue
17947  *  @param[out] RgSchErrInfo *err
17948  *  @return  S16
17949  *      -# ROK
17950  *      -# RFAILED
17951  **/
17952 #ifdef ANSI
17953 S16 rgSCHCmnContResUlGrant
17954 (
17955 RgSchCellCb  *cell,
17956 RgSchUeCb    *ue,
17957 RgSchErrInfo *err
17958 )
17959 #else
17960 S16 rgSCHCmnContResUlGrant(cell, ue, err)
17961 RgSchCellCb  *cell;
17962 RgSchUeCb    *ue;
17963 RgSchErrInfo *err;
17964 #endif
17965 {
17966    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
17967
17968    #ifdef EMTC_ENABLE
17969    if(cell->emtcEnable)
17970    {
17971       if(ue->isEmtcUe)
17972       {
17973          cellSch->apisEmtcUl->rgSCHContResUlGrant(cell, ue);
17974          return ROK;
17975       }
17976    }
17977    else
17978 #endif
17979    {
17980       cellSch->apisUl->rgSCHContResUlGrant(cell, ue);
17981    }
17982    return ROK;
17983 }
17984
17985 /**
17986  * @brief SR reception handling.
17987  *
17988  * @details
17989  *
17990  *     Function : rgSCHCmnSrRcvd
17991  *
17992  *     - Update UE's position within/across uplink scheduling queues
17993  *     - Update priority of LCGs if needed.
17994  *
17995  *  @param[in]  RgSchCellCb  *cell
17996  *  @param[in]  RgSchUeCb    *ue
17997  *  @param[in]  CmLteTimingInfo frm
17998  *  @param[out] RgSchErrInfo *err
17999  *  @return  S16
18000  *      -# ROK
18001  *      -# RFAILED
18002  **/
18003 #ifdef ANSI
18004 S16 rgSCHCmnSrRcvd
18005 (
18006 RgSchCellCb  *cell,
18007 RgSchUeCb    *ue,
18008 CmLteTimingInfo frm,
18009 RgSchErrInfo *err
18010 )
18011 #else
18012 S16 rgSCHCmnSrRcvd(cell, ue, frm, err)
18013 RgSchCellCb  *cell;
18014 RgSchUeCb    *ue;
18015 CmLteTimingInfo frm;
18016 RgSchErrInfo *err;
18017 #endif
18018 {
18019    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
18020    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18021    CmLList      *node    = ueUl->ulAllocLst.last;
18022
18023
18024 #ifdef EMTC_ENABLE
18025    emtcStatsUlTomSrInd++;
18026 #endif
18027
18028    RGSCH_INCR_SUB_FRAME(frm, 1); /* 1 TTI after the time SR was sent */
18029    while (node)
18030    {
18031       RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)node->node;
18032       if (RGSCH_TIMEINFO_SAME(frm, allRcd->allocTime))
18033       {
18034          break;
18035       }
18036       node = node->prev;
18037    }
18038    //TODO_SID Need to check when it is getting triggered
18039    ue->isSrGrant = TRUE;
18040 #ifdef EMTC_ENABLE
18041    if(cell->emtcEnable)
18042    {
18043       if(ue->isEmtcUe)
18044       {
18045          cellSch->apisEmtcUl->rgSCHSrRcvd(cell, ue);
18046          return ROK;
18047       }
18048    }
18049    else
18050 #endif
18051    {
18052       cellSch->apisUl->rgSCHSrRcvd(cell, ue);
18053    }
18054    return ROK;
18055 }
18056
18057 /**
18058  * @brief Returns first uplink allocation to send reception
18059  *        request to PHY.
18060  *
18061  * @details
18062  *
18063  *     Function: rgSCHCmnFirstRcptnReq(cell)
18064  *     Purpose:  This function returns the first uplink allocation
18065  *               (or NULLP if there is none) in the subframe
18066  *               in which is expected to prepare and send reception
18067  *               request to PHY.
18068  *
18069  *     Invoked by: TOM
18070  *
18071  *  @param[in]  RgSchCellCb      *cell
18072  *  @return  RgSchUlAlloc*
18073  **/
18074 #ifdef ANSI
18075 RgSchUlAlloc *rgSCHCmnFirstRcptnReq
18076 (
18077 RgSchCellCb      *cell
18078 )
18079 #else
18080 RgSchUlAlloc *rgSCHCmnFirstRcptnReq(cell)
18081 RgSchCellCb      *cell;
18082 #endif
18083 {
18084    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18085 /* ACC_TDD */
18086    RgSchUlAlloc* alloc = NULLP;
18087
18088
18089    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
18090    {
18091            RgSchUlSf* sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18092            alloc = rgSCHUtlUlAllocFirst(sf);
18093
18094            if (alloc && alloc->hqProc == NULLP)
18095            {
18096                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18097            }
18098    }
18099
18100    return (alloc);
18101 }
18102
18103 /**
18104  * @brief Returns first uplink allocation to send reception
18105  *        request to PHY.
18106  *
18107  * @details
18108  *
18109  *     Function: rgSCHCmnNextRcptnReq(cell)
18110  *     Purpose:  This function returns the next uplink allocation
18111  *               (or NULLP if there is none) in the subframe
18112  *               in which is expected to prepare and send reception
18113  *               request to PHY.
18114  *
18115  *     Invoked by: TOM
18116  *
18117  *  @param[in]  RgSchCellCb      *cell
18118  *  @return  RgSchUlAlloc*
18119  **/
18120 #ifdef ANSI
18121 RgSchUlAlloc *rgSCHCmnNextRcptnReq
18122 (
18123 RgSchCellCb      *cell,
18124 RgSchUlAlloc     *alloc
18125 )
18126 #else
18127 RgSchUlAlloc *rgSCHCmnNextRcptnReq(cell, alloc)
18128 RgSchCellCb      *cell;
18129 RgSchUlAlloc     *alloc;
18130 #endif
18131 {
18132    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18133 /* ACC-TDD */
18134    //RgSchUlSf      *sf   = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18135
18136 /* ACC-TDD */
18137    if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO)
18138    {
18139            RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx];
18140
18141            alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18142            if (alloc && alloc->hqProc == NULLP)
18143            {
18144                    alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18145            }
18146    }
18147    else
18148    {
18149            alloc = NULLP;
18150    }
18151
18152    return (alloc);
18153 }
18154 /**
18155  * @brief Collates DRX enabled UE's scheduled in this SF
18156  *
18157  * @details
18158  *
18159  *     Function: rgSCHCmnDrxStrtInActvTmrInUl(cell)
18160  *     Purpose:  This function collates the link
18161  *               of UE's scheduled in this SF who
18162  *               have drx enabled. It then calls
18163  *               DRX specific function to start/restart
18164  *               inactivity timer in Ul
18165  *
18166  *     Invoked by: TOM
18167  *
18168  *  @param[in]  RgSchCellCb      *cell
18169  *  @return Void
18170  **/
18171 #ifdef ANSI
18172 Void rgSCHCmnDrxStrtInActvTmrInUl
18173 (
18174 RgSchCellCb      *cell
18175 )
18176 #else
18177 Void rgSCHCmnDrxStrtInActvTmrInUl(cell)
18178 RgSchCellCb      *cell;
18179 #endif
18180 {
18181    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18182    RgSchUlSf      *sf     = &(cellUl->ulSfArr[cellUl->schdIdx]);
18183    RgSchUlAlloc   *alloc  = rgSCHUtlUlAllocFirst(sf);
18184    CmLListCp       ulUeLst;
18185    RgSchUeCb       *ueCb;
18186
18187
18188    cmLListInit(&ulUeLst);
18189
18190    while(alloc)
18191    {
18192       ueCb = alloc->ue;
18193
18194       if (ueCb)
18195       {
18196          if (!(alloc->grnt.isRtx) && ueCb->isDrxEnabled && !(ueCb->isSrGrant)
18197 #ifdef LTEMAC_SPS
18198              /* ccpu00139513- DRX inactivity timer should not be started for 
18199               * UL SPS occasions */
18200              && (alloc->hqProc->isSpsOccnHqP == FALSE) 
18201 #endif
18202              )
18203          {
18204             cmLListAdd2Tail(&ulUeLst,&(ueCb->ulDrxInactvTmrLnk));
18205             ueCb->ulDrxInactvTmrLnk.node = (PTR)ueCb;
18206          }
18207       }
18208
18209       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18210    }/*while(alloc)*/
18211
18212    (Void)rgSCHDrxStrtInActvTmr(cell,&ulUeLst,RG_SCH_DRX_UL);
18213
18214    return;
18215 }
18216
18217
18218 /**
18219  * @brief Returns first uplink allocation to send HARQ feedback
18220  *        request to PHY.
18221  *
18222  * @details
18223  *
18224  *     Function: rgSCHCmnFirstHqFdbkAlloc
18225  *     Purpose:  This function returns the first uplink allocation
18226  *               (or NULLP if there is none) in the subframe
18227  *               for which it is expected to prepare and send HARQ
18228  *               feedback to PHY.
18229  *
18230  *     Invoked by: TOM
18231  *
18232  *  @param[in]  RgSchCellCb      *cell
18233  *  @param[in]  uint8_t               idx
18234  *  @return  RgSchUlAlloc*
18235  **/
18236 #ifdef ANSI
18237 RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc
18238 (
18239 RgSchCellCb      *cell,
18240 uint8_t               idx 
18241 )
18242 #else
18243 RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc(cell, idx)
18244 RgSchCellCb      *cell;
18245 uint8_t               idx;
18246 #endif
18247 {
18248    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18249 /* ACC-TDD */
18250    RgSchUlAlloc  *alloc = NULLP;
18251
18252
18253    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
18254    {
18255           RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
18256           alloc    = rgSCHUtlUlAllocFirst(sf);
18257
18258           while (alloc && (alloc->hqProc == NULLP))
18259           {
18260                   alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18261           }
18262    }
18263
18264    return (alloc);
18265 }
18266
18267 /**
18268  * @brief Returns next allocation to send HARQ feedback for.
18269  *
18270  * @details
18271  *
18272  *     Function: rgSCHCmnNextHqFdbkAlloc(cell)
18273  *     Purpose:  This function returns the next uplink allocation
18274  *               (or NULLP if there is none) in the subframe
18275  *               for which HARQ feedback needs to be sent.
18276  *
18277  *     Invoked by: TOM
18278  *
18279  *  @param[in]  RgSchCellCb      *cell
18280  *  @return  RgSchUlAlloc*
18281  **/
18282 #ifdef ANSI
18283 RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc
18284 (
18285 RgSchCellCb      *cell,
18286 RgSchUlAlloc     *alloc,
18287 uint8_t               idx 
18288 )
18289 #else
18290 RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc(cell, alloc, idx)
18291 RgSchCellCb      *cell;
18292 RgSchUlAlloc     *alloc;
18293 uint8_t               idx; 
18294 #endif
18295 {
18296    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18297
18298    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
18299    {
18300       RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
18301
18302       alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18303       while (alloc && (alloc->hqProc == NULLP))
18304       {
18305          alloc = rgSCHUtlUlAllocNxt(sf, alloc);
18306       }
18307    }
18308    else
18309    {
18310           alloc = NULLP;
18311    }
18312    return (alloc);
18313 }
18314
18315 /***********************************************************
18316  *
18317  *     Func : rgSCHCmnUlGetITbsFrmIMcs
18318  *
18319  *     Desc : Returns the Itbs that is mapped to an Imcs
18320  *            for the case of uplink.
18321  *
18322  *     Ret  :
18323  *
18324  *     Notes:
18325  *
18326  *     File :
18327  *
18328  **********************************************************/
18329 #ifdef ANSI
18330 uint8_t rgSCHCmnUlGetITbsFrmIMcs
18331 (
18332 uint8_t          iMcs
18333 )
18334 #else
18335 uint8_t rgSCHCmnUlGetITbsFrmIMcs(iMcs)
18336 uint8_t          iMcs;
18337 #endif
18338 {
18339
18340    return (rgUlIMcsTbl[iMcs].iTbs);
18341 }
18342
18343 /***********************************************************
18344  *
18345  *     Func : rgSCHCmnUlGetIMcsFrmITbs
18346  *
18347  *     Desc : Returns the Imcs that is mapped to an Itbs
18348  *            for the case of uplink.
18349  *
18350  *     Ret  :
18351  *
18352  *     Notes: For iTbs 19, iMcs is dependant on modulation order.
18353  *            Refer to 36.213, Table 8.6.1-1 and 36.306 Table 4.1-2
18354  *            for UE capability information
18355  *
18356  *     File :
18357  *
18358  **********************************************************/
18359 #ifdef ANSI
18360 uint8_t rgSCHCmnUlGetIMcsFrmITbs
18361 (
18362 uint8_t                iTbs,
18363 CmLteUeCategory   ueCtg
18364 )
18365 #else
18366 uint8_t rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg)
18367 uint8_t                iTbs;
18368 CmLteUeCategory   ueCtg;
18369 #endif
18370 {
18371    uint8_t iMcs;
18372
18373    if (iTbs <= 10)
18374    {
18375       iMcs = iTbs;
18376    }
18377    /*a higher layer can force a 64QAM UE to transmit at 16QAM.
18378     * We currently do not support this. Once the support for such
18379     * is added, ueCtg should be replaced by current transmit
18380     * modulation configuration.Refer to 36.213 -8.6.1
18381     */
18382    else if ( iTbs < 19 )
18383    {
18384       iMcs = iTbs + 1;
18385    }
18386    else if ((iTbs == 19) && (ueCtg != CM_LTE_UE_CAT_5))
18387    {
18388       iMcs = iTbs + 1;
18389    }
18390    else
18391    {
18392       iMcs = iTbs + 2;
18393    }
18394
18395 #ifdef LTE_TDD
18396    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
18397       was seen when IMCS exceeds 20  on T2k TDD*/
18398    if (iMcs > 20)
18399    {
18400       iMcs = 20;
18401    }
18402 #endif
18403
18404    return (iMcs);
18405 }
18406
18407 /***********************************************************
18408  *
18409  *     Func : rgSCHCmnUlMinTbBitsForITbs
18410  *
18411  *     Desc : Returns the minimum number of bits that can
18412  *            be given as grant for a specific CQI.
18413  *
18414  *     Ret  :
18415  *
18416  *     Notes:
18417  *
18418  *     File :
18419  *
18420  **********************************************************/
18421 #ifdef ANSI
18422 uint32_t rgSCHCmnUlMinTbBitsForITbs
18423 (
18424 RgSchCmnUlCell     *cellUl,
18425 uint8_t                 iTbs
18426 )
18427 #else
18428 uint32_t rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs)
18429 RgSchCmnUlCell   *cellUl;
18430 uint8_t               iTbs;
18431 #endif
18432 {
18433
18434    RGSCH_ARRAY_BOUND_CHECK(0, rgTbSzTbl[0], iTbs); 
18435
18436    return (rgTbSzTbl[0][iTbs][cellUl->sbSize-1]);
18437 }
18438
18439 /***********************************************************
18440  *
18441  *     Func : rgSCHCmnUlSbAlloc
18442  *
18443  *     Desc : Given a required 'number of subbands' and a hole,
18444  *            returns a suitable alloc such that the subband
18445  *            allocation size is valid
18446  *
18447  *     Ret  :
18448  *
18449  *     Notes: Does not assume either passed numSb or hole size
18450  *            to be valid for allocation, and hence arrives at
18451  *            an acceptable value.
18452  *     File :
18453  *
18454  **********************************************************/
18455 #ifdef ANSI
18456 RgSchUlAlloc *rgSCHCmnUlSbAlloc
18457 (
18458 RgSchUlSf       *sf,
18459 uint8_t              numSb,
18460 RgSchUlHole     *hole
18461 )
18462 #else
18463 RgSchUlAlloc *rgSCHCmnUlSbAlloc(sf, numSb, hole)
18464 RgSchUlSf       *sf;
18465 uint8_t              numSb;
18466 RgSchUlHole     *hole;
18467 #endif
18468 {
18469    uint8_t           holeSz; /* valid hole size */
18470    RgSchUlAlloc *alloc;
18471
18472    if ((holeSz = rgSchCmnMult235Tbl[hole->num].prvMatch) == hole->num)
18473    {
18474       numSb = rgSchCmnMult235Tbl[numSb].match;
18475       if (numSb >= holeSz)
18476       {
18477          alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
18478       }
18479       else
18480       {
18481          alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
18482       }
18483    }
18484    else
18485    {
18486       if (numSb < holeSz)
18487       {
18488          numSb = rgSchCmnMult235Tbl[numSb].match;
18489       }
18490       else
18491       {
18492          numSb = rgSchCmnMult235Tbl[numSb].prvMatch;
18493       }
18494
18495       if ( numSb >= holeSz )
18496       {
18497          numSb = holeSz;
18498       }
18499       alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
18500    }
18501    return (alloc);
18502 }
18503
18504 /**
18505  * @brief To fill the RgSchCmnUeUlAlloc structure of UeCb.
18506  *
18507  * @details
18508  *
18509  *     Function: rgSCHCmnUlUeFillAllocInfo
18510  *     Purpose:  Specific scheduler to call this API to fill the alloc
18511  *               information.
18512  *
18513  *     Invoked by: Scheduler
18514  *
18515  *  @param[in]  RgSchCellCb      *cell
18516  *  @param[out] RgSchUeCb        *ue
18517  *  @return   Void
18518  **/
18519 #ifdef ANSI
18520 Void rgSCHCmnUlUeFillAllocInfo
18521 (
18522 RgSchCellCb      *cell,
18523 RgSchUeCb        *ue
18524 )
18525 #else
18526 Void rgSCHCmnUlUeFillAllocInfo(cell, ue)
18527 RgSchCellCb      *cell;
18528 RgSchUeCb        *ue;
18529 #endif
18530 {
18531    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18532    RgSchCmnUeUlAlloc  *ulAllocInfo;
18533    RgSchCmnUlUe       *ueUl;
18534
18535
18536    ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18537    ulAllocInfo = &ueUl->alloc;
18538
18539    /* Fill alloc structure */
18540    rgSCHCmnUlAllocFillTpc(cell, ue, ulAllocInfo->alloc);
18541    rgSCHCmnUlAllocFillNdmrs(cellUl, ulAllocInfo->alloc);
18542    rgSCHCmnUlAllocLnkHqProc(ue, ulAllocInfo->alloc, ulAllocInfo->alloc->hqProc,
18543                      ulAllocInfo->alloc->hqProc->isRetx);
18544    /* Fill PDCCH */
18545    rgSCHCmnUlFillPdcchWithAlloc(ulAllocInfo->alloc->pdcch,
18546          ulAllocInfo->alloc, ue);
18547    /* Recording information about this allocation */
18548    rgSCHCmnUlRecordUeAlloc(cell, ue);
18549
18550    /* Update the UE's outstanding allocation */
18551    if (!ulAllocInfo->alloc->hqProc->isRetx)
18552    {
18553       rgSCHCmnUlUpdOutStndAlloc(cell, ue, ulAllocInfo->allocdBytes);
18554    }
18555
18556    return;
18557 }
18558
18559 /**
18560  * @brief Update the UEs outstanding alloc based on the BSR report's timing.
18561  *
18562  *
18563  * @details
18564  *
18565  *     Function: rgSCHCmnUpdUlCompEffBsr
18566  *     Purpose:  Clear off all the allocations from outstanding allocation that
18567  *     are later than or equal to BSR timing information (stored in UEs datIndTime).
18568  *
18569  *     Invoked by: Scheduler
18570  *
18571  *  @param[in]  RgSchUeCb *ue
18572  *  @return  Void
18573  **/
18574 #ifdef ANSI
18575 static Void rgSCHCmnUpdUlCompEffBsr
18576 (
18577 RgSchUeCb *ue
18578 )
18579 #else
18580 static Void rgSCHCmnUpdUlCompEffBsr(ue)
18581 RgSchUeCb *ue;
18582 #endif
18583 {
18584    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,ue->cell);
18585    CmLList   *node = ueUl->ulAllocLst.last;
18586    RgSchCmnAllocRecord *allRcd;
18587    uint32_t outStndAlloc=0;
18588    uint32_t nonLcg0OutStndAllocBs=0;
18589    uint32_t nonLcg0Bsr=0;
18590    uint8_t  lcgId;
18591    RgSchCmnLcg *cmnLcg = NULLP;
18592
18593    while (node)
18594    {
18595       allRcd = (RgSchCmnAllocRecord *)node->node;
18596       if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime))
18597       {
18598          node = node->next;
18599          break;
18600       }
18601       node = node->prev;
18602    }
18603    while (node)
18604    {
18605       allRcd = (RgSchCmnAllocRecord *)node->node;
18606       node = node->next;
18607       outStndAlloc += allRcd->alloc;
18608    }
18609  
18610    cmnLcg = (RgSchCmnLcg *)(ue->ul.lcgArr[0].sch);
18611    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
18612    if (cmnLcg->bs > outStndAlloc)
18613    {
18614       cmnLcg->bs -= outStndAlloc;
18615       ue->ul.minReqBytes = cmnLcg->bs;
18616       outStndAlloc = 0;
18617    }
18618    else
18619    {
18620       nonLcg0OutStndAllocBs = outStndAlloc - cmnLcg->bs;
18621       cmnLcg->bs = 0;
18622    }
18623
18624    for(lcgId = 1;lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++)
18625    {
18626       if(RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
18627       {
18628          cmnLcg = ((RgSchCmnLcg *) (ue->ul.lcgArr[lcgId].sch));
18629          if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
18630          {
18631             nonLcg0Bsr += cmnLcg->bs;
18632          }
18633       }
18634    }
18635    nonLcg0Bsr += ue->ul.nonGbrLcgBs;  
18636    if (nonLcg0OutStndAllocBs > nonLcg0Bsr)
18637    {
18638       nonLcg0Bsr = 0;
18639    }
18640    else
18641    {
18642       nonLcg0Bsr -= nonLcg0OutStndAllocBs;
18643    }
18644    ue->ul.nonLcg0Bs = nonLcg0Bsr;
18645    /* Cap effBsr with nonLcg0Bsr and append lcg0 bs.
18646     * nonLcg0Bsr limit applies only to lcg1,2,3 */
18647    /* better be handled in individual scheduler */
18648    ue->ul.effBsr = nonLcg0Bsr +\
18649                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
18650    return;
18651 }
18652
18653 /**
18654  * @brief  Records information about the current allocation.
18655  *
18656  * @details
18657  *
18658  *     Function: rgSCHCmnUlRecordUeAlloc
18659  *     Purpose:  Records information about the curent allocation.
18660  *               This includes the allocated bytes, as well
18661  *               as some power information.
18662  *
18663  *     Invoked by: Scheduler
18664  *
18665  *  @param[in]  RgSchCellCb *cell
18666  *  @param[in]  RgSchUeCb   *ue
18667  *  @return  Void
18668  **/
18669 #ifdef ANSI
18670 Void rgSCHCmnUlRecordUeAlloc
18671 (
18672 RgSchCellCb *cell,
18673 RgSchUeCb   *ue
18674 )
18675 #else
18676 Void rgSCHCmnUlRecordUeAlloc(cell, ue)
18677 RgSchCellCb *cell;
18678 RgSchUeCb   *ue;
18679 #endif
18680 {
18681 #ifdef LTE_TDD
18682    RgSchCmnUlCell     *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
18683 #endif
18684    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18685    CmLListCp           *lst = &ueUl->ulAllocLst;
18686    CmLList             *node = ueUl->ulAllocLst.first;
18687    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
18688    RgSchCmnUeUlAlloc  *ulAllocInfo = &ueUl->alloc;
18689    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
18690
18691    cmLListDelFrm(lst, &allRcd->lnk);
18692 #ifndef LTE_TDD
18693    /* To the crntTime, add the MIN time at which UE will
18694     * actually send the BSR i.e DELTA+4 */
18695    allRcd->allocTime = cell->crntTime;
18696    /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
18697 #ifdef EMTC_ENABLE
18698    if(ue->isEmtcUe == TRUE)
18699    {
18700       RGSCH_INCR_SUB_FRAME_EMTC(allRcd->allocTime,
18701                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
18702    }
18703    else
18704 #endif
18705    {
18706       RGSCH_INCR_SUB_FRAME(allRcd->allocTime,
18707                            (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA));
18708    }
18709 #else
18710    allRcd->allocTime = cellUl->schdTime;
18711 #endif
18712    cmLListAdd2Tail(lst, &allRcd->lnk);
18713
18714    /* Filling in the parameters to be recorded */
18715    allRcd->alloc = ulAllocInfo->allocdBytes;
18716    //allRcd->numRb = ulAllocInfo->alloc->grnt.numRb;
18717    allRcd->numRb = (ulAllocInfo->alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
18718    /*Recording the UL CQI derived from the maxUlCqi */
18719    allRcd->cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
18720    allRcd->tpc   = ulAllocInfo->alloc->grnt.tpc;
18721
18722    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
18723
18724    cell->measurements.ulBytesCnt += ulAllocInfo->allocdBytes;
18725
18726    return;
18727 }
18728
18729 /** PHR handling for MSG3
18730  * @brief  Records allocation information of msg3 in the the UE.
18731  *
18732  * @details
18733  *
18734  *     Function: rgSCHCmnUlRecMsg3Alloc
18735  *     Purpose:  Records information about msg3 allocation.
18736  *               This includes the allocated bytes, as well
18737  *               as some power information.
18738  *
18739  *     Invoked by: Scheduler
18740  *
18741  *  @param[in]  RgSchCellCb *cell
18742  *  @param[in]  RgSchUeCb   *ue
18743  *  @param[in]  RgSchRaCb   *raCb
18744  *  @return  Void
18745  **/
18746 #ifdef ANSI
18747 Void rgSCHCmnUlRecMsg3Alloc
18748 (
18749 RgSchCellCb *cell,
18750 RgSchUeCb   *ue,
18751 RgSchRaCb   *raCb
18752 )
18753 #else
18754 Void rgSCHCmnUlRecMsg3Alloc(cell, ue, raCb)
18755 RgSchCellCb *cell;
18756 RgSchUeCb   *ue;
18757 RgSchRaCb   *raCb;
18758 #endif
18759 {
18760    RgSchCmnUlUe        *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
18761    CmLListCp           *lst = &ueUl->ulAllocLst;
18762    CmLList             *node = ueUl->ulAllocLst.first;
18763    RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node);
18764
18765    /* Stack Crash problem for TRACE5 changes */
18766
18767    cmLListDelFrm(lst, node);
18768    allRcd->allocTime = raCb->msg3AllocTime;
18769    cmLListAdd2Tail(lst, node);
18770
18771    /* Filling in the parameters to be recorded */
18772    allRcd->alloc = raCb->msg3Grnt.datSz;
18773    allRcd->numRb = raCb->msg3Grnt.numRb;
18774    allRcd->cqi   = raCb->ccchCqi;
18775    allRcd->tpc   = raCb->msg3Grnt.tpc;
18776
18777    rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb);
18778
18779    return;
18780 }
18781 /**
18782  * @brief Keeps track of the most recent RG_SCH_CMN_MAX_ALLOC_TRACK
18783  * allocations to track. Adds this allocation to the ueUl's ulAllocLst.
18784  *
18785  *
18786  * @details
18787  *
18788  *     Function: rgSCHCmnUlUpdOutStndAlloc
18789  *     Purpose:  Recent Allocation shall be at First Pos'n.
18790  *               Remove the last node, update the fields
18791  *                with the new allocation and add at front.
18792  *
18793  *     Invoked by: Scheduler
18794  *
18795  *  @param[in]  RgSchCellCb *cell
18796  *  @param[in]  RgSchUeCb   *ue
18797  *  @param[in]  uint32_t alloc
18798  *  @return  Void
18799  **/
18800 #ifdef ANSI
18801 Void rgSCHCmnUlUpdOutStndAlloc
18802 (
18803 RgSchCellCb *cell,
18804 RgSchUeCb   *ue,
18805 uint32_t alloc
18806 )
18807 #else
18808 Void rgSCHCmnUlUpdOutStndAlloc(cell, ue, alloc)
18809 RgSchCellCb *cell;
18810 RgSchUeCb   *ue;
18811 uint32_t alloc;
18812 #endif
18813 {
18814    uint32_t                 nonLcg0Alloc=0;
18815
18816    /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/
18817    if (((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs > alloc)
18818    {
18819       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs -= alloc;
18820    }
18821    else
18822    {
18823       nonLcg0Alloc = alloc - ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
18824       ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = 0;
18825    }
18826
18827    if (nonLcg0Alloc >= ue->ul.nonLcg0Bs)
18828    {
18829       ue->ul.nonLcg0Bs  = 0;
18830    }
18831    else
18832    {
18833       ue->ul.nonLcg0Bs  -= nonLcg0Alloc;
18834    }
18835    /* Cap effBsr with effAmbr and append lcg0 bs.
18836     * effAmbr limit applies only to lcg1,2,3 non GBR LCG's*/
18837    /* better be handled in individual scheduler */
18838    ue->ul.effBsr = ue->ul.nonLcg0Bs +\
18839                   ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs;
18840 #ifdef RGR_V1
18841    if (ue->ul.effBsr == 0)
18842    {
18843       if (ue->bsrTmr.tmrEvnt != TMR_NONE)
18844       {
18845          rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
18846       }
18847       /* ccpu00133008 */
18848       if (FALSE == ue->isSrGrant)
18849       {
18850          if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
18851          {
18852             /*
18853             rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR,
18854                   ue->ul.bsrTmrCfg.prdBsrTmr);
18855             */
18856          }
18857       }
18858    }
18859 #endif
18860    /* Resetting UEs lower Cap */
18861    ue->ul.minReqBytes = 0;
18862
18863    return;
18864 }
18865
18866
18867 /**
18868  * @brief Returns the "Itbs" for a given UE.
18869  *
18870  * @details
18871  *
18872  *     Function: rgSCHCmnUlGetITbs
18873  *     Purpose:  This function returns the "Itbs" for a given UE.
18874  *
18875  *     Invoked by: Scheduler
18876  *
18877  *  @param[in]  RgSchUeCb        *ue
18878  *  @return     uint8_t
18879  **/
18880 #ifdef ANSI
18881 uint8_t rgSCHCmnUlGetITbs
18882 (
18883 RgSchCellCb      *cell,
18884 RgSchUeCb        *ue,
18885 Bool             isEcp
18886 )
18887 #else
18888 uint8_t rgSCHCmnUlGetITbs(cell, ue, isEcp)
18889 RgSchCellCb      *cell;
18890 RgSchUeCb        *ue;
18891 Bool             isEcp;
18892 #endif
18893 {
18894    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
18895    /* CQI will be capped to maxUlCqi for 16qam UEs */
18896    CmLteUeCategory  ueCtgy = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
18897    uint8_t            cqi;
18898 #ifdef UL_LA
18899    S32            iTbs;
18900    uint8_t            maxiTbs = rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][ueUl->maxUlCqi]; 
18901 #endif
18902
18903
18904    /* #ifdef RG_SCH_CMN_EXT_CP_SUP For ECP pick index 1 */
18905 #ifdef TFU_UPGRADE
18906    if ( (ueCtgy != CM_LTE_UE_CAT_5) &&
18907         (ueUl->validUlCqi > ueUl->maxUlCqi)
18908       )
18909    {
18910       cqi = ueUl->maxUlCqi;
18911    }
18912    else
18913    {
18914       cqi = ueUl->validUlCqi;
18915    }
18916
18917 #ifdef UL_LA
18918    iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
18919
18920    RG_SCH_CHK_ITBS_RANGE(iTbs, maxiTbs); 
18921
18922    iTbs = RGSCH_MIN(iTbs,  ue->cell->thresholds.maxUlItbs);
18923
18924 #ifdef LTE_TDD
18925    /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption
18926       was seen when IMCS exceeds 20 on T2k TDD */
18927    if (iTbs > 19)
18928    {
18929       iTbs = 19;
18930    }
18931 #endif
18932    return (iTbs);
18933 #endif 
18934 #else
18935    if ( (ueCtgy != CM_LTE_UE_CAT_5) && (ueUl->crntUlCqi[0] > ueUl->maxUlCqi ))
18936    {
18937       cqi = ueUl->maxUlCqi;
18938    }
18939    else
18940    {
18941       cqi = ueUl->crntUlCqi[0];
18942    }
18943 #endif
18944    return (rgSchCmnUlCqiToTbsTbl[(uint8_t)isEcp][cqi]);
18945 }
18946
18947 /**
18948  * @brief This function adds the UE to DLRbAllocInfo TX lst.
18949  *
18950  * @details
18951  *
18952  *     Function: rgSCHCmnDlRbInfoAddUeTx
18953  *     Purpose:  This function adds the UE to DLRbAllocInfo TX lst.
18954  *
18955  *     Invoked by: Common Scheduler
18956  *
18957  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
18958  *  @param[in]  RgSchUeCb             *ue
18959  *  @param[in]  RgSchDlHqProcCb       *hqP
18960  *  @return  Void
18961  *
18962  **/
18963 #ifdef ANSI
18964 static Void rgSCHCmnDlRbInfoAddUeTx
18965 (
18966 RgSchCellCb        *cell,
18967 RgSchCmnDlRbAllocInfo *allocInfo,
18968 RgSchUeCb             *ue,
18969 RgSchDlHqProcCb       *hqP
18970 )
18971 #else
18972 static Void rgSCHCmnDlRbInfoAddUeTx(cell, allocInfo, ue, hqP)
18973 RgSchCellCb        *cell;
18974 RgSchCmnDlRbAllocInfo *allocInfo;
18975 RgSchUeCb             *ue;
18976 RgSchDlHqProcCb       *hqP;
18977 #endif
18978 {
18979    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
18980
18981
18982    if (hqP->reqLnk.node == NULLP)
18983    {
18984       if (cellSch->dl.isDlFreqSel)
18985       {
18986          cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
18987            &allocInfo->dedAlloc.txHqPLst, hqP);
18988       }
18989       else
18990       {
18991          {
18992             cmLListAdd2Tail(&allocInfo->dedAlloc.txHqPLst, &hqP->reqLnk);
18993          }
18994          hqP->reqLnk.node = (PTR)hqP;
18995       }
18996    }
18997    return;
18998 }
18999
19000 /**
19001  * @brief This function adds the UE to DLRbAllocInfo RETX lst.
19002  *
19003  * @details
19004  *
19005  *     Function: rgSCHCmnDlRbInfoAddUeRetx
19006  *     Purpose:  This function adds the UE to DLRbAllocInfo RETX lst.
19007  *
19008  *     Invoked by: Common Scheduler
19009  *
19010  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19011  *  @param[in]  RgSchUeCb             *ue
19012  *  @param[in]  RgSchDlHqProcCb       *hqP
19013  *  @return  Void
19014  *
19015  **/
19016 #ifdef ANSI
19017 static Void rgSCHCmnDlRbInfoAddUeRetx
19018 (
19019 RgSchCellCb        *cell,
19020 RgSchCmnDlRbAllocInfo *allocInfo,
19021 RgSchUeCb             *ue,
19022 RgSchDlHqProcCb       *hqP
19023 )
19024 #else
19025 static Void rgSCHCmnDlRbInfoAddUeRetx(cell, allocInfo, ue, hqP)
19026 RgSchCellCb        *cell;
19027 RgSchCmnDlRbAllocInfo *allocInfo;
19028 RgSchUeCb             *ue;
19029 RgSchDlHqProcCb       *hqP;
19030 #endif
19031 {
19032    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
19033
19034
19035    if (cellSch->dl.isDlFreqSel)
19036    {
19037       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
19038         &allocInfo->dedAlloc.retxHqPLst, hqP);
19039    }
19040    else
19041    {
19042       /* checking UE's presence in this lst is unnecessary */
19043       cmLListAdd2Tail(&allocInfo->dedAlloc.retxHqPLst, &hqP->reqLnk);
19044       hqP->reqLnk.node = (PTR)hqP;
19045    }
19046    return;
19047 }
19048
19049 /**
19050  * @brief This function adds the UE to DLRbAllocInfo TX-RETX lst.
19051  *
19052  * @details
19053  *
19054  *     Function: rgSCHCmnDlRbInfoAddUeRetxTx
19055  *     Purpose:  This adds the UE to DLRbAllocInfo TX-RETX lst.
19056  *
19057  *     Invoked by: Common Scheduler
19058  *
19059  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19060  *  @param[in]  RgSchUeCb             *ue
19061  *  @param[in]  RgSchDlHqProcCb       *hqP
19062  *  @return  Void
19063  *
19064  **/
19065 #ifdef ANSI
19066 static Void rgSCHCmnDlRbInfoAddUeRetxTx
19067 (
19068 RgSchCellCb        *cell,
19069 RgSchCmnDlRbAllocInfo *allocInfo,
19070 RgSchUeCb             *ue,
19071 RgSchDlHqProcCb       *hqP
19072 )
19073 #else
19074 static Void rgSCHCmnDlRbInfoAddUeRetxTx(allocInfo, ue, hqP)
19075 RgSchCellCb        *cell;
19076 RgSchCmnDlRbAllocInfo *allocInfo;
19077 RgSchUeCb             *ue;
19078 RgSchDlHqProcCb       *hqP;
19079 #endif
19080 {
19081    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(ue->cell);
19082
19083
19084    if (cellSch->dl.isDlFreqSel)
19085    {
19086       cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell,
19087         &allocInfo->dedAlloc.txRetxHqPLst, hqP);
19088    }
19089    else
19090    {
19091       cmLListAdd2Tail(&allocInfo->dedAlloc.txRetxHqPLst, &hqP->reqLnk);
19092       hqP->reqLnk.node = (PTR)hqP;
19093    }
19094    return;
19095 }
19096
19097 /**
19098  * @brief This function adds the UE to DLRbAllocInfo NonSchdRetxLst.
19099  *
19100  * @details
19101  *
19102  *     Function: rgSCHCmnDlAdd2NonSchdRetxLst 
19103  *     Purpose:  During RB estimation for RETX, if allocation fails
19104  *               then appending it to NonSchdRetxLst, the further
19105  *               action is taken as part of Finalization in
19106  *               respective schedulers.
19107  *
19108  *     Invoked by: Common Scheduler
19109  *
19110  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19111  *  @param[in]  RgSchUeCb             *ue
19112  *  @param[in]  RgSchDlHqProcCb       *hqP
19113  *  @return  Void
19114  *
19115  **/
19116 #ifdef ANSI
19117 static Void rgSCHCmnDlAdd2NonSchdRetxLst 
19118 (
19119 RgSchCmnDlRbAllocInfo *allocInfo,
19120 RgSchUeCb             *ue,
19121 RgSchDlHqProcCb       *hqP
19122 )
19123 #else
19124 static Void rgSCHCmnDlAdd2NonSchdRetxLst(allocInfo, ue, hqP)
19125 RgSchCmnDlRbAllocInfo *allocInfo;
19126 RgSchUeCb             *ue;
19127 RgSchDlHqProcCb       *hqP;
19128 #endif
19129 {
19130    CmLList         *schdLnkNode;
19131
19132
19133 #ifdef LTEMAC_SPS
19134    if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && 
19135          (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)))
19136    {
19137       return;
19138    }
19139 #endif
19140
19141    schdLnkNode = &hqP->schdLstLnk;
19142    RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
19143    cmLListAdd2Tail(&allocInfo->dedAlloc.nonSchdRetxHqPLst, schdLnkNode);
19144
19145    return;
19146 }
19147
19148
19149
19150 /**
19151  * @brief This function adds the UE to DLRbAllocInfo NonSchdTxRetxLst.
19152  *
19153  * @details
19154  *
19155  *     Function: rgSCHCmnDlAdd2NonSchdTxRetxLst 
19156  *     Purpose:  During RB estimation for TXRETX, if allocation fails
19157  *               then appending it to NonSchdTxRetxLst, the further
19158  *               action is taken as part of Finalization in
19159  *               respective schedulers.
19160  *
19161  *     Invoked by: Common Scheduler
19162  *
19163  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
19164  *  @param[in]  RgSchUeCb             *ue
19165  *  @param[in]  RgSchDlHqProcCb       *hqP
19166  *  @return  Void
19167  *
19168  **/
19169 #ifdef LTE_TDD
19170 /**
19171  * @brief This function handles the initialisation of DL HARQ/ACK feedback
19172  *        timing information for eaach DL subframe.
19173  *
19174  * @details
19175  *
19176  *     Function: rgSCHCmnDlANFdbkInit
19177  *     Purpose:  Each DL subframe stores the sfn and subframe
19178  *               information of UL subframe in which it expects
19179  *               HARQ ACK/NACK feedback for this subframe.It
19180  *               generates the information based on Downlink
19181  *               Association Set Index table.
19182  *
19183  *     Invoked by: Scheduler
19184  *
19185  *  @param[in]  RgSchCellCb*     cell
19186  *  @return     S16
19187  *
19188  **/
19189 #ifdef ANSI
19190 static S16 rgSCHCmnDlANFdbkInit
19191 (
19192 RgSchCellCb                *cell
19193 )
19194 #else
19195 static S16 rgSCHCmnDlANFdbkInit(cell)
19196 RgSchCellCb                *cell;
19197 #endif
19198 {
19199  uint8_t                   sfCount;
19200  uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
19201  uint8_t                   maxDlSubfrms = cell->numDlSubfrms;
19202  uint8_t                   sfNum;
19203  uint8_t                   idx;
19204  uint8_t                   dlIdx;
19205  uint8_t                   calcSfnOffset;
19206  S8                   calcSfNum;
19207  uint8_t                   ulSfCnt =0;
19208  RgSchTddSubfrmInfo   ulSubfrmInfo;
19209  uint8_t                   maxUlSubfrms;
19210
19211
19212    ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19213    maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19214
19215    /* Generate HARQ ACK/NACK feedback information for each DL sf in a radio frame
19216     * Calculate this information based on DL Association set Index table */
19217    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19218    {
19219       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19220             RG_SCH_TDD_UL_SUBFRAME)
19221       {
19222          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19223       }
19224       ulSfCnt++;
19225
19226       for(idx=0; idx < rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
19227             numFdbkSubfrms; idx++)
19228       {
19229          calcSfNum = sfNum - rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\
19230                      subfrmNum[idx];
19231          if(calcSfNum < 0)
19232          {
19233             calcSfnOffset = RGSCH_CEIL(-calcSfNum, RGSCH_NUM_SUB_FRAMES);
19234          }
19235          else
19236          {
19237             calcSfnOffset = 0;
19238          }
19239
19240          calcSfNum = ((RGSCH_NUM_SUB_FRAMES * calcSfnOffset) + calcSfNum)\
19241                      % RGSCH_NUM_SUB_FRAMES;
19242
19243          if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19244          {
19245             dlIdx = calcSfNum;
19246          }
19247          else if((ulSubfrmInfo.switchPoints == 2) && (calcSfNum <= \
19248                   RG_SCH_CMN_SPL_SUBFRM_6))
19249          {
19250             dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19251          }
19252          else
19253          {
19254             dlIdx = calcSfNum - maxUlSubfrms;
19255          }
19256
19257          cell->subFrms[dlIdx]->dlFdbkInfo.subframe = sfNum;
19258          cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = calcSfnOffset;
19259          cell->subFrms[dlIdx]->dlFdbkInfo.m = idx;
19260       }
19261       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19262    }
19263
19264    /* DL subframes in the subsequent radio frames are initialized
19265     * with the previous radio frames  */
19266    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;\
19267          dlIdx++)
19268    {
19269       sfNum = dlIdx - rgSchTddNumDlSubfrmTbl[ulDlCfgIdx]\
19270               [RGSCH_NUM_SUB_FRAMES-1];
19271       cell->subFrms[dlIdx]->dlFdbkInfo.subframe = \
19272                                                   cell->subFrms[sfNum]->dlFdbkInfo.subframe;
19273       cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = \
19274                                                    cell->subFrms[sfNum]->dlFdbkInfo.sfnOffset;
19275       cell->subFrms[dlIdx]->dlFdbkInfo.m = cell->subFrms[sfNum]->dlFdbkInfo.m;
19276    }
19277    return ROK;
19278 }
19279
19280 /**
19281  * @brief This function handles the initialization of uplink association
19282  *        set information for each DL subframe.
19283  *
19284  *
19285  * @details
19286  *
19287  *     Function: rgSCHCmnDlKdashUlAscInit
19288  *     Purpose:  Each DL sf stores the sfn and sf information of UL sf
19289  *               in which it expects HQ ACK/NACK trans. It generates the information
19290  *               based on k` in UL association set index table.
19291  *
19292  *     Invoked by: Scheduler
19293  *
19294  *  @param[in]  RgSchCellCb*     cell
19295  *  @return     S16
19296  *
19297  **/
19298 #ifdef ANSI
19299 static S16 rgSCHCmnDlKdashUlAscInit
19300 (
19301 RgSchCellCb                *cell
19302 )
19303 #else
19304 static S16 rgSCHCmnDlKdashUlAscInit(cell)
19305 RgSchCellCb                *cell;
19306 #endif
19307 {
19308  uint8_t                   sfCount;
19309  uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
19310  uint8_t                   maxDlSubfrms = cell->numDlSubfrms;
19311  uint8_t                   sfNum;
19312  uint8_t                   dlIdx;
19313  S8                   calcSfnOffset;
19314  S8                   calcSfNum;
19315  uint8_t                   ulSfCnt =0;
19316  RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19317  uint8_t                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19318                                      [RGSCH_NUM_SUB_FRAMES-1];
19319  uint8_t                   dlPres = 0;
19320
19321
19322    /* Generate ACK/NACK offset information for each DL subframe in a radio frame
19323     * Calculate this information based on K` in UL Association Set table */
19324    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19325    {
19326       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19327             RG_SCH_TDD_UL_SUBFRAME)
19328       {
19329          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19330       }
19331       ulSfCnt++;
19332
19333       calcSfNum = (sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum] + \
19334             RGSCH_NUM_SUB_FRAMES) % RGSCH_NUM_SUB_FRAMES;
19335       calcSfnOffset = sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum];
19336       if(calcSfnOffset < 0)
19337       {
19338          calcSfnOffset = RGSCH_CEIL(-calcSfnOffset, RGSCH_NUM_SUB_FRAMES);
19339       }
19340       else
19341       {
19342          calcSfnOffset = 0;
19343       }
19344
19345       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19346       {
19347          dlIdx = calcSfNum;
19348       }
19349       else if((ulSubfrmInfo.switchPoints == 2) &&
19350             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
19351       {
19352          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19353       }
19354       else
19355       {
19356          dlIdx = calcSfNum - maxUlSubfrms;
19357       }
19358
19359       cell->subFrms[dlIdx]->ulAscInfo.subframe = sfNum;
19360       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = calcSfnOffset;
19361
19362       /* set dlIdx for which ulAscInfo is updated */
19363       dlPres = dlPres | (1 << dlIdx);
19364       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19365    }
19366
19367    /* Set Invalid information for which ulAscInfo is not present */
19368    for (sfCount = 0;
19369          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19370          sfCount++)
19371    {
19372       /* If dlPres is 0, ulAscInfo is not present in that DL index */
19373       if(! ((dlPres >> sfCount)&0x01))
19374       {
19375          cell->subFrms[sfCount]->ulAscInfo.sfnOffset =
19376             RGSCH_INVALID_INFO;
19377          cell->subFrms[sfCount]->ulAscInfo.subframe =
19378             RGSCH_INVALID_INFO;
19379       }
19380    }
19381
19382    /* DL subframes in the subsequent radio frames are initialized
19383     * with the previous radio frames  */
19384    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;
19385          dlIdx++)
19386    {
19387       sfNum = dlIdx - \
19388               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19389       cell->subFrms[dlIdx]->ulAscInfo.subframe =
19390          cell->subFrms[sfNum]->ulAscInfo.subframe;
19391       cell->subFrms[dlIdx]->ulAscInfo.sfnOffset =
19392          cell->subFrms[sfNum]->ulAscInfo.sfnOffset;
19393    }
19394    return ROK;
19395 }
19396
19397
19398 /**
19399  * @brief This function initialises the 'Np' value for 'p'
19400  *
19401  * @details
19402  *
19403  *     Function: rgSCHCmnDlNpValInit
19404  *     Purpose:  To initialise the 'Np' value for each 'p'. It is used
19405  *               to find the mapping between nCCE and 'p' and used in
19406  *               HARQ ACK/NACK reception.
19407  *
19408  *     Invoked by: Scheduler
19409  *
19410  *  @param[in]  RgSchCellCb*     cell
19411  *  @return     S16
19412  *
19413  **/
19414 #ifdef ANSI
19415 static S16 rgSCHCmnDlNpValInit
19416 (
19417 RgSchCellCb                *cell
19418 )
19419 #else
19420 static S16 rgSCHCmnDlNpValInit(cell)
19421 RgSchCellCb                *cell;
19422 #endif
19423 {
19424    uint8_t    idx;
19425    uint16_t   np;
19426
19427    /* Always Np is 0 for p=0 */
19428    cell->rgSchTddNpValTbl[0] = 0;
19429
19430    for(idx=1; idx < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; idx++)
19431    {
19432       np = cell->bwCfg.dlTotalBw * (idx * RG_SCH_CMN_NUM_SUBCAR - 4);
19433       cell->rgSchTddNpValTbl[idx] = (uint8_t) (np/36);
19434    }
19435
19436    return ROK;
19437 }
19438
19439 /**
19440  * @brief This function handles the creation of RACH preamble
19441  *        list to queue the preambles and process at the scheduled
19442  *        time.
19443  *
19444  * @details
19445  *
19446  *     Function: rgSCHCmnDlCreateRachPrmLst
19447  *     Purpose:  To create RACH preamble list based on RA window size.
19448  *               It is used to queue the preambles and process it at the
19449  *               scheduled time.
19450  *
19451  *     Invoked by: Scheduler
19452  *
19453  *  @param[in]  RgSchCellCb*     cell
19454  *  @return     S16
19455  *
19456  **/
19457 #ifdef ANSI
19458 static S16 rgSCHCmnDlCreateRachPrmLst
19459 (
19460 RgSchCellCb                *cell
19461 )
19462 #else
19463 static S16 rgSCHCmnDlCreateRachPrmLst(cell)
19464 RgSchCellCb                *cell;
19465 #endif
19466 {
19467  uint8_t       raArrSz;
19468  S16       ret;
19469  uint8_t       lstSize;
19470
19471
19472    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
19473
19474    lstSize = raArrSz * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES;
19475
19476    cell->raInfo.maxRaSize = raArrSz;
19477    ret = rgSCHUtlAllocSBuf(cell->instIdx,
19478          (Data **)(&cell->raInfo.raReqLst), (Size)(lstSize * sizeof(CmLListCp)));
19479    if (ret != ROK)
19480    {
19481       return (ret);
19482    }
19483
19484    cell->raInfo.lstSize = lstSize;
19485
19486    return ROK;
19487 }
19488
19489
19490 /**
19491  * @brief This function handles the initialization of RACH Response
19492  *        information at each DL subframe.
19493  *
19494  * @details
19495  *
19496  *     Function: rgSCHCmnDlRachInfoInit
19497  *     Purpose:  Each DL subframe stores the sfn and subframe information of
19498  *               possible RACH response allowed for UL subframes. It generates
19499  *               the information based on PRACH configuration.
19500  *
19501  *     Invoked by: Scheduler
19502  *
19503  *  @param[in]  RgSchCellCb*     cell
19504  *  @return     S16
19505  *
19506  **/
19507 #ifdef ANSI
19508 static S16 rgSCHCmnDlRachInfoInit
19509 (
19510 RgSchCellCb                *cell
19511 )
19512 #else
19513 static S16 rgSCHCmnDlRachInfoInit(cell)
19514 RgSchCellCb                *cell;
19515 #endif
19516 {
19517    uint8_t                   sfCount;
19518    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
19519    uint8_t                   sfNum;
19520    uint8_t                   ulSfCnt =0;
19521    uint8_t                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19522                                        [RGSCH_NUM_SUB_FRAMES-1];
19523    uint8_t                   raArrSz;
19524    RgSchTddRachRspLst        rachRspLst[3][RGSCH_NUM_SUB_FRAMES];
19525    uint8_t                   startWin;
19526    uint8_t                   endWin;
19527    uint8_t                   sfnIdx;
19528    uint8_t                   subfrmIdx;
19529    uint8_t                   endSubfrmIdx;
19530    uint8_t                   startSubfrmIdx;
19531    S16                       ret;
19532    RgSchTddRachDelInfo       *delInfo;
19533    S8                        sfnOffset;
19534    uint8_t                   numSubfrms;
19535
19536
19537    memset(rachRspLst, 0, sizeof(rachRspLst));
19538
19539    RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz);
19540
19541    /* Include Special subframes */
19542    maxUlSubfrms = maxUlSubfrms + \
19543                   rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx].switchPoints;
19544    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19545    {
19546       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
19547             RG_SCH_TDD_DL_SUBFRAME)
19548       {
19549          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19550       }
19551       ulSfCnt++;
19552
19553       startWin = (sfNum + RG_SCH_CMN_RARSP_WAIT_PRD + \
19554             ((RgSchCmnCell *)cell->sc.sch)->dl.numRaSubFrms);
19555       endWin = (startWin + cell->rachCfg.raWinSize - 1);
19556       startSubfrmIdx =
19557          rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][startWin%RGSCH_NUM_SUB_FRAMES];
19558       /* Find the next DL subframe starting from Subframe 0 */
19559       if((startSubfrmIdx % RGSCH_NUM_SUB_FRAMES) == 0)
19560       {
19561          startWin = RGSCH_CEIL(startWin, RGSCH_NUM_SUB_FRAMES);
19562          startWin = startWin * RGSCH_NUM_SUB_FRAMES;
19563       }
19564
19565       endSubfrmIdx =
19566          rgSchTddLowDlSubfrmIdxTbl[ulDlCfgIdx][endWin%RGSCH_NUM_SUB_FRAMES];
19567       endWin = (endWin/RGSCH_NUM_SUB_FRAMES) * RGSCH_NUM_SUB_FRAMES \
19568                + endSubfrmIdx;
19569       if(startWin > endWin)
19570       {
19571          continue;
19572       }
19573       /* Find all the possible RACH Response transmission
19574        * time within the RA window size */
19575       startSubfrmIdx = startWin%RGSCH_NUM_SUB_FRAMES;
19576       for(sfnIdx = startWin/RGSCH_NUM_SUB_FRAMES;
19577             sfnIdx <= endWin/RGSCH_NUM_SUB_FRAMES; sfnIdx++)
19578       {
19579          if(sfnIdx == endWin/RGSCH_NUM_SUB_FRAMES)
19580          {
19581             endSubfrmIdx = endWin%RGSCH_NUM_SUB_FRAMES;
19582          }
19583          else
19584          {
19585             endSubfrmIdx = RGSCH_NUM_SUB_FRAMES-1;
19586          }
19587
19588          /* Find all the possible RACH Response transmission
19589           * time within radio frame */
19590          for(subfrmIdx = startSubfrmIdx;
19591                subfrmIdx <= endSubfrmIdx; subfrmIdx++)
19592          {
19593             if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][subfrmIdx] ==
19594                   RG_SCH_TDD_UL_SUBFRAME)
19595             {
19596                continue;
19597             }
19598             subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
19599             /* Find the next DL subframe starting from Subframe 0 */
19600             if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
19601             {
19602                break;
19603             }
19604             RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx], subfrmIdx);
19605             numSubfrms =
19606                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
19607             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset = sfnIdx;
19608             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].subframe[numSubfrms]
19609                = sfNum;
19610             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms++;
19611          }
19612          startSubfrmIdx = RG_SCH_CMN_SUBFRM_0;
19613       }
19614       /* Update the subframes to be deleted at this subframe */
19615       /* Get the subframe after the end of RA window size */
19616       endWin++;
19617       endSubfrmIdx++;
19618       sfnOffset = endWin/RGSCH_NUM_SUB_FRAMES;
19619       if(sfnOffset < 0)
19620       {
19621          sfnOffset += raArrSz;
19622       }
19623       sfnIdx = (endWin/RGSCH_NUM_SUB_FRAMES) % raArrSz;
19624
19625       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx],endSubfrmIdx-1);
19626       if((endSubfrmIdx == RGSCH_NUM_SUB_FRAMES) ||
19627             (rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx] ==
19628              RGSCH_NUM_SUB_FRAMES))
19629       {
19630          subfrmIdx =
19631             rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][RG_SCH_CMN_SUBFRM_0];
19632       }
19633       else
19634       {
19635          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx];
19636       }
19637
19638       delInfo = &rachRspLst[sfnIdx][subfrmIdx].delInfo;
19639       delInfo->sfnOffset = sfnOffset;
19640       delInfo->subframe[delInfo->numSubfrms] = sfNum;
19641       delInfo->numSubfrms++;
19642
19643       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19644    }
19645
19646    ret = rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz);
19647    if (ret != ROK)
19648    {
19649       return (ret);
19650    }
19651
19652    return ROK;
19653 }
19654
19655 /**
19656  * @brief This function handles the initialization of PHICH information
19657  *        for each DL subframe based on PHICH table.
19658  *
19659  * @details
19660  *
19661  *     Function: rgSCHCmnDlPhichOffsetInit
19662  *     Purpose:  Each DL subf stores the sfn and subf information of UL subframe
19663  *               for which it trnsmts PHICH in this subframe. It generates the information
19664  *               based on PHICH table.
19665  *
19666  *     Invoked by: Scheduler
19667  *
19668  *  @param[in]  RgSchCellCb*     cell
19669  *  @return     S16
19670  *
19671  **/
19672 #ifdef ANSI
19673 static S16 rgSCHCmnDlPhichOffsetInit
19674 (
19675 RgSchCellCb                *cell
19676 )
19677 #else
19678 static S16 rgSCHCmnDlPhichOffsetInit(cell)
19679 RgSchCellCb                *cell;
19680 #endif
19681 {
19682    uint8_t                   sfCount;
19683    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
19684    uint8_t                   maxDlSubfrms = cell->numDlSubfrms;
19685    uint8_t                   sfNum;
19686    uint8_t                   dlIdx;
19687    uint8_t                   dlPres = 0;
19688    uint8_t                   calcSfnOffset;
19689    uint8_t                   calcSfNum;
19690    uint8_t                   ulSfCnt =0;
19691    RgSchTddSubfrmInfo   ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx];
19692    uint8_t                   maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\
19693                                        [RGSCH_NUM_SUB_FRAMES-1];
19694
19695
19696    /* Generate PHICH offset information for each DL subframe in a radio frame
19697     * Calculate this information based on K in PHICH table */
19698    for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++)
19699    {
19700       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] !=
19701             RG_SCH_TDD_UL_SUBFRAME)
19702       {
19703          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19704       }
19705       ulSfCnt++;
19706
19707       calcSfNum = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) % \
19708                   RGSCH_NUM_SUB_FRAMES;
19709       calcSfnOffset = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) / \
19710                       RGSCH_NUM_SUB_FRAMES;
19711
19712       if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1)
19713       {
19714          dlIdx = calcSfNum;
19715       }
19716       else if((ulSubfrmInfo.switchPoints == 2) &&
19717             (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6))
19718       {
19719          dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1;
19720       }
19721       else
19722       {
19723          dlIdx = calcSfNum - maxUlSubfrms;
19724       }
19725
19726       cell->subFrms[dlIdx]->phichOffInfo.subframe = sfNum;
19727       cell->subFrms[dlIdx]->phichOffInfo.numSubfrms = 1;
19728
19729       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = calcSfnOffset;
19730
19731       /* set dlIdx for which phich offset is updated */
19732       dlPres = dlPres | (1 << dlIdx);
19733       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
19734    }
19735
19736    /* Set Invalid information for which phich offset is not present */
19737    for (sfCount = 0;
19738          sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19739          sfCount++)
19740    {
19741       /* If dlPres is 0, phich offset is not present in that DL index */
19742       if(! ((dlPres >> sfCount)&0x01))
19743       {
19744          cell->subFrms[sfCount]->phichOffInfo.sfnOffset =
19745             RGSCH_INVALID_INFO;
19746          cell->subFrms[sfCount]->phichOffInfo.subframe =
19747             RGSCH_INVALID_INFO;
19748          cell->subFrms[sfCount]->phichOffInfo.numSubfrms = 0;
19749       }
19750    }
19751
19752    /* DL subframes in the subsequent radio frames are
19753     * initialized with the previous radio frames  */
19754    for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms;
19755          dlIdx < maxDlSubfrms; dlIdx++)
19756    {
19757       sfNum = dlIdx - \
19758               rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
19759
19760       cell->subFrms[dlIdx]->phichOffInfo.subframe =
19761          cell->subFrms[sfNum]->phichOffInfo.subframe;
19762
19763       cell->subFrms[dlIdx]->phichOffInfo.sfnOffset =
19764          cell->subFrms[sfNum]->phichOffInfo.sfnOffset;
19765    }
19766    return ROK;
19767 }
19768
19769
19770 /**
19771  * @brief Updation of Sch vars per TTI.
19772  *
19773  * @details
19774  *
19775  *     Function: rgSCHCmnUpdVars
19776  *     Purpose:  Updation of Sch vars per TTI.
19777  *
19778  *  @param[in]  RgSchCellCb *cell
19779  *  @return  Void
19780  *
19781  **/
19782 #ifdef ANSI
19783 Void rgSCHCmnUpdVars
19784 (
19785 RgSchCellCb *cell
19786 )
19787 #else
19788 Void rgSCHCmnUpdVars(cell)
19789 RgSchCellCb *cell;
19790 #endif
19791 {
19792    RgSchCmnUlCell         *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
19793    CmLteTimingInfo        timeInfo;
19794    uint8_t                idx;
19795    uint8_t                ulSubframe;
19796    uint8_t                ulDlCfgIdx = cell->ulDlCfgIdx;
19797    uint8_t                msg3Subfrm;
19798    uint8_t                Mval;
19799  
19800    /* ccpu00132654-ADD- Initializing all the indices in every subframe*/ 
19801    rgSCHCmnInitVars(cell);
19802
19803    idx = (cell->crntTime.slot + TFU_ULCNTRL_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
19804    /* Calculate the UL scheduling subframe idx based on the 
19805       Pusch k table */
19806    if(rgSchTddPuschTxKTbl[ulDlCfgIdx][idx] != 0)
19807    {
19808       /* PUSCH transmission is based on offset from DL
19809        * PDCCH scheduling */
19810       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); 
19811       ulSubframe = rgSchTddPuschTxKTbl[ulDlCfgIdx][timeInfo.subframe];
19812       /* Add the DCI-0 to PUSCH time to get the time of UL subframe */
19813       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, ulSubframe);
19814 #ifdef LTEMAC_SPS
19815       cellUl->schdTti = timeInfo.sfn * 10 + timeInfo.subframe;
19816 #endif
19817       /* Fetch the corresponding  UL subframe Idx in UL sf array */ 
19818       cellUl->schdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
19819       /* Fetch the corresponding  UL Harq Proc ID */ 
19820       cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
19821       cellUl->schdTime = timeInfo;
19822    }
19823    Mval = rgSchTddPhichMValTbl[ulDlCfgIdx][idx]; 
19824    if(Mval)
19825    {
19826       /* Fetch the tx time for DL HIDCI-0 */
19827       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA);
19828       /* Fetch the corresponding n-k tx time of PUSCH */
19829       cellUl->hqFdbkIdx[0] = rgSCHCmnGetPhichUlSfIdx(&timeInfo, cell);
19830       /* Retx will happen according to the Pusch k table */
19831       cellUl->reTxIdx[0] = cellUl->schdIdx;
19832       
19833       if(ulDlCfgIdx == 0) 
19834       {
19835          /* Calculate the ReTxIdx corresponding to hqFdbkIdx[0] */
19836          cellUl->reTxIdx[0] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
19837                                                 cellUl->hqFdbkIdx[0]);
19838          if(Mval == 2)
19839          {
19840             /* At Idx 1 store the UL SF adjacent(left) to the UL SF
19841                given at idx 0 */  
19842             cellUl->hqFdbkIdx[1] = (cellUl->hqFdbkIdx[0]-1 + 
19843                                    cellUl->numUlSubfrms) % cellUl->numUlSubfrms;
19844             /* Calculate the ReTxIdx corresponding to hqFdbkIdx[1] */
19845             cellUl->reTxIdx[1] = rgSchUtlCfg0ReTxIdx(cell,timeInfo,
19846                                                 cellUl->hqFdbkIdx[1]);
19847          }                               
19848       }
19849    }
19850
19851    idx = (cell->crntTime.slot + TFU_RECPREQ_DLDELTA) % RGSCH_NUM_SUB_FRAMES;
19852    if (rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == RG_SCH_TDD_UL_SUBFRAME)
19853    {
19854       RGSCHCMNADDTOCRNTTIME(cell->crntTime, timeInfo, TFU_RECPREQ_DLDELTA)
19855       cellUl->rcpReqIdx   = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
19856    }
19857    idx = (cell->crntTime.slot+RG_SCH_CMN_DL_DELTA) % RGSCH_NUM_SUB_FRAMES;
19858    
19859    /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in
19860      special subframe */                       
19861    if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] != RG_SCH_TDD_UL_SUBFRAME)
19862    {
19863       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
19864       msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
19865       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, msg3Subfrm);
19866       cellUl->msg3SchdIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
19867       cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell);
19868    }
19869 #ifdef LTEMAC_SPS
19870    if(!rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][idx])
19871    {
19872       cellUl->spsUlRsrvIdx = RGSCH_INVALID_INFO;
19873    }
19874    else
19875    {
19876       /* introduce some reuse with above code? */
19877       uint8_t    offst;
19878       RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA)
19879       //offst = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe];
19880       offst = rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][timeInfo.subframe];
19881       RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, offst);
19882       cellUl->spsUlRsrvIdx     = rgSCHCmnGetUlSfIdx(&timeInfo, cell);
19883       /* The harq proc continues to be accessed and used the same delta before
19884        * actual data occurance, and hence use the same idx */
19885       cellUl->spsUlRsrvHqProcIdx = cellUl->schdHqProcIdx;
19886    }
19887 #endif
19888
19889    /* RACHO: update cmn sched specific RACH variables,
19890     * mainly the prachMaskIndex */
19891    rgSCHCmnUpdRachParam(cell);
19892
19893    return;
19894 }
19895
19896 /**
19897  * @brief To get 'p' value from nCCE.
19898  *
19899  * @details
19900  *
19901  *     Function: rgSCHCmnGetPValFrmCCE
19902  *     Purpose:  Gets 'p' value for HARQ ACK/NACK reception from CCE.
19903  *
19904  *  @param[in]  RgSchCellCb   *cell
19905  *  @param[in]  uint8_t            cce
19906  *  @return uint8_t
19907  *
19908  **/
19909 #ifdef ANSI
19910 uint8_t  rgSCHCmnGetPValFrmCCE
19911 (
19912 RgSchCellCb *cell,
19913 uint8_t          cce
19914 )
19915 #else
19916 uint8_t  rgSCHCmnGetPValFrmCCE(cell, cce)
19917 RgSchCellCb *cell;
19918 uint8_t          cce;
19919 #endif
19920 {
19921    uint8_t i;
19922
19923    for(i=1; i < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; i++)
19924    {
19925       if(cce < cell->rgSchTddNpValTbl[i])
19926       {
19927          return (i-1);
19928       }
19929    }
19930    return (0);
19931 }
19932 #endif
19933
19934 /***********************************************************
19935  *
19936  *     Func : rgSCHCmnUlAdapRetx
19937  *
19938  *     Desc : Adaptive retransmission for an allocation.
19939  *
19940  *     Ret  :
19941  *
19942  *     Notes:
19943  *
19944  *     File :
19945  *
19946  **********************************************************/
19947 #ifdef ANSI
19948 static Void rgSCHCmnUlAdapRetx
19949 (
19950 RgSchUlAlloc    *alloc,
19951 RgSchUlHqProcCb *proc
19952 )
19953 #else
19954 static Void rgSCHCmnUlAdapRetx(alloc, proc)
19955 RgSchUlAlloc    *alloc;
19956 RgSchUlHqProcCb *proc;
19957 #endif
19958 {
19959
19960    rgSCHUhmRetx(proc, alloc);
19961 #ifndef RG_5GTF
19962    if (proc->rvIdx != 0)
19963    {
19964       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[proc->rvIdx];
19965    }
19966    else
19967 #endif
19968    {
19969       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
19970    }
19971    return;
19972 }
19973
19974 /**
19975  * @brief Scheduler invocation per TTI.
19976  *
19977  * @details
19978  *
19979  *     Function: rgSCHCmnHdlUlInactUes
19980  *     Purpose:
19981  *
19982  *     Invoked by: Common Scheduler
19983  *
19984  *  @param[in]  RgSchCellCb *cell
19985  *  @return  Void
19986  **/
19987 #ifdef ANSI
19988 static Void rgSCHCmnHdlUlInactUes
19989 (
19990 RgSchCellCb  *cell
19991 )
19992 #else
19993 static Void rgSCHCmnHdlUlInactUes(cell)
19994 RgSchCellCb  *cell;
19995 #endif
19996 {
19997    RgSchCmnCell  *cellSch  = RG_SCH_CMN_GET_CELL(cell);
19998    CmLListCp     ulInactvLst;
19999    /* Get a List of Inactv UEs for UL*/
20000    cmLListInit(&ulInactvLst);
20001
20002    /* Trigger Spfc Schedulers with Inactive UEs */
20003    rgSCHMeasGapANRepGetUlInactvUe (cell, &ulInactvLst);
20004    /* take care of this in UL retransmission */
20005    cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst);
20006
20007    return;
20008 }
20009
20010 /**
20011  * @brief Scheduler invocation per TTI.
20012  *
20013  * @details
20014  *
20015  *     Function: rgSCHCmnHdlDlInactUes
20016  *     Purpose:
20017  *
20018  *     Invoked by: Common Scheduler
20019  *
20020  *  @param[in]  RgSchCellCb *cell
20021  *  @return  Void
20022  **/
20023 #ifdef ANSI
20024 static Void rgSCHCmnHdlDlInactUes
20025 (
20026 RgSchCellCb  *cell
20027 )
20028 #else
20029 static Void rgSCHCmnHdlDlInactUes(cell)
20030 RgSchCellCb  *cell;
20031 #endif
20032 {
20033    RgSchCmnCell *cellSch  = RG_SCH_CMN_GET_CELL(cell);
20034    CmLListCp    dlInactvLst;
20035    /* Get a List of Inactv UEs for DL */
20036    cmLListInit(&dlInactvLst);
20037
20038    /* Trigger Spfc Schedulers with Inactive UEs */
20039    rgSCHMeasGapANRepGetDlInactvUe (cell, &dlInactvLst);
20040
20041    cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst);
20042    return;
20043 }
20044
20045 /* RACHO: Rach handover functions start here */
20046 /***********************************************************
20047  *
20048  *     Func : rgSCHCmnUeIdleExdThrsld
20049  *
20050  *     Desc : RETURN ROK if UE has been idle more
20051  *            than threshold.
20052  *
20053  *     Ret  :
20054  *
20055  *     Notes:
20056  *
20057  *     File :
20058  *
20059  **********************************************************/
20060 #ifdef ANSI
20061 static S16 rgSCHCmnUeIdleExdThrsld
20062 (
20063 RgSchCellCb     *cell,
20064 RgSchUeCb       *ue
20065 )
20066 #else
20067 static S16 rgSCHCmnUeIdleExdThrsld(cell, ue)
20068 RgSchCellCb     *cell;
20069 RgSchUeCb       *ue;
20070 #endif
20071 {
20072    /* Time difference in subframes */
20073    uint32_t sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, ue->ul.ulTransTime);
20074
20075
20076    if (sfDiff > (uint32_t)RG_SCH_CMN_UE_IDLE_THRSLD(ue))
20077    {
20078       return ROK;
20079    }
20080    else
20081    {
20082       return RFAILED;
20083    }
20084 }
20085
20086 \f
20087 /**
20088  * @brief Scheduler processing for Ded Preambles on cell configuration.
20089  *
20090  * @details
20091  *
20092  *     Function : rgSCHCmnCfgRachDedPrm
20093  *
20094  *     This function does requisite initialisation
20095  *     for RACH Ded Preambles.
20096  *
20097  *
20098  *  @param[in]  RgSchCellCb   *cell
20099  *  @return  Void
20100  **/
20101 #ifdef ANSI
20102 static Void rgSCHCmnCfgRachDedPrm
20103 (
20104 RgSchCellCb   *cell
20105 )
20106 #else
20107 static Void rgSCHCmnCfgRachDedPrm(cell)
20108 RgSchCellCb   *cell;
20109 #endif
20110 {
20111    RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20112    uint32_t          gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
20113    uint32_t          sfDiff;
20114    uint8_t           cnt;
20115
20116    if (cell->macPreambleSet.pres == NOTPRSNT)
20117    {
20118       return;
20119    }
20120    cellSch->rachCfg.numDedPrm = cell->macPreambleSet.size;
20121    cellSch->rachCfg.dedPrmStart = cell->macPreambleSet.start;
20122    /* Initialize handover List */
20123    cmLListInit(&cellSch->rachCfg.hoUeLst);
20124    /* Initialize pdcch Order List */
20125    cmLListInit(&cellSch->rachCfg.pdcchOdrLst);
20126
20127    /* Intialize the rapId to UE mapping structure */
20128    for (cnt = 0; cnt<cellSch->rachCfg.numDedPrm; cnt++)
20129    {
20130       cellSch->rachCfg.rapIdMap[cnt].rapId = cellSch->rachCfg.dedPrmStart + \
20131                                              cnt;
20132       cmLListInit(&cellSch->rachCfg.rapIdMap[cnt].assgndUes);
20133    }
20134    /* Perform Prach Mask Idx, remDedPrm, applFrm initializations */
20135    /* Set remDedPrm as numDedPrm */
20136    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
20137    /* Initialize applFrm */
20138    cellSch->rachCfg.prachMskIndx = 0;
20139    if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_EVEN)
20140    {
20141       cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + \
20142             (cell->crntTime.sfn % 2)) % RGSCH_MAX_SFN;
20143    }
20144 #ifdef LTE_TDD
20145    else if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ODD)
20146    {
20147       if((cell->crntTime.sfn%2) == 0)
20148       {
20149          cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + 1)\
20150                                         % RGSCH_MAX_SFN;
20151       }
20152    }
20153 #endif
20154    else /* ANY sfn */
20155    {
20156       cellSch->rachCfg.applFrm.sfn = cell->crntTime.sfn;
20157    }
20158    /* Initialize cellSch->rachCfg.applFrm as >= crntTime.
20159     * This is because of RGSCH_CALC_SF_DIFF logic */
20160    if (cellSch->rachCfg.applFrm.sfn == cell->crntTime.sfn)
20161    {
20162       while (cellSch->rachCfg.prachMskIndx < cell->rachCfg.raOccasion.size)
20163       {
20164          if (cell->crntTime.slot <\
20165                cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx])
20166          {
20167             break;
20168          }
20169          cellSch->rachCfg.prachMskIndx++;
20170       }
20171       if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size)
20172       {
20173          if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
20174          {
20175             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) %\
20176                                            RGSCH_MAX_SFN;
20177          }
20178          else
20179          {
20180             cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) %\
20181                                            RGSCH_MAX_SFN;
20182          }
20183          cellSch->rachCfg.prachMskIndx = 0;
20184       }
20185       cellSch->rachCfg.applFrm.slot = \
20186                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20187    }
20188    else
20189    {
20190       cellSch->rachCfg.applFrm.slot = \
20191                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20192    }
20193
20194    /* Note first param to this macro should always be the latest in time */
20195    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
20196    while (sfDiff <= gap)
20197    {
20198       rgSCHCmnUpdNxtPrchMskIdx(cell);
20199       sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime);
20200    }
20201
20202    return;
20203 }
20204
20205 /**
20206  * @brief Updates the PRACH MASK INDEX.
20207  *
20208  * @details
20209  *
20210  *     Function: rgSCHCmnUpdNxtPrchMskIdx
20211  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
20212  *     CFG is always >= "n"+"DELTA", where "n" is the crntTime
20213  *     of the cell. If not, applFrm is updated to the next avl
20214  *     PRACH oppurtunity as per the PRACH Cfg Index configuration.
20215  *
20216  *
20217  *     Invoked by: Common Scheduler
20218  *
20219  *  @param[in]  RgSchCellCb *cell
20220  *  @return  Void
20221  **/
20222 #ifdef ANSI
20223 static Void rgSCHCmnUpdNxtPrchMskIdx
20224 (
20225 RgSchCellCb  *cell
20226 )
20227 #else
20228 static Void rgSCHCmnUpdNxtPrchMskIdx(cell)
20229 RgSchCellCb  *cell;
20230 #endif
20231 {
20232    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20233
20234    /* Determine the next prach mask Index */
20235    if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size - 1)
20236    {
20237       /* PRACH within applFrm.sfn are done, go to next AVL sfn */
20238       cellSch->rachCfg.prachMskIndx = 0;
20239       if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY)
20240       {
20241          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) % \
20242                                         RGSCH_MAX_SFN;
20243       }
20244       else/* RGR_SFN_EVEN or RGR_SFN_ODD */
20245       {
20246          cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) % \
20247                                         RGSCH_MAX_SFN;
20248       }
20249       cellSch->rachCfg.applFrm.slot = cell->rachCfg.raOccasion.\
20250                                           subFrameNum[0];
20251    }
20252    else /* applFrm.sfn is still valid */
20253    {
20254       cellSch->rachCfg.prachMskIndx += 1;
20255       if ( cellSch->rachCfg.prachMskIndx < RGR_MAX_SUBFRAME_NUM )
20256       {
20257          cellSch->rachCfg.applFrm.slot = \
20258                                           cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx];
20259       }
20260    }
20261    return;
20262 }
20263
20264 /**
20265  * @brief Updates the Ded preamble RACH parameters
20266  *        every TTI.
20267  *
20268  * @details
20269  *
20270  *     Function: rgSCHCmnUpdRachParam
20271  *     Purpose:  Ensures the "applFrm" field of Cmn Sched RACH
20272  *     CFG is always >= "n"+"6"+"DELTA", where "n" is the crntTime
20273  *     of the cell. If not, applFrm is updated to the next avl
20274  *     PRACH oppurtunity as per the PRACH Cfg Index configuration,
20275  *     accordingly the "remDedPrm" is reset to "numDedPrm" and
20276  *     "prachMskIdx" field is updated as per "applFrm".
20277  *
20278  *
20279  *     Invoked by: Common Scheduler
20280  *
20281  *  @param[in]  RgSchCellCb *cell
20282  *  @return  Void
20283  **/
20284 #ifdef ANSI
20285 static Void rgSCHCmnUpdRachParam
20286 (
20287 RgSchCellCb  *cell
20288 )
20289 #else
20290 static Void rgSCHCmnUpdRachParam(cell)
20291 RgSchCellCb  *cell;
20292 #endif
20293 {
20294
20295    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20296    uint32_t             gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP;
20297    uint32_t             sfDiff;
20298
20299    if (cell->macPreambleSet.pres == NOTPRSNT)
20300    {
20301       return;
20302    }
20303    sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, \
20304          cell->crntTime);
20305    if (sfDiff > gap)
20306    {
20307       /* applFrm is still a valid next Prach Oppurtunity */
20308       return;
20309    }
20310    rgSCHCmnUpdNxtPrchMskIdx(cell);
20311    /* Reset remDedPrm as numDedPrm */
20312    cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm;
20313
20314    return;
20315 }
20316
20317 /**
20318  * @brief Dedicated Preamble allocation function.
20319  *
20320  * @details
20321  *
20322  *     Function: rgSCHCmnAllocPOParam
20323  *     Purpose:  Allocate pdcch, rapId and PrachMskIdx.
20324  *     Set mapping of UE with the allocated rapId.
20325  *
20326  *     Invoked by: Common Scheduler
20327  *
20328  *  @param[in]   RgSchCellCb *cell
20329  *  @param[in]   RgSchDlSf   *dlSf
20330  *  @param[in]   RgSchUeCb   *ue
20331  *  @param[out]  RgSchPdcch  **pdcch
20332  *  @param[out]  uint8_t          *rapId
20333  *  @param[out]  uint8_t          *prachMskIdx
20334  *  @return  Void
20335  **/
20336 #ifdef ANSI
20337 static S16 rgSCHCmnAllocPOParam
20338 (
20339 RgSchCellCb  *cell,
20340 RgSchDlSf    *dlSf,
20341 RgSchUeCb    *ue,
20342 RgSchPdcch   **pdcch,
20343 uint8_t           *rapId,
20344 uint8_t           *prachMskIdx
20345 )
20346 #else
20347 static S16 rgSCHCmnAllocPOParam(cell, dlSf, ue, pdcch, rapId, prachMskIdx)
20348 RgSchCellCb  *cell;
20349 RgSchDlSf    *dlSf;
20350 RgSchUeCb    *ue;
20351 RgSchPdcch   **pdcch;
20352 uint8_t           *rapId;
20353 uint8_t           *prachMskIdx;
20354 #endif
20355 {
20356
20357    RgSchCmnCell    *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20358    RgSchCmnDlUe    *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20359
20360
20361    if (cell->macPreambleSet.pres == PRSNT_NODEF)
20362    {
20363       if (cellSch->rachCfg.remDedPrm == 0)
20364       {
20365          return RFAILED;
20366       }
20367       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
20368       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
20369       {
20370          return RFAILED;
20371       }
20372       /* The stored prachMskIdx is the index of PRACH Oppurtunities in
20373        * raOccasions.subframes[].
20374        * Converting the same to the actual PRACHMskIdx to be transmitted. */
20375       *prachMskIdx = cellSch->rachCfg.prachMskIndx + 1;
20376       /* Distribution starts from dedPrmStart till dedPrmStart + numDedPrm */
20377       *rapId =  cellSch->rachCfg.dedPrmStart +
20378          cellSch->rachCfg.numDedPrm - cellSch->rachCfg.remDedPrm;
20379       cellSch->rachCfg.remDedPrm--;
20380       /* Map UE with the allocated RapId */
20381       ueDl->rachInfo.asgnOppr = cellSch->rachCfg.applFrm;
20382       RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, cellSch->rachCfg.rapIdMap, (*rapId - cellSch->rachCfg.dedPrmStart));
20383       cmLListAdd2Tail(&cellSch->rachCfg.rapIdMap[*rapId - cellSch->rachCfg.dedPrmStart].assgndUes, 
20384              &ueDl->rachInfo.rapIdLnk);
20385       ueDl->rachInfo.rapIdLnk.node = (PTR)ue;
20386       ueDl->rachInfo.poRapId = *rapId;
20387    }
20388    else /* if dedicated preambles not configured */
20389    {
20390       /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
20391       if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP)
20392       {
20393          return RFAILED;
20394       }
20395       *prachMskIdx = 0;
20396       *rapId       = 0;
20397    }
20398
20399    return ROK;
20400 }
20401
20402 /**
20403  * @brief Dowlink Scheduling Handler.
20404  *
20405  * @details
20406  *
20407  *     Function: rgSCHCmnGenPdcchOrder
20408  *     Purpose:  For each UE in PO Q, grab a PDCCH,
20409  *     get an available ded RapId and fill PDCCH
20410  *     with PO information.
20411  *
20412  *     Invoked by: Common Scheduler
20413  *
20414  *  @param[in]  RgSchCellCb *cell
20415  *  @param[in]  RgSchDlSf   *dlSf
20416  *  @return  Void
20417  **/
20418 #ifdef ANSI
20419 static Void rgSCHCmnGenPdcchOrder
20420 (
20421 RgSchCellCb  *cell,
20422 RgSchDlSf    *dlSf
20423 )
20424 #else
20425 static Void rgSCHCmnGenPdcchOrder(cell, dlSf)
20426 RgSchCellCb  *cell;
20427 RgSchDlSf    *dlSf;
20428 #endif
20429 {
20430    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
20431    CmLList           *node = cellSch->rachCfg.pdcchOdrLst.first;
20432    RgSchUeCb         *ue;
20433    uint8_t                rapId;
20434    uint8_t                prachMskIdx;
20435    RgSchPdcch        *pdcch = NULLP;
20436
20437
20438    while (node)
20439    {
20440       ue = (RgSchUeCb *)node->node;
20441       node = node->next;
20442       /* Skip sending for this subframe is Measuring or inActive in UL due
20443        * to MeasGap or inactie due to DRX
20444        */
20445       if  ((ue->measGapCb.isMeasuring == TRUE) ||
20446            (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) ||
20447            (ue->isDrxEnabled &&
20448              ue->dl.dlInactvMask & RG_DRX_INACTIVE)
20449            )
20450       {
20451          continue;
20452       }
20453       if (rgSCHCmnAllocPOParam(cell, dlSf, ue, &pdcch, &rapId,\
20454                &prachMskIdx) != ROK)
20455       {
20456          /* No More rapIds left for the valid next avl Oppurtunity.
20457           * Unsatisfied UEs here would be given a chance, when the
20458           * prach Mask Index changes as per rachUpd every TTI */
20459
20460          /* PDDCH can also be ordered with rapId=0, prachMskIdx=0
20461           * so that UE triggers a RACH procedure with non-dedicated preamble.
20462           * But the implementation here does not do this. Instead, the "break"
20463           * here implies, that PDCCH Odr always given with valid rapId!=0,
20464           * prachMskIdx!=0 if dedicated preambles are configured.
20465           * If not configured, then trigger a PO with rapId=0,prchMskIdx=0*/
20466          break;
20467       }
20468       /* Fill pdcch with pdcch odr information */
20469       rgSCHCmnFillPdcchOdr2Sf(cell, ue, pdcch, rapId, prachMskIdx);
20470       /* Remove this UE from the PDCCH ORDER QUEUE */
20471       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
20472       /* Reset UE's power state */
20473       rgSCHPwrUeReset(cell, ue);
20474    }
20475    return;
20476 }
20477
20478 \f
20479 /**
20480  * @brief This function add UE to PdcchOdr Q if not already present.
20481  *
20482  * @details
20483  *
20484  *     Function: rgSCHCmnDlAdd2PdcchOdrQ
20485  *     Purpose:
20486  *
20487  *     Invoked by: CMN Scheduler
20488  *
20489  *  @param[in]  RgSchCellCb*  cell
20490  *  @param[in]  RgSchUeCb*    ue
20491  *  @return  Void
20492  *
20493  **/
20494 #ifdef ANSI
20495 static Void rgSCHCmnDlAdd2PdcchOdrQ
20496 (
20497 RgSchCellCb                *cell,
20498 RgSchUeCb                  *ue
20499 )
20500 #else
20501 static Void rgSCHCmnDlAdd2PdcchOdrQ(cell, ue)
20502 RgSchCellCb                *cell;
20503 RgSchUeCb                  *ue;
20504 #endif
20505 {
20506    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20507    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20508
20509
20510    if (ueDl->rachInfo.poLnk.node == NULLP)
20511    {
20512       cmLListAdd2Tail(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
20513       ueDl->rachInfo.poLnk.node = (PTR)ue;
20514    }
20515    return;
20516 }
20517
20518 \f
20519 /**
20520  * @brief This function rmvs UE to PdcchOdr Q if not already present.
20521  *
20522  * @details
20523  *
20524  *     Function: rgSCHCmnDlRmvFrmPdcchOdrQ
20525  *     Purpose:
20526  *
20527  *     Invoked by: CMN Scheduler
20528  *
20529  *  @param[in]  RgSchCellCb*  cell
20530  *  @param[in]  RgSchUeCb*    ue
20531  *  @return  Void
20532  *
20533  **/
20534 #ifdef ANSI
20535 static Void rgSCHCmnDlRmvFrmPdcchOdrQ
20536 (
20537 RgSchCellCb                *cell,
20538 RgSchUeCb                  *ue
20539 )
20540 #else
20541 static Void rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue)
20542 RgSchCellCb                *cell;
20543 RgSchUeCb                  *ue;
20544 #endif
20545 {
20546    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20547    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20548
20549
20550    cmLListDelFrm(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk);
20551    ueDl->rachInfo.poLnk.node = NULLP;
20552    return;
20553 }
20554
20555 /**
20556  * @brief Fill pdcch with PDCCH order information.
20557  *
20558  * @details
20559  *
20560  *     Function: rgSCHCmnFillPdcchOdr2Sf
20561  *     Purpose:  Fill PDCCH with PDCCH order information,
20562  *
20563  *     Invoked by: Common Scheduler
20564  *
20565  *  @param[in]  RgSchUeCb   *ue
20566  *  @param[in]  RgSchPdcch  *pdcch
20567  *  @param[in]  uint8_t          rapId
20568  *  @param[in]  uint8_t          prachMskIdx
20569  *  @return  Void
20570  **/
20571 #ifdef ANSI
20572 static Void rgSCHCmnFillPdcchOdr2Sf
20573 (
20574 RgSchCellCb *cell,
20575 RgSchUeCb   *ue,
20576 RgSchPdcch  *pdcch,
20577 uint8_t          rapId,
20578 uint8_t          prachMskIdx
20579 )
20580 #else
20581 static Void rgSCHCmnFillPdcchOdr2Sf(ue, pdcch, rapId, prachMskIdx)
20582 RgSchCellCb *cell;
20583 RgSchUeCb   *ue;
20584 RgSchPdcch  *pdcch;
20585 uint8_t          rapId;
20586 uint8_t          prachMskIdx;
20587 #endif
20588 {
20589    RgSchUeACqiCb  *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); 
20590
20591
20592    pdcch->rnti                                         = ue->ueId;
20593    pdcch->dci.dciFormat                                = TFU_DCI_FORMAT_1A;
20594    pdcch->dci.u.format1aInfo.isPdcchOrder = TRUE;
20595    pdcch->dci.u.format1aInfo.t.pdcchOrder.preambleIdx  = rapId;
20596    pdcch->dci.u.format1aInfo.t.pdcchOrder.prachMaskIdx = prachMskIdx;
20597
20598    /* Request for APer CQI immediately after PDCCH Order */
20599    /* CR ccpu00144525 */
20600 #ifdef TFU_UPGRADE
20601    if(ue->dl.ueDlCqiCfg.aprdCqiCfg.pres)
20602    {
20603       ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC;
20604       acqiCb->aCqiTrigWt = 0;
20605    }
20606 #endif   
20607
20608    return;
20609 }
20610
20611 \f
20612 /**
20613  * @brief UE deletion for scheduler.
20614  *
20615  * @details
20616  *
20617  *     Function : rgSCHCmnDelRachInfo
20618  *
20619  *     This functions deletes all scheduler information
20620  *     pertaining to an UE.
20621  *
20622  *  @param[in]  RgSchCellCb  *cell
20623  *  @param[in]  RgSchUeCb    *ue
20624  *  @return  Void
20625  **/
20626 #ifdef ANSI
20627 static Void rgSCHCmnDelRachInfo
20628 (
20629 RgSchCellCb  *cell,
20630 RgSchUeCb    *ue
20631 )
20632 #else
20633 static Void rgSCHCmnDelRachInfo(cell, ue)
20634 RgSchCellCb  *cell;
20635 RgSchUeCb    *ue;
20636 #endif
20637 {
20638    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
20639    RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20640    uint8_t            rapIdIdx;
20641
20642
20643    if (ueDl->rachInfo.poLnk.node)
20644    {
20645       rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue);
20646    }
20647    if (ueDl->rachInfo.hoLnk.node)
20648    {
20649       cmLListDelFrm(&cellSch->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk);
20650       ueDl->rachInfo.hoLnk.node = NULLP;
20651    }
20652    if (ueDl->rachInfo.rapIdLnk.node)
20653    {
20654       rapIdIdx = ueDl->rachInfo.poRapId - cellSch->rachCfg.dedPrmStart;
20655       cmLListDelFrm(&cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes, 
20656           &ueDl->rachInfo.rapIdLnk);
20657       ueDl->rachInfo.rapIdLnk.node = NULLP;
20658    }
20659    return;
20660 }
20661
20662 /**
20663  * @brief This function retrieves the ue which has sent this raReq
20664  * and it allocates grant for UEs undergoing (for which RAR
20665  * is being generated) HandOver/PdcchOrder.
20666  *
20667  *
20668  * @details
20669  *
20670  *     Function: rgSCHCmnHdlHoPo
20671  *     Purpose:  This function  retrieves the ue which has sent this raReq
20672  *               and it allocates grant for UEs undergoing (for which RAR
20673  *               is being generated) HandOver/PdcchOrder.
20674  *
20675  *     Invoked by: Common Scheduler
20676  *
20677  *  @param[in]  RgSchCellCb           *cell
20678  *  @param[out] CmLListCp             *raRspLst
20679  *  @param[in]  RgSchRaReqInfo        *raReq
20680  *  @return  Void
20681  *
20682  **/
20683 #ifdef ANSI
20684 static Void rgSCHCmnHdlHoPo
20685 (
20686 RgSchCellCb           *cell,
20687 CmLListCp             *raRspLst,
20688 RgSchRaReqInfo        *raReq
20689 )
20690 #else
20691 static Void rgSCHCmnHdlHoPo(cell, raRspLst, raReq)
20692 RgSchCellCb           *cell;
20693 CmLListCp             *raRspLst;
20694 RgSchRaReqInfo        *raReq;
20695 #endif
20696 {
20697    RgSchUeCb             *ue = raReq->ue;
20698
20699    if ( ue->isDrxEnabled )
20700    {
20701       rgSCHDrxDedRa(cell,ue);
20702    }
20703    rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq);
20704    return;
20705 }
20706
20707 /**
20708  * @brief This function retrieves the UE which has sent this raReq
20709  * for handover case.
20710  *
20711  *
20712  * @details
20713  *
20714  *     Function: rgSCHCmnGetHoUe
20715  *     Purpose:  This function retrieves the UE which has sent this raReq
20716  *     for handover case.
20717  *
20718  *     Invoked by: Common Scheduler
20719  *
20720  *  @param[in]  RgSchCellCb           *cell
20721  *  @param[in]  RgSchRaReqInfo        *raReq
20722  *  @return  RgSchUeCb*
20723  *
20724  **/
20725 #ifdef ANSI
20726 RgSchUeCb* rgSCHCmnGetHoUe
20727 (
20728 RgSchCellCb           *cell,
20729 uint16_t                   rapId
20730 )
20731 #else
20732 RgSchUeCb* rgSCHCmnGetHoUe(cell, rapId)
20733 RgSchCellCb           *cell;
20734 uint16_t                   rapId
20735 #endif
20736 {
20737    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20738    CmLList               *node;
20739    CmLListCp             *ueLst;
20740    RgSchUeCb             *ue;
20741    RgSchCmnDlUe          *ueDl;
20742
20743    ueLst = &cellSch->rachCfg.hoUeLst;
20744    node = ueLst->first;
20745    while (node)
20746    {
20747       ue = (RgSchUeCb *)node->node;
20748       node = node->next;
20749       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20750       if (ueDl->rachInfo.hoRapId == rapId)
20751       {
20752          return (ue);
20753       }
20754    }
20755    return (NULLP);
20756 }
20757
20758 #ifdef ANSI
20759 static Void rgSCHCmnDelDedPreamble
20760 (
20761 RgSchCellCb           *cell,
20762 uint8_t                    preambleId
20763 )
20764 #else
20765 static rgSCHCmnDelDedPreamble(cell, preambleId)
20766 RgSchCellCb           *cell;
20767 uint8_t                    preambleId;
20768 #endif
20769 {
20770    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20771    CmLList               *node;
20772    CmLListCp             *ueLst;
20773    RgSchUeCb             *ue;
20774    RgSchCmnDlUe          *ueDl;
20775
20776    ueLst = &cellSch->rachCfg.hoUeLst;
20777    node = ueLst->first;
20778    while (node)
20779    {
20780       ue = (RgSchUeCb *)node->node;
20781       node = node->next;
20782       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20783       if (ueDl->rachInfo.hoRapId == preambleId)
20784       {
20785          cmLListDelFrm(ueLst, &ueDl->rachInfo.hoLnk);
20786          ueDl->rachInfo.hoLnk.node = (PTR)NULLP;
20787       }
20788    }
20789 }
20790
20791 /**
20792  * @brief This function retrieves the UE which has sent this raReq
20793  * for PDCCh Order case.
20794  *
20795  *
20796  * @details
20797  *
20798  *     Function: rgSCHCmnGetPoUe
20799  *     Purpose:  This function retrieves the UE which has sent this raReq
20800  *     for PDCCH Order case.
20801  *
20802  *     Invoked by: Common Scheduler
20803  *
20804  *  @param[in]  RgSchCellCb           *cell
20805  *  @param[in]  RgSchRaReqInfo        *raReq
20806  *  @return  RgSchUeCb*
20807  *
20808  **/
20809 #ifdef ANSI
20810 RgSchUeCb* rgSCHCmnGetPoUe
20811 (
20812 RgSchCellCb           *cell,
20813 uint16_t              rapId,
20814 CmLteTimingInfo       timingInfo
20815 )
20816 #else
20817 RgSchUeCb* rgSCHCmnGetPoUe(cell, rapId, timingInfo)
20818 RgSchCellCb           *cell;
20819 uint16_t              rapId;
20820 CmLteTimingInfo       timingInfo;
20821 #endif
20822 {
20823    RgSchCmnCell          *cellSch = (RgSchCmnCell *)(cell->sc.sch);
20824    CmLList               *node;
20825    CmLListCp             *ueLst;
20826    RgSchUeCb             *ue;
20827    RgSchCmnDlUe          *ueDl;
20828    uint8_t                rapIdIdx;
20829
20830    rapIdIdx = rapId -cellSch->rachCfg.dedPrmStart;
20831    ueLst = &cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes;
20832    node = ueLst->first;
20833    while (node)
20834    {
20835       ue = (RgSchUeCb *)node->node;
20836       node = node->next;
20837       ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
20838       /* Remove UEs irrespective.
20839        * Old UE associations are removed.*/
20840       cmLListDelFrm(ueLst, &ueDl->rachInfo.rapIdLnk);
20841       ueDl->rachInfo.rapIdLnk.node = (PTR)NULLP;
20842       if (RGSCH_TIMEINFO_SAME(ueDl->rachInfo.asgnOppr, timingInfo))
20843       {
20844          return (ue);
20845       }
20846    }
20847
20848    return (NULLP);
20849 }
20850
20851
20852 /**
20853  * @brief This function returns the valid UL cqi for a given UE.
20854  *
20855  * @details
20856  *
20857  *     Function: rgSCHCmnUlGetCqi
20858  *     Purpose:  This function returns the "valid UL cqi" for a given UE
20859  *               based on UE category
20860  *
20861  *     Invoked by: Scheduler
20862  *     
20863  *  @param[in]  RgSchUeCb        *ue
20864  *  @param[in]  uint8_t               ueCtgy
20865  *  @return     uint8_t 
20866  **/
20867 #ifdef ANSI
20868 uint8_t rgSCHCmnUlGetCqi
20869 (
20870 RgSchCellCb      *cell,
20871 RgSchUeCb        *ue,
20872 CmLteUeCategory  ueCtgy
20873 )
20874 #else
20875 uint8_t rgSCHCmnUlGetCqi(cell, ue, ueCtgy)
20876 RgSchCellCb      *cell;
20877 RgSchUeCb        *ue;
20878 CmLteUeCategory  ueCtgy;
20879 #endif
20880 {
20881    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
20882    uint8_t            cqi;
20883
20884    
20885    cqi = ueUl->maxUlCqi;
20886 #ifdef TFU_UPGRADE
20887    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
20888         (ueUl->validUlCqi > ueUl->maxUlCqi)))
20889    {
20890       cqi = ueUl->validUlCqi;
20891    }
20892 #else   
20893    if (!((ueCtgy != CM_LTE_UE_CAT_5) && 
20894          (ueUl->crntUlCqi[0] > ueUl->maxUlCqi )))
20895    {
20896       cqi = ueUl->crntUlCqi[0];
20897    }
20898 #endif    
20899    return (cqi);
20900 }/* End of rgSCHCmnUlGetCqi */
20901
20902 /***********************************************************
20903  *
20904  *     Func : rgSCHCmnUlRbAllocForPoHoUe
20905  *
20906  *     Desc : Do uplink RB allocation for a HO/PO UE.
20907  *
20908  *     Ret  :
20909  *
20910  *     Notes: Note that as of now, for retx, maxRb
20911  *            is not considered. Alternatives, such
20912  *            as dropping retx if it crosses maxRb
20913  *            could be considered.
20914  *
20915  *     File :
20916  *
20917  **********************************************************/
20918 #ifdef ANSI
20919 static S16 rgSCHCmnUlRbAllocForPoHoUe
20920 (
20921 RgSchCellCb           *cell,
20922 RgSchUlSf             *sf,
20923 RgSchUeCb             *ue,
20924 uint8_t                    maxRb
20925 )
20926 #else
20927 static S16 rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, maxRb)
20928 RgSchCellCb           *cell;
20929 RgSchUlSf             *sf;
20930 RgSchUeCb             *ue;
20931 uint8_t                    maxRb;
20932 #endif
20933 {
20934    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
20935    RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(ue,cell);
20936    uint8_t           sbSize  = cellUl->sbSize;
20937    uint32_t          maxBits = ue->ul.maxBytesPerUePerTti*8;
20938    uint32_t          bits;
20939    RgSchUlAlloc *alloc;
20940    uint32_t          nPrb;
20941    uint8_t           iTbs;
20942    uint32_t          eff;
20943    uint32_t          numSb;
20944    uint8_t           iMcs;
20945    uint8_t           iMcsCrnt;
20946    uint8_t           cqi;
20947    uint8_t           modOdr;
20948    RgSchUlHole      *hole;
20949    RgSchUlHqProcCb  *proc = &ueUl->hqEnt.hqProcCb[cellUl->msg3SchdHqProcIdx];
20950    CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue));
20951
20952    if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
20953    {
20954       return RFAILED;
20955    }
20956    /*MS_WORKAROUND for HO ccpu00121116*/
20957    cqi   = rgSCHCmnUlGetCqi(cell, ue, ueCtg);
20958    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend], cqi);
20959    iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
20960    iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg);
20961    while(iMcs > RG_SCH_CMN_MAX_MSG3_IMCS)
20962    {
20963        cqi--;
20964        iTbs  = rgSchCmnUlCqiToTbsTbl[(uint8_t)cell->isCpUlExtend][cqi];
20965        iMcs  = rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg);
20966    }
20967    /* Filling the modorder in the grant structure*/
20968    RG_SCH_UL_MCS_TO_MODODR(iMcs,modOdr);
20969    if (!cell->isCpUlExtend)
20970    {
20971       eff   = rgSchCmnNorUlEff[0][iTbs];
20972    }
20973    else
20974    {
20975       eff   = rgSchCmnExtUlEff[0][iTbs];
20976    }
20977
20978    bits = ueUl->alloc.reqBytes * 8;
20979
20980 #if (ERRCLASS & ERRCLS_DEBUG)
20981    if (!bits)
20982    {
20983       return RFAILED;
20984    }
20985 #endif
20986
20987    if (bits < rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs))
20988    {
20989       numSb = 1;
20990       nPrb = numSb * sbSize;
20991    }
20992    else
20993    {
20994       if (bits > maxBits)
20995       {
20996          bits  = maxBits;
20997          nPrb  = bits * 1024 / eff / RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl);
20998          if (nPrb > maxRb)
20999          {
21000             nPrb = maxRb;
21001          }
21002          numSb = nPrb / sbSize;
21003       }
21004       else
21005       {
21006          /*ccpu00128775:MOD-Change to get upper threshold nPrb*/
21007          nPrb = RGSCH_CEIL((RGSCH_CEIL(bits * 1024, eff)),
21008                   RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl));
21009          if (nPrb > maxRb)
21010          {
21011             nPrb = maxRb;
21012          }
21013          numSb = RGSCH_DIV_ROUND(nPrb, sbSize);
21014       }
21015    }
21016    iMcsCrnt = iMcs;
21017
21018    alloc = rgSCHCmnUlSbAlloc(sf, (uint8_t)RGSCH_MIN(numSb, cellUl->maxSbPerUe),\
21019                              hole);
21020    if (alloc == NULLP)
21021    {
21022       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
21023          "rgSCHCmnUlRbAllocForPoHoUe(): Could not get UlAlloc");
21024       return RFAILED;
21025    }
21026    rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
21027    
21028    /* Filling the modorder in the grant structure start*/
21029    alloc->grnt.modOdr = (TfuModScheme) modOdr;
21030    alloc->grnt.iMcs = iMcs;
21031    alloc->grnt.iMcsCrnt = iMcsCrnt;
21032    alloc->grnt.hop = 0;
21033    /* Fix for ccpu00123915*/
21034    alloc->forMsg3 = TRUE;
21035    alloc->hqProc = proc;
21036    alloc->hqProc->ulSfIdx = cellUl->msg3SchdIdx;
21037    alloc->ue = ue;
21038    alloc->rnti = ue->ueId;
21039    /* updating initNumRbs in case of HO */
21040 #ifdef TFU_UPGRADE
21041    ue->initNumRbs = alloc->grnt.numRb;
21042 #endif
21043    ueUl->alloc.alloc = alloc;
21044    iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs);
21045    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs);
21046    alloc->grnt.datSz    = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8;
21047    /* MS_WORKAROUND for HO ccpu00121124*/
21048    /*[Adi temp change] Need to fil modOdr */
21049    RG_SCH_UL_MCS_TO_MODODR(alloc->grnt.iMcsCrnt,alloc->grnt.modOdr);
21050    rgSCHUhmNewTx(proc, ueUl->hqEnt.maxHqRetx, alloc);
21051    /* No grant attr recorded now */
21052    return ROK;
21053 }
21054
21055 /**
21056  * @brief This function allocates grant for UEs undergoing (for which RAR
21057  * is being generated) HandOver/PdcchOrder.
21058  *
21059  *
21060  * @details
21061  *
21062  *     Function: rgSCHCmnAllocPoHoGrnt
21063  *     Purpose:  This function allocates grant for UEs undergoing (for which RAR
21064  *               is being generated) HandOver/PdcchOrder.
21065  *
21066  *     Invoked by: Common Scheduler
21067  *
21068  *  @param[in]  RgSchCellCb           *cell
21069  *  @param[out] CmLListCp             *raRspLst,
21070  *  @param[in]  RgSchUeCb             *ue
21071  *  @param[in]  RgSchRaReqInfo        *raReq
21072  *  @return  Void
21073  *
21074  **/
21075 #ifdef ANSI
21076 static Void rgSCHCmnAllocPoHoGrnt
21077 (
21078 RgSchCellCb           *cell,
21079 CmLListCp             *raRspLst,
21080 RgSchUeCb             *ue,
21081 RgSchRaReqInfo        *raReq
21082 )
21083 #else
21084 static Void rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq)
21085 RgSchCellCb           *cell;
21086 CmLListCp             *raRspLst;
21087 RgSchUeCb             *ue;
21088 RgSchRaReqInfo        *raReq;
21089 #endif
21090 {
21091    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21092    RgSchCmnUlUe    *ueUl   = RG_SCH_CMN_GET_UL_UE(ue,cell);
21093    RgSchUlGrnt     *grnt;
21094    RgSchUlSf       *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx];
21095
21096
21097    /* Clearing previous allocs if any*/
21098    rgSCHCmnUlUeDelAllocs(cell, ue);
21099    /* Fix : syed allocs are limited */
21100    if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf)
21101    {
21102       return;
21103    }
21104    ueUl->alloc.reqBytes = RG_SCH_MIN_GRNT_HOPO;
21105    if (rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, RGSCH_MAX_UL_RB) != ROK)
21106    {
21107       return;
21108    }
21109
21110    /* Fill grant information */
21111    grnt = &ueUl->alloc.alloc->grnt;
21112
21113    /* KWork fix */
21114    if (grnt == NULLP)
21115    {
21116       RLOG_ARG1(L_ERROR,DBG_INSTID,cell->instIdx,  "Failed to get"
21117         "the grant for HO/PDCCH Order. CRNTI:%d",ue->ueId);
21118       return;
21119    }
21120    ue->ul.rarGrnt.rapId = raReq->raReq.rapId;
21121    ue->ul.rarGrnt.hop = grnt->hop;
21122    ue->ul.rarGrnt.rbStart = grnt->rbStart;
21123    ue->ul.rarGrnt.numRb = grnt->numRb;
21124    ue->ul.rarGrnt.tpc = grnt->tpc;
21125    ue->ul.rarGrnt.iMcsCrnt = grnt->iMcsCrnt;
21126    ue->ul.rarGrnt.ta.pres = TRUE;
21127    ue->ul.rarGrnt.ta.val = raReq->raReq.ta;
21128    ue->ul.rarGrnt.datSz = grnt->datSz;
21129    if((sf->numACqiCount < RG_SCH_MAX_ACQI_PER_ULSF) && (RG_SCH_APCQI_NO != ue->dl.reqForCqi)) 
21130    {
21131 #ifdef LTE_ADV
21132       uint8_t    idx = 0; 
21133       /* Send two bits cqireq field if more than one cells are configured else one*/
21134       for (idx = 1;idx < CM_LTE_MAX_CELLS;idx++)
21135       {
21136          if (ue->cellInfo[idx] != NULLP)
21137          {
21138             ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
21139             break;
21140          }
21141       }
21142       if (idx == CM_LTE_MAX_CELLS)
21143 #endif
21144       {
21145          ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi;
21146       }
21147       ue->dl.reqForCqi = RG_SCH_APCQI_NO;
21148       sf->numACqiCount++;
21149    }
21150    else
21151    {
21152       ue->ul.rarGrnt.cqiReqBit = 0;
21153    }
21154    /* Attach Ho/Po allocation to RAR Rsp cont free Lst */
21155    cmLListAdd2Tail(raRspLst, &ue->ul.rarGrnt.raRspLnk);
21156    ue->ul.rarGrnt.raRspLnk.node = (PTR)ue;
21157
21158    return;
21159 }
21160
21161 /**
21162  * @brief This is a utility function to set the fields in
21163  * an UL harq proc which is identified for non-adaptive retx
21164  *
21165  * @details
21166  *
21167  *     Function: rgSCHCmnUlNonadapRetx 
21168  *     Purpose:  Sets the fields in UL Harq  proc for non-adaptive retx 
21169  *
21170  * @param[in]  RgSchCmnUlCell  *cellUl 
21171  * @param[out] RgSchUlAlloc    *alloc
21172  * @param[in]  uint8_t              idx 
21173  * @return  Void
21174  *
21175  **/
21176 #ifdef UNUSED_FUNC
21177 #ifdef ANSI
21178 static Void rgSCHCmnUlNonadapRetx
21179 (
21180 RgSchCmnUlCell  *cellUl,
21181 RgSchUlAlloc    *alloc,
21182 uint8_t              idx
21183 )
21184 #else
21185 static Void rgSCHCmnUlNonadapRetx(cellUl, alloc, idx)
21186 RgSchCmnUlCell  *cellUl;
21187 RgSchUlAlloc    *alloc;
21188 uint8_t              idx;
21189 #endif
21190 {
21191    rgSCHUhmRetx(alloc->hqProc, alloc);
21192
21193    /* Update alloc to retx */
21194    alloc->hqProc->isRetx = TRUE;
21195    alloc->hqProc->ulSfIdx = cellUl->reTxIdx[idx];
21196
21197    if (alloc->hqProc->rvIdx != 0)
21198    {
21199       alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[alloc->hqProc->rvIdx];
21200    }
21201    else
21202    {
21203       alloc->grnt.iMcsCrnt = alloc->grnt.iMcs;
21204    }
21205    alloc->grnt.isRtx = TRUE;
21206    alloc->pdcch = NULLP;
21207    return;
21208 }
21209 /**
21210  * @brief Check if 2 allocs overlap
21211  *
21212  * @details
21213  *
21214  *     Function : rgSCHCmnUlAllocsOvrLap
21215  *
21216  *      - Return TRUE if alloc1 and alloc2 overlap.
21217  *
21218  *  @param[in]  RgSchUlAlloc  *alloc1
21219  *  @param[in]  RgSchUlAlloc  *alloc2
21220  *  @return  Bool
21221  **/
21222 #ifdef ANSI
21223 static Bool rgSCHCmnUlAllocsOvrLap
21224 (
21225 RgSchUlAlloc    *alloc1,
21226 RgSchUlAlloc    *alloc2
21227 )
21228 #else
21229 static Bool rgSCHCmnUlAllocsOvrLap(alloc1, alloc2)
21230 RgSchUlAlloc    *alloc1;
21231 RgSchUlAlloc    *alloc2;
21232 #endif
21233 {
21234
21235
21236    if (((alloc1->sbStart >= alloc2->sbStart) &&
21237          (alloc1->sbStart <= alloc2->sbStart + alloc2->numSb-1)) ||
21238         ((alloc2->sbStart >= alloc1->sbStart) &&
21239          (alloc2->sbStart <= alloc1->sbStart + alloc1->numSb-1)))
21240    {
21241       return (TRUE);
21242    }
21243    return (FALSE);
21244 }
21245 /**
21246  * @brief Copy allocation Info from src to dst.
21247  *
21248  * @details
21249  *
21250  *     Function : rgSCHCmnUlCpyAllocInfo
21251  *
21252  *      - Copy allocation Info from src to dst.
21253  *
21254  *  @param[in]  RgSchUlAlloc  *srcAlloc
21255  *  @param[in]  RgSchUlAlloc  *dstAlloc
21256  *  @return  Void
21257  **/
21258 #ifdef ANSI
21259 static Void rgSCHCmnUlCpyAllocInfo
21260 (
21261 RgSchCellCb     *cell,
21262 RgSchUlAlloc    *srcAlloc,
21263 RgSchUlAlloc    *dstAlloc
21264 )
21265 #else
21266 static Void rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc)
21267 RgSchCellCb     *cell;
21268 RgSchUlAlloc    *srcAlloc;
21269 RgSchUlAlloc    *dstAlloc;
21270 #endif
21271 {
21272    RgSchCmnUlUe *ueUl;
21273
21274    dstAlloc->grnt = srcAlloc->grnt;
21275    dstAlloc->hqProc = srcAlloc->hqProc;
21276    /* Fix : syed During UE context release, hqProc->alloc
21277     * was pointing to srcAlloc instead of dstAlloc and
21278     * freeing from incorrect sf->allocDb was
21279     * corrupting the list. */
21280     /* In case of SPS Occasion Allocation is done in advance and 
21281        at a later time Hq Proc is linked. Hence HqProc
21282        pointer in alloc shall be NULL */
21283 #ifdef LTEMAC_SPS
21284    if (dstAlloc->hqProc)
21285 #endif
21286    {
21287       dstAlloc->hqProc->alloc = dstAlloc;
21288    }
21289    dstAlloc->ue = srcAlloc->ue;
21290    dstAlloc->rnti = srcAlloc->rnti;
21291    dstAlloc->forMsg3 = srcAlloc->forMsg3;
21292    dstAlloc->raCb  = srcAlloc->raCb;
21293    dstAlloc->pdcch = srcAlloc->pdcch;
21294    /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
21295    if (dstAlloc->ue)
21296    {
21297       ueUl = RG_SCH_CMN_GET_UL_UE(dstAlloc->ue,cell);
21298       ueUl->alloc.alloc = dstAlloc;
21299 #ifdef LTEMAC_SPS
21300       if (dstAlloc->ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
21301       {
21302          if((dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc != NULLP)
21303                && (dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc == srcAlloc))
21304          {
21305             dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc = dstAlloc;
21306          }
21307       }
21308 #endif
21309    }
21310
21311    return;
21312 }
21313 /**
21314  * @brief Update TX and RETX subframe's allocation
21315  *        markings.
21316  *
21317  * @details
21318  *
21319  *     Function : rgSCHCmnUlInsAllocFrmNewSf2OldSf
21320  *
21321  *      - Release all preassigned allocations of newSf and merge
21322  *        them to oldSf.
21323  *      - If alloc of newSf collide with one or more allocs of oldSf
21324  *        - mark all such allocs of oldSf for Adaptive Retx.
21325  *      - Swap the alloc and hole DB references of oldSf and newSf.
21326  *
21327  *  @param[in]  RgSchCellCb   *cell
21328  *  @param[in]  RgSchUlSf     *newSf
21329  *  @param[in]  RgSchUlSf     *oldSf
21330  *  @param[in]  RgSchUlAlloc  *srcAlloc
21331  *  @return  Void
21332  **/
21333 #ifdef ANSI
21334 static Void rgSCHCmnUlInsAllocFrmNewSf2OldSf
21335 (
21336 RgSchCellCb     *cell,
21337 RgSchUlSf       *newSf,
21338 RgSchUlSf       *oldSf,
21339 RgSchUlAlloc    *srcAlloc
21340 )
21341 #else
21342 static Void rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, srcAlloc)
21343 RgSchCellCb     *cell;
21344 RgSchUlSf       *newSf;
21345 RgSchUlSf       *oldSf;
21346 RgSchUlAlloc    *srcAlloc;
21347 #endif
21348 {
21349    RgSchUlAlloc   *alloc, *dstAlloc, *nxtAlloc;
21350
21351    /* MS_WORKAROUND ccpu00120827 */
21352    RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
21353    uint8_t remAllocs;
21354
21355    if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
21356    {
21357       do
21358       {
21359          nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);
21360          /* If there is an overlap between alloc and srcAlloc
21361           * then alloc is marked for Adaptive retx and it is released
21362           * from txSf */
21363          if (rgSCHCmnUlAllocsOvrLap(alloc, srcAlloc) == TRUE)
21364          {
21365             rgSCHCmnUlUpdAllocRetx(cell, alloc);
21366             rgSCHUtlUlAllocRls(oldSf, alloc);
21367          }
21368          /* No further allocs spanning the srcAlloc subbands */
21369          if (srcAlloc->sbStart + srcAlloc->numSb - 1  <= alloc->sbStart)
21370          {
21371             break;
21372          }
21373       } while ((alloc = nxtAlloc) != NULLP);
21374    }
21375
21376    /* After freeing all the colliding allocs, request for an allocation
21377     * specifying the start and numSb with in txSf. This function should
21378     * always return positively with a nonNULL dstAlloc */
21379     /* MS_WORKAROUND ccpu00120827 */
21380    remAllocs = schCmnCell->ul.maxAllocPerUlSf - *oldSf->allocCountRef;
21381    if (!remAllocs)
21382    {
21383       /* Fix : If oldSf already has max Allocs then release the
21384        * old RETX alloc to make space for new alloc of newSf.
21385        * newSf allocs(i.e new Msg3s) are given higher priority
21386        * over retx allocs. */      
21387       if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP)
21388       {
21389          do
21390          {
21391             nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc);           
21392             if (!alloc->mrgdNewTxAlloc)
21393             {
21394                /* If alloc is for RETX */                   
21395                /* TODO: Incase of this ad also in case of choosing
21396                 * and alloc for ADAP RETX, we need to send ACK for
21397                 * the corresponding alloc in PHICH */               
21398 #ifndef EMTC_ENABLE
21399                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc);
21400 #else
21401                rgSCHCmnUlFreeAllocation(cell, oldSf, alloc,FALSE);
21402 #endif
21403                break;
21404             }               
21405          }while((alloc = nxtAlloc) != NULLP);
21406       }
21407    }
21408    dstAlloc = rgSCHUtlUlGetSpfcAlloc(oldSf, srcAlloc->sbStart, srcAlloc->numSb);
21409 #ifdef ERRCLS_KW
21410    /* This should never happen */
21411    if (dstAlloc == NULLP)
21412    {
21413       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d "
21414          "rgSCHUtlUlGetSpfcAlloc failed in rgSCHCmnUlInsAllocFrmNewSf2OldSf",
21415          srcAlloc->rnti);
21416       return;
21417    }
21418 #endif
21419    /* Copy the srcAlloc's state information in to dstAlloc */
21420    rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc);
21421    /* Set new Tx merged Alloc Flag to TRUE, indicating that this
21422     * alloc shall not be processed for non-adaptive retransmission */
21423    dstAlloc->mrgdNewTxAlloc = TRUE;
21424    return;
21425 }
21426 /**
21427  * @brief Merge all allocations of newSf to oldSf.
21428  *
21429  * @details
21430  *
21431  *     Function : rgSCHCmnUlMergeSfAllocs
21432  *
21433  *      - Merge all allocations of newSf to oldSf.
21434  *      - If newSf's alloc collides with oldSf's alloc
21435  *        then oldSf's alloc is marked for adaptive Retx
21436  *        and is released from oldSf to create space for
21437  *        newSf's alloc.
21438  *
21439  *  @param[in]  RgSchCellCb  *cell
21440  *  @param[in]  RgSchUlSf    *oldSf
21441  *  @param[in]  RgSchUlSf    *newSf
21442  *  @return  Void
21443  **/
21444 #ifdef ANSI
21445 static Void rgSCHCmnUlMergeSfAllocs
21446 (
21447 RgSchCellCb  *cell,
21448 RgSchUlSf    *oldSf,
21449 RgSchUlSf    *newSf
21450 )
21451 #else
21452 static Void rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf)
21453 RgSchCellCb  *cell;
21454 RgSchUlSf    *oldSf;
21455 RgSchUlSf    *newSf;
21456 #endif
21457 {
21458    RgSchUlAlloc    *alloc, *nxtAlloc;
21459    UNUSED(cell);
21460
21461    /* Merge each alloc of newSf in to oldSf
21462     * and release it from newSf */
21463    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
21464    {
21465       do
21466       {
21467          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
21468          rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, alloc);
21469          rgSCHUtlUlAllocRls(newSf, alloc);
21470       } while((alloc = nxtAlloc) != NULLP);
21471    }
21472    return;
21473 }
21474 /**
21475  * @brief Swap Hole/Alloc DB context of newSf and oldSf.
21476  *
21477  * @details
21478  *
21479  *     Function : rgSCHCmnUlSwapSfAllocs
21480  *
21481  *      - Swap Hole/Alloc DB context of newSf and oldSf.
21482  *
21483  *  @param[in]  RgSchCellCb  *cell
21484  *  @param[in]  RgSchUlSf    *oldSf
21485  *  @param[in]  RgSchUlSf    *newSf
21486  *  @return  Void
21487  **/
21488 #ifdef ANSI
21489 static Void rgSCHCmnUlSwapSfAllocs
21490 (
21491 RgSchCellCb  *cell,
21492 RgSchUlSf    *oldSf,
21493 RgSchUlSf    *newSf
21494 )
21495 #else
21496 static Void rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf)
21497 RgSchCellCb  *cell;
21498 RgSchUlSf    *oldSf;
21499 RgSchUlSf    *newSf;
21500 #endif
21501 {
21502    RgSchUlAllocDb *tempAllocDb  = newSf->allocDb;
21503    RgSchUlHoleDb  *tempHoleDb   = newSf->holeDb;
21504    uint8_t              tempAvailSbs = newSf->availSubbands;
21505
21506    UNUSED(cell);
21507
21508    newSf->allocDb       = oldSf->allocDb;
21509    newSf->holeDb        = oldSf->holeDb;
21510    newSf->availSubbands = oldSf->availSubbands;
21511
21512    oldSf->allocDb = tempAllocDb;
21513    oldSf->holeDb  = tempHoleDb;
21514    oldSf->availSubbands = tempAvailSbs;
21515       
21516    /* Fix ccpu00120610*/
21517    newSf->allocCountRef = &newSf->allocDb->count;
21518    oldSf->allocCountRef = &oldSf->allocDb->count;
21519    return;
21520 }
21521 /**
21522  * @brief Perform non-adaptive RETX for non-colliding allocs.
21523  *
21524  * @details
21525  *
21526  *     Function : rgSCHCmnUlPrcNonAdptRetx
21527  *
21528  *      - Perform non-adaptive RETX for non-colliding allocs.
21529  *
21530  *  @param[in]  RgSchCellCb  *cell
21531  *  @param[in]  RgSchUlSf    *newSf
21532  *  @param[in]  uint8_t           idx
21533  *  @return  Void
21534  **/
21535 #ifdef ANSI
21536 static Void rgSCHCmnUlPrcNonAdptRetx
21537 (
21538 RgSchCellCb  *cell,
21539 RgSchUlSf    *newSf,
21540 uint8_t           idx
21541 )
21542 #else
21543 static Void rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx)
21544 RgSchCellCb  *cell;
21545 RgSchUlSf    *newSf;
21546 uint8_t           idx;
21547 #endif
21548 {
21549    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21550    RgSchUlAlloc    *alloc, *nxtAlloc;
21551
21552    /* perform non-adaptive retx allocation(adjustment) */
21553    if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP)
21554    {
21555       do
21556       {
21557          nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc);
21558          /* A merged new TX alloc, reset the state and skip */
21559          if (alloc->mrgdNewTxAlloc)
21560          {
21561             alloc->mrgdNewTxAlloc = FALSE;
21562             continue;
21563          }
21564          
21565
21566          rgSCHCmnUlNonadapRetx(cellUl, alloc, idx);
21567
21568       } while((alloc = nxtAlloc) != NULLP);
21569    }
21570    return;
21571 }
21572
21573 /**
21574  * @brief Update TX and RETX subframe's allocation
21575  *        markings.
21576  *
21577  * @details
21578  *
21579  *     Function : rgSCHCmnUlPrfmSfMerge
21580  *
21581  *      - Release all preassigned allocations of newSf and merge
21582  *        them to oldSf.
21583  *      - If alloc of newSf collide with one or more allocs of oldSf
21584  *        - mark all such allocs of oldSf for Adaptive Retx.
21585  *      - Swap the alloc and hole DB references of oldSf and newSf.
21586  *      - The allocs which did not collide with pre-assigned msg3
21587  *        allocs are marked for non-adaptive RETX.
21588  *
21589  *  @param[in]  RgSchCellCb  *cell
21590  *  @param[in]  RgSchUlSf    *oldSf
21591  *  @param[in]  RgSchUlSf    *newSf
21592  *  @param[in]  uint8_t           idx 
21593  *  @return  Void
21594  **/
21595 #ifdef ANSI
21596 static Void rgSCHCmnUlPrfmSfMerge
21597 (
21598 RgSchCellCb  *cell,
21599 RgSchUlSf    *oldSf,
21600 RgSchUlSf    *newSf,
21601 uint8_t           idx
21602 )
21603 #else
21604 static Void rgSCHCmnUlPrfmSfMerge(cell, oldSf, newSf, idx)
21605 RgSchCellCb  *cell;
21606 RgSchUlSf    *oldSf;
21607 RgSchUlSf    *newSf;
21608 uint8_t           idx;
21609 #endif
21610 {
21611    /* Preassigned resources for msg3 in newSf.
21612     * Hence do adaptive retx for all NACKED TXs */
21613    rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf);
21614    /* swap alloc and hole DBs of oldSf and newSf. */
21615    rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf);
21616    /* Here newSf has the resultant merged allocs context */
21617    /* Perform non-adaptive RETX for non-colliding allocs */
21618    rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx);
21619    
21620    return;
21621 }
21622 #endif
21623 /**
21624  * @brief Update TX and RETX subframe's allocation
21625  *        markings.
21626  *
21627  * @details
21628  *
21629  *     Function : rgSCHCmnUlRmvCmpltdAllocs
21630  *
21631  *      - Free all Transmission which are ACKED
21632  *        OR for which MAX retransmission have
21633  *        occurred.
21634  *
21635  *
21636  *  @param[in]  RgSchCellCb    *cell,
21637  *  @param[in]  RgSchUlSf      *sf
21638  *  @return  Void
21639  **/
21640 #ifdef ANSI
21641 static Void rgSCHCmnUlRmvCmpltdAllocs
21642 (
21643 RgSchCellCb    *cell,
21644 RgSchUlSf      *sf
21645 )
21646 #else
21647 static Void rgSCHCmnUlRmvCmpltdAllocs(cell, sf)
21648 RgSchCellCb    *cell;
21649 RgSchUlSf      *sf;
21650 #endif
21651 {
21652    RgSchUlAlloc    *alloc, *nxtAlloc;
21653
21654    if ((alloc = rgSCHUtlUlAllocFirst(sf)) == NULLP)
21655    {
21656       return;
21657    }
21658    do
21659    {
21660       nxtAlloc = rgSCHUtlUlAllocNxt(sf, alloc);
21661 #ifdef UL_ADPT_DBG      
21662       printf("rgSCHCmnUlRmvCmpltdAllocs:time(%d %d) alloc->hqProc->remTx %d hqProcId(%d) \n",cell->crntTime.sfn,cell->crntTime.slot,alloc->hqProc->remTx, alloc->grnt.hqProcId);
21663 #endif
21664       alloc->hqProc->rcvdCrcInd = TRUE;
21665       if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0))
21666       {
21667
21668         /* SR_RACH_STATS : MSG 3 MAX RETX FAIL*/
21669          if ((alloc->forMsg3 == TRUE) && (alloc->hqProc->remTx == 0))
21670          {
21671             rgNumMsg3FailMaxRetx++;
21672 #ifdef TENB_STATS
21673             cell->tenbStats->sch.msg3Fail++;
21674 #endif
21675          }
21676
21677 #ifdef MAC_SCH_STATS
21678     if(alloc->ue != NULLP)
21679     {
21680        /* access from ulHarqProc*/
21681        RgSchUeCb       *ueCb  = alloc->ue;
21682        RgSchCmnUe      *cmnUe = (RgSchCmnUe*)ueCb->sch;
21683        RgSchCmnUlUe    *ulUe  = &(cmnUe->ul);
21684        uint8_t              cqi    = ulUe->crntUlCqi[0];  
21685        uint16_t             numUlRetx = ueCb->ul.hqEnt.maxHqRetx - alloc->hqProc->remTx;
21686
21687        hqRetxStats.ulCqiStat[(cqi - 1)].mcs = alloc->grnt.iMcs;
21688
21689        switch (numUlRetx)
21690        {
21691           case 1:
21692              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1++;
21693              break;
21694           case 2:
21695              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2++;
21696              break;
21697          case 3:
21698             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3++;
21699             break;
21700          case 4:
21701             hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4++;
21702             break;
21703       }
21704       hqRetxStats.ulCqiStat[(cqi - 1)].totalTx = \
21705              hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1 + \
21706             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
21707             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
21708             (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4 * 4);
21709    }
21710
21711 #endif /*MAC_SCH_STATS*/
21712          rgSCHCmnUlFreeAllocation(cell, sf, alloc);
21713       }
21714       /*ccpu00106104 MOD added check for AckNackRep */
21715       /*added check for acknack so that adaptive retx considers ue
21716        inactivity due to ack nack repetition*/
21717       else if((alloc->ue != NULLP) && (TRUE != alloc->forMsg3))
21718       {
21719         rgSCHCmnUlUpdAllocRetx(cell, alloc);
21720         rgSCHUtlUlAllocRls(sf, alloc);
21721       }
21722    } while ((alloc = nxtAlloc) != NULLP);
21723
21724    return;
21725 }
21726
21727 /**
21728  * @brief Update an uplink subframe.
21729  *
21730  * @details
21731  *
21732  *     Function : rgSCHCmnRlsUlSf
21733  *
21734  *     For each allocation
21735  *      - if no more tx needed
21736  *         - Release allocation
21737  *      - else
21738  *         - Perform retransmission
21739  *
21740  *  @param[in]  RgSchUlSf *sf
21741  *  @param[in]  uint8_t        idx 
21742  *  @return  Void
21743  **/
21744 #ifdef ANSI
21745 Void rgSCHCmnRlsUlSf
21746 (
21747 RgSchCellCb    *cell,
21748 uint8_t              idx
21749 )
21750 #else
21751 Void rgSCHCmnRlsUlSf(cell, idx)
21752 RgSchCellCb    *cell;
21753 uint8_t              idx;
21754 #endif
21755 {
21756
21757    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21758    
21759    if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) 
21760    {
21761       RgSchUlSf   *oldSf  = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]];
21762
21763       /* Initialize the reTxLst of UL HqProcs for RETX subframe */
21764       if (rgSCHUtlUlAllocFirst(oldSf) == NULLP)
21765       {
21766          return;
21767       }
21768       /* Release all completed TX allocs from sf */
21769       rgSCHCmnUlRmvCmpltdAllocs(cell, oldSf);
21770
21771       oldSf->numACqiCount = 0;
21772    }
21773    return;
21774 }
21775
21776 /**
21777  * @brief Handle uplink allocation for retransmission.
21778  *
21779  * @details
21780  *
21781  *     Function : rgSCHCmnUlUpdAllocRetx
21782  *
21783  *     - Perform adaptive retransmission
21784  *
21785  *  @param[in]  RgSchUlSf *sf
21786  *  @param[in]  RgSchUlAlloc  *alloc
21787  *  @return  Void
21788  **/
21789 #ifdef ANSI
21790 static Void rgSCHCmnUlUpdAllocRetx
21791 (
21792 RgSchCellCb    *cell,
21793 RgSchUlAlloc   *alloc
21794 )
21795 #else
21796 static Void rgSCHCmnUlUpdAllocRetx(cell, alloc)
21797 RgSchCellCb    *cell;
21798 RgSchUlAlloc   *alloc;
21799 #endif
21800 {
21801    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
21802
21803
21804    alloc->hqProc->reTxAlloc.rnti    =  alloc->rnti;
21805    alloc->hqProc->reTxAlloc.numSb   =  alloc->numSb;
21806    alloc->hqProc->reTxAlloc.iMcs   =  alloc->grnt.iMcs;
21807 #ifdef RG_5GTF
21808    alloc->hqProc->reTxAlloc.dciFrmt =  alloc->grnt.dciFrmt;
21809    alloc->hqProc->reTxAlloc.numLyr   =  alloc->grnt.numLyr;
21810    alloc->hqProc->reTxAlloc.vrbgStart =  alloc->grnt.vrbgStart;
21811    alloc->hqProc->reTxAlloc.numVrbg   =  alloc->grnt.numVrbg;
21812    alloc->hqProc->reTxAlloc.modOdr   =  alloc->grnt.modOdr;
21813 #endif
21814    //iTbs = rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
21815    //iTbs = alloc->grnt.iMcs;
21816    //RGSCH_ARRAY_BOUND_CHECK( 0, rgTbSzTbl[0], iTbs);
21817    alloc->hqProc->reTxAlloc.tbSz = alloc->grnt.datSz;
21818       //rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1]/8;
21819    alloc->hqProc->reTxAlloc.ue      = alloc->ue;
21820    alloc->hqProc->reTxAlloc.forMsg3 = alloc->forMsg3;
21821    alloc->hqProc->reTxAlloc.raCb = alloc->raCb;
21822
21823    /* Set as retransmission is pending */
21824    alloc->hqProc->isRetx = TRUE;
21825    alloc->hqProc->alloc = NULLP;
21826    alloc->hqProc->ulSfIdx = RGSCH_INVALID_INFO;
21827 #ifdef UL_ADPT_DBG  
21828    printf("Adding Harq Proc Id in the retx list  hqProcId %d \n",alloc->grnt.hqProcId); 
21829 #endif
21830    cmLListAdd2Tail(&cmnUlCell->reTxLst, &alloc->hqProc->reTxLnk);
21831    alloc->hqProc->reTxLnk.node = (PTR)alloc->hqProc;
21832    return;
21833 }
21834
21835 /**
21836  * @brief Attempts allocation for msg3s for which ADAP retransmissions
21837  *     are required.
21838  *
21839  * @details
21840  *
21841  *     Function : rgSCHCmnUlAdapRetxAlloc
21842  *
21843  *     Attempts allocation for msg3s for which ADAP retransmissions
21844  *     are required.
21845  *
21846  *  @param[in]  RgSchCellCb       *cell
21847  *  @param[in]  RgSchUlSf         *sf
21848  *  @param[in]  RgSchUlHqProcCb   *proc;
21849  *  @param[in]  RgSchUlHole       *hole;
21850  *  @return  uint8_t
21851  **/
21852 #ifdef ANSI
21853 static Bool rgSCHCmnUlAdapRetxAlloc
21854 (
21855 RgSchCellCb       *cell,
21856 RgSchUlSf         *sf,
21857 RgSchUlHqProcCb   *proc,
21858 RgSchUlHole       *hole
21859 )
21860 #else
21861 static Bool rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole)
21862 RgSchCellCb       *cell;
21863 RgSchUlSf         *sf;
21864 RgSchUlHqProcCb   *proc;
21865 RgSchUlHole       *hole;
21866 #endif
21867 {
21868    uint8_t              numSb = proc->reTxAlloc.numSb;
21869    uint8_t              iMcs  = proc->reTxAlloc.iMcs;
21870    CmLteTimingInfo frm = cell->crntTime;
21871    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
21872    RgSchDlSf       *dlSf;
21873    RgSchPdcch      *pdcch;
21874    RgSchUlAlloc    *alloc;
21875
21876    /* Fetch PDCCH for msg3 */
21877    /* ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/
21878    /* Introduced timing delta for UL control */
21879    RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA);
21880    dlSf = rgSCHUtlSubFrmGet(cell, frm);
21881    pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
21882    if (pdcch == NULLP)
21883    {
21884       return (FALSE);
21885    }
21886
21887    /* Fetch UL Alloc for msg3 */
21888    if (numSb <= hole->num)
21889    {
21890       alloc                = rgSCHUtlUlAllocGetHole(sf, numSb, hole);
21891       
21892       /* KWork fix */
21893          if(alloc == NULLP)
21894          {
21895             rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
21896             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
21897                   "UL Alloc fail for msg3 retx for rnti: %d\n", 
21898                   proc->reTxAlloc.rnti);
21899             return (FALSE);
21900          }
21901
21902       rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc);
21903       alloc->grnt.iMcs     = iMcs;
21904       alloc->grnt.datSz    = proc->reTxAlloc.tbSz;
21905 #ifdef RG_5GTF
21906 #else
21907       //RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr);
21908 #endif
21909       /* Fill UL Alloc for msg3 */
21910       /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/
21911       alloc->grnt.nDmrs    = 0;
21912       alloc->grnt.hop      = 0;
21913       alloc->grnt.delayBit = 0;
21914       alloc->grnt.isRtx    = TRUE;
21915       proc->ulSfIdx        = cellUl->schdIdx;
21916 #ifdef RG_5GTF
21917       proc->schdTime = cellUl->schdTime;
21918       alloc->grnt.hqProcId = proc->procId;
21919       alloc->grnt.dciFrmt = proc->reTxAlloc.dciFrmt;
21920       alloc->grnt.numLyr = proc->reTxAlloc.numLyr;
21921       alloc->grnt.vrbgStart = proc->reTxAlloc.vrbgStart;
21922       alloc->grnt.numVrbg = proc->reTxAlloc.numVrbg;
21923       alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg);
21924       alloc->grnt.modOdr = proc->reTxAlloc.modOdr;
21925
21926       /* TODO : Hardcoding these as of now */
21927       alloc->grnt.hop = 0;
21928       alloc->grnt.SCID = 0;
21929       alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE;
21930       alloc->grnt.PMI = 0;
21931       alloc->grnt.uciOnxPUSCH = 0;
21932 #endif
21933       alloc->rnti          = proc->reTxAlloc.rnti;
21934       /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
21935       alloc->ue            = proc->reTxAlloc.ue;
21936       alloc->pdcch         = pdcch;
21937       alloc->forMsg3       = proc->reTxAlloc.forMsg3;
21938       alloc->raCb          = proc->reTxAlloc.raCb;
21939       alloc->hqProc        = proc;
21940       alloc->isAdaptive    = TRUE;
21941 #ifdef LTE_L2_MEAS
21942       sf->totPrb  += alloc->grnt.numRb;
21943 #endif
21944       /* FIX : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */
21945       if (alloc->raCb)
21946       {
21947          alloc->raCb->msg3Grnt= alloc->grnt;
21948 #ifndef LTE_TDD
21949          /* To the crntTime, add the time at which UE will
21950           * actually send MSG3 */
21951          alloc->raCb->msg3AllocTime = cell->crntTime;
21952          RGSCH_INCR_SUB_FRAME(alloc->raCb->msg3AllocTime, RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL);
21953 #else
21954          alloc->raCb->msg3AllocTime =  cellUl->schdTime;
21955 #endif
21956          rgSCHCmnUlAdapRetx(alloc, proc);
21957          /* Fill PDCCH with alloc info */
21958          pdcch->rnti                           = alloc->rnti;
21959          pdcch->dci.dciFormat                  = TFU_DCI_FORMAT_0;
21960          pdcch->dci.u.format0Info.hoppingEnbld = alloc->grnt.hop;
21961          pdcch->dci.u.format0Info.rbStart      = alloc->grnt.rbStart;
21962          pdcch->dci.u.format0Info.numRb        = alloc->grnt.numRb;
21963          pdcch->dci.u.format0Info.mcs          = alloc->grnt.iMcsCrnt;
21964          pdcch->dci.u.format0Info.ndi          = alloc->hqProc->ndi;
21965          pdcch->dci.u.format0Info.nDmrs        = alloc->grnt.nDmrs;
21966          pdcch->dci.u.format0Info.tpcCmd       = alloc->grnt.tpc;
21967
21968 #ifdef LTE_TDD
21969 #ifdef TFU_TDD
21970          /* ulIdx setting for cfg 0 shall be appropriately fixed thru ccpu00109015 */
21971          pdcch->dci.u.format0Info.ulIdx = RG_SCH_ULIDX_MSB;
21972          pdcch->dci.u.format0Info.dai = RG_SCH_MAX_DAI_IDX;
21973 #endif
21974 #endif
21975          pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_0];
21976       }
21977       else
21978       {
21979          RgSchCmnUlUe *ueUl    = RG_SCH_CMN_GET_UL_UE(alloc->ue,cell);
21980 #ifdef TFU_UPGRADE
21981          alloc->ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE);
21982 #endif
21983 #ifdef LTE_L2_MEAS
21984          ue->ul.nPrb = alloc->grnt.numRb;
21985 #endif
21986          ueUl->alloc.alloc = alloc;
21987          /* FIx: Removed the call to rgSCHCmnUlAdapRetx */
21988          rgSCHCmnUlUeFillAllocInfo(cell, alloc->ue);
21989          /* Setting csireq as false for Adaptive Retx*/
21990          ueUl->alloc.alloc->pdcch->dci.u.format0Info.cqiReq = RG_SCH_APCQI_NO;
21991          pdcch->dciNumOfBits = alloc->ue->dciSize.cmnSize[TFU_DCI_FORMAT_0];
21992       }
21993       /* Reset as retransmission is done */
21994       proc->isRetx = FALSE;
21995    }
21996    else /* Intg fix */
21997    {
21998       rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
21999       RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
22000                "Num SB not suffiecient for adap retx for rnti: %d", 
22001                proc->reTxAlloc.rnti);
22002       return (FALSE);
22003    }
22004    return (TRUE);
22005 }
22006
22007 /* Fix: syed Adaptive Msg3 Retx crash. */
22008 /**
22009  * @brief Releases all Adaptive Retx HqProcs which failed for
22010  *        allocations in this scheduling occassion.
22011  *
22012  * @details
22013  *
22014  *     Function : rgSCHCmnUlSfRlsRetxProcs
22015  *
22016  *
22017  *  @param[in]  RgSchCellCb *cell
22018  *  @param[in]  RgSchUlSf   *sf
22019  *  @return  uint8_t
22020  **/
22021 #ifdef UNUSED_FUNC
22022 #ifdef ANSI
22023 static Void rgSCHCmnUlSfRlsRetxProcs
22024 (
22025 RgSchCellCb *cell,
22026 RgSchUlSf   *sf
22027 )
22028 #else
22029 static Void rgSCHCmnUlSfRlsRetxProcs(cell, sf)
22030 RgSchCellCb *cell;
22031 RgSchUlSf   *sf;
22032 #endif
22033 {
22034    CmLListCp         *cp;
22035    CmLList           *node;
22036    RgSchUlHqProcCb   *proc;
22037    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22038
22039
22040    cp = &(cellUl->reTxLst);
22041    node = cp->first;
22042    while (node)
22043    {
22044       proc  = (RgSchUlHqProcCb *)node->node;
22045       node = node->next;
22046       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
22047       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
22048       proc->reTxLnk.node = (PTR)NULLP;
22049    }
22050    return;
22051 }
22052 #endif   
22053
22054 /**
22055  * @brief Attempts allocation for UEs for which retransmissions
22056  *     are required.
22057  *
22058  * @details
22059  *
22060  *     Function : rgSCHCmnUlSfReTxAllocs
22061  *
22062  *     Attempts allocation for UEs for which retransmissions
22063  *     are required.
22064  *
22065  *  @param[in]  RgSchCellCb *cell
22066  *  @param[in]  RgSchUlSf   *sf
22067  *  @return  uint8_t
22068  **/
22069 #ifdef ANSI
22070 static Void rgSCHCmnUlSfReTxAllocs
22071 (
22072 RgSchCellCb *cell,
22073 RgSchUlSf   *sf
22074 )
22075 #else
22076 static Void rgSCHCmnUlSfReTxAllocs(cell, sf)
22077 RgSchCellCb *cell;
22078 RgSchUlSf   *sf;
22079 #endif
22080 {
22081    CmLListCp         *cp;
22082    CmLList           *node;
22083    RgSchUlHqProcCb   *proc;
22084    RgSchUlHole       *hole;
22085    RgSchUeCb         *ue;
22086    RgSchCmnCell      *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
22087    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
22088
22089    cp = &(cellUl->reTxLst);
22090    node = cp->first;
22091    while ((node))
22092    {
22093       proc  = (RgSchUlHqProcCb *)node->node;
22094       ue = proc->reTxAlloc.ue;
22095       node = node->next;
22096       /*ccpu00106104 MOD added check for AckNackRep */
22097       /*added check for acknack so that adaptive retx considers ue
22098        inactivity due to ack nack repetition*/
22099       if((ue != NULLP) &&
22100             ((ue->measGapCb.isMeasuring == TRUE)||
22101                (ue->ackNakRepCb.isAckNakRep == TRUE)))
22102       {
22103          continue;
22104       }
22105       /* Fix for ccpu00123917: Check if maximum allocs per UL sf have been exhausted */
22106       if (((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
22107             || (sf->allocDb->count == schCmnCell->ul.maxAllocPerUlSf))
22108       {
22109          /* No more UL BW then return */
22110          break;
22111       }
22112       /* perform adaptive retx for UE's */
22113       if (rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) == FALSE)
22114       {
22115          continue;
22116       }
22117       /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */
22118       cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk);
22119       /* Fix: syed Adaptive Msg3 Retx crash. */
22120       proc->reTxLnk.node = (PTR)NULLP;
22121    }
22122    return;
22123 }
22124
22125 /**
22126  * @brief Handles RB allocation for downlink.
22127  *
22128  * @details
22129  *
22130  *     Function : rgSCHCmnDlRbAlloc
22131  *
22132  *     Invoking Module Processing:
22133  *     - This function is invoked for DL RB allocation
22134  *
22135  *     Processing Steps:
22136  *     - If cell is frequency selecive,
22137  *       - Call rgSCHDlfsAllocRb().
22138  *     - else,
22139  *       - Call rgSCHCmnNonDlfsRbAlloc().
22140  *
22141  *  @param[in]  RgSchCellCb        *cell
22142  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
22143  *  @return  Void
22144  **/
22145
22146 #ifdef ANSI
22147 static Void rgSCHCmnDlRbAlloc
22148 (
22149 RgSchCellCb           *cell,
22150 RgSchCmnDlRbAllocInfo *allocInfo
22151 )
22152 #else
22153 static Void rgSCHCmnDlRbAlloc(cell, allocInfo)
22154 RgSchCellCb           *cell;
22155 RgSchCmnDlRbAllocInfo *allocInfo;
22156 #endif
22157 {
22158    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
22159
22160    if (cellSch->dl.isDlFreqSel)
22161    {
22162       printf("5GTF_ERROR DLFS SCH Enabled\n");
22163       cellSch->apisDlfs->rgSCHDlfsAllocRb(cell, allocInfo);
22164    }
22165    else
22166    {
22167       rgSCHCmnNonDlfsRbAlloc(cell, allocInfo);
22168    }
22169    return;
22170 }
22171
22172 #ifdef LTEMAC_SPS
22173
22174 /**
22175  * @brief Determines number of RBGs and RBG subset sizes for the given DL
22176  * bandwidth and rbgSize
22177  *
22178  * @details
22179  *     Function : rgSCHCmnDlGetRbgInfo
22180  *
22181  *
22182  *     Processing Steps:
22183  *     - Fill-up rbgInfo data structure for given DL bandwidth and rbgSize
22184  *
22185  *   @param[in]  uint8_t             dlTotalBw
22186  *   @param[in]  uint8_t             dlSubsetBw
22187  *   @param[in]  uint8_t             maxRaType1SubsetBw
22188  *   @param[in]  uint8_t             rbgSize
22189  *   @param[out] RgSchBwRbgInfo *rbgInfo
22190  *  @return Void
22191  **/
22192 #ifdef ANSI
22193 Void rgSCHCmnDlGetRbgInfo
22194 (
22195 uint8_t             dlTotalBw,
22196 uint8_t             dlSubsetBw,
22197 uint8_t             maxRaType1SubsetBw,
22198 uint8_t             rbgSize,
22199 RgSchBwRbgInfo *rbgInfo
22200 )
22201 #else
22202 Void rgSCHCmnDlGetRbgInfo(dlTotalBw, dlSubsetBw, maxRaType1SubsetBw,
22203       rbgSize, rbgInfo)
22204 uint8_t             dlTotalBw;
22205 uint8_t             dlSubsetBw;
22206 uint8_t             maxRaType1SubsetBw;
22207 uint8_t             rbgSize;
22208 RgSchBwRbgInfo *rbgInfo;
22209 #endif
22210 {
22211 #ifdef RGSCH_SPS_UNUSED
22212    uint8_t    idx           = 0;
22213    uint8_t    lastRbgIdx    = ((dlTotalBw + rbgSize - 1)/rbgSize) - 1;
22214    uint8_t    currRbgSize   = rbgSize;
22215    uint8_t    subsetSizeIdx = 0;
22216    uint8_t    subsetSize[RG_SCH_NUM_RATYPE1_SUBSETS] = {0};
22217    uint8_t    lastRbgSize = rbgSize - (dlTotalBw - ((dlTotalBw/rbgSize) * rbgSize));
22218    uint8_t    numRaType1Rbgs = (maxRaType1SubsetBw + rbgSize - 1)/rbgSize;
22219 #endif
22220
22221    /* Compute maximum number of SPS RBGs for the cell */
22222    rbgInfo->numRbgs =  ((dlSubsetBw + rbgSize - 1)/rbgSize);
22223
22224 #ifdef RGSCH_SPS_UNUSED
22225    /* Distribute RBGs across subsets except last RBG */
22226    for (;idx < numRaType1Rbgs - 1; ++idx)
22227    {
22228       subsetSize[subsetSizeIdx] += currRbgSize;
22229       subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
22230    }
22231
22232    /* Computation for last RBG */
22233    if (idx == lastRbgIdx)
22234    {
22235       currRbgSize = lastRbgSize;
22236    }
22237    subsetSize[subsetSizeIdx] += currRbgSize;
22238    subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize;
22239 #endif
22240
22241    /* Update the computed sizes */
22242 #ifdef RGSCH_SPS_UNUSED
22243    rbgInfo->lastRbgSize = currRbgSize;
22244 #endif
22245    rbgInfo->lastRbgSize = rbgSize - 
22246             (dlSubsetBw - ((dlSubsetBw/rbgSize) * rbgSize));
22247 #ifdef RGSCH_SPS_UNUSED
22248    memcpy(rbgInfo->rbgSubsetSize, subsetSize, 4 * sizeof(uint8_t));
22249 #endif
22250    rbgInfo->numRbs = (rbgInfo->numRbgs * rbgSize > dlTotalBw) ?
22251       dlTotalBw:(rbgInfo->numRbgs * rbgSize);
22252    rbgInfo->rbgSize = rbgSize;
22253 }
22254
22255 /**
22256  * @brief Handles RB allocation for Resource allocation type 0
22257  *
22258  * @details
22259  *
22260  *     Function : rgSCHCmnDlRaType0Alloc
22261  *
22262  *     Invoking Module Processing:
22263  *     - This function is invoked for DL RB allocation for resource allocation
22264  *     type 0
22265  *
22266  *     Processing Steps:
22267  *     - Determine the available positions in the rbgMask.
22268  *     - Allocate RBGs in the available positions.
22269  *     - Update RA Type 0, RA Type 1 and RA type 2 masks.
22270  *
22271  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22272  *  @param[in]   uint8_t             rbsReq
22273  *  @param[in]   RgSchBwRbgInfo *rbgInfo
22274  *  @param[out]  uint8_t             *numAllocRbs
22275  *  @param[out]  RgSchDlSfAllocInfo *resAllocInfo
22276  *  @param[in]   Bool           isPartialAlloc
22277  *
22278  *  @return  Void
22279  **/
22280
22281 #ifdef ANSI
22282 uint8_t rgSCHCmnDlRaType0Alloc
22283 (
22284 RgSchDlSfAllocInfo *allocedInfo,
22285 uint8_t                 rbsReq,
22286 RgSchBwRbgInfo     *rbgInfo,
22287 uint8_t                 *numAllocRbs,
22288 RgSchDlSfAllocInfo *resAllocInfo,
22289 Bool               isPartialAlloc
22290 )
22291 #else
22292 uint8_t rgSCHCmnDlRaType0Alloc(allocedInfo, rbsReq, rbgInfo,
22293       numAllocRbs, resAllocInfo, isPartialAlloc)
22294 RgSchDlSfAllocInfo *allocedInfo;
22295 uint8_t                 rbsReq;
22296 RgSchBwRbgInfo     *rbgInfo;
22297 uint8_t                 *numAllocRbs;
22298 RgSchDlSfAllocInfo *resAllocInfo;
22299 Bool               isPartialAlloc;
22300 #endif
22301 {
22302    /* Note: This function atttempts allocation only full allocation */
22303    uint32_t      remNumRbs, rbgPosInRbgMask, ueRaType2Mask;
22304    uint8_t       type2MaskIdx, cnt, rbIdx;
22305    uint8_t       maskSize, rbg;
22306    uint8_t       bestNumAvailRbs = 0;
22307    uint8_t       usedRbs = 0;
22308    uint8_t       numAllocRbgs = 0;
22309    uint8_t       rbgSize = rbgInfo->rbgSize;
22310    uint32_t      *rbgMask = &(resAllocInfo->raType0Mask);
22311 #ifdef RGSCH_SPS_UNUSED
22312    uint8_t       rbgSubset;
22313    uint32_t      ueRaType1Mask;
22314    uint32_t      *raType1Mask = resAllocInfo->raType1Mask;
22315    uint32_t      *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22316 #endif
22317    uint32_t      *raType2Mask = resAllocInfo->raType2Mask;
22318
22319    uint32_t      allocedMask = allocedInfo->raType0Mask;
22320
22321    maskSize = rbgInfo->numRbgs;
22322
22323    *numAllocRbs = 0;
22324    RG_SCH_CMN_DL_COUNT_ONES(allocedMask, maskSize, &usedRbs);
22325    if (maskSize == usedRbs)
22326    {
22327       /* All RBGs are allocated, including the last one */
22328       remNumRbs = 0;
22329    }
22330    else
22331    {
22332       remNumRbs = (maskSize - usedRbs - 1) * rbgSize; /* vamsee: removed minus 1 */
22333
22334       /* If last RBG is available, add last RBG size */
22335       if (!(allocedMask & (1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(maskSize - 1))))
22336       {
22337          remNumRbs += rbgInfo->lastRbgSize;
22338       }
22339    }
22340
22341    /* If complete allocation is needed, check if total requested RBs are available else
22342     * check the best available RBs */
22343    if (!isPartialAlloc)
22344    {
22345       if (remNumRbs >= rbsReq)
22346       {
22347          bestNumAvailRbs = rbsReq;
22348       }
22349    }
22350    else
22351    {
22352       bestNumAvailRbs = remNumRbs > rbsReq ? rbsReq : remNumRbs;
22353    }
22354
22355    /* Allocate for bestNumAvailRbs */
22356    if (bestNumAvailRbs)
22357    {
22358       for (rbg = 0; rbg < maskSize - 1; ++rbg)
22359       {
22360          rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22361          if (!(allocedMask & rbgPosInRbgMask))
22362          {
22363             /* Update RBG mask */
22364             *rbgMask |= rbgPosInRbgMask;
22365
22366             /* Compute RB index of the first RB of the RBG allocated */
22367             rbIdx = rbg * rbgSize;
22368
22369             for (cnt = 0; cnt < rbgSize; ++cnt)
22370             {
22371 #ifdef RGSCH_SPS_UNUSED
22372                ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22373 #endif
22374                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22375 #ifdef RGSCH_SPS_UNUSED
22376                /* Update RBG mask for RA type 1 */
22377                raType1Mask[rbgSubset] |= ueRaType1Mask;
22378                raType1UsedRbs[rbgSubset]++;
22379 #endif
22380                /* Update RA type 2 mask */
22381                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22382                rbIdx++;
22383             }
22384             *numAllocRbs += rbgSize;
22385             remNumRbs -= rbgSize;
22386             ++numAllocRbgs;
22387             if (*numAllocRbs >= bestNumAvailRbs)
22388             {
22389                break;
22390             }
22391          }
22392       }
22393       /* If last RBG available and allocation is not completed, allocate
22394        * last RBG */
22395       if (*numAllocRbs < bestNumAvailRbs)
22396       {
22397          rbgPosInRbgMask =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22398          *rbgMask |= rbgPosInRbgMask;
22399          *numAllocRbs += rbgInfo->lastRbgSize;
22400
22401          /* Compute RB index of the first RB of the last RBG */
22402          rbIdx = ((rbgInfo->numRbgs - 1 ) * rbgSize ); /* removed minus 1  vamsee */
22403
22404          for (cnt = 0; cnt < rbgInfo->lastRbgSize; ++cnt)
22405          {
22406 #ifdef RGSCH_SPS_UNUSED
22407             ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22408 #endif
22409             ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22410 #ifdef RGSCH_SPS_UNUSED
22411             /* Update RBG mask for RA type 1 */
22412             raType1Mask[rbgSubset] |=  ueRaType1Mask;
22413             raType1UsedRbs[rbgSubset]++;
22414 #endif
22415             /* Update RA type 2 mask */
22416             raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22417             rbIdx++;
22418          }
22419          remNumRbs -= rbgInfo->lastRbgSize;
22420          ++numAllocRbgs;
22421       }
22422       /* Note: this should complete allocation, not checking for the
22423        * same */
22424    }
22425
22426    return (numAllocRbgs);
22427 }
22428
22429 #ifdef RGSCH_SPS_UNUSED
22430 /**
22431  * @brief Handles RB allocation for Resource allocation type 1
22432  *
22433  * @details
22434  *
22435  *     Function : rgSCHCmnDlRaType1Alloc
22436  *
22437  *     Invoking Module Processing:
22438  *     - This function is invoked for DL RB allocation for resource allocation
22439  *     type 1
22440  *
22441  *     Processing Steps:
22442  *     - Determine the available positions in the subsets.
22443  *     - Allocate RB in the available subset.
22444  *     - Update RA Type1, RA type 0 and RA type 2 masks.
22445  *
22446  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22447  *  @param[in]   uint8_t                 rbsReq
22448  *  @param[in]   RgSchBwRbgInfo     *rbgInfo
22449  *  @param[in]   uint8_t                 startRbgSubset
22450  *  @param[in]   uint8_t                 *allocRbgSubset
22451  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
22452  *  @param[in]   Bool               isPartialAlloc
22453  *
22454  *  @return  uint8_t
22455  *  Number of allocated RBs
22456  **/
22457
22458 #ifdef ANSI
22459 uint8_t rgSCHCmnDlRaType1Alloc
22460 (
22461 RgSchDlSfAllocInfo *allocedInfo,
22462 uint8_t                 rbsReq,
22463 RgSchBwRbgInfo     *rbgInfo,
22464 uint8_t                 startRbgSubset,
22465 uint8_t                 *allocRbgSubset,
22466 RgSchDlSfAllocInfo *resAllocInfo,
22467 Bool               isPartialAlloc
22468 )
22469 #else
22470 uint8_t rgSCHCmnDlRaType1Alloc(allocedInfo, rbsReq,rbgInfo,startRbgSubset,
22471       allocRbgSubset, resAllocInfo, isPartialAlloc)
22472 RgSchDlSfAllocInfo *allocedInfo;
22473 uint8_t                 rbsReq;
22474 RgSchBwRbgInfo     *rbgInfo;
22475 uint8_t                 startRbgSubset;
22476 uint8_t                 *allocRbgSubset;
22477 RgSchDlSfAllocInfo *resAllocInfo;
22478 Bool               isPartialAlloc;
22479 #endif
22480 {
22481    /* Note: This function atttempts only full allocation */
22482    uint8_t          *rbgSubsetSzArr;
22483    uint8_t          type2MaskIdx, subsetIdx, rbIdx, rbInSubset, rbgInSubset;
22484    uint8_t          offset, rbg, maskSize, bestSubsetIdx;
22485    uint8_t          startPos = 0;
22486    uint8_t          bestNumAvailRbs = 0;
22487    uint8_t          numAllocRbs = 0;
22488    uint32_t         ueRaType2Mask, ueRaType0Mask, rbPosInSubset;
22489    uint32_t         remNumRbs, allocedMask;
22490    uint8_t          usedRbs = 0;
22491    uint8_t          rbgSize = rbgInfo->rbgSize;
22492    uint8_t          rbgSubset = startRbgSubset;
22493    uint32_t         *rbgMask = &resAllocInfo->raType0Mask;
22494    uint32_t         *raType1Mask = resAllocInfo->raType1Mask;
22495    uint32_t         *raType2Mask = resAllocInfo->raType2Mask;
22496    uint32_t         *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22497    uint32_t         *allocMask = allocedInfo->raType1Mask;
22498
22499    /* Initialize the subset size Array */
22500    rbgSubsetSzArr = rbgInfo->rbgSubsetSize;
22501
22502    /* Perform allocation for RA type 1 */
22503    for (subsetIdx = 0;subsetIdx < rbgSize; ++subsetIdx)
22504    {
22505       allocedMask = allocMask[rbgSubset];
22506       maskSize = rbgSubsetSzArr[rbgSubset];
22507
22508       /* Determine number of available RBs in the subset */
22509       usedRbs = allocedInfo->raType1UsedRbs[subsetIdx];
22510       remNumRbs = maskSize - usedRbs;
22511
22512       if (remNumRbs >= rbsReq)
22513       {
22514          bestNumAvailRbs = rbsReq;
22515          bestSubsetIdx = rbgSubset;
22516          break;
22517       }
22518       else if (isPartialAlloc && (remNumRbs > bestNumAvailRbs))
22519       {
22520          bestNumAvailRbs = remNumRbs;
22521          bestSubsetIdx = rbgSubset;
22522       }
22523
22524       rbgSubset = (rbgSubset + 1) % rbgSize;
22525    } /* End of for (each rbgsubset) */
22526
22527    if (bestNumAvailRbs)
22528    {
22529       /* Initialize alloced mask and subsetSize depending on the RBG
22530        * subset of allocation */
22531       uint8_t        startIdx = 0;
22532       maskSize = rbgSubsetSzArr[bestSubsetIdx];
22533       allocedMask = allocMask[bestSubsetIdx];
22534       RG_SCH_CMN_DL_GET_START_POS(allocedMask, maskSize,
22535             &startPos);
22536       for (; startIdx < rbgSize; ++startIdx, ++startPos)
22537       {
22538          for (rbInSubset = startPos; rbInSubset < maskSize;
22539                rbInSubset = rbInSubset + rbgSize)
22540          {
22541             rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
22542             if (!(allocedMask & rbPosInSubset))
22543             {
22544                raType1Mask[bestSubsetIdx] |= rbPosInSubset;
22545                raType1UsedRbs[bestSubsetIdx]++;
22546
22547                /* Compute RB index value for the RB being allocated */
22548                rbgInSubset = rbInSubset /rbgSize;
22549                offset = rbInSubset % rbgSize;
22550                rbg = (rbgInSubset * rbgSize) + bestSubsetIdx;
22551                rbIdx = (rbg * rbgSize) + offset;
22552
22553                /* Update RBG mask for RA type 0 allocation */
22554                ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
22555                *rbgMask |= ueRaType0Mask;
22556
22557                /* Update RA type 2 mask */
22558                ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx);
22559                raType2Mask[type2MaskIdx] |= ueRaType2Mask;
22560
22561                /* Update the counters */
22562                numAllocRbs++;
22563                remNumRbs--;
22564                if (numAllocRbs == bestNumAvailRbs)
22565                {
22566                   break;
22567                }
22568             }
22569          } /* End of for (each position in the subset mask) */
22570          if (numAllocRbs == bestNumAvailRbs)
22571          {
22572             break;
22573          }
22574       } /* End of for startIdx = 0 to rbgSize */
22575
22576       *allocRbgSubset = bestSubsetIdx;
22577    } /* End of if (bestNumAvailRbs) */
22578
22579    return (numAllocRbs);
22580 }
22581 #endif
22582 /**
22583  * @brief Handles RB allocation for Resource allocation type 2
22584  *
22585  * @details
22586  *
22587  *     Function : rgSCHCmnDlRaType2Alloc
22588  *
22589  *     Invoking Module Processing:
22590  *     - This function is invoked for DL RB allocation for resource allocation
22591  *     type 2
22592  *
22593  *     Processing Steps:
22594  *     - Determine the available positions in the mask
22595  *     - Allocate best fit cosecutive RBs.
22596  *     - Update RA Type2, RA type 1 and RA type 0 masks.
22597  *
22598  *  @param[in]   RgSchDlSfAllocInfo *allocedInfo
22599  *  @param[in]   uint8_t             rbsReq
22600  *  @param[in]   RgSchBwRbgInfo *rbgInfo
22601  *  @param[out]  uint8_t             *rbStart
22602  *  @param[out]  rgSchDlSfAllocInfo *resAllocInfo
22603  *  @param[in]   Bool           isPartialAlloc
22604  *
22605  *  @return  uint8_t
22606  *  Number of allocated RBs
22607  **/
22608
22609 #ifdef ANSI
22610 uint8_t rgSCHCmnDlRaType2Alloc
22611 (
22612 RgSchDlSfAllocInfo *allocedInfo,
22613 uint8_t                 rbsReq,
22614 RgSchBwRbgInfo     *rbgInfo,
22615 uint8_t                 *rbStart,
22616 RgSchDlSfAllocInfo *resAllocInfo,
22617 Bool               isPartialAlloc
22618 )
22619 #else
22620 uint8_t rgSCHCmnDlRaType2Alloc(allocedInfo, rbsReq, rbgInfo, rbStart,
22621       resAllocInfo, isPartialAlloc)
22622 RgSchDlSfAllocInfo *allocedInfo;
22623 uint8_t                 rbsReq;
22624 RgSchBwRbgInfo     *rbgInfo;
22625 uint8_t                 *rbStart;
22626 RgSchDlSfAllocInfo *resAllocInfo;
22627 Bool               isPartialAlloc;
22628 #endif
22629 {
22630    uint8_t          numAllocRbs = 0;
22631    uint8_t          rbIdx;
22632    uint8_t          rbgSize = rbgInfo->rbgSize;
22633    uint32_t         *rbgMask = &resAllocInfo->raType0Mask;
22634 #ifdef RGSCH_SPS_UNUSED
22635    uint32_t         *raType1Mask = resAllocInfo->raType1Mask;
22636 #endif
22637    uint32_t         *raType2Mask = resAllocInfo->raType2Mask;
22638 #ifdef RGSCH_SPS_UNUSED
22639    uint32_t         *raType1UsedRbs = resAllocInfo->raType1UsedRbs;
22640 #endif
22641    uint32_t         *allocedMask = allocedInfo->raType2Mask;
22642
22643    /* Note: This function atttempts only full allocation */
22644    rgSCHCmnDlGetBestFitHole(allocedMask, rbgInfo->numRbs,
22645          raType2Mask, rbsReq, rbStart, &numAllocRbs, isPartialAlloc);
22646    if (numAllocRbs)
22647    {
22648       /* Update the allocation in RA type 0 and RA type 1 masks */
22649       uint8_t rbCnt = numAllocRbs;
22650 #ifdef RGSCH_SPS_UNUSED
22651       uint8_t rbgSubset;
22652       uint32_t ueRaType1Mask;
22653 #endif
22654       uint32_t ueRaType0Mask;
22655       rbIdx = *rbStart;
22656
22657       while(rbCnt)
22658       {
22659          /* Update RBG mask for RA type 0 allocation */
22660          ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize);
22661          *rbgMask |= ueRaType0Mask;
22662
22663 #ifdef RGSCH_SPS_UNUSED
22664          /* Update RBG mask for RA type 1 */
22665          ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset);
22666          raType1Mask[rbgSubset] |= ueRaType1Mask;
22667          raType1UsedRbs[rbgSubset]++;
22668 #endif
22669          /* Update the counters */
22670          --rbCnt;
22671          rbIdx++;
22672       }
22673    }
22674
22675    return (numAllocRbs);
22676 }
22677
22678 /**
22679  * @brief Determines RA type 0 mask from given RB index.
22680  *
22681  * @details
22682  *
22683  *     Function : rgSCHCmnGetRaType0Mask
22684  *
22685  *
22686  *     Processing Steps:
22687  *     - Determine RA Type 0 mask for given rbIdex and rbg size.
22688  *
22689  *  @param[in]  uint8_t          rbIdx
22690  *  @param[in]  uint8_t          rbgSize
22691  *  @return  uint32_t RA type 0 mask
22692  **/
22693 #ifdef ANSI
22694 static uint32_t rgSCHCmnGetRaType0Mask
22695 (
22696 uint8_t                rbIdx,
22697 uint8_t                rbgSize
22698 )
22699 #else
22700 static uint32_t rgSCHCmnGetRaType0Mask(rbIdx, rbgSize)
22701 uint8_t                rbIdx;
22702 uint8_t                rbgSize;
22703 #endif
22704 {
22705    uint8_t rbg;
22706    uint32_t rbgPosInRbgMask = 0;
22707
22708    rbg = rbIdx/rbgSize;
22709    rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg);
22710
22711    return (rbgPosInRbgMask);
22712 }
22713
22714 #ifdef RGSCH_SPS_UNUSED
22715 /**
22716  * @brief Determines RA type 1 mask from given RB index.
22717  *
22718  * @details
22719  *
22720  *     Function : rgSCHCmnGetRaType1Mask
22721  *
22722  *
22723  *     Processing Steps:
22724  *     - Determine RA Type 1 mask for given rbIdex and rbg size.
22725  *
22726  *  @param[in]  uint8_t          rbIdx
22727  *  @param[in]  uint8_t          rbgSize
22728  *  @param[out] uint8_t          *type1Subset
22729  *  @return  uint32_t RA type 1 mask
22730  **/
22731 #ifdef ANSI
22732 static uint32_t rgSCHCmnGetRaType1Mask
22733 (
22734 uint8_t                rbIdx,
22735 uint8_t                rbgSize,
22736 uint8_t                *type1Subset
22737 )
22738 #else
22739 static uint32_t rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, type1Subset)
22740 uint8_t                rbIdx;
22741 uint8_t                rbgSize;
22742 uint8_t                *type1Subset;
22743 #endif
22744 {
22745    uint8_t rbg, rbgSubset, rbgInSubset, offset, rbInSubset;
22746    uint32_t rbPosInSubset;
22747
22748    rbg = rbIdx/rbgSize;
22749    rbgSubset = rbg % rbgSize;
22750    rbgInSubset = rbg/rbgSize;
22751    offset = rbIdx % rbgSize;
22752    rbInSubset = rbgInSubset * rbgSize + offset;
22753    rbPosInSubset =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset);
22754
22755    *type1Subset = rbgSubset;
22756    return (rbPosInSubset);
22757
22758 #endif /* RGSCH_SPS_UNUSED */
22759 /**
22760  * @brief Determines RA type 2 mask from given RB index.
22761  *
22762  * @details
22763  *
22764  *     Function : rgSCHCmnGetRaType2Mask
22765  *
22766  *
22767  *     Processing Steps:
22768  *     - Determine RA Type 2 mask for given rbIdx and rbg size.
22769  *
22770  *  @param[in]  uint8_t          rbIdx
22771  *  @param[out] uint8_t          *maskIdx
22772  *  @return  uint32_t RA type 2 mask
22773  **/
22774 #ifdef ANSI
22775 static uint32_t rgSCHCmnGetRaType2Mask
22776 (
22777 uint8_t                rbIdx,
22778 uint8_t                *maskIdx
22779 )
22780 #else
22781 static uint32_t rgSCHCmnGetRaType2Mask(rbIdx, maskIdx)
22782 uint8_t                rbIdx;
22783 uint8_t                *maskIdx;
22784 #endif
22785 {
22786    uint32_t rbPosInType2;
22787
22788    *maskIdx = rbIdx / 32;
22789    rbPosInType2 =  1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbIdx % 32);
22790
22791    return (rbPosInType2);
22792 }
22793
22794 /**
22795  * @brief Performs resource allocation for a non-SPS UE in SPS bandwidth
22796  *
22797  * @details
22798  *
22799  *     Function : rgSCHCmnAllocUeInSpsBw
22800  *
22801  *
22802  *     Processing Steps:
22803  *       - Determine allocation for the UE.
22804  *       - Use resource allocation type 0, 1 and 2 for allocation
22805  *         within maximum SPS bandwidth.
22806  *
22807  *  @param[in]  RgSchDlSf       *dlSf
22808  *  @param[in]  RgSchCellCb     *cell
22809  *  @param[in]  RgSchUeCb       *ue
22810  *  @param[in]  RgSchDlRbAlloc  *rbAllocInfo
22811  *  @param[in]  Bool            isPartialAlloc
22812  *  @return  Bool
22813  *             ROK      success
22814  *             RFAILED  failed
22815  **/
22816 #ifdef ANSI
22817 Bool rgSCHCmnAllocUeInSpsBw
22818 (
22819 RgSchDlSf           *dlSf,
22820 RgSchCellCb         *cell,
22821 RgSchUeCb           *ue,
22822 RgSchDlRbAlloc      *rbAllocInfo,
22823 Bool                isPartialAlloc
22824 )
22825 #else
22826 Bool rgSCHCmnAllocUeInSpsBw(dlSf, cell, ue, rbAllocInfo, isPartialAlloc)
22827 RgSchDlSf           *dlSf;
22828 RgSchCellCb         *cell;
22829 RgSchUeCb           *ue;
22830 RgSchDlRbAlloc      *rbAllocInfo;
22831 Bool                isPartialAlloc;
22832 #endif
22833 {
22834    uint8_t                  rbgSize = cell->rbgSize;
22835    uint8_t                  numAllocRbs = 0;
22836    uint8_t                  numAllocRbgs = 0;
22837    uint8_t                  rbStart = 0;
22838    uint8_t                  idx, noLyr, iTbs;
22839    RgSchCmnDlUe        *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
22840    RgSchDlSfAllocInfo  *dlSfAlloc = &rbAllocInfo->dlSf->dlSfAllocInfo;
22841    RgSchBwRbgInfo      *spsRbgInfo = &cell->spsBwRbgInfo;
22842
22843    /* SPS_FIX : Check if this Hq proc is scheduled */
22844    if ((0 == rbAllocInfo->tbInfo[0].schdlngForTb) &&
22845          (0 == rbAllocInfo->tbInfo[1].schdlngForTb))
22846    {
22847       return (TRUE);
22848    }
22849
22850    /* Check if the requirement can be accomodated in SPS BW */
22851    if (dlSf->spsAllocdBw == spsRbgInfo->numRbs)
22852    {
22853       /* SPS Bandwidth has been exhausted: no further allocations possible */
22854       return (FALSE);
22855    }
22856    if (!isPartialAlloc)
22857    {
22858       if((dlSf->spsAllocdBw + rbAllocInfo->rbsReq) > spsRbgInfo->numRbs)
22859       {
22860          return (TRUE);
22861       }
22862    }
22863
22864    /* Perform allocation for RA type 0 if rbsReq is multiple of RBG size (also
22865     * if RBG size = 1) */
22866    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
22867    {
22868       rbAllocInfo->rbsReq += (rbgSize - rbAllocInfo->rbsReq % rbgSize);
22869       numAllocRbgs = rgSCHCmnDlRaType0Alloc(dlSfAlloc,
22870             rbAllocInfo->rbsReq, spsRbgInfo, &numAllocRbs,
22871             &rbAllocInfo->resAllocInfo, isPartialAlloc);
22872    }
22873 #ifdef RGSCH_SPS_UNUSED
22874    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
22875    {
22876       /* If no RBS could be allocated, attempt RA TYPE 1 */
22877
22878       numAllocRbs = rgSCHCmnDlRaType1Alloc(dlSfAlloc,
22879             rbAllocInfo->rbsReq, spsRbgInfo, (uint8_t)dlSfAlloc->nxtRbgSubset,
22880             &rbAllocInfo->allocInfo.raType1.rbgSubset,
22881             &rbAllocInfo->resAllocInfo, isPartialAlloc);
22882
22883       if(numAllocRbs)
22884       {
22885          dlSfAlloc->nxtRbgSubset =
22886             (rbAllocInfo->allocInfo.raType1.rbgSubset + 1 ) % rbgSize;
22887       }
22888    }
22889 #endif
22890    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
22891    {
22892       numAllocRbs = rgSCHCmnDlRaType2Alloc(dlSfAlloc,
22893             rbAllocInfo->rbsReq, spsRbgInfo,
22894             &rbStart, &rbAllocInfo->resAllocInfo, isPartialAlloc);
22895    }
22896    if (!numAllocRbs)
22897    {
22898       return (TRUE);
22899    }
22900
22901    if (!(rbAllocInfo->pdcch =
22902             rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi,\
22903                rbAllocInfo->dciFormat, FALSE)))
22904    {
22905       /* Note: Returning TRUE since PDCCH might be available for another UE */
22906       return (TRUE);
22907    }
22908
22909    /* Update Tb info for each scheduled TB */
22910    iTbs = rbAllocInfo->tbInfo[0].iTbs;
22911    noLyr = rbAllocInfo->tbInfo[0].noLyr;
22912    rbAllocInfo->tbInfo[0].bytesAlloc =
22913       rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
22914
22915    if (rbAllocInfo->tbInfo[1].schdlngForTb)
22916    {
22917       iTbs = rbAllocInfo->tbInfo[1].iTbs;
22918       noLyr = rbAllocInfo->tbInfo[1].noLyr;
22919       rbAllocInfo->tbInfo[1].bytesAlloc =
22920          rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;
22921    }
22922
22923    /* Update rbAllocInfo with the allocation information */
22924    if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0)
22925    {
22926       rbAllocInfo->allocInfo.raType0.dlAllocBitMask =
22927          rbAllocInfo->resAllocInfo.raType0Mask;
22928       rbAllocInfo->allocInfo.raType0.numDlAlloc = numAllocRbgs;
22929    }
22930 #ifdef RGSCH_SPS_UNUSED
22931    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1)
22932    {
22933       rbAllocInfo->allocInfo.raType1.dlAllocBitMask =
22934          rbAllocInfo->resAllocInfo.raType1Mask[rbAllocInfo->allocInfo.raType1.rbgSubset];
22935       rbAllocInfo->allocInfo.raType1.numDlAlloc = numAllocRbs;
22936       rbAllocInfo->allocInfo.raType1.shift = 0;
22937    }
22938 #endif
22939    else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2)
22940    {
22941       rbAllocInfo->allocInfo.raType2.isLocal = TRUE;
22942       rbAllocInfo->allocInfo.raType2.rbStart = rbStart;
22943       rbAllocInfo->allocInfo.raType2.numRb = numAllocRbs;
22944    }
22945
22946    rbAllocInfo->rbsAlloc = numAllocRbs;
22947    rbAllocInfo->tbInfo[0].schdlngForTb = TRUE;
22948
22949    /* Update allocation masks for RA types 0, 1 and 2 in DL SF */
22950
22951    /* Update type 0 allocation mask */
22952    dlSfAlloc->raType0Mask |= rbAllocInfo->resAllocInfo.raType0Mask;
22953 #ifdef RGSCH_SPS_UNUSED
22954    /* Update type 1 allocation masks */
22955    for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
22956    {
22957       dlSfAlloc->raType1Mask[idx] |= rbAllocInfo->resAllocInfo.raType1Mask[idx];
22958       dlSfAlloc->raType1UsedRbs[idx] +=
22959          rbAllocInfo->resAllocInfo.raType1UsedRbs[idx];
22960    }
22961 #endif
22962    /* Update type 2 allocation masks */
22963    for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
22964    {
22965       dlSfAlloc->raType2Mask[idx] |= rbAllocInfo->resAllocInfo.raType2Mask[idx];
22966    }
22967
22968    dlSf->spsAllocdBw += numAllocRbs;
22969    return (TRUE);
22970 }
22971
22972 /***********************************************************
22973  *
22974  *     Func : rgSCHCmnDlGetBestFitHole
22975  *
22976  *
22977  *     Desc : Converts the best fit hole into allocation and returns the
22978  *     allocation information.
22979  *
22980  *
22981  *     Ret  : Void
22982  *
22983  *
22984  *     Notes:
22985  *
22986  *     File :
22987  *
22988  **********************************************************/
22989 #ifdef ANSI
22990 static Void rgSCHCmnDlGetBestFitHole
22991 (
22992 uint32_t         *allocMask,
22993 uint8_t          numMaskRbs,
22994 uint32_t         *crntAllocMask,
22995 uint8_t          rbsReq,
22996 uint8_t          *allocStart,
22997 uint8_t          *allocNumRbs,
22998 Bool        isPartialAlloc
22999 )
23000 #else
23001 static  Void rgSCHCmnDlGetBestFitHole (allocMask, numMaskRbs,
23002         crntAllocMask, rbsReq, allocStart, allocNumRbs, isPartialAlloc)
23003 uint32_t         *allocMask;
23004 uint8_t          numMaskRbs;
23005 uint32_t         *crntAllocMask;
23006 uint8_t          rbsReq;
23007 uint8_t          *allocStart;
23008 uint8_t          *allocNumRbs;
23009 Bool        isPartialAlloc;
23010 #endif
23011 {
23012    uint8_t maskSz = (numMaskRbs + 31)/32;
23013    uint8_t maxMaskPos = (numMaskRbs % 32);
23014    uint8_t maskIdx, maskPos;
23015    uint8_t numAvailRbs = 0;
23016    uint8_t bestAvailNumRbs = 0;
23017    S8 bestStartPos = -1;
23018    S8 startPos = -1;
23019    uint32_t tmpMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
23020    uint32_t bestMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0};
23021
23022    *allocNumRbs = numAvailRbs;
23023    *allocStart = 0;
23024
23025    for (maskIdx = 0; maskIdx < maskSz; ++maskIdx)
23026    {
23027       maxMaskPos = 31;
23028       if (maskIdx == (maskSz - 1))
23029       {
23030          if (numMaskRbs % 32)
23031          {
23032             maxMaskPos = numMaskRbs % 32;
23033          }
23034       }
23035       for (maskPos = 0; maskPos < maxMaskPos; ++maskPos)
23036       {
23037          if (!(allocMask[maskIdx] & (1 << (31 - maskPos))))
23038          {
23039             tmpMask[maskIdx] |= (1 << (31 - maskPos));
23040             if (startPos == -1)
23041             {
23042                startPos = maskIdx * 32 + maskPos;
23043             }
23044             ++numAvailRbs;
23045             if (numAvailRbs == rbsReq)
23046             {
23047                *allocStart = (uint8_t)startPos;
23048                *allocNumRbs = rbsReq;
23049                break;
23050             }
23051          }
23052          else
23053          {
23054             if (numAvailRbs > bestAvailNumRbs)
23055             {
23056                bestAvailNumRbs = numAvailRbs;
23057                bestStartPos = startPos;
23058                memcpy(bestMask, tmpMask, 4 * sizeof(uint32_t));
23059             }
23060             numAvailRbs = 0;
23061             startPos = -1;
23062             memset(tmpMask, 0, 4 * sizeof(uint32_t));
23063          }
23064       }
23065       if (*allocNumRbs == rbsReq)
23066       {
23067          break;
23068       }
23069    }
23070
23071    if (*allocNumRbs == rbsReq)
23072    {
23073       /* Convert the hole into allocation */
23074       memcpy(crntAllocMask, tmpMask, 4 * sizeof(uint32_t));
23075       return;
23076    }
23077    else
23078    {
23079       if (bestAvailNumRbs && isPartialAlloc)
23080       {
23081          /* Partial allocation could have been done */
23082          *allocStart = (uint8_t)bestStartPos;
23083          *allocNumRbs = bestAvailNumRbs;
23084          /* Convert the hole into allocation */
23085          memcpy(crntAllocMask, bestMask, 4 * sizeof(uint32_t));
23086       }
23087    }
23088
23089    return;
23090 }
23091 #endif /* LTEMAC_SPS */
23092
23093 /***************************************************************************
23094  *
23095  * NON-DLFS Allocation functions
23096  *
23097  * *************************************************************************/
23098 #ifndef LTE_TDD
23099 #ifdef DEBUGP
23100 /**
23101  * @brief Function to find out code rate
23102  *
23103  * @details
23104  *
23105  *     Function : rgSCHCmnFindCodeRate
23106  *
23107  *     Processing Steps:
23108  *
23109  *  @param[in]      RgSchCellCb     *cell
23110  *  @param[in]      RgSchDlSf       *dlSf
23111  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23112  *  @return  void
23113  **/
23114 #ifdef UNUSED_FUNC
23115 #ifdef ANSI
23116 static Void rgSCHCmnFindCodeRate
23117 (
23118 RgSchCellCb           *cell,
23119 RgSchDlSf             *dlSf,
23120 RgSchDlRbAlloc        *allocInfo,
23121 uint8_t                    idx
23122 )
23123 #else
23124 static Void rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,idx)
23125 RgSchCellCb           *cell;
23126 RgSchDlSf             *dlSf;
23127 RgSchDlRbAlloc        *allocInfo;
23128 uint8_t                    idx;
23129 #endif
23130 {
23131     return;
23132
23133 }
23134 #endif
23135
23136 /* Adjust the Imcs and bytes allocated also with respect to the adjusted
23137    RBs - Here we will find out the Imcs by identifying first Highest
23138    number of bits compared to the original bytes allocated.  */
23139 /**
23140  * @brief Adjust IMCS according to tbSize and ITBS
23141  *
23142  * @details
23143  *
23144  *     Function : rgSCHCmnNonDlfsPbchTbImcsAdj
23145  *
23146  *     Processing Steps:
23147  *      - Adjust Imcs according to tbSize and ITBS.
23148  *
23149  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23150  *  @param[in]      uint8_t              *idx
23151  *  @return  void
23152  **/
23153 #ifdef ANSI
23154 static Void rgSCHCmnNonDlfsPbchTbImcsAdj
23155 (
23156 RgSchCellCb      *cell,
23157 RgSchDlRbAlloc   *allocInfo,
23158 uint8_t               idx,
23159 uint8_t               rbsReq
23160 )
23161 #else
23162 static Void rgSCHCmnNonDlfsPbchTbImcsAdj(cell,allocInfo, idx, rbsReq)
23163 RgSchCellCb      *cell;
23164 RgSchDlRbAlloc   *allocInfo;
23165 uint8_t               idx;
23166 uint8_t               rbsReq;
23167 #endif
23168 {
23169    uint8_t             noLyrs = 0;
23170    uint8_t             tbs = 0;
23171    uint32_t            origBytesReq;
23172    uint8_t             noRbgs = 0;
23173    uint8_t             noRbs = 0;
23174    RgSchDlSf     *dlSf = allocInfo->dlSf;
23175
23176    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
23177    noLyrs = allocInfo->tbInfo[idx].noLyr;
23178
23179    if((allocInfo->raType == RG_SCH_CMN_RA_TYPE0))
23180    {
23181       noRbgs = RGSCH_CEIL((allocInfo->rbsReq + dlSf->lstRbgDfct), cell->rbgSize);
23182       noRbs = (noRbgs * cell->rbgSize) - dlSf->lstRbgDfct;
23183    }
23184    else
23185    {
23186        noRbs = allocInfo->rbsReq;
23187    }
23188
23189    /* This line will help in case if tbs is zero and reduction in MCS is not possible */
23190    if (allocInfo->rbsReq == 0 )
23191    {
23192       return;
23193    }
23194    origBytesReq = rgTbSzTbl[noLyrs - 1][tbs][rbsReq - 1]/8;
23195
23196    /* Find out the ITbs & Imcs by identifying first Highest
23197       number of bits compared to the original bytes allocated.*/
23198    if(tbs > 0)
23199    {
23200       if(((rgTbSzTbl[noLyrs - 1][0][noRbs - 1])/8) < origBytesReq)
23201       {
23202           RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyrs - 1], tbs);
23203           while(((rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1])/8) > origBytesReq)
23204           {
23205               tbs--;
23206           }
23207       }
23208       else
23209       {
23210           tbs = 0;
23211       }
23212       allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1]/8;
23213       allocInfo->tbInfo[idx].iTbs = tbs;
23214       RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
23215    }
23216
23217    return;
23218 }
23219 /* Added funcion to adjust TBSize*/
23220 /**
23221  * @brief Function to adjust the tbsize in case of subframe 0 & 5 when
23222  * we were not able to do RB alloc adjustment by adding extra required Rbs
23223  *
23224  * @details
23225  *
23226  *     Function : rgSCHCmnNonDlfsPbchTbSizeAdj
23227  *
23228  *     Processing Steps:
23229  *
23230  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23231  *  @param[in]      uint8_t            numOvrlapgPbchRb
23232  *  @param[in]      uint8_t            idx
23233  *  @param[in]      uint8_t            pbchSsRsSym
23234  *  @return  void
23235  **/
23236 #ifdef ANSI
23237 static Void rgSCHCmnNonDlfsPbchTbSizeAdj
23238 (
23239 RgSchDlRbAlloc        *allocInfo,
23240 uint8_t                    numOvrlapgPbchRb,
23241 uint8_t                    pbchSsRsSym,
23242 uint8_t                    idx,
23243 uint32_t                   bytesReq
23244 )
23245 #else
23246 static Void rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,idx,bytesReq)
23247 RgSchDlRbAlloc        *allocInfo;
23248 uint8_t                    numOvrlapgPbchRb;
23249 uint8_t                    pbchSsRsSym;
23250 uint8_t                    idx;
23251 uint32_t                   bytesReq;
23252 #endif
23253 {
23254    uint32_t             reducedTbs = 0;
23255    uint8_t              noLyrs = 0;
23256    uint8_t              tbs = 0;
23257
23258    noLyrs = allocInfo->tbInfo[idx].noLyr;
23259
23260    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs);
23261
23262    reducedTbs = bytesReq - (((uint32_t)numOvrlapgPbchRb * (uint32_t)pbchSsRsSym * 6)/8);
23263
23264    /* find out the ITbs & Imcs by identifying first Highest
23265     number of bits compared with reduced bits considering the bits that are
23266     reserved for PBCH/PSS/SSS */
23267    if(((rgTbSzTbl[noLyrs - 1][0][allocInfo->rbsReq - 1])/8) < reducedTbs)
23268    {
23269        while(((rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1])/8) > reducedTbs)
23270        {
23271            tbs--;
23272        }
23273    }
23274    else
23275    {
23276        tbs = 0;
23277    }
23278    allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1]/8;
23279    allocInfo->tbInfo[idx].iTbs = tbs;
23280    RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs);
23281
23282    return;
23283 }
23284
23285 /* Added this function to find num of ovrlapping PBCH rb*/
23286 /**
23287  * @brief Function to find out how many additional rbs are available
23288  *    in the entire bw which can be allocated to a UE
23289  * @details
23290  *
23291  *     Function : rgSCHCmnFindNumAddtlRbsAvl
23292  *
23293  *     Processing Steps:
23294  *      - Calculates number of additinal rbs available
23295  *
23296  *  @param[in]      RgSchCellCb     *cell
23297  *  @param[in]      RgSchDlSf       *dlSf
23298  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23299  *  @param[out]      uint8_t            addtlRbsAvl
23300  *  @return  void
23301  **/
23302 #ifdef ANSI
23303 static uint8_t rgSCHCmnFindNumAddtlRbsAvl
23304 (
23305 RgSchCellCb           *cell,
23306 RgSchDlSf             *dlSf,
23307 RgSchDlRbAlloc        *allocInfo
23308 )
23309 #else
23310 static uint8_t rgSCHCmnFindNumAddtlRbsAvl(cell,dlSf,allocInfo)
23311 RgSchCellCb           *cell;
23312 RgSchDlSf             *dlSf;
23313 RgSchDlRbAlloc        *allocInfo;
23314 #endif
23315 {
23316     uint8_t addtlRbsAvl = 0;
23317
23318
23319     if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
23320     {
23321          addtlRbsAvl = (((dlSf->type0End - dlSf->type2End + 1)*\
23322                         cell->rbgSize) - dlSf->lstRbgDfct) - allocInfo->rbsReq;
23323     }
23324     else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
23325     {
23326        addtlRbsAvl = (dlSf->bw - dlSf->bwAlloced) - allocInfo->rbsReq;
23327     }
23328
23329     return (addtlRbsAvl);
23330
23331 }
23332 /* Added this function to find num of ovrlapping PBCH rb*/
23333 /**
23334  * @brief Function to find out how many of the requested RBs are
23335  *        falling in the center 6 RBs of the downlink bandwidth.
23336  * @details
23337  *
23338  *     Function : rgSCHCmnFindNumPbchOvrlapRbs
23339  *
23340  *     Processing Steps:
23341  *      - Calculates number of overlapping rbs
23342  *
23343  *  @param[in]      RgSchCellCb     *cell
23344  *  @param[in]      RgSchDlSf       *dlSf
23345  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23346  *  @param[out]      uint8_t*            numOvrlapgPbchRb
23347  *  @return  void
23348  **/
23349 #ifdef ANSI
23350 static Void rgSCHCmnFindNumPbchOvrlapRbs
23351 (
23352 RgSchCellCb           *cell,
23353 RgSchDlSf             *dlSf,
23354 RgSchDlRbAlloc        *allocInfo,
23355 uint8_t                    *numOvrlapgPbchRb
23356 )
23357 #else
23358 static Void rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,numOvrlapgPbchRb)
23359 RgSchCellCb           *cell;
23360 RgSchDlSf             *dlSf;
23361 RgSchDlRbAlloc        *allocInfo;
23362 uint8_t                    *numOvrlapgPbchRb;
23363 #endif
23364 {
23365     *numOvrlapgPbchRb = 0;
23366    /*Find if we have already crossed the start boundary for PBCH 6 RBs,
23367     * if yes then lets find the number of RBs which are getting overlapped
23368     * with this allocation.*/
23369    if(dlSf->bwAlloced <= (cell->pbchRbStart))
23370    {
23371       /*We have not crossed the start boundary of PBCH RBs. Now we need
23372        * to know that if take this allocation then how much PBCH RBs
23373        * are overlapping with this allocation.*/
23374       /* Find out the overlapping RBs in the centre 6 RBs */
23375        if((dlSf->bwAlloced + allocInfo->rbsReq) > cell->pbchRbStart)
23376        {
23377            *numOvrlapgPbchRb = (dlSf->bwAlloced + allocInfo->rbsReq) - (cell->pbchRbStart);
23378            if(*numOvrlapgPbchRb > 6)
23379                 *numOvrlapgPbchRb = 6;
23380        }
23381    }
23382    else if ((dlSf->bwAlloced > (cell->pbchRbStart)) &&
23383          (dlSf->bwAlloced < (cell->pbchRbEnd)))
23384    {
23385       /*We have already crossed the start boundary of PBCH RBs.We need to
23386        * find that if we take this allocation then how much of the RBs for
23387        * this allocation will overlap with PBCH RBs.*/
23388       /* Find out the overlapping RBs in the centre 6 RBs */
23389       if(dlSf->bwAlloced + allocInfo->rbsReq < (cell->pbchRbEnd))
23390       {
23391          /*If we take this allocation then also we are not crossing the
23392           * end boundary of PBCH 6 RBs.*/
23393          *numOvrlapgPbchRb = allocInfo->rbsReq;
23394       }
23395       else
23396       {
23397          /*If we take this allocation then we are crossing the
23398           * end boundary of PBCH 6 RBs.*/
23399          *numOvrlapgPbchRb = (cell->pbchRbEnd) - dlSf->bwAlloced;
23400       }
23401    }
23402     return;
23403
23404 }
23405 /**
23406  * @brief Performs RB allocation adjustment if the requested RBs are
23407  *        falling in the center 6 RBs of the downlink bandwidth.
23408  * @details
23409  *
23410  *     Function : rgSCHCmnNonDlfsPbchRbAllocAdj
23411  *
23412  *     Processing Steps:
23413  *      - Allocate consecutively available RBs.
23414  *
23415  *  @param[in]      RgSchCellCb     *cell
23416  *  @param[in,out]  RgSchDlRbAlloc  *allocInfo
23417  *  @param[in]      uint8_t               pbchSsRsSym
23418  *  @return  void
23419  **/
23420 #ifdef ANSI
23421 static Void rgSCHCmnNonDlfsPbchRbAllocAdj
23422 (
23423 RgSchCellCb      *cell,
23424 RgSchDlRbAlloc   *allocInfo,
23425 uint8_t               pbchSsRsSym,
23426 Bool             isBcchPcch
23427 )
23428 #else
23429 static Void rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo,pbchSsRsSym)
23430 RgSchCellCb      *cell;
23431 RgSchDlRbAlloc   *allocInfo;
23432 uint8_t               pbchSsRsSym;
23433 Bool             isBcchPcch;
23434 #endif
23435 {
23436    RgSchDlSf     *dlSf = allocInfo->dlSf;
23437    uint8_t             numOvrlapgPbchRb = 0;
23438    uint8_t             numOvrlapgAdtlPbchRb = 0;
23439    uint8_t             totSym;
23440    uint8_t             addtlRbsReq = 0;
23441    uint8_t             moreAddtlRbsReq = 0;
23442    uint8_t             addtlRbsAdd = 0;
23443    uint8_t             moreAddtlRbsAdd = 0;
23444    uint8_t             tbs;
23445    uint8_t             origRbsReq = 0;
23446    uint32_t            bytesReq;
23447    uint8_t             noLyr;
23448    uint8_t             divResult;
23449
23450
23451
23452
23453    origRbsReq = allocInfo->rbsReq;
23454    rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23455
23456   totSym =  (cell->isCpDlExtend) ? RGSCH_TOT_NUM_SYM_EXTCP : RGSCH_TOT_NUM_SYM_NORCP;
23457
23458    /* Additional RBs are allocated by considering the loss due to
23459       the reserved symbols for CFICH, PBCH, PSS, SSS and cell specific RS */
23460
23461    divResult = (numOvrlapgPbchRb * pbchSsRsSym)/totSym;
23462    if((numOvrlapgPbchRb * pbchSsRsSym) % totSym)
23463    {
23464       divResult++;
23465    }
23466    addtlRbsReq = divResult;
23467
23468    RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, addtlRbsReq, addtlRbsAdd)
23469
23470    /*Now RBs requires is original requested RBs + these additional RBs to make
23471     * up for PSS/SSS/BCCH.*/
23472    allocInfo->rbsReq = allocInfo->rbsReq + addtlRbsAdd;
23473
23474    /*Check if with these additional RBs we have taken up, these are also falling
23475     * under PBCH RBs range, if yes then we would need to account for
23476     * PSS/BSS/BCCH for these additional RBs too.*/
23477    if(addtlRbsAdd && ((dlSf->bwAlloced + allocInfo->rbsReq - addtlRbsAdd) < (cell->pbchRbEnd)))
23478    {
23479       if((dlSf->bwAlloced + allocInfo->rbsReq) <= (cell->pbchRbEnd))
23480       {
23481       /*With additional RBs taken into account, we are not crossing the
23482        * PBCH RB end boundary.Thus here we need to account just for
23483        * overlapping PBCH RBs for these additonal RBs.*/
23484           divResult = (addtlRbsAdd * pbchSsRsSym)/totSym;
23485           if((addtlRbsAdd * pbchSsRsSym) % totSym)
23486           {
23487             divResult++;
23488           }
23489
23490           moreAddtlRbsReq = divResult;
23491
23492           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
23493
23494           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
23495       }
23496       else
23497       {
23498
23499          /*Here we have crossed the PBCH RB end boundary, thus we need to take
23500           * into account the overlapping RBs for additional RBs which will be
23501           * subset of addtlRbs.*/
23502           numOvrlapgAdtlPbchRb = (cell->pbchRbEnd) - ((dlSf->bwAlloced + allocInfo->rbsReq) -  addtlRbsAdd);
23503
23504           divResult = (numOvrlapgAdtlPbchRb * pbchSsRsSym)/totSym;
23505           if((numOvrlapgAdtlPbchRb * pbchSsRsSym) % totSym)
23506           {
23507              divResult++;
23508           }
23509
23510           moreAddtlRbsReq =  divResult;
23511
23512           RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd)
23513
23514           allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd;
23515       }
23516    }
23517    if (isBcchPcch == TRUE)
23518    {
23519       return;
23520    }
23521
23522    RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
23523    if(tbs == 6)
23524    {
23525       /* This case might be for Imcs value 6 and NPrb = 1 case  - Not
23526          Adjusting either RBs or Imcs or Bytes Allocated */
23527       allocInfo->rbsReq = allocInfo->rbsReq - addtlRbsAdd - moreAddtlRbsAdd;
23528    }
23529    else if(tbs && ((0 == addtlRbsAdd) && (moreAddtlRbsAdd == 0)))
23530    {
23531        /*In case of a situation where we the entire bandwidth is already occupied
23532         * and we dont have room to add additional Rbs then in order to decrease the
23533         * code rate we reduce the tbsize such that we reduce the present calculated
23534         * tbsize by number of bytes that would be occupied by PBCH/PSS/SSS in overlapping
23535         * rbs and find the nearest tbsize which would be less than this deduced value*/
23536
23537       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23538
23539       noLyr = allocInfo->tbInfo[0].noLyr;
23540       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyr - 1], tbs);
23541       bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
23542
23543       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,bytesReq);
23544
23545       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23546       {
23547           noLyr = allocInfo->tbInfo[1].noLyr;
23548           bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8;
23549           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,bytesReq);
23550       }
23551
23552    }
23553    else if(tbs && ((addtlRbsAdd != addtlRbsReq) ||
23554           (addtlRbsAdd && (moreAddtlRbsReq != moreAddtlRbsAdd))))
23555    {
23556        /*In case of a situation where we were not able to add required number of
23557         * additional RBs then we adjust the Imcs based on original RBs requested.
23558         * Doing this would comensate for the few extra Rbs we have added but inorder
23559         * to comensate for number of RBS we couldnt add we again do the TBSize adjustment*/
23560
23561       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
23562
23563       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23564       {
23565           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
23566       }
23567
23568       rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb);
23569       numOvrlapgPbchRb = numOvrlapgPbchRb - (addtlRbsAdd + moreAddtlRbsAdd);
23570
23571       rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,allocInfo->tbInfo[0].bytesReq);
23572
23573       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23574       {
23575           rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,allocInfo->tbInfo[1].bytesReq);
23576       }
23577
23578    }
23579    else
23580    {
23581        /*We hit this code when we were able to add the required additional RBS
23582         * hence we should adjust the IMcs based on orignals RBs requested*/
23583
23584       rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq);
23585
23586       if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
23587       {
23588           rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq);
23589       }
23590    }
23591
23592    return;
23593 } /* end of rgSCHCmnNonDlfsPbchRbAllocAdj */
23594 #endif
23595 #endif
23596 /**
23597  * @brief Performs RB allocation for frequency non-selective cell.
23598  *
23599  * @details
23600  *
23601  *     Function : rgSCHCmnNonDlfsCmnRbAlloc
23602  *
23603  *     Processing Steps:
23604  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
23605  *
23606  *  @param[in]      RgSchCellCb     *cell
23607  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
23608  *  @return  S16
23609  *      -# ROK
23610  *      -# RFAILED
23611  **/
23612 #ifdef ANSI
23613 static S16 rgSCHCmnNonDlfsCmnRbAlloc
23614 (
23615 RgSchCellCb      *cell,
23616 RgSchDlRbAlloc   *allocInfo
23617 )
23618 #else
23619 static S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo)
23620 RgSchCellCb      *cell;
23621 RgSchDlRbAlloc   *allocInfo;
23622 #endif
23623 {
23624 #ifndef LTE_TDD
23625 #ifdef LTEMAC_SPS
23626 #endif
23627    uint8_t pbchSsRsSym = 0;
23628    uint8_t pbchFrame = 0;
23629    uint8_t  tbs = 0;
23630    RgSchCmnDlCell   *cellDl    = RG_SCH_CMN_GET_DL_CELL(cell); 
23631 #endif
23632    RgSchDlSf     *dlSf   = allocInfo->dlSf;
23633 #ifdef LTEMAC_SPS
23634    uint8_t                  rbStart = 0;
23635    uint8_t                  spsRbsAlloc = 0;
23636    RgSchDlSfAllocInfo  *dlSfAlloc = &allocInfo->dlSf->dlSfAllocInfo;
23637 #endif
23638
23639    allocInfo->tbInfo[0].noLyr = 1;
23640
23641 #ifdef LTEMAC_SPS
23642    /* Note: Initialize the masks to 0, this might not be needed since alloInfo
23643     * is initialized to 0 at the beginning of allcoation */
23644    allocInfo->resAllocInfo.raType0Mask = 0;
23645    memset(allocInfo->resAllocInfo.raType1Mask, 0,
23646          RG_SCH_NUM_RATYPE1_32BIT_MASK * sizeof (uint32_t));
23647    memset(allocInfo->resAllocInfo.raType2Mask, 0,
23648          RG_SCH_NUM_RATYPE2_32BIT_MASK * sizeof (uint32_t));
23649
23650    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
23651          (dlSf->bwAlloced == dlSf->bw))
23652 #else
23653    if(dlSf->bwAlloced == dlSf->bw)
23654 #endif
23655    {
23656       return RFAILED;
23657    }
23658 #ifndef LTE_TDD
23659    if (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))
23660    {
23661 #ifdef LTEMAC_SPS
23662       if ((allocInfo->tbInfo[0].imcs < 29) && (dlSf->bwAlloced < dlSf->bw))
23663 #else
23664       if(allocInfo->tbInfo[0].imcs < 29)
23665 #endif
23666       {
23667          /* set the remaining RBs for the requested UE */
23668          allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
23669          RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
23670          allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[0][tbs][allocInfo->rbsReq - 1]/8;
23671       }
23672       else
23673       {
23674 #ifdef LTEMAC_SPS
23675          /* Attempt RA Type 2 allocation in SPS Bandwidth */
23676          if (dlSf->spsAllocdBw < cell->spsBwRbgInfo.numRbs) 
23677          {
23678             spsRbsAlloc =
23679                rgSCHCmnDlRaType2Alloc(dlSfAlloc,
23680                      allocInfo->rbsReq, &cell->spsBwRbgInfo, &rbStart,
23681                      &allocInfo->resAllocInfo, FALSE);
23682             /* rbsAlloc assignment moved from line 16671 to here to avoid
23683              * compilation error. Recheck */
23684             dlSf->spsAllocdBw += spsRbsAlloc;
23685          }
23686          if (!spsRbsAlloc)
23687 #endif /* LTEMAC_SPS */
23688          {
23689             return RFAILED;
23690          }
23691       }
23692    }
23693 #endif
23694
23695    /* Update allocation information */
23696    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
23697    if (allocInfo->pdcch == NULLP)
23698    {
23699       return RFAILED;
23700    }
23701    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
23702    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
23703    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
23704    allocInfo->allocInfo.raType2.isLocal = TRUE;
23705 #ifdef LTEMAC_SPS
23706    if (spsRbsAlloc) 
23707    {
23708       allocInfo->allocInfo.raType2.rbStart = rbStart;
23709       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
23710       allocInfo->rbsAlloc = allocInfo->rbsReq;
23711    }
23712 #endif
23713
23714 #ifdef LTEMAC_SPS
23715    if (!spsRbsAlloc)
23716    {
23717 #endif
23718 #ifndef LTE_TDD
23719       if(dlSf->sfNum)
23720       {
23721          if(!(dlSf->sfNum == 5))
23722          {
23723             /* case for subframes 1 to 9 except 5 */
23724 #ifdef LTEMAC_SPS
23725             allocInfo->allocInfo.raType2.rbStart = rbStart;
23726 #else
23727             /*Fix for ccpu00123918*/
23728             allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
23729 #endif
23730          }
23731          else
23732          {
23733             pbchFrame = 1; /* case for subframe 5 */
23734             /* In subframe 5, symbols are reserved for PSS and SSS and CFICH
23735                and Cell Specific Reference Signals */
23736             pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PSS_SSS_SYM) *
23737                   RGSCH_NUM_SC_IN_RB + cell->numCellRSPerSf);
23738          }
23739       }
23740       else
23741       {
23742          pbchFrame = 1;
23743          /* In subframe 0, symbols are reserved for PSS, SSS, PBCH, CFICH and
23744             and Cell Specific Reference signals */
23745          pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PBCH_SYM +
23746                   RGSCH_NUM_PSS_SSS_SYM) * RGSCH_NUM_SC_IN_RB +
23747                cell->numCellRSPerSf);
23748       } /* end of outer else */
23749
23750       if((pbchFrame) &&
23751             (((dlSf->bwAlloced + allocInfo->rbsReq) - cell->pbchRbStart) > 0)&&
23752             (dlSf->bwAlloced < cell->pbchRbEnd))
23753       {
23754          if(allocInfo->tbInfo[0].imcs < 29)
23755          {
23756             rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo, pbchSsRsSym, TRUE);
23757          }
23758       }
23759 #endif
23760 #ifdef LTEMAC_SPS
23761    }
23762 #endif
23763
23764 #ifdef LTEMAC_SPS
23765    if (!spsRbsAlloc)
23766    {  
23767 #endif
23768       /*Fix for ccpu00123918*/
23769       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
23770       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
23771       allocInfo->rbsAlloc = allocInfo->rbsReq;
23772
23773       /* LTE_ADV_FLAG_REMOVED_START */
23774 #ifndef LTE_TDD
23775       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
23776       {
23777          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
23778                allocInfo->allocInfo.raType2.rbStart, \
23779                allocInfo->allocInfo.raType2.numRb);
23780       }
23781       else
23782 #endif
23783       {
23784          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
23785                allocInfo->allocInfo.raType2.rbStart, \
23786                allocInfo->allocInfo.raType2.numRb);
23787       }
23788
23789 #ifdef LTEMAC_SPS
23790    }
23791 #endif
23792    /* LTE_ADV_FLAG_REMOVED_END */
23793    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
23794
23795
23796 #ifdef LTEMAC_SPS
23797    if (spsRbsAlloc)
23798    {
23799       uint8_t    idx;
23800       /* Update type 0, 1 and 2 masks */
23801       dlSfAlloc->raType0Mask    |= allocInfo->resAllocInfo.raType0Mask;
23802 #ifdef RGSCH_SPS_UNUSED
23803       for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx)
23804       {
23805          dlSfAlloc->raType1Mask[idx] |=
23806             allocInfo->resAllocInfo.raType1Mask[idx];
23807          dlSfAlloc->raType1UsedRbs[idx] +=
23808             allocInfo->resAllocInfo.raType1UsedRbs[idx];
23809       }
23810 #endif
23811       for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx)
23812       {
23813          dlSfAlloc->raType2Mask[idx] |=
23814             allocInfo->resAllocInfo.raType2Mask[idx];
23815       }
23816    }
23817 #endif
23818
23819    return ROK;
23820 }
23821
23822
23823 /**
23824  * @brief Performs RB allocation for frequency non-selective cell.
23825  *
23826  * @details
23827  *
23828  *     Function : rgSCHCmnNonDlfsCmnRbAllocRar
23829  *
23830  *     Processing Steps:
23831  *      - Allocate consecutively available RBs for BCCH/PCCH/RAR.
23832  *
23833  *  @param[in]      RgSchCellCb     *cell
23834  *  @param[in, out] RgSchDlRbAlloc  *allocInfo
23835  *  @return  S16
23836  *      -# ROK
23837  *      -# RFAILED
23838  **/
23839 #ifdef ANSI
23840 static S16 rgSCHCmnNonDlfsCmnRbAllocRar
23841 (
23842  RgSchCellCb      *cell,
23843  RgSchDlRbAlloc   *allocInfo
23844  )
23845 #else
23846 static S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo)
23847    RgSchCellCb      *cell;
23848    RgSchDlRbAlloc   *allocInfo;
23849 #endif
23850 {
23851    RgSchDlSf     *dlSf   = allocInfo->dlSf;
23852
23853
23854    if(dlSf->bwAlloced == dlSf->bw)
23855    {
23856       return RFAILED;
23857    }
23858
23859    allocInfo->tbInfo[0].noLyr = 1;
23860 #ifndef RG_5GTF
23861    /* Update allocation information */
23862    allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf);
23863    if (allocInfo->pdcch == NULLP)
23864    {
23865       return RFAILED;
23866    }
23867    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
23868    allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A];
23869    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
23870    allocInfo->allocInfo.raType2.isLocal = TRUE;
23871
23872    /*Fix for ccpu00123918*/
23873    allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
23874    allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
23875    allocInfo->rbsAlloc = allocInfo->rbsReq;
23876
23877    /* LTE_ADV_FLAG_REMOVED_END */
23878    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
23879
23880 #else
23881    allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, NULLP, dlSf, 13, TFU_DCI_FORMAT_B1, FALSE);
23882    if (allocInfo->pdcch == NULLP)
23883    {
23884       return RFAILED;
23885    }
23886    RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
23887    if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
23888    {
23889       printf("5GTF_ERROR vrbg allocated > 25\n");
23890       return RFAILED;
23891    }
23892
23893    allocInfo->tbInfo[0].cmnGrnt.vrbgStart = beamInfo->vrbgStart;
23894    allocInfo->tbInfo[0].cmnGrnt.numVrbg = allocInfo->vrbgReq;
23895
23896    /* Update allocation information */
23897    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
23898
23899    allocInfo->tbInfo[0].cmnGrnt.xPDSCHRange = 1;  
23900    allocInfo->tbInfo[0].cmnGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
23901          allocInfo->tbInfo[0].cmnGrnt.vrbgStart, allocInfo->tbInfo[0].cmnGrnt.numVrbg);
23902
23903    allocInfo->tbInfo[0].cmnGrnt.rbStrt = (allocInfo->tbInfo[0].cmnGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
23904    allocInfo->tbInfo[0].cmnGrnt.numRb = (allocInfo->tbInfo[0].cmnGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
23905
23906    beamInfo->vrbgStart += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
23907    beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].cmnGrnt.numVrbg;
23908    allocInfo->tbInfo[0].cmnGrnt.rv = 0;
23909    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
23910
23911 #endif
23912    printf("\n[%s],allocInfo->tbInfo[0].bytesAlloc:%u,vrbgReq:%u\n",
23913          __func__,allocInfo->tbInfo[0].bytesAlloc,allocInfo->vrbgReq);
23914
23915    return ROK;
23916 }
23917
23918
23919 /* LTE_ADV_FLAG_REMOVED_START */
23920 #ifndef LTE_TDD
23921 /**
23922  * @brief To check if DL BW available for non-DLFS allocation.
23923  *
23924  * @details
23925  *
23926  *     Function : rgSCHCmnNonDlfsBwAvlbl
23927  *
23928  *     Processing Steps:
23929  *      - Determine availability based on RA Type.
23930  *
23931  *  @param[in]  RgSchCellCb     *cell
23932  *  @param[in]  RgSchDlSf       *dlSf
23933  *  @param[in]  RgSchDlRbAlloc  *allocInfo
23934  *
23935  *  @return Bool
23936  *      -# TRUE
23937  *      -# FALSE
23938  **/
23939 #ifdef UNUSED_FUNC
23940 #ifdef ANSI
23941 static Bool rgSCHCmnNonDlfsSFRBwAvlbl
23942 (
23943 RgSchCellCb        *cell,
23944 RgSchSFRPoolInfo   **sfrpoolInfo,
23945 RgSchDlSf          *dlSf,
23946 RgSchDlRbAlloc     *allocInfo,
23947 Bool               isUeCellEdge
23948 )
23949 #else
23950 static Bool rgSCHCmnNonDlfsSFRBwAvlbl(cell, sfrpoolInfo, dlSf, allocInfo, isUeCellEdge)
23951 RgSchCellCb        *cell;
23952 RgSchSFRPoolInfo   **sfrpoolInfo;
23953 RgSchDlSf          *dlSf;
23954 RgSchDlRbAlloc     *allocInfo;
23955 Bool               isUeCellEdge;
23956 #endif
23957 {
23958    CmLListCp   *l;
23959    CmLListCp   *l1;
23960    CmLList     *n;
23961    CmLList     *n1;
23962    RgSchSFRPoolInfo  *sfrPool;
23963    RgSchSFRPoolInfo  *sfrCEPool;
23964
23965    uint8_t tbs;
23966    uint8_t noLyrs;
23967    RgSchSFRPoolInfo *poolWithMaxAvlblBw = NULLP;
23968    uint32_t bwAvlbl = 0;
23969    uint32_t addtnlPRBs = 0;
23970
23971    if (dlSf->bw <= dlSf->bwAlloced)
23972    {
23973       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
23974             "BW is fully allocated for subframe (%d) CRNTI:%d", dlSf->sfNum,allocInfo->rnti);
23975       return FALSE;
23976    }
23977
23978    if (dlSf->sfrTotalPoolInfo.ccBwFull == TRUE)
23979    {
23980       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
23981             "BW is fully allocated for CC Pool CRNTI:%d",allocInfo->rnti);
23982       return FALSE;
23983    }
23984
23985    if ((dlSf->sfrTotalPoolInfo.ceBwFull == TRUE) && (isUeCellEdge))
23986    {
23987       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, 
23988             "BW is fully allocated for CE Pool CRNTI:%d",allocInfo->rnti);
23989       return FALSE;
23990    }  
23991
23992    /* We first check if the ue scheduled is a cell edge or cell centre and accordingly check the avaialble
23993       memory in their pool. If the cell centre UE doesnt have Bw available in its pool, then it will check
23994       Bw availability in cell edge pool but the other way around is NOT possible.   */
23995    if(isUeCellEdge)
23996    {   
23997       l = &dlSf->sfrTotalPoolInfo.cePool;
23998    }
23999    else
24000    {
24001       l = &dlSf->sfrTotalPoolInfo.ccPool; 
24002    }     
24003
24004    n = cmLListFirst(l);
24005
24006    while(n)       
24007    {
24008       if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
24009       {
24010          sfrPool = (RgSchSFRPoolInfo*)(n->node);
24011
24012          /* MS_FIX for ccpu00123919 : Number of RBs in case of RETX should be same as that of initial transmission. */
24013          if(allocInfo->tbInfo[0].tbCb->txCntr)
24014          {
24015             /* If RB assignment is being done for RETX. Then if reqRbs are   a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
24016              * not a multiple of rbgSize then check if lsgRbgDfct exists */
24017             if (allocInfo->rbsReq % cell->rbgSize == 0)
24018             {
24019                if ((sfrPool->type2End == dlSf->type2End) && dlSf->lstRbgDfct)
24020                {
24021                   /* In this scenario we are wasting the last RBG for this dlSf */
24022                   sfrPool->type0End--;
24023                   sfrPool->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24024
24025                   dlSf->lstRbgDfct = 0;
24026
24027                   /*ABHINAV To check if these variables need to be taken care of*/
24028                   dlSf->type0End--;
24029                   dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24030                }
24031             }
24032             else
24033             {
24034                if (dlSf->lstRbgDfct)
24035                {
24036                   /* Check if type0 allocation can cater to this RETX requirement */
24037                   if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
24038                   {
24039                      return (FALSE);
24040                   }
24041                   else
24042                   {
24043                      if (sfrPool->type2End != dlSf->type2End)   /*Search again for some pool which has the END RBG of the BandWidth*/
24044                      {
24045                         continue;                                       
24046                      }  
24047                   }
24048                }
24049                else
24050                {
24051                   /* cannot allocate same number of required RBs */
24052                   return (FALSE);                    
24053                }
24054             }
24055          }
24056
24057          /*rg002.301 ccpu00120391 MOD condition is modified approprialtely to find if rbsReq is less than available RBS*/
24058          if(allocInfo->rbsReq <= (((sfrPool->type0End - sfrPool->type2End + 1)*\
24059                      cell->rbgSize) - dlSf->lstRbgDfct))
24060          {
24061             *sfrpoolInfo = sfrPool;
24062             return (TRUE);
24063          }
24064          else
24065          {
24066             if (sfrPool->bw <= sfrPool->bwAlloced + cell->rbgSize)
24067             {
24068                n = cmLListNext(l);
24069                /* If the ue is cell centre then it will simply check the memory available in next pool.
24070                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
24071
24072                if((!isUeCellEdge) && (!n->node))
24073                {
24074                   l = &dlSf->sfrTotalPoolInfo.cePool;
24075                   n = cmLListFirst(l);
24076                }
24077
24078                continue; 
24079             }    
24080
24081             /* MS_FIX: Number of RBs in case of RETX should be same as that of initial transmission */
24082             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24083             {
24084                /*rg002.301 ccpu00120391 MOD setting the remaining RBs  for the requested UE*/
24085                allocInfo->rbsReq = (((sfrPool->type0End - sfrPool->type2End + 1)*\
24086                         cell->rbgSize) - dlSf->lstRbgDfct);
24087                RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24088                noLyrs = allocInfo->tbInfo[0].noLyr;
24089                allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24090                *sfrpoolInfo = sfrPool;
24091                return (TRUE);
24092             }
24093             else
24094             {
24095                n = cmLListNext(l);
24096
24097                /* If the ue is cell centre then it will simply check the memory available in next pool.
24098                   But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */
24099                if((!isUeCellEdge) && (!n->node))
24100                {
24101                   l = &dlSf->sfrTotalPoolInfo.cePool;
24102                   n = cmLListFirst(l);
24103                }
24104
24105                continue;
24106             }
24107
24108          //   return (FALSE);
24109          }
24110       }
24111       else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
24112       {
24113          sfrPool = (RgSchSFRPoolInfo*)(n->node);
24114          /* This is a Case where a UE was CC and had more RBs allocated than present in CE pool.
24115             In case this UE whn become CE with retx going on, then BW is not sufficient for Retx */
24116          if ((isUeCellEdge) &&
24117             (allocInfo->tbInfo[0].tbCb->txCntr != 0))
24118          {
24119             if(allocInfo->rbsReq > (sfrPool->bw - sfrPool->bwAlloced))
24120             {
24121                /* Adjust CE BW such that Retx alloc is successful */
24122                /* Check if merging CE with adjacent CC pool will be sufficient to process Retx */
24123
24124                /* If no Type 0 allocations are made from this pool */
24125                if (sfrPool->type0End == (((sfrPool->poolendRB + 1) / cell->rbgSize) - 1))
24126                {
24127                   if (sfrPool->adjCCPool &&
24128                         (sfrPool->adjCCPool->type2Start == sfrPool->poolendRB + 1) &&
24129                         (allocInfo->rbsReq <= ((sfrPool->bw - sfrPool->bwAlloced) + 
24130                                                ((sfrPool->adjCCPool->bw - sfrPool->adjCCPool->bwAlloced)))))
24131                   {
24132                      addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
24133
24134                      /* Adjusting CE Pool Info */
24135                      sfrPool->bw += addtnlPRBs;
24136                      sfrPool->type0End = ((sfrPool->poolendRB + addtnlPRBs + 1) /
24137                            cell->rbgSize) - 1;
24138
24139                      /* Adjusting CC Pool Info */
24140                      sfrPool->adjCCPool->type2Start += addtnlPRBs;
24141                      sfrPool->adjCCPool->type2End = RGSCH_CEIL(sfrPool->adjCCPool->type2Start, 
24142                            cell->rbgSize);
24143                      sfrPool->adjCCPool->bw -= addtnlPRBs;
24144                      *sfrpoolInfo = sfrPool;
24145                      return (TRUE);
24146                   }
24147                }
24148             }
24149          }
24150
24151          /* Check if CC pool is one of the following:
24152           * 1. |CE| + |CC "CCPool2Exists" = TRUE|
24153           * 2. |CC "CCPool2Exists" = FALSE| + |CE| + |CC "CCPool2Exists" = TRUE|
24154           */ 
24155          if(TRUE == sfrPool->CCPool2Exists)
24156          {
24157             l1 = &dlSf->sfrTotalPoolInfo.cePool;
24158             n1 = cmLListFirst(l1); 
24159             sfrCEPool = (RgSchSFRPoolInfo*)(n1->node);
24160             if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced))
24161             {
24162                *sfrpoolInfo = sfrCEPool;
24163                return (TRUE);
24164             }
24165             else if(allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))  
24166             {
24167                *sfrpoolInfo = sfrPool;
24168                return (TRUE);
24169             }
24170             /* Check if CE and CC boundary has unallocated prbs */
24171             else if ((sfrPool->poolstartRB == sfrPool->type2Start) &&
24172                   (sfrCEPool->type0End  == ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1))
24173             {
24174                if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced) + 
24175                      (sfrPool->bw - sfrPool->bwAlloced))
24176                {
24177                   /* Checking if BW can be allocated partly from CE pool and partly
24178                    * from CC pool
24179                    */
24180                   addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced);
24181                   /* Updating CE and CC  type2 parametrs based on the RBs allocated
24182                    * from these pools*/
24183                   sfrPool->type2Start -= addtnlPRBs;
24184                   sfrPool->type2End = RGSCH_CEIL(sfrPool->type2Start, cell->rbgSize);
24185                   sfrPool->bw += addtnlPRBs;
24186                   if (addtnlPRBs == (sfrCEPool->bw - sfrCEPool->bwAlloced))
24187                   {
24188                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
24189                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
24190                   }
24191                   else
24192                   {
24193                      sfrCEPool->bw -= addtnlPRBs;
24194                      sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1 - addtnlPRBs) / cell->rbgSize) - 1;
24195                   }
24196                   *sfrpoolInfo = sfrPool;
24197                   return (TRUE);
24198                }
24199                else if ( bwAvlbl < 
24200                      ((sfrCEPool->bw - sfrCEPool->bwAlloced) +
24201                       (sfrPool->bw - sfrPool->bwAlloced)))
24202                {
24203                   /* All the Prbs from CE BW shall be allocated */
24204                   if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24205                   {
24206                      sfrPool->type2Start   = sfrCEPool->type2Start;
24207                      sfrPool->bw          += sfrCEPool->bw - sfrCEPool->bwAlloced;
24208                      sfrCEPool->type2Start = sfrCEPool->poolendRB + 1;
24209                      sfrCEPool->bwAlloced  = sfrCEPool->bw; 
24210                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE;
24211
24212                      /* set the remaining RBs for the requested UE */
24213                      allocInfo->rbsReq = (sfrPool->bw - sfrPool->bwAlloced);
24214                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24215                      noLyrs = allocInfo->tbInfo[0].noLyr;
24216                      allocInfo->tbInfo[0].bytesReq = 
24217                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24218                      *sfrpoolInfo = sfrPool;               
24219                      return (TRUE);
24220                   }
24221                   else
24222                   {
24223                      return (FALSE);
24224                   }
24225                }
24226             }
24227          } 
24228
24229          /* Checking if no. of RBs required can be allocated from
24230           * SFR pool. 
24231           * 1. If available return the SFR pool.
24232           * 2. Else update the RBs required parameter based on the 
24233           *    BW available in the pool 
24234           * 3. Return FALSE if no B/W is available. 
24235           */
24236          if (allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced))
24237          {
24238             *sfrpoolInfo = sfrPool;
24239             return (TRUE);
24240          }
24241          else
24242          {
24243             if(allocInfo->tbInfo[0].tbCb->txCntr == 0)
24244             {
24245                if (bwAvlbl < sfrPool->bw - sfrPool->bwAlloced)
24246                {
24247                   if (isUeCellEdge)
24248                   {
24249                      dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
24250                   }
24251                   bwAvlbl = sfrPool->bw - sfrPool->bwAlloced;
24252                   poolWithMaxAvlblBw = sfrPool;
24253                }
24254                n = cmLListNext(l);
24255
24256                if ((isUeCellEdge == FALSE) && (n == NULLP))
24257                {
24258                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
24259                   {
24260                      l = &dlSf->sfrTotalPoolInfo.cePool;
24261                      n = cmLListFirst(l);                          
24262                   }
24263                }
24264
24265                if (n == NULLP)
24266                {
24267                   if (bwAvlbl == 0)
24268                   {                                                             
24269                      if (isUeCellEdge)
24270                      {
24271                         dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; 
24272                      }
24273                      else
24274                      {
24275                         dlSf->sfrTotalPoolInfo.ccBwFull = TRUE;  
24276                      }
24277                      return (FALSE);
24278                   }
24279                   else
24280                   {
24281                      /* set the remaining RBs for the requested UE */
24282                      allocInfo->rbsReq = poolWithMaxAvlblBw->bw - 
24283                         poolWithMaxAvlblBw->bwAlloced;
24284                      RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24285                      noLyrs = allocInfo->tbInfo[0].noLyr;
24286                      allocInfo->tbInfo[0].bytesReq = 
24287                         rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24288                      *sfrpoolInfo = poolWithMaxAvlblBw;            
24289                      return (TRUE);
24290                   }
24291                }                          
24292             }
24293             else
24294             {                   
24295                n = cmLListNext(l);
24296
24297                if ((isUeCellEdge == FALSE) && (n == NULLP))
24298                {
24299                   if(l != &dlSf->sfrTotalPoolInfo.cePool)
24300                   {
24301                      l = &dlSf->sfrTotalPoolInfo.cePool;
24302                      n = cmLListFirst(l);                          
24303                   }
24304                }
24305
24306                if (n == NULLP)
24307                {
24308                   return (FALSE);
24309                }
24310             }
24311
24312          }
24313       }   
24314    } 
24315    return (FALSE);
24316 }
24317 #endif
24318 #endif /* end of ifndef LTE_TDD*/
24319 /* LTE_ADV_FLAG_REMOVED_END */
24320
24321 /**
24322  * @brief To check if DL BW available for non-DLFS allocation.
24323  *
24324  * @details
24325  *
24326  *     Function : rgSCHCmnNonDlfsUeRbAlloc
24327  *
24328  *     Processing Steps:
24329  *      - Determine availability based on RA Type.
24330  *
24331  *  @param[in]  RgSchCellCb     *cell
24332  *  @param[in]  RgSchDlSf       *dlSf
24333  *  @param[in]  RgSchDlRbAlloc  *allocInfo
24334  *
24335  *  @return Bool
24336  *      -# TRUE
24337  *      -# FALSE
24338  **/
24339 #ifdef UNUSED_FUNC
24340 #ifdef ANSI
24341 static Bool rgSCHCmnNonDlfsBwAvlbl
24342 (
24343 RgSchCellCb        *cell,
24344 RgSchDlSf          *dlSf,
24345 RgSchDlRbAlloc     *allocInfo
24346 )
24347 #else
24348 static Bool rgSCHCmnNonDlfsBwAvlbl(cell, dlSf, allocInfo)
24349 RgSchCellCb        *cell;
24350 RgSchDlSf          *dlSf;
24351 RgSchDlRbAlloc     *allocInfo;
24352 #endif
24353 {
24354    uint8_t tbs;
24355    uint8_t noLyrs;
24356    uint8_t ignoredDfctRbg = FALSE;
24357
24358    if (dlSf->bw <= dlSf->bwAlloced)
24359    {
24360       RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, "(%d:%d)FAILED CRNTI:%d",
24361          dlSf->bw, dlSf->bwAlloced,allocInfo->rnti);
24362       return (FALSE);
24363    }
24364    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
24365    {
24366        /* Fix for ccpu00123919 : Number of RBs in case of RETX should be same as 
24367         * that of initial transmission. */
24368        if(allocInfo->tbInfo[0].tbCb->txCntr)
24369        {
24370           /* If RB assignment is being done for RETX. Then if reqRbs are 
24371            * a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is 
24372            * not a multiple of rbgSize then check if lsgRbgDfct exists */
24373           if (allocInfo->rbsReq % cell->rbgSize == 0)
24374           {
24375              if (dlSf->lstRbgDfct)
24376              {
24377                 /* In this scenario we are wasting the last RBG for this dlSf */
24378                 
24379                 dlSf->type0End--;
24380                 dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct);
24381                 /* Fix: MUE_PERTTI_DL */
24382                 dlSf->lstRbgDfct = 0;
24383                 ignoredDfctRbg = TRUE;
24384                 
24385              }
24386           }
24387           else
24388           {
24389              if (dlSf->lstRbgDfct)
24390              {
24391                 /* Check if type0 allocation can cater to this RETX requirement */
24392                 if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct))
24393                 {
24394                    return (FALSE);
24395                 }
24396              }
24397              else
24398              {
24399                 /* cannot allocate same number of required RBs */
24400                 return (FALSE);              
24401              }
24402           }
24403        }
24404
24405        /* Condition is modified approprialtely to find
24406         * if rbsReq is less than available RBS*/
24407       if(allocInfo->rbsReq <= (((dlSf->type0End - dlSf->type2End + 1)*\
24408                cell->rbgSize) - dlSf->lstRbgDfct))
24409       {
24410          return (TRUE);
24411       }
24412       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
24413        * allocation in TDD when requested RBs are more than available RBs*/
24414       else
24415       {
24416           /* MS_WORKAROUND for ccpu00122022 */
24417          if (dlSf->bw < dlSf->bwAlloced + cell->rbgSize)
24418          {
24419             /* ccpu00132358- Re-assigning the values which were updated above 
24420              * if it is RETX and Last  RBG available*/
24421             if(ignoredDfctRbg == TRUE)
24422             {
24423                dlSf->type0End++;
24424                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
24425                dlSf->lstRbgDfct = 1;
24426             }
24427
24428
24429             return (FALSE);
24430          }
24431          /* Fix: Number of RBs in case of RETX should be same as 
24432           * that of initial transmission. */
24433          if(allocInfo->tbInfo[0].tbCb->txCntr == 0 
24434 #ifdef LTE_ADV
24435             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
24436 #endif
24437             )
24438          {
24439             /* Setting the remaining RBs for the requested UE*/
24440             allocInfo->rbsReq = (((dlSf->type0End - dlSf->type2End + 1)*\
24441                         cell->rbgSize) - dlSf->lstRbgDfct);
24442             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24443             noLyrs = allocInfo->tbInfo[0].noLyr;
24444             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24445             /* DwPts Scheduling Changes Start */
24446 #if LTE_TDD
24447             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24448             {   
24449                allocInfo->tbInfo[0].bytesReq = 
24450                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
24451             }
24452 #endif            
24453             /* DwPts Scheduling Changes End */
24454          }
24455          else
24456          {
24457                     /* ccpu00132358- Re-assigning the values which were updated above 
24458              * if it is RETX and Last  RBG available*/
24459             if(ignoredDfctRbg == TRUE)
24460             {
24461                dlSf->type0End++;
24462                dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct);
24463                dlSf->lstRbgDfct = 1;
24464             }
24465
24466             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "FAILED for CRNTI:%d",
24467                   allocInfo->rnti);
24468             printf ("RB Alloc failed for LAA TB type 0\n");
24469             return (FALSE);
24470          }
24471          return (TRUE);
24472       }
24473    }
24474    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
24475    {
24476       if (allocInfo->rbsReq <= (dlSf->bw - dlSf->bwAlloced))
24477       {
24478          return (TRUE);
24479       }
24480       /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB 
24481        * allocation in TDD when requested RBs are more than available RBs*/
24482       else
24483       {
24484          /* Fix: Number of RBs in case of RETX should be same as 
24485           * that of initial transmission. */
24486          if((allocInfo->tbInfo[0].tbCb->txCntr == 0) 
24487 #ifdef LTE_ADV
24488             && (FALSE == rgSCHLaaIsLaaTB(allocInfo))
24489 #endif
24490             )
24491          {
24492             /* set the remaining RBs for the requested UE */
24493             allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced;
24494             RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs);
24495             noLyrs = allocInfo->tbInfo[0].noLyr;
24496             allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8;
24497             /* DwPts Scheduling Changes Start */
24498 #ifdef LTE_TDD
24499             if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24500             {   
24501                allocInfo->tbInfo[0].bytesReq = 
24502                         rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; 
24503             }
24504 #endif            
24505             /* DwPts Scheduling Changes End */
24506          }
24507          else
24508          {
24509             printf ("RB Alloc failed for LAA TB type 2\n");
24510             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti);
24511             return (FALSE);
24512          }
24513          /* Fix: Number of RBs in case of RETX should be same as 
24514           * that of initial transmission. */
24515          return (TRUE);
24516       }
24517    }
24518    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti);
24519    return (FALSE);
24520 }
24521 #endif
24522 /* LTE_ADV_FLAG_REMOVED_START */
24523 #ifndef LTE_TDD
24524 /**
24525  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24526  *
24527  * @details
24528  *
24529  *     Function : rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
24530  *
24531  *     Processing Steps:
24532  *
24533  *  @param[in]  RgSchCellCb     *cell
24534  *  @param[in]  RgSchDlSf       *dlSf
24535  *  @param[in]  uint8_t              rbStrt
24536  *  @param[in]  uint8_t              numRb
24537  *
24538  *  @return Void
24539  **/
24540 #ifdef ANSI
24541 Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc
24542 (
24543 RgSchCellCb        *cell,
24544 RgSchDlSf          *dlSf,
24545 uint8_t                 rbStrt,
24546 uint8_t                 numRb
24547 )
24548 #else
24549 Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, rbStrt, numRb)
24550 RgSchCellCb        *cell;
24551 RgSchDlSf          *dlSf;
24552 uint8_t                 rbStrt;
24553 uint8_t                 numRb;
24554 #endif
24555
24556    CmLListCp   *l;
24557    CmLList     *n;
24558    RgSchSFRPoolInfo  *sfrPool;
24559    
24560    l = &dlSf->sfrTotalPoolInfo.ccPool;
24561      
24562    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
24563    dlSf->bwAlloced += numRb;
24564    dlSf->type2Start += numRb;
24565    n = cmLListFirst(l);
24566         
24567    while(n->node)
24568    {
24569         sfrPool = (RgSchSFRPoolInfo*)(n->node);
24570         n = cmLListNext(l);
24571          
24572          /* 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   */
24573         if((sfrPool->poolendRB >= dlSf->type2Start) && (sfrPool->type2Start < dlSf->type2Start))
24574         {
24575                 sfrPool->type2End   =  dlSf->type2End;
24576                 sfrPool->bwAlloced  =  dlSf->type2Start - sfrPool->poolstartRB; 
24577                 sfrPool->type2Start =  dlSf->type2Start;
24578         }          
24579         else 
24580         { 
24581                 /* If the pool contains all RBs allocated in this allocation*/
24582                 if(dlSf->type2Start > sfrPool->poolendRB)
24583                 {                
24584                         sfrPool->type2End   =  sfrPool->type0End + 1;
24585                         sfrPool->bwAlloced  =  sfrPool->bw; 
24586                         sfrPool->type2Start =  sfrPool->poolendRB + 1;             
24587                 }  
24588         }
24589       if (!n)
24590       { 
24591          if (l != &dlSf->sfrTotalPoolInfo.cePool)
24592          {
24593             l = &dlSf->sfrTotalPoolInfo.cePool;   
24594             n = cmLListFirst(l);
24595          }
24596          else
24597             return;
24598       }
24599    }
24600    return;
24601 }
24602
24603 /**
24604  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24605  *
24606  * @details
24607  *
24608  *     Function : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
24609  *
24610  *     Processing Steps:
24611  *
24612  *  @param[in]  RgSchCellCb     *cell
24613  *  @param[in]  RgSchDlSf       *dlSf
24614  *  @param[in]  uint8_t              rbStrt
24615  *  @param[in]  uint8_t              numRb
24616  *
24617  *  @return Void
24618  **/
24619 #ifdef UNUSED_FUNC
24620 #ifdef ANSI
24621 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc
24622 (
24623 RgSchCellCb        *cell,
24624 RgSchUeCb          *ue,
24625 RgSchDlSf          *dlSf,
24626 uint8_t                 rbStrt,
24627 uint8_t                 numRb
24628 )
24629 #else
24630 static S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc(cell, ue, dlSf, rbStrt, numRb)
24631 RgSchCellCb        *cell;
24632 RgSchUeCb          *ue;
24633 RgSchDlSf          *dlSf;
24634 uint8_t                 rbStrt;
24635 uint8_t                 numRb;
24636 #endif
24637 {
24638    CmLListCp   *l;
24639    CmLList     *n;
24640    RgSchSFRPoolInfo  *sfrCCPool1 = NULL;
24641    RgSchSFRPoolInfo  *sfrCCPool2 = NULL;
24642    S16 ret = RFAILED;
24643
24644    /* Move the type2End pivot forward */
24645    
24646    
24647    l = &dlSf->sfrTotalPoolInfo.ccPool;
24648    n = cmLListFirst(l);
24649    while(n)
24650    {
24651       sfrCCPool1 = (RgSchSFRPoolInfo*)(n->node);
24652       /* KWork fix */
24653       if (sfrCCPool1 ==  NULLP)
24654             {
24655                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,  "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
24656                         "sfrCCPool1 is NULL for CRNTI:%d",ue->ueId);
24657                return RFAILED;
24658             }
24659       n = cmLListNext(l);
24660       if(n)
24661       {
24662           sfrCCPool2 = (RgSchSFRPoolInfo*)(n->node);
24663           n = cmLListNext(l);
24664       }
24665       if((sfrCCPool1) && (sfrCCPool2))
24666       { 
24667           /* Based on RNTP info, the CC user is assigned high power per subframe basis */
24668           if(((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
24669               (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) || 
24670              ((dlSf->type2Start >= sfrCCPool2->pwrHiCCRange.startRb) &&
24671               (dlSf->type2Start + numRb < sfrCCPool2->pwrHiCCRange.endRb)))
24672           {
24673                ue->lteAdvUeCb.isCCUePHigh = TRUE;
24674
24675                /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
24676                ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
24677                if (ret != ROK)
24678                {
24679                     RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():"
24680                       "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
24681                     return RFAILED;
24682                }
24683            }
24684       }
24685       else
24686       {
24687          if((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) &&
24688                (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb))
24689          {
24690             ue->lteAdvUeCb.isCCUePHigh = TRUE;
24691
24692             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
24693             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw);
24694             if (ret != ROK)
24695             {
24696                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,   "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" 
24697                         "rgSCHCmnBuildRntpInfo() function returned RFAILED CRNTI:%d",ue->ueId);
24698                return RFAILED;
24699             }
24700          }
24701       }
24702    }
24703    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
24704 #ifndef LTEMAC_SPS
24705    dlSf->bwAlloced += numRb;
24706    /*MS_FIX for ccpu00123918*/
24707    dlSf->type2Start += numRb;
24708 #endif
24709    return ROK;
24710
24711 }
24712 #endif
24713 #endif /* end of ifndef LTE_TDD*/
24714 /* LTE_ADV_FLAG_REMOVED_END */
24715 /**
24716  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
24717  *
24718  * @details
24719  *
24720  *     Function : rgSCHCmnNonDlfsUpdTyp2Alloc
24721  *
24722  *     Processing Steps:
24723  *
24724  *  @param[in]  RgSchCellCb     *cell
24725  *  @param[in]  RgSchDlSf       *dlSf
24726  *  @param[in]  uint8_t              rbStrt
24727  *  @param[in]  uint8_t              numRb
24728  *
24729  *  @return Void
24730  **/
24731 #ifdef ANSI
24732 static Void rgSCHCmnNonDlfsUpdTyp2Alloc
24733 (
24734 RgSchCellCb        *cell,
24735 RgSchDlSf          *dlSf,
24736 uint8_t                 rbStrt,
24737 uint8_t                 numRb
24738 )
24739 #else
24740 static Void rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, rbStrt, numRb)
24741 RgSchCellCb        *cell;
24742 RgSchDlSf          *dlSf;
24743 uint8_t                 rbStrt;
24744 uint8_t                 numRb;
24745 #endif
24746 {
24747    /* Move the type2End pivot forward */
24748    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
24749 //#ifndef LTEMAC_SPS
24750    dlSf->bwAlloced += numRb;
24751    /*Fix for ccpu00123918*/
24752    dlSf->type2Start += numRb;
24753 //#endif
24754    return;
24755 }
24756
24757 /**
24758  * @brief To do DL allocation using TYPE0 RA.
24759  *
24760  * @details
24761  *
24762  *     Function : rgSCHCmnNonDlfsType0Alloc
24763  *
24764  *     Processing Steps:
24765  *      - Perform TYPE0 allocation using the RBGs between
24766  *        type0End and type2End.
24767  *      - Build the allocation mask as per RBG positioning.
24768  *      - Update the allocation parameters.
24769  *
24770  *  @param[in]  RgSchCellCb     *cell
24771  *  @param[in]  RgSchDlSf       *dlSf
24772  *  @param[in]  RgSchDlRbAlloc  *allocInfo
24773  *
24774  *  @return Void
24775  **/
24776 #ifdef UNUSED_FUNC
24777 #ifdef ANSI
24778 static Void rgSCHCmnNonDlfsType0Alloc
24779 (
24780 RgSchCellCb        *cell,
24781 RgSchDlSf          *dlSf,
24782 RgSchDlRbAlloc     *allocInfo,
24783 RgSchUeCb          *ue
24784 )
24785 #else
24786 static Void rgSCHCmnNonDlfsType0Alloc(cell, dlSf, allocInfo, dlUe)
24787 RgSchCellCb        *cell;
24788 RgSchDlSf          *dlSf;
24789 RgSchDlRbAlloc     *allocInfo;
24790 RgSchUeCb          *ue;
24791 #endif
24792 {
24793    uint32_t dlAllocMsk = 0;
24794    uint8_t  rbgFiller = dlSf->lstRbgDfct;
24795    uint8_t  noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
24796    //uint8_t  noRbgs = (allocInfo->rbsReq + rbgFiller)/ cell->rbgSize;
24797    uint8_t  noRbs;
24798    uint8_t  noLyr;
24799    uint8_t  iTbs;
24800    uint32_t          tb1BytesAlloc = 0;
24801    uint32_t          tb2BytesAlloc = 0;
24802    RgSchCmnDlUe *dlUe         = RG_SCH_CMN_GET_DL_UE(ue,cell);
24803
24804    //if(noRbgs == 0) noRbgs = 1; /* Not required as ceilling is used above*/
24805
24806    /* Fix for ccpu00123919*/
24807    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
24808    if (dlSf->bwAlloced + noRbs > dlSf->bw)
24809    {
24810       if (--noRbgs == 0)
24811       {
24812          return;
24813       }
24814       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
24815    }
24816
24817    /* Fix for ccpu00138701: Ceilling is using to derive num of RBGs, Therefore, 
24818    *  after this operation,checking Max TB size and Max RBs are not crossed
24819    * if it is crossed then decrement num of RBGs. */
24820    //if((noRbs + rbgFiller) % cell->rbgSize)
24821    if((noRbs > allocInfo->rbsReq) &&
24822          (allocInfo->rbsReq + rbgFiller) % cell->rbgSize)
24823    {/* considering ue category limitation
24824      * due to ceiling */
24825
24826 #ifdef LTE_ADV
24827       if (rgSCHLaaIsLaaTB(allocInfo)== FALSE)
24828 #endif
24829       {
24830          if ((allocInfo->tbInfo[0].schdlngForTb) && (!allocInfo->tbInfo[0].tbCb->txCntr))
24831          {
24832             iTbs = allocInfo->tbInfo[0].iTbs;
24833             noLyr = allocInfo->tbInfo[0].noLyr;
24834             tb1BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
24835          }
24836
24837          if ((allocInfo->tbInfo[1].schdlngForTb) && (!allocInfo->tbInfo[1].tbCb->txCntr))
24838          {
24839             iTbs = allocInfo->tbInfo[1].iTbs;
24840             noLyr = allocInfo->tbInfo[1].noLyr;
24841             tb2BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
24842          }
24843       }
24844       
24845       /* Only Check for New Tx No need for Retx */
24846       if (tb1BytesAlloc || tb2BytesAlloc)
24847       {
24848          if (( ue->dl.aggTbBits >= dlUe->maxTbBits) ||
24849                (tb1BytesAlloc >= dlUe->maxTbSz/8) ||
24850                (tb2BytesAlloc >= dlUe->maxTbSz/8) ||
24851                (noRbs >= dlUe->maxRb))
24852          {
24853             if (--noRbgs == 0)
24854             {
24855                return;
24856             }
24857             noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
24858          }
24859       }
24860    }
24861    /* type0End would have been initially (during subfrm Init) at the bit position
24862     * (cell->noOfRbgs - 1), 0 being the most significant.
24863     * Getting DlAllocMsk for noRbgs and at the appropriate position */
24864    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - dlSf->type0End));
24865    /* Move backwards the type0End pivot */
24866    dlSf->type0End -= noRbgs;
24867    /*Fix for ccpu00123919*/
24868    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
24869    /* Update the bwAlloced field accordingly */
24870 //#ifndef LTEMAC_SPS    /* ccpu00129474*/
24871    dlSf->bwAlloced += noRbs;
24872 //#endif
24873    /* Update Type0 Alloc Info */
24874    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
24875    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
24876    allocInfo->rbsAlloc = noRbs;
24877
24878    /* Update Tb info for each scheduled TB */
24879    iTbs = allocInfo->tbInfo[0].iTbs;
24880    noLyr = allocInfo->tbInfo[0].noLyr;
24881    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
24882     * RETX TB Size is same as Init TX TB Size */
24883    if (allocInfo->tbInfo[0].tbCb->txCntr)
24884    {
24885       allocInfo->tbInfo[0].bytesAlloc =
24886          allocInfo->tbInfo[0].bytesReq;
24887    }
24888    else
24889    {
24890       allocInfo->tbInfo[0].bytesAlloc =
24891          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
24892       /* DwPts Scheduling Changes Start */
24893 #ifdef LTE_TDD
24894       if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24895       {
24896          allocInfo->tbInfo[0].bytesAlloc =
24897             rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
24898       }
24899 #endif      
24900       /* DwPts Scheduling Changes End */
24901    }
24902
24903    if (allocInfo->tbInfo[1].schdlngForTb)
24904    {
24905       iTbs = allocInfo->tbInfo[1].iTbs;
24906       noLyr = allocInfo->tbInfo[1].noLyr;
24907       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
24908        * RETX TB Size is same as Init TX TB Size */
24909       if (allocInfo->tbInfo[1].tbCb->txCntr)
24910       {
24911          allocInfo->tbInfo[1].bytesAlloc =
24912             allocInfo->tbInfo[1].bytesReq;
24913       }
24914       else
24915       {
24916          allocInfo->tbInfo[1].bytesAlloc =
24917             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
24918          /* DwPts Scheduling Changes Start */
24919 #ifdef LTE_TDD
24920          if (dlSf->sfType == RG_SCH_SPL_SF_DATA)
24921          {
24922             allocInfo->tbInfo[1].bytesAlloc =
24923                rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8;
24924          }
24925 #endif      
24926          /* DwPts Scheduling Changes End */
24927       }
24928    }
24929
24930    /* The last RBG which can be smaller than the RBG size is consedered
24931     * only for the first time allocation of TYPE0 UE */
24932    dlSf->lstRbgDfct = 0;
24933    return;
24934 }
24935 #endif
24936 #ifndef LTE_TDD
24937
24938 /**
24939  * @brief To prepare RNTP value from the PRB allocation (P-High -> 1 and P-Low -> 0)
24940  *
24941  * @details
24942  *
24943  *     Function : rgSCHCmnBuildRntpInfo
24944  *
24945  *     Processing Steps:
24946  *
24947  *  @param[in]  uint8_t                 *rntpPtr
24948  *  @param[in]  uint8_t                 startRb
24949  *  @param[in]  uint8_t                 numRb
24950  *
24951  *  @return Void
24952  **/
24953 #ifdef UNUSED_FUNC
24954 #ifdef ANSI
24955 static S16 rgSCHCmnBuildRntpInfo
24956 (
24957 RgSchCellCb        *cell,
24958 uint8_t                 *rntpPtr,
24959 uint8_t                       startRb,
24960 uint8_t                  nmbRb,
24961 uint16_t                 bw
24962 )
24963 #else
24964 static S16 rgSCHCmnBuildRntpInfo(cell, rntpPtr, startRb, nmbRb, bw)
24965 RgSchCellCb        *cell;
24966 uint8_t                 *rntpPtr;
24967 uint8_t                       startRb;
24968 uint8_t                  nmbRb;
24969 uint16_t                 bw;
24970 #endif
24971 {
24972    uint16_t rbPtrStartIdx;              /* Start Index of Octete Buffer to be filled */
24973    uint16_t rbPtrEndIdx;                /* End Index of Octete Buffer to be filled */
24974    uint16_t rbBitLoc;                   /* Bit Location to be set as 1 in the current Byte */
24975    uint16_t nmbRbPerByte;               /* PRB's to be set in the current Byte (in case of multiple Bytes) */
24976
24977
24978    rbPtrStartIdx = (startRb)/8;
24979    rbPtrEndIdx   = (startRb + nmbRb)/8;
24980
24981    if (rntpPtr == NULLP)
24982    {
24983       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
24984                "rgSCHCmnBuildRntpInfo():"
24985                "rntpPtr can't be NULLP (Memory Allocation Failed)");
24986       return RFAILED;
24987    }
24988
24989    while(rbPtrStartIdx <= rbPtrEndIdx)
24990    {
24991       rbBitLoc = (startRb)%8;
24992
24993       /* case 1: startRb and endRb lies in same Byte */
24994       if (rbPtrStartIdx == rbPtrEndIdx)
24995       {
24996          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
24997                                      | (((1<<nmbRb)-1)<<rbBitLoc);
24998       }
24999
25000       /* case 2: startRb and endRb lies in different Byte */
25001       if (rbPtrStartIdx != rbPtrEndIdx)
25002       {
25003          nmbRbPerByte = 8 - rbBitLoc;
25004          nmbRb        = nmbRb - nmbRbPerByte;
25005          rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx]
25006                                      | (((1<<nmbRbPerByte)-1)<<rbBitLoc);
25007          startRb = startRb + nmbRbPerByte;
25008       }
25009
25010       rbPtrStartIdx++;
25011    }
25012
25013    /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** Adding Debug logs */
25014
25015    /* dsfr_pal_fixes ** 25-March-2013 ** SKS ** Adding Debug logs to print RNTP */
25016
25017    return ROK;
25018 }
25019
25020 /**
25021  * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation.
25022  *
25023  * @details
25024  *
25025  *     Function : rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
25026  *
25027  *     Processing Steps:
25028  *
25029  *  @param[in]  RgSchCellCb     *cell
25030  *  @param[in]  RgSchDlSf       *dlSf
25031  *  @param[in]  uint8_t              rbStrt
25032  *  @param[in]  uint8_t              numRb
25033  *
25034  *  @return Void
25035  **/
25036 #ifdef ANSI
25037 static S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc
25038 (
25039 RgSchCellCb        *cell,
25040 RgSchUeCb                  *ue,
25041 RgSchDlSf          *dlSf,
25042 RgSchSFRPoolInfo   *sfrPool,
25043 uint8_t                 rbStrt,
25044 uint8_t                 numRb
25045 )
25046 #else
25047 static S16 rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrPool, rbStrt, numRb)
25048 RgSchCellCb        *cell;
25049 RgSchUeCb          *ue;
25050 RgSchDlSf          *dlSf;
25051 RgSchSFRPoolInfo   *sfrPool;
25052 uint8_t                 rbStrt;
25053 uint8_t                 numRb;
25054 #endif
25055 {
25056 #ifndef LTEMAC_SPS
25057    S16 ret;
25058 #endif
25059
25060    dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
25061    sfrPool->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize);
25062    
25063 #ifndef LTEMAC_SPS
25064    dlSf->type2Start += numRb;
25065    dlSf->bwAlloced += numRb;
25066    
25067    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
25068    {
25069       /* Based on RNTP info, the CC user is assigned high power per subframe basis */
25070       if(FALSE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge)
25071       {
25072          if((sfrPool->type2Start >= sfrPool->pwrHiCCRange.startRb) &&
25073                (sfrPool->type2Start + numRb < sfrPool->pwrHiCCRange.endRb))
25074          {
25075             ue->lteAdvUeCb.isCCUePHigh = TRUE;
25076
25077             /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
25078             ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
25079             if (ret != ROK)
25080             {
25081                RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
25082                         "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
25083                return RFAILED;
25084             }
25085          }
25086       }
25087       else
25088       {
25089          /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */
25090          ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw);
25091          if (ret != ROK)
25092          {
25093             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():"
25094                      "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId);
25095             return RFAILED;
25096          }
25097       }
25098    }
25099    sfrPool->type2Start += numRb;
25100    sfrPool->bwAlloced += numRb;
25101 #endif 
25102
25103    return ROK;
25104 }
25105
25106 /**
25107  * @brief To do DL allocation using TYPE0 RA.
25108  *
25109  * @details
25110  *
25111  *     Function : rgSCHCmnNonDlfsSFRPoolType0Alloc
25112  *
25113  *     Processing Steps:
25114  *      - Perform TYPE0 allocation using the RBGs between type0End and type2End.
25115  *      - Build the allocation mask as per RBG positioning.
25116  *      - Update the allocation parameters.
25117  *
25118  *  @param[in]  RgSchCellCb     *cell
25119  *  @param[in]  RgSchDlSf       *dlSf
25120  *  @param[in]  RgSchDlRbAlloc  *allocInfo
25121  *
25122  *  @return Void
25123  **/
25124 #ifdef ANSI
25125 static Void rgSCHCmnNonDlfsSFRPoolType0Alloc
25126 (
25127 RgSchCellCb        *cell,
25128 RgSchDlSf          *dlSf,
25129 RgSchSFRPoolInfo   *poolInfo,
25130 RgSchDlRbAlloc     *allocInfo
25131 )
25132 #else
25133 static Void rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, poolInfo, allocInfo)
25134 RgSchCellCb        *cell;
25135 RgSchDlSf          *dlSf;
25136 RgSchSFRPoolInfo   *poolInfo;
25137 RgSchDlRbAlloc     *allocInfo;
25138 #endif
25139 {
25140    uint32_t dlAllocMsk = 0;
25141    uint8_t  rbgFiller = 0;
25142    uint8_t  noRbgs = 0;
25143    uint8_t  noRbs;
25144    uint8_t  noLyr;
25145    uint8_t  iTbs;
25146
25147
25148    if (poolInfo->poolstartRB + poolInfo->bw == dlSf->bw)
25149    {
25150                 if (poolInfo->type0End == dlSf->bw/4)
25151                 {
25152                         rbgFiller = dlSf->lstRbgDfct;
25153                         /* The last RBG which can be smaller than the RBG size is consedered
25154                         * only for the first time allocation of TYPE0 UE */
25155                         dlSf->lstRbgDfct = 0;
25156                 }
25157    }
25158
25159    noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize);
25160
25161    /* Abhinav to-do start */
25162    /* MS_FIX for ccpu00123919*/
25163    noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25164    if (dlSf->bwAlloced + noRbs > dlSf->bw)
25165    {
25166       if (--noRbgs == 0)
25167       {
25168          return;
25169       }
25170       noRbs = (noRbgs * cell->rbgSize) - rbgFiller;
25171    }
25172    /* Abhinav to-do end */
25173
25174
25175    
25176    /* type0End would have been initially (during subfrm Init) at the bit position
25177     * (cell->noOfRbgs - 1), 0 being the most significant.
25178     * Getting DlAllocMsk for noRbgs and at the appropriate position */
25179    dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - poolInfo->type0End));
25180    /* Move backwards the type0End pivot */
25181    poolInfo->type0End -= noRbgs;
25182    /*MS_FIX for ccpu00123919*/
25183    /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/
25184    /* Update the bwAlloced field accordingly */
25185    poolInfo->bwAlloced += noRbs + dlSf->lstRbgDfct;
25186    dlSf->bwAlloced += noRbs + dlSf->lstRbgDfct;
25187    
25188    /* Update Type0 Alloc Info */
25189    allocInfo->allocInfo.raType0.numDlAlloc = noRbgs;
25190    allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk;
25191    allocInfo->rbsAlloc = noRbs;
25192
25193    /* Update Tb info for each scheduled TB */
25194    iTbs = allocInfo->tbInfo[0].iTbs;
25195    noLyr = allocInfo->tbInfo[0].noLyr;
25196    /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant.
25197     * RETX TB Size is same as Init TX TB Size */
25198    if (allocInfo->tbInfo[0].tbCb->txCntr)
25199    {
25200       allocInfo->tbInfo[0].bytesAlloc =
25201          allocInfo->tbInfo[0].bytesReq;
25202    }
25203    else
25204    {
25205       allocInfo->tbInfo[0].bytesAlloc =
25206          rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25207    }
25208
25209    if (allocInfo->tbInfo[1].schdlngForTb)
25210    {
25211       iTbs = allocInfo->tbInfo[1].iTbs;
25212       noLyr = allocInfo->tbInfo[1].noLyr;
25213       /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant
25214        * RETX TB Size is same as Init TX TB Size */
25215       if (allocInfo->tbInfo[1].tbCb->txCntr)
25216       {
25217          allocInfo->tbInfo[1].bytesAlloc =
25218             allocInfo->tbInfo[1].bytesReq;
25219       }
25220       else
25221       {
25222          allocInfo->tbInfo[1].bytesAlloc =
25223             rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;
25224       }
25225    }
25226
25227    /* The last RBG which can be smaller than the RBG size is consedered
25228     * only for the first time allocation of TYPE0 UE */
25229    dlSf->lstRbgDfct = 0;
25230    return;
25231 }
25232 #endif
25233 /**
25234  * @brief Computes RNTP Info for a subframe.
25235  *
25236  * @details
25237  *
25238  *     Function :  rgSCHCmnNonDlfsDsfrRntpComp 
25239  *
25240  *     Processing Steps:
25241  *      - Computes RNTP info from individual pools.
25242  *
25243  *  @param[in]  RgSchDlSf       *dlSf
25244  *
25245  *  @return  void
25246  
25247  **/
25248 #ifdef ANSI
25249 static void rgSCHCmnNonDlfsDsfrRntpComp
25250 (
25251 RgSchCellCb         *cell,
25252 RgSchDlSf          *dlSf
25253 )
25254 #else
25255 static void rgSCHCmnNonDlfsDsfrRntpComp(cell, dlSf)
25256 RgSchCellCb         *cell;
25257 RgSchDlSf          *dlSf;
25258 #endif
25259 {
25260    static uint16_t samples = 0;
25261    uint16_t i;
25262    uint16_t bwBytes = (dlSf->bw-1)/8;
25263    RgrLoadInfIndInfo *rgrLoadInf;
25264    uint16_t len;
25265    uint16_t ret     = ROK;
25266
25267
25268    len = (dlSf->bw % 8 == 0) ? dlSf->bw/8 : dlSf->bw/8 + 1;
25269
25270    /* RNTP info is ORed every TTI and the sample is stored in cell control block */ 
25271    for(i = 0; i <= bwBytes; i++)
25272    {
25273      cell->rntpAggrInfo.val[i] |= dlSf->rntpInfo.val[i];
25274    }
25275    samples = samples + 1;
25276    /* After every 1000 ms, the RNTP info will be sent to application to be further sent to all neighbouring eNB
25277          informing them about the load indication for cell edge users */
25278    if(RG_SCH_MAX_RNTP_SAMPLES == samples)
25279    {
25280       /* ccpu00134492 */
25281       ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf,
25282                sizeof(RgrLoadInfIndInfo));
25283       if (ret != ROK)
25284       {
25285          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Could not "
25286             "allocate memory for sending LoadInfo");
25287          return;  
25288       }
25289      
25290       rgrLoadInf->u.rntpInfo.pres = cell->rntpAggrInfo.pres;
25291       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
25292       rgrLoadInf->u.rntpInfo.len  = len;
25293
25294       /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
25295       rgrLoadInf->u.rntpInfo.val = cell->rntpAggrInfo.val; 
25296       rgrLoadInf->cellId = cell->cellId;
25297
25298       /* dsfr_pal_fixes ** 22-March-2013 ** SKS */
25299       rgrLoadInf->bw = dlSf->bw;
25300       rgrLoadInf->type = RGR_SFR;
25301
25302       ret = rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf);
25303       if(ret == RFAILED)
25304       {
25305          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsDsfrRntpComp():"
25306                   "rgSCHUtlRgrLoadInfInd() returned RFAILED");
25307       }
25308
25309       memset(cell->rntpAggrInfo.val,0,len);
25310       samples = 0;
25311    }
25312  } 
25313 /* LTE_ADV_FLAG_REMOVED_END */
25314
25315 /* LTE_ADV_FLAG_REMOVED_START */
25316 /**
25317  * @brief Performs RB allocation per UE from a pool.
25318  *
25319  * @details
25320  *
25321  *     Function : rgSCHCmnSFRNonDlfsUeRbAlloc
25322  *
25323  *     Processing Steps:
25324  *      - Allocate consecutively available RBs.
25325  *
25326  *  @param[in]  RgSchCellCb     *cell
25327  *  @param[in]  RgSchUeCb       *ue
25328  *  @param[in]  RgSchDlSf       *dlSf
25329  *  @param[out] uint8_t              *isDlBwAvail
25330  *
25331  *  @return  S16
25332  *      -# ROK
25333  *      -# RFAILED
25334  **/
25335 #ifdef UNUSED_FUNC
25336 #ifdef ANSI
25337 static S16 rgSCHCmnSFRNonDlfsUeRbAlloc
25338 (
25339 RgSchCellCb        *cell,
25340 RgSchUeCb          *ue,
25341 RgSchDlSf          *dlSf,
25342 uint8_t                 *isDlBwAvail
25343 )
25344 #else
25345 static S16 rgSCHCmnSFRNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail)
25346 RgSchCellCb        *cell;
25347 RgSchUeCb          *ue;
25348 RgSchDlSf          *dlSf;
25349 uint8_t                 *isDlBwAvail;
25350 #endif
25351 {
25352    RgSchDlRbAlloc  *allocInfo;
25353    RgSchCmnDlUe    *dlUe;
25354    Bool isUECellEdge;
25355    RgSchSFRPoolInfo *sfrpoolInfo = NULLP;
25356
25357
25358    isUECellEdge = RG_SCH_CMN_IS_UE_CELL_EDGE(ue);
25359
25360    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
25361    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25362    *isDlBwAvail = TRUE;
25363
25364    /*Find which pool is available for this UE*/
25365    if (rgSCHCmnNonDlfsSFRBwAvlbl(cell,  &sfrpoolInfo, dlSf, allocInfo, isUECellEdge) != TRUE)
25366    {
25367       /* SFR_FIX - If this is CE UE there may be BW available in CC Pool
25368          So CC UEs will be scheduled */
25369       if (isUECellEdge)
25370       {
25371          *isDlBwAvail = TRUE;
25372       }
25373       else
25374       {
25375          *isDlBwAvail = FALSE;
25376       }
25377       return RFAILED;
25378    }
25379
25380    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX || dlUe->proc->tbInfo[1].isAckNackDtx)
25381    {
25382       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
25383    }
25384    else
25385    {
25386       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
25387    }
25388    
25389    if (!(allocInfo->pdcch))
25390    {
25391       /* Returning ROK since PDCCH might be available for another UE and further allocations could be done */
25392       return RFAILED;
25393    }
25394    
25395 #ifdef LTEMAC_SPS
25396    allocInfo->rnti = ue->ueId;
25397 #endif
25398
25399    if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2)
25400    {
25401       allocInfo->allocInfo.raType2.isLocal = TRUE;
25402       /* rg004.201 patch - ccpu00109921 fix end */
25403       /* MS_FIX for ccpu00123918*/
25404       allocInfo->allocInfo.raType2.rbStart = (uint8_t)sfrpoolInfo->type2Start;
25405       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
25406       /* rg007.201 - Changes for MIMO feature addition */
25407       /* rg008.201 - Removed dependency on MIMO compile-time flag */
25408       rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrpoolInfo, \
25409             allocInfo->allocInfo.raType2.rbStart, \
25410             allocInfo->allocInfo.raType2.numRb);
25411       allocInfo->rbsAlloc = allocInfo->rbsReq;
25412       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25413    }
25414    else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0)
25415    {
25416       rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, sfrpoolInfo, allocInfo);
25417    }
25418 #ifndef LTE_TDD
25419 #ifdef DEBUGP
25420    rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,0);
25421    if(allocInfo->tbInfo[1].schdlngForTb == TRUE)
25422    {
25423       rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,1);
25424    }
25425 #endif
25426 #endif
25427
25428 #if defined(LTEMAC_SPS)
25429    /* Update the sub-frame with new allocation */
25430    dlSf->bwAlloced += allocInfo->rbsReq;
25431 #endif
25432
25433    return ROK;
25434 }
25435 #endif
25436 /* LTE_ADV_FLAG_REMOVED_END */
25437 #endif /* LTE_TDD */
25438
25439 /**
25440  * @brief Performs RB allocation per UE for frequency non-selective cell.
25441  *
25442  * @details
25443  *
25444  *     Function : rgSCHCmnNonDlfsUeRbAlloc
25445  *
25446  *     Processing Steps:
25447  *      - Allocate consecutively available RBs.
25448  *
25449  *  @param[in]  RgSchCellCb     *cell
25450  *  @param[in]  RgSchUeCb       *ue
25451  *  @param[in]  RgSchDlSf       *dlSf
25452  *  @param[out] uint8_t              *isDlBwAvail
25453  *
25454  *  @return  S16
25455  *      -# ROK
25456  *      -# RFAILED
25457  **/
25458 #ifdef ANSI
25459 static S16 rgSCHCmnNonDlfsUeRbAlloc
25460 (
25461 RgSchCellCb        *cell,
25462 RgSchUeCb          *ue,
25463 RgSchDlSf          *dlSf,
25464 uint8_t                 *isDlBwAvail
25465 )
25466 #else
25467 static S16 rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail)
25468 RgSchCellCb        *cell;
25469 RgSchUeCb          *ue;
25470 RgSchDlSf          *dlSf;
25471 uint8_t                 *isDlBwAvail;
25472 #endif
25473 {
25474    RgSchDlRbAlloc  *allocInfo;
25475    RgSchCmnDlUe    *dlUe;
25476 #ifdef LAA_DBG
25477    uint32_t            dbgRbsReq = 0;
25478 #endif
25479
25480 #ifdef RG_5GTF
25481    RgSch5gtfUeCb  *ue5gtfCb = &(ue->ue5gtfCb);
25482         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[ue5gtfCb->BeamId]);
25483 #endif
25484    dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell);
25485    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
25486    *isDlBwAvail = TRUE;
25487
25488         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
25489         {
25490            RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
25491          "5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
25492          ue->ueId);
25493            printf("5GTF_ERROR vrbg allocated > 25\n");
25494                 return RFAILED;
25495         }
25496
25497    if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX 
25498        || dlUe->proc->tbInfo[1].isAckNackDtx)
25499    {
25500       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE);
25501    }
25502    else
25503    {
25504       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE);
25505    }
25506    if (!(allocInfo->pdcch))
25507    {
25508       /* Returning ROK since PDCCH might be available for another UE and
25509        * further allocations could be done */
25510       RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
25511          "5GTF_ERROR : PDCCH allocation failed :ue (%u)",
25512          ue->ueId);
25513            printf("5GTF_ERROR PDCCH allocation failed\n");
25514       return RFAILED;
25515    }
25516 #ifdef RG_5GTF
25517         //maxPrb = RGSCH_MIN((allocInfo->vrbgReq * MAX_5GTF_VRBG_SIZE), ue5gtfCb->maxPrb);
25518    //maxPrb = RGSCH_MIN(maxPrb, 
25519                 //((beamInfo->totVrbgAvail - beamInfo->vrbgStart)* MAX_5GTF_VRBG_SIZE)));
25520         //TODO_SID Need to check for vrbg available after scheduling for same beam.
25521         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
25522         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
25523         //TODO_SID: Setting for max TP
25524         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
25525         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
25526          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
25527         allocInfo->tbInfo[0].tbCb->dlGrnt.SCID = 0;
25528         allocInfo->tbInfo[0].tbCb->dlGrnt.dciFormat = allocInfo->dciFormat;
25529    //Filling temporarily
25530    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
25531    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
25532
25533         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
25534         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
25535         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25536 #endif
25537
25538    return ROK;
25539 }
25540
25541 #ifdef RGR_V1
25542 /**
25543  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
25544  *
25545  * @details
25546  *
25547  *     Function : rgSCHCmnNonDlfsCcchSduAlloc
25548  *
25549  *     Processing Steps:
25550  *     - For each element in the list, Call rgSCHCmnNonDlfsCcchSduRbAlloc().
25551  *        - If allocation is successful, add the ueCb to scheduled list of CCCH
25552  *        SDU.
25553  *        - else, add UeCb to non-scheduled list.
25554  *
25555  *  @param[in]      RgSchCellCb         *cell
25556  *  @param[in, out] RgSchCmnCcchSduRbAlloc *allocInfo
25557  *  @param[in]      uint8_t                  isRetx
25558  *
25559  *  @return  Void
25560  **/
25561 #ifdef ANSI
25562 static Void rgSCHCmnNonDlfsCcchSduAlloc
25563 (
25564 RgSchCellCb         *cell,
25565 RgSchCmnCcchSduRbAlloc *allocInfo,
25566 uint8_t                  isRetx
25567 )
25568 #else
25569 static Void rgSCHCmnNonDlfsCcchSduAlloc(cell, allocInfo, isRetx)
25570 RgSchCellCb         *cell;
25571 RgSchCmnCcchSduRbAlloc *allocInfo;
25572 uint8_t                  isRetx;
25573 #endif
25574 {
25575    S16             ret;
25576    CmLListCp       *ccchSduLst        = NULLP;
25577    CmLListCp       *schdCcchSduLst    = NULLP;
25578    CmLListCp       *nonSchdCcchSduLst = NULLP;
25579    CmLList         *schdLnkNode    = NULLP;
25580    CmLList         *toBeSchdLnk    = NULLP;
25581    RgSchDlSf       *dlSf           = allocInfo->ccchSduDlSf;
25582    RgSchUeCb       *ueCb           = NULLP;
25583    RgSchDlHqProcCb *hqP            = NULLP;
25584
25585    if (isRetx)
25586    {
25587       /* Initialize re-transmitting lists */
25588       ccchSduLst = &(allocInfo->ccchSduRetxLst);
25589       schdCcchSduLst = &(allocInfo->schdCcchSduRetxLst);
25590       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduRetxLst);
25591    }
25592    else
25593    {
25594       /* Initialize transmitting lists */
25595       ccchSduLst = &(allocInfo->ccchSduTxLst);
25596       schdCcchSduLst = &(allocInfo->schdCcchSduTxLst);
25597       nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduTxLst);
25598    }
25599
25600    /* Perform allocaations  for the list */
25601    toBeSchdLnk = cmLListFirst(ccchSduLst);
25602    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
25603    {
25604       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25605       ueCb = hqP->hqE->ue;
25606       schdLnkNode = &hqP->schdLstLnk;
25607       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25608       ret = rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf);
25609       if (ret != ROK)
25610       {
25611          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
25612           * list and return */
25613          do
25614          {
25615             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25616             ueCb = hqP->hqE->ue;
25617             schdLnkNode = &hqP->schdLstLnk;
25618             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25619             cmLListAdd2Tail(nonSchdCcchSduLst, schdLnkNode);
25620             toBeSchdLnk = toBeSchdLnk->next;
25621          } while(toBeSchdLnk);
25622          return;
25623       }
25624
25625       /* Allocation successful: Add UE to the scheduled list */
25626       cmLListAdd2Tail(schdCcchSduLst, schdLnkNode);
25627    }
25628
25629
25630    return;
25631 }
25632
25633 /**
25634  * @brief Performs RB allocation for CcchSdu for frequency non-selective cell.
25635  *
25636  * @details
25637  *
25638  *     Function : rgSCHCmnNonDlfsCcchSduRbAlloc
25639  *
25640  *     Processing Steps:
25641  *     - Fetch PDCCH
25642  *     - Allocate consecutively available RBs
25643  *
25644  *  @param[in] RgSchCellCb     *cell
25645  *  @param[in] RgSchUeCb       *ueCb
25646  *  @param[in] RgSchDlSf       *dlSf
25647  *  @return  S16
25648  *      -# ROK
25649  *      -# RFAILED
25650  **/
25651 #ifdef ANSI
25652 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc
25653 (
25654 RgSchCellCb        *cell,
25655 RgSchUeCb          *ueCb,
25656 RgSchDlSf          *dlSf
25657 )
25658 #else
25659 static S16 rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf)
25660 RgSchCellCb        *cell;
25661 RgSchUeCb          *ueCb;
25662 RgSchDlSf          *dlSf;
25663 #endif
25664 {
25665    RgSchDlRbAlloc  *allocInfo;
25666    RgSchCmnDlUe         *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
25667
25668
25669
25670    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb,cell);
25671
25672    /* [ccpu00138802]-MOD-If Bw is less than required, return fail
25673       It will be allocated in next TTI */
25674 #ifdef LTEMAC_SPS
25675    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
25676          (dlSf->bwAlloced == dlSf->bw))
25677 #else
25678    if((dlSf->bwAlloced == dlSf->bw) ||
25679       (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
25680 #endif
25681    {
25682       return RFAILED;
25683    }
25684    /* Retrieve PDCCH */
25685    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
25686    if (ueDl->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
25687    {
25688       /*      allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, dlSf, y, ueDl->cqi,
25689        *      TFU_DCI_FORMAT_1A, TRUE);*/
25690       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, TRUE);
25691    }
25692    else
25693    {
25694       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE);
25695    }
25696    if (!(allocInfo->pdcch))
25697    {
25698       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
25699       return RFAILED;
25700    }
25701
25702    /* Update allocation information */
25703    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25704    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
25705    allocInfo->allocInfo.raType2.isLocal = TRUE;
25706
25707       /*Fix for ccpu00123918*/
25708       /* Push this harq process back to the free queue */
25709       allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
25710       allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
25711       allocInfo->rbsAlloc = allocInfo->rbsReq;
25712       allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25713       /* Update the sub-frame with new allocation */
25714       /* ccpu00129469 */
25715       /* LTE_ADV_FLAG_REMOVED_START */
25716 #ifndef LTE_TDD
25717       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
25718       {
25719          rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf,
25720                allocInfo->allocInfo.raType2.rbStart,
25721                allocInfo->allocInfo.raType2.numRb);
25722       }
25723       else
25724 #endif /* end of ifndef LTE_TDD*/
25725       {
25726          rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, 
25727                allocInfo->allocInfo.raType2.rbStart, 
25728                allocInfo->allocInfo.raType2.numRb);
25729       }
25730
25731    /* LTE_ADV_FLAG_REMOVED_END */
25732    /* ccpu00131941 - bwAlloced is updated from SPS bandwidth */  
25733
25734
25735    return ROK;
25736 }
25737 #endif
25738
25739 /**
25740  * @brief Performs RB allocation for Msg4 for frequency non-selective cell.
25741  *
25742  * @details
25743  *
25744  *     Function : rgSCHCmnNonDlfsMsg4RbAlloc
25745  *
25746  *     Processing Steps:
25747  *     - Fetch PDCCH
25748  *     - Allocate consecutively available RBs
25749  *
25750  *  @param[in] RgSchCellCb     *cell
25751  *  @param[in] RgSchRaCb       *raCb
25752  *  @param[in] RgSchDlSf       *dlSf
25753  *  @return  S16
25754  *      -# ROK
25755  *      -# RFAILED
25756  **/
25757 #ifdef ANSI
25758 static S16 rgSCHCmnNonDlfsMsg4RbAlloc
25759 (
25760 RgSchCellCb        *cell,
25761 RgSchRaCb          *raCb,
25762 RgSchDlSf          *dlSf
25763 )
25764 #else
25765 static S16 rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf)
25766 RgSchCellCb        *cell;
25767 RgSchRaCb          *raCb;
25768 RgSchDlSf          *dlSf;
25769 #endif
25770 {
25771    RgSchDlRbAlloc  *allocInfo;
25772
25773
25774    allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(raCb);
25775
25776 #ifdef RG_5GTF
25777         RgSchSfBeamInfo  *beamInfo = &(dlSf->sfBeamInfo[0]);
25778         if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG)
25779         {
25780            RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId,
25781          "5GTF_ERROR : vrbg allocated > 25 :ue (%u)",
25782          raCb->ue->ueId);
25783            printf("5GTF_ERROR vrbg allocated > 25\n");
25784                 return RFAILED;
25785         }
25786 #endif
25787 #ifdef LTEMAC_SPS
25788    if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) &&
25789          (dlSf->bwAlloced == dlSf->bw))
25790 #else
25791    if((dlSf->bwAlloced == dlSf->bw) ||
25792             (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)))
25793 #endif
25794    {
25795
25796       return RFAILED;
25797    }
25798
25799    /* DTX Changes: One Variable is passed to check whether it is DTX or Not */
25800    if (raCb->dlHqE->msg4Proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)
25801    {
25802       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, TRUE);
25803    }
25804    else
25805    {
25806       allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, FALSE);
25807    }
25808    if (!(allocInfo->pdcch))
25809    {
25810       /* Returning RFAILED since PDCCH not available for any CCCH allocations */
25811       return RFAILED;
25812    }
25813    
25814 #ifndef RG_5GTF
25815  /* SR_RACH_STATS : MSG4 TX Failed */
25816    allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
25817
25818    /* Update allocation information */
25819    allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
25820    allocInfo->raType = RG_SCH_CMN_RA_TYPE2;
25821    allocInfo->allocInfo.raType2.isLocal = TRUE;
25822
25823
25824         /*Fix for ccpu00123918*/
25825         allocInfo->allocInfo.raType2.rbStart = (uint8_t)dlSf->type2Start;
25826         allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq;
25827         /* LTE_ADV_FLAG_REMOVED_START */
25828 #ifndef LTE_TDD
25829         if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
25830         {
25831           rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \
25832                 allocInfo->allocInfo.raType2.rbStart, \
25833                 allocInfo->allocInfo.raType2.numRb);
25834         }
25835         else
25836 #endif /* end of ifndef LTE_TDD */
25837         {
25838           rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \
25839                 allocInfo->allocInfo.raType2.rbStart, \
25840                 allocInfo->allocInfo.raType2.numRb);
25841         }
25842         /* LTE_ADV_FLAG_REMOVED_END */
25843
25844    allocInfo->rbsAlloc = allocInfo->rbsReq;
25845    allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25846
25847 #else
25848
25849   allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE;
25850
25851         allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart;
25852         allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq;
25853
25854    /* Update allocation information */
25855    allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
25856
25857         allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1;      
25858         allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, 
25859          allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg);
25860
25861    allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE);
25862    allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE);
25863
25864
25865         beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg;
25866         beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; 
25867         allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq;
25868
25869 #endif
25870
25871    return ROK;
25872 }
25873
25874 /**
25875  * @brief Performs RB allocation for Msg4 lists of frequency non-selective cell.
25876  *
25877  * @details
25878  *
25879  *     Function : rgSCHCmnNonDlfsMsg4Alloc
25880  *
25881  *     Processing Steps:
25882  *     - For each element in the list, Call rgSCHCmnNonDlfsMsg4RbAlloc().
25883  *        - If allocation is successful, add the raCb to scheduled list of MSG4.
25884  *        - else, add RaCb to non-scheduled list.
25885  *
25886  *  @param[in]      RgSchCellCb         *cell
25887  *  @param[in, out] RgSchCmnMsg4RbAlloc *allocInfo
25888  *  @param[in]      uint8_t                  isRetx
25889  *
25890  *  @return  Void
25891  **/
25892 #ifdef ANSI
25893 static Void rgSCHCmnNonDlfsMsg4Alloc
25894 (
25895 RgSchCellCb         *cell,
25896 RgSchCmnMsg4RbAlloc *allocInfo,
25897 uint8_t                  isRetx
25898 )
25899 #else
25900 static Void rgSCHCmnNonDlfsMsg4Alloc(cell, allocInfo, isRetx)
25901 RgSchCellCb         *cell;
25902 RgSchCmnMsg4RbAlloc *allocInfo;
25903 uint8_t                  isRetx;
25904 #endif
25905 {
25906    S16             ret;
25907    CmLListCp       *msg4Lst        = NULLP;
25908    CmLListCp       *schdMsg4Lst    = NULLP;
25909    CmLListCp       *nonSchdMsg4Lst = NULLP;
25910    CmLList         *schdLnkNode    = NULLP;
25911    CmLList         *toBeSchdLnk    = NULLP;
25912    RgSchDlSf       *dlSf           = allocInfo->msg4DlSf;
25913    RgSchRaCb       *raCb           = NULLP;
25914    RgSchDlHqProcCb *hqP            = NULLP;
25915
25916    if (isRetx)
25917    {
25918       /* Initialize re-transmitting lists */
25919       msg4Lst = &(allocInfo->msg4RetxLst);
25920       schdMsg4Lst = &(allocInfo->schdMsg4RetxLst);
25921       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4RetxLst);
25922    }
25923    else
25924    {
25925       /* Initialize transmitting lists */
25926       msg4Lst = &(allocInfo->msg4TxLst);
25927       schdMsg4Lst = &(allocInfo->schdMsg4TxLst);
25928       nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4TxLst);
25929    }
25930
25931    /* Perform allocaations  for the list */
25932    toBeSchdLnk = cmLListFirst(msg4Lst);
25933    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
25934    {
25935       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25936       raCb = hqP->hqE->raCb;
25937       schdLnkNode = &hqP->schdLstLnk;
25938       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25939       ret = rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf);
25940       if (ret != ROK)
25941       {
25942          /* Allocation failed: Add remaining MSG4 nodes to non-scheduled
25943           * list and return */
25944          do
25945          {
25946             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
25947             raCb = hqP->hqE->raCb;
25948             schdLnkNode = &hqP->schdLstLnk;
25949             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
25950             cmLListAdd2Tail(nonSchdMsg4Lst, schdLnkNode);
25951             toBeSchdLnk = toBeSchdLnk->next;
25952          } while(toBeSchdLnk);
25953          return;
25954       }
25955
25956       /* Allocation successful: Add UE to the scheduled list */
25957       cmLListAdd2Tail(schdMsg4Lst, schdLnkNode);
25958       if (isRetx)
25959       {
25960       }
25961    }
25962
25963
25964    return;
25965 }
25966
25967 /**
25968  * @brief Performs RB allocation for the list of UEs of a frequency
25969  * non-selective cell.
25970  *
25971  * @details
25972  *
25973  *     Function : rgSCHCmnNonDlfsDedRbAlloc
25974  *
25975  *     Processing Steps:
25976  *     - For each element in the list, Call rgSCHCmnNonDlfsUeRbAlloc().
25977  *        - If allocation is successful, add the ueCb to scheduled list of UEs.
25978  *        - else, add ueCb to non-scheduled list of UEs.
25979  *
25980  *  @param[in]      RgSchCellCb        *cell
25981  *  @param[in, out] RgSchCmnUeRbAlloc  *allocInfo
25982  *  @param[in]      CmLListCp          *ueLst,
25983  *  @param[in, out] CmLListCp          *schdHqPLst,
25984  *  @param[in, out] CmLListCp          *nonSchdHqPLst
25985  *
25986  *  @return  Void
25987  **/
25988 #ifdef ANSI
25989 Void rgSCHCmnNonDlfsDedRbAlloc
25990 (
25991 RgSchCellCb        *cell,
25992 RgSchCmnUeRbAlloc  *allocInfo,
25993 CmLListCp          *ueLst,
25994 CmLListCp          *schdHqPLst,
25995 CmLListCp          *nonSchdHqPLst
25996 )
25997 #else
25998 Void rgSCHCmnNonDlfsDedRbAlloc(cell, allocInfo, ueLst,
25999         schdHqPLst, nonSchdHqPLst)
26000 RgSchCellCb        *cell;
26001 RgSchCmnUeRbAlloc  *allocInfo;
26002 CmLListCp          *ueLst;
26003 CmLListCp          *schdHqPLst;
26004 CmLListCp          *nonSchdHqPLst;
26005 #endif
26006 {
26007    S16             ret;
26008    CmLList         *schdLnkNode  = NULLP;
26009    CmLList         *toBeSchdLnk  = NULLP;
26010    RgSchDlSf       *dlSf         = allocInfo->dedDlSf;
26011    RgSchUeCb       *ue           = NULLP;
26012    RgSchDlHqProcCb *hqP          = NULLP;
26013    uint8_t         isDlBwAvail;
26014
26015
26016    /* Perform allocaations  for the list */
26017    toBeSchdLnk = cmLListFirst(ueLst);
26018    for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next)
26019    {
26020       hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26021       ue = hqP->hqE->ue;
26022       schdLnkNode = &hqP->schdLstLnk;
26023       RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26024
26025       ret = rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, &isDlBwAvail);
26026       if (!isDlBwAvail)
26027       {
26028          /* Allocation failed: Add remaining UEs to non-scheduled
26029           * list and return */
26030          do
26031          {
26032             hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node);
26033             ue = hqP->hqE->ue;
26034             schdLnkNode = &hqP->schdLstLnk;
26035             RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP);
26036             cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
26037             toBeSchdLnk = toBeSchdLnk->next;
26038          } while(toBeSchdLnk);
26039          break; 
26040       }
26041
26042       if (ret == ROK)
26043       {
26044 #if defined (TENB_STATS) && defined (RG_5GTF)
26045          cell->tenbStats->sch.dl5gtfRbAllocPass++;
26046 #endif
26047          /* Allocation successful: Add UE to the scheduled list */
26048          cmLListAdd2Tail(schdHqPLst, schdLnkNode);
26049       }
26050       else
26051       {
26052 #if defined (TENB_STATS) && defined (RG_5GTF)
26053          cell->tenbStats->sch.dl5gtfRbAllocFail++;
26054 #endif
26055          /* Allocation failed : Add UE to the non-scheduled list */
26056                         printf("5GTF_ERROR Dl rb alloc failed adding nonSchdHqPLst\n");
26057          cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode);
26058       }
26059    }
26060
26061    return;
26062 }
26063
26064 /**
26065  * @brief Handles RB allocation for frequency non-selective cell.
26066  *
26067  * @details
26068  *
26069  *     Function : rgSCHCmnNonDlfsRbAlloc
26070  *
26071  *     Invoking Module Processing:
26072  *      - SCH shall invoke this if downlink frequency selective is disabled for
26073  *        the cell for RB allocation.
26074  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
26075  *        estimate and subframe for each allocation to be made to SCH.
26076  *
26077  *     Processing Steps:
26078  *     - Allocate sequentially for common channels.
26079  *     - For transmitting and re-transmitting UE list.
26080  *      - For each UE:
26081  *       - Perform wide-band allocations for UE in increasing order of
26082  *         frequency.
26083  *       - Determine Imcs for the allocation.
26084  *       - Determine RA type.
26085  *       - Determine DCI format.
26086  *
26087  *  @param[in]  RgSchCellCb        *cell
26088  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
26089  *  @return  Void
26090  **/
26091
26092 #ifdef ANSI
26093 Void rgSCHCmnNonDlfsRbAlloc
26094 (
26095 RgSchCellCb           *cell,
26096 RgSchCmnDlRbAllocInfo *allocInfo
26097 )
26098 #else
26099 Void rgSCHCmnNonDlfsRbAlloc(cell, allocInfo)
26100 RgSchCellCb           *cell;
26101 RgSchCmnDlRbAllocInfo *allocInfo;
26102 #endif
26103 {
26104    uint8_t                 raRspCnt = 0;
26105    RgSchDlRbAlloc     *reqAllocInfo;
26106
26107    /* Allocate for MSG4 retransmissions */
26108    if (allocInfo->msg4Alloc.msg4RetxLst.count)
26109    {
26110       printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc RetxLst\n");
26111       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), TRUE);
26112    }
26113
26114    /* Allocate for MSG4 transmissions */
26115    /* Assuming all the nodes in the list need allocations: rbsReq is valid */
26116    if (allocInfo->msg4Alloc.msg4TxLst.count)
26117    {
26118       printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc txLst\n");
26119       rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), FALSE);
26120    }
26121 #ifdef RGR_V1
26122    /* Allocate for CCCH SDU (received after guard timer expiry)
26123     * retransmissions */
26124    if (allocInfo->ccchSduAlloc.ccchSduRetxLst.count)
26125    {
26126       printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
26127       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), TRUE);
26128    }
26129
26130    /* Allocate for CCCD SDU transmissions */
26131    /* Allocate for CCCH SDU (received after guard timer expiry) transmissions */
26132    if (allocInfo->ccchSduAlloc.ccchSduTxLst.count)
26133    {
26134       printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n");
26135       rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), FALSE);
26136    }
26137 #endif
26138
26139    /* Allocate for Random access response */
26140    for (raRspCnt = 0; raRspCnt < RG_SCH_CMN_MAX_CMN_PDCCH; ++raRspCnt)
26141    {
26142       /* Assuming that the requests will be filled in sequentially */
26143       reqAllocInfo = &(allocInfo->raRspAlloc[raRspCnt]);
26144       if (!reqAllocInfo->rbsReq)
26145       {
26146          break;
26147       }
26148       printf("5GTF_ERROR calling RAR rgSCHCmnNonDlfsCmnRbAlloc\n");
26149    //   if ((rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo)) != ROK)
26150       if ((rgSCHCmnNonDlfsCmnRbAllocRar(cell, reqAllocInfo)) != ROK)
26151       {
26152          break;
26153       }
26154    }
26155
26156    /* Allocate for RETX+TX UEs */
26157    if(allocInfo->dedAlloc.txRetxHqPLst.count)
26158    {
26159       printf("5GTF_ERROR TX RETX rgSCHCmnNonDlfsDedRbAlloc\n");
26160       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26161             &(allocInfo->dedAlloc.txRetxHqPLst),
26162             &(allocInfo->dedAlloc.schdTxRetxHqPLst),
26163             &(allocInfo->dedAlloc.nonSchdTxRetxHqPLst));
26164    }
26165
26166    if((allocInfo->dedAlloc.retxHqPLst.count))
26167    {
26168       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26169             &(allocInfo->dedAlloc.retxHqPLst),
26170             &(allocInfo->dedAlloc.schdRetxHqPLst),
26171             &(allocInfo->dedAlloc.nonSchdRetxHqPLst));
26172    }
26173
26174    /* Allocate for transmitting UEs */
26175    if((allocInfo->dedAlloc.txHqPLst.count))
26176    {
26177       rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc),
26178             &(allocInfo->dedAlloc.txHqPLst),
26179             &(allocInfo->dedAlloc.schdTxHqPLst),
26180             &(allocInfo->dedAlloc.nonSchdTxHqPLst));
26181    }
26182    {
26183       RgSchCmnCell  *cmnCell = RG_SCH_CMN_GET_CELL(cell);
26184       if ((allocInfo->dedAlloc.txRetxHqPLst.count + 
26185                allocInfo->dedAlloc.retxHqPLst.count + 
26186                allocInfo->dedAlloc.txHqPLst.count) > 
26187             cmnCell->dl.maxUePerDlSf)
26188       {
26189 #ifndef ALIGN_64BIT
26190          RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by"
26191                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %ld retx %ld tx %ld\n",
26192                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
26193                   allocInfo->dedAlloc.retxHqPLst.count,
26194                   allocInfo->dedAlloc.txHqPLst.count));
26195 #else
26196          RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by"
26197                   " scheduler exceed maximumUePerDlSf(%u)tx-retx %d retx %d tx %d\n",
26198                   cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count,
26199                   allocInfo->dedAlloc.retxHqPLst.count,
26200                   allocInfo->dedAlloc.txHqPLst.count));
26201 #endif
26202       }
26203    }
26204 #ifndef LTE_TDD
26205    /* LTE_ADV_FLAG_REMOVED_START */
26206    if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
26207    {    
26208       printf("5GTF_ERROR RETX rgSCHCmnNonDlfsDsfrRntpComp\n");
26209       rgSCHCmnNonDlfsDsfrRntpComp(cell, allocInfo->dedAlloc.dedDlSf); 
26210    }  
26211    /* LTE_ADV_FLAG_REMOVED_END */
26212 #endif /* LTE_TDD */
26213    return;
26214 }
26215
26216 /***********************************************************
26217  *
26218  *     Func : rgSCHCmnCalcRiv
26219  *
26220  *     Desc : This function calculates RIV.
26221  *
26222  *     Ret  : None.
26223  *
26224  *     Notes: None.
26225  *
26226  *     File : rg_sch_utl.c
26227  *
26228  **********************************************************/
26229 #ifdef LTEMAC_SPS
26230 #ifdef ANSI
26231 uint32_t rgSCHCmnCalcRiv
26232 (
26233 uint8_t           bw,
26234 uint8_t           rbStart,
26235 uint8_t           numRb
26236 )
26237 #else
26238 uint32_t rgSCHCmnCalcRiv(bw, rbStart, numRb)
26239 uint8_t           bw;
26240 uint8_t           rbStart;
26241 uint8_t           numRb;
26242 #endif
26243 #else
26244 #ifdef ANSI
26245 uint32_t rgSCHCmnCalcRiv
26246 (
26247 uint8_t           bw,
26248 uint8_t           rbStart,
26249 uint8_t           numRb
26250 )
26251 #else
26252 uint32_t rgSCHCmnCalcRiv(bw, rbStart, numRb)
26253 uint8_t           bw;
26254 uint8_t           rbStart;
26255 uint8_t           numRb;
26256 #endif
26257 #endif
26258 {
26259    uint8_t           numRbMinus1 = numRb - 1;
26260    uint32_t          riv;
26261
26262
26263    if (numRbMinus1 <= bw/2)
26264    {
26265       riv = bw * numRbMinus1 + rbStart;
26266    }
26267    else
26268    {
26269       riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
26270    }
26271    return (riv);
26272 } /* rgSCHCmnCalcRiv */
26273
26274 #ifdef LTE_TDD
26275 /**
26276  * @brief This function allocates and copies the RACH response scheduling
26277  *        related information into cell control block.
26278  *
26279  * @details
26280  *
26281  *     Function: rgSCHCmnDlCpyRachInfo
26282  *     Purpose:  This function allocates and copies the RACH response
26283  *               scheduling related information into cell control block
26284  *               for each DL subframe.
26285  *
26286  *
26287  *     Invoked by: Scheduler
26288  *
26289  *  @param[in]  RgSchCellCb*           cell
26290  *  @param[in]  RgSchTddRachRspLst     rachRspLst[][RGSCH_NUM_SUB_FRAMES]
26291  *  @param[in]  uint8_t                     raArrSz
26292  *  @return     S16
26293  *
26294  **/
26295 #ifdef ANSI
26296 static S16 rgSCHCmnDlCpyRachInfo
26297 (
26298 RgSchCellCb                *cell,
26299 RgSchTddRachRspLst         rachRspLst[][RGSCH_NUM_SUB_FRAMES],
26300 uint8_t                         raArrSz
26301 )
26302 #else
26303 static S16 rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz)
26304 RgSchCellCb                *cell;
26305 RgSchTddRachRspLst         rachRspLst[][RGSCH_NUM_SUB_FRAMES];
26306 uint8_t                         raArrSz;
26307 #endif
26308 {
26309    uint8_t                   ulDlCfgIdx = cell->ulDlCfgIdx;
26310    uint8_t                   sfNum;
26311    S16                  sfnIdx;
26312    uint16_t                  subfrmIdx;
26313    uint8_t                   numRfs;
26314    uint8_t                   numSubfrms;
26315    uint8_t                   sfcount;
26316    S16                   ret;
26317
26318
26319    /* Allocate RACH response information for each DL
26320     * subframe in a radio frame */
26321    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cell->rachRspLst,
26322          rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1] *
26323          sizeof(RgSchTddRachRspLst));
26324    if (ret != ROK)
26325    {
26326       return (ret);
26327    }
26328
26329    for(sfnIdx=raArrSz-1; sfnIdx>=0; sfnIdx--)
26330    {
26331       for(subfrmIdx=0; subfrmIdx < RGSCH_NUM_SUB_FRAMES; subfrmIdx++)
26332       {
26333          subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx];
26334          if(subfrmIdx == RGSCH_NUM_SUB_FRAMES)
26335          {
26336             break;
26337          }
26338
26339          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx],subfrmIdx);
26340          numSubfrms =
26341             rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
26342
26343          RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddNumDlSubfrmTbl[ulDlCfgIdx],subfrmIdx);
26344          sfNum = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][subfrmIdx]-1;
26345          numRfs = cell->rachRspLst[sfNum].numRadiofrms;
26346          /* For each DL subframe in which RACH response can
26347           * be sent is updated */
26348          if(numSubfrms > 0)
26349          {
26350             cell->rachRspLst[sfNum].rachRsp[numRfs].sfnOffset =
26351                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset;
26352             for(sfcount=0; sfcount < numSubfrms; sfcount++)
26353             {
26354                cell->rachRspLst[sfNum].rachRsp[numRfs].\
26355                   subframe[sfcount] =
26356                   rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].\
26357                   subframe[sfcount];
26358             }
26359             cell->rachRspLst[sfNum].rachRsp[numRfs].numSubfrms =
26360                rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms;
26361             cell->rachRspLst[sfNum].numRadiofrms++;
26362          }
26363
26364          /* Copy the subframes to be deleted at ths subframe */
26365          numSubfrms =
26366             rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
26367          if(numSubfrms > 0)
26368          {
26369             cell->rachRspLst[sfNum].delInfo.sfnOffset =
26370                rachRspLst[sfnIdx][subfrmIdx].delInfo.sfnOffset;
26371             for(sfcount=0; sfcount < numSubfrms; sfcount++)
26372             {
26373                cell->rachRspLst[sfNum].delInfo.subframe[sfcount] =
26374                   rachRspLst[sfnIdx][subfrmIdx].delInfo.subframe[sfcount];
26375             }
26376             cell->rachRspLst[sfNum].delInfo.numSubfrms =
26377                rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms;
26378          }
26379       }
26380    }
26381    return ROK;
26382 }
26383 #endif
26384 /**
26385  * @brief This function determines the iTbs based on the new CFI, 
26386  *        CQI and BLER based delta iTbs 
26387  *
26388  * @details
26389  *
26390  *     Function: rgSchCmnFetchItbs
26391  *     Purpose:  Fetch the new iTbs when CFI changes.
26392  *
26393  *  @param[in]  RgSchCellCb           *cell
26394  *  @param[in]  RgSchCmnDlUe          *ueDl
26395  *  @param[in]  uint8_t                    cqi
26396  *
26397  *  @return S32 iTbs
26398  *
26399  **/
26400 #ifdef LTE_TDD
26401 #ifdef ANSI
26402 static S32 rgSchCmnFetchItbs 
26403 (
26404 RgSchCellCb        *cell,
26405 RgSchCmnDlUe       *ueDl,
26406 RgSchDlSf          *subFrm,
26407 uint8_t                 cqi,
26408 uint8_t                 cfi,
26409 uint8_t                 cwIdx,
26410 uint8_t                 noLyr
26411 )
26412 #else
26413 static S32 rgSchCmnFetchItbs (cell, ueDl, subFrm, cqi, cfi, cwIdx, noLyr)
26414 RgSchCellCb        *cell;
26415 RgSchCmnDlUe       *ueDl; 
26416 RgSchDlSf          *subFrm;
26417 uint8_t                 cqi;
26418 uint8_t                 cfi;
26419 uint8_t                 cwIdx;
26420 uint8_t                 noLyr;
26421 #endif
26422 #else
26423 #ifdef ANSI
26424 static S32 rgSchCmnFetchItbs 
26425 (
26426 RgSchCellCb        *cell,
26427 RgSchCmnDlUe       *ueDl,
26428 uint8_t                 cqi,
26429 uint8_t                 cfi,
26430 uint8_t                 cwIdx,
26431 uint8_t                 noLyr
26432 )
26433 #else
26434 static S32 rgSchCmnFetchItbs (cell, ueDl, cqi, cfi, cwIdx, noLyr)
26435 RgSchCellCb        *cell;
26436 RgSchCmnDlUe       *ueDl; 
26437 uint8_t                 cqi;
26438 uint8_t                 cfi;
26439 uint8_t                 cwIdx;
26440 uint8_t                 noLyr;
26441 #endif 
26442 #endif
26443 {
26444
26445    RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
26446    S32 iTbs = 0;
26447
26448
26449 #ifdef LTE_TDD      
26450    /* Special Handling for Spl Sf when CFI is 3 as 
26451     * CFI in Spl Sf will be max 2 */
26452    if(subFrm->sfType == RG_SCH_SPL_SF_DATA) 
26453    {
26454       if((cellDl->currCfi == 3) || 
26455             ((cell->bwCfg.dlTotalBw <= 10) && (cellDl->currCfi == 1)))
26456       {    
26457          /* Use CFI 2 in this case */
26458          iTbs = (ueDl->laCb[cwIdx].deltaiTbs + 
26459                ((*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][2]))[cqi])* 100)/100;
26460
26461          RG_SCH_CHK_ITBS_RANGE(iTbs, RGSCH_NUM_ITBS - 1);
26462       }
26463       else
26464       {
26465          iTbs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1];
26466       }
26467       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
26468    }   
26469    else /* CFI Changed. Update with new iTbs Reset the BLER*/
26470 #endif         
26471    {
26472       S32 tmpiTbs  = (*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][cfi]))[cqi];
26473       
26474       iTbs = (ueDl->laCb[cwIdx].deltaiTbs + tmpiTbs*100)/100;
26475
26476       RG_SCH_CHK_ITBS_RANGE(iTbs, tmpiTbs);     
26477
26478       iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs);
26479
26480       ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1] = iTbs;
26481
26482       ueDl->lastCfi = cfi;
26483       ueDl->laCb[cwIdx].deltaiTbs = 0;
26484    }
26485
26486    return (iTbs);
26487
26488 \f
26489 /**
26490  * @brief This function determines the RBs and Bytes required for BO
26491  *        transmission for UEs configured with TM 1/2/6/7.
26492  *
26493  * @details
26494  *
26495  *     Function: rgSCHCmnDlAllocTxRb1Tb1Cw
26496  *     Purpose:  Allocate TB1 on CW1.
26497  *
26498  *               Reference Parameter effBo is filled with alloced bytes.
26499  *               Returns RFAILED if BO not satisfied at all.
26500  *
26501  *     Invoked by: rgSCHCmnDlAllocTxRbTM1/2/6/7
26502  *
26503  *  @param[in]  RgSchCellCb           *cell
26504  *  @param[in]  RgSchDlSf             *subFrm
26505  *  @param[in]  RgSchUeCb             *ue
26506  *  @param[in]  uint32_t                   bo
26507  *  @param[out] uint32_t                   *effBo
26508  *  @param[in]  RgSchDlHqProcCb       *proc
26509  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26510  *  @return  Void
26511  *
26512  **/
26513 #ifdef ANSI
26514 static Void rgSCHCmnDlAllocTxRb1Tb1Cw
26515 (
26516 RgSchCellCb                *cell,
26517 RgSchDlSf                  *subFrm,
26518 RgSchUeCb                  *ue,
26519 uint32_t                        bo,
26520 uint32_t                        *effBo,
26521 RgSchDlHqProcCb            *proc,
26522 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26523 )
26524 #else
26525 static Void rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26526 RgSchCellCb                *cell;
26527 RgSchDlSf                  *subFrm;
26528 RgSchUeCb                  *ue;
26529 uint32_t                        bo;
26530 uint32_t                        *effBo;
26531 RgSchDlHqProcCb            *proc;
26532 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26533 #endif
26534 {
26535    RgSchDlRbAlloc   *allocInfo;
26536    S16              ret;
26537    uint8_t               numRb;
26538
26539    ret = ROK;
26540    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26541 #ifdef RG_5GTF
26542    if (ue->ue5gtfCb.rank == 2)
26543    {
26544       allocInfo->dciFormat = TFU_DCI_FORMAT_B2;
26545    }
26546    else
26547    {
26548       allocInfo->dciFormat = TFU_DCI_FORMAT_B1;
26549    }
26550 #else
26551    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
26552          allocInfo->raType);
26553 #endif
26554    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
26555          bo, &numRb, effBo);
26556    if (ret == RFAILED)
26557    {
26558       /* If allocation couldn't be made then return */
26559       return;
26560    }
26561    /* Adding UE to RbAllocInfo TX Lst */
26562    rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
26563    /* Fill UE alloc Info */
26564    allocInfo->rbsReq = numRb;
26565    allocInfo->dlSf   = subFrm;
26566 #ifdef RG_5GTF
26567    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
26568 #endif
26569
26570    return;
26571 }
26572
26573 \f
26574 /**
26575  * @brief This function determines the RBs and Bytes required for BO
26576  *        retransmission for UEs configured with TM 1/2/6/7.
26577  *
26578  * @details
26579  *
26580  *     Function: rgSCHCmnDlAllocRetxRb1Tb1Cw
26581  *     Purpose:  Allocate TB1 on CW1.
26582  *
26583  *               Reference Parameter effBo is filled with alloced bytes.
26584  *               Returns RFAILED if BO not satisfied at all.
26585  *
26586  *     Invoked by: rgSCHCmnDlAllocRetxRbTM1/2/6/7
26587  *
26588  *  @param[in]  RgSchCellCb           *cell
26589  *  @param[in]  RgSchDlSf             *subFrm
26590  *  @param[in]  RgSchUeCb             *ue
26591  *  @param[in]  uint32_t                   bo
26592  *  @param[out] uint32_t                   *effBo
26593  *  @param[in]  RgSchDlHqProcCb       *proc
26594  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26595  *  @return  Void
26596  *
26597  **/
26598 #ifdef ANSI
26599 static Void rgSCHCmnDlAllocRetxRb1Tb1Cw
26600 (
26601 RgSchCellCb                *cell,
26602 RgSchDlSf                  *subFrm,
26603 RgSchUeCb                  *ue,
26604 uint32_t                        bo,
26605 uint32_t                        *effBo,
26606 RgSchDlHqProcCb            *proc,
26607 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26608 )
26609 #else
26610 static Void rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26611 RgSchCellCb                *cell;
26612 RgSchDlSf                  *subFrm;
26613 RgSchUeCb                  *ue;
26614 uint32_t                        bo;
26615 uint32_t                        *effBo;
26616 RgSchDlHqProcCb            *proc;
26617 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26618 #endif
26619 {
26620    RgSchDlRbAlloc   *allocInfo;
26621    S16              ret;
26622    uint8_t               numRb;
26623
26624    ret = ROK;
26625    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
26626
26627 #ifndef RG_5GTF
26628    /* 5GTF: RETX DCI format same as TX */
26629    allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
26630       &allocInfo->raType);
26631 #endif
26632
26633    /* Get the Allocation in terms of RBs that are required for
26634     * this retx of TB1 */
26635    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
26636          1, &numRb, effBo);
26637    if (ret == RFAILED)
26638    {
26639       /* Allocation couldn't be made for Retx */
26640       /* Fix : syed If TxRetx allocation failed then add the UE along with the proc
26641        * to the nonSchdTxRetxUeLst and let spfc scheduler take care of it during
26642        * finalization. */        
26643       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
26644       return;
26645    }
26646    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
26647    /* Fill UE alloc Info */
26648    allocInfo->rbsReq = numRb;
26649    allocInfo->dlSf   = subFrm;
26650 #ifdef RG_5GTF
26651    allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE;
26652 #endif
26653
26654    return;
26655 }
26656
26657 \f
26658 /**
26659  * @brief This function determines the RBs and Bytes required for BO
26660  *        transmission for UEs configured with TM 2.
26661  *
26662  * @details
26663  *
26664  *     Function: rgSCHCmnDlAllocTxRbTM1
26665  *     Purpose:
26666  *
26667  *               Reference Parameter effBo is filled with alloced bytes.
26668  *               Returns RFAILED if BO not satisfied at all.
26669  *
26670  *     Invoked by: rgSCHCmnDlAllocTxRb
26671  *
26672  *  @param[in]  RgSchCellCb           *cell
26673  *  @param[in]  RgSchDlSf             *subFrm
26674  *  @param[in]  RgSchUeCb             *ue
26675  *  @param[in]  uint32_t                   bo
26676  *  @param[out] uint32_t                   *effBo
26677  *  @param[in]  RgSchDlHqProcCb       *proc
26678  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26679  *  @return Void
26680  *
26681  **/
26682 #ifdef ANSI
26683 static Void rgSCHCmnDlAllocTxRbTM1
26684 (
26685 RgSchCellCb                *cell,
26686 RgSchDlSf                  *subFrm,
26687 RgSchUeCb                  *ue,
26688 uint32_t                        bo,
26689 uint32_t                        *effBo,
26690 RgSchDlHqProcCb            *proc,
26691 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26692 )
26693 #else
26694 static Void rgSCHCmnDlAllocTxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26695 RgSchCellCb                *cell;
26696 RgSchDlSf                  *subFrm;
26697 RgSchUeCb                  *ue;
26698 uint32_t                        bo;
26699 uint32_t                        *effBo;
26700 RgSchDlHqProcCb            *proc;
26701 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26702 #endif
26703 {
26704    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
26705    return;
26706 }
26707
26708 \f
26709 /**
26710  * @brief This function determines the RBs and Bytes required for BO
26711  *        retransmission for UEs configured with TM 2.
26712  *
26713  * @details
26714  *
26715  *     Function: rgSCHCmnDlAllocRetxRbTM1
26716  *     Purpose:
26717  *
26718  *               Reference Parameter effBo is filled with alloced bytes.
26719  *               Returns RFAILED if BO not satisfied at all.
26720  *
26721  *     Invoked by: rgSCHCmnDlAllocRetxRb
26722  *
26723  *  @param[in]  RgSchCellCb           *cell
26724  *  @param[in]  RgSchDlSf             *subFrm
26725  *  @param[in]  RgSchUeCb             *ue
26726  *  @param[in]  uint32_t                   bo
26727  *  @param[out] uint32_t                   *effBo
26728  *  @param[in]  RgSchDlHqProcCb       *proc
26729  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26730  *  @return Void
26731  *
26732  **/
26733 #ifdef ANSI
26734 static Void rgSCHCmnDlAllocRetxRbTM1
26735 (
26736 RgSchCellCb                *cell,
26737 RgSchDlSf                  *subFrm,
26738 RgSchUeCb                  *ue,
26739 uint32_t                        bo,
26740 uint32_t                        *effBo,
26741 RgSchDlHqProcCb            *proc,
26742 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26743 )
26744 #else
26745 static Void rgSCHCmnDlAllocRetxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26746 RgSchCellCb                *cell;
26747 RgSchDlSf                  *subFrm;
26748 RgSchUeCb                  *ue;
26749 uint32_t                        bo;
26750 uint32_t                        *effBo;
26751 RgSchDlHqProcCb            *proc;
26752 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26753 #endif
26754 {
26755    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
26756    return;
26757 }
26758
26759 \f
26760 /**
26761  * @brief This function determines the RBs and Bytes required for BO
26762  *        transmission for UEs configured with TM 2.
26763  *
26764  * @details
26765  *
26766  *     Function: rgSCHCmnDlAllocTxRbTM2
26767  *     Purpose:
26768  *
26769  *               Reference Parameter effBo is filled with alloced bytes.
26770  *               Returns RFAILED if BO not satisfied at all.
26771  *
26772  *     Invoked by: rgSCHCmnDlAllocTxRb
26773  *
26774  *  @param[in]  RgSchCellCb           *cell
26775  *  @param[in]  RgSchDlSf             *subFrm
26776  *  @param[in]  RgSchUeCb             *ue
26777  *  @param[in]  uint32_t                   bo
26778  *  @param[out] uint32_t                   *effBo
26779  *  @param[in]  RgSchDlHqProcCb       *proc
26780  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26781  *  @return Void
26782  *
26783  **/
26784 #ifdef ANSI
26785 static Void rgSCHCmnDlAllocTxRbTM2
26786 (
26787 RgSchCellCb                *cell,
26788 RgSchDlSf                  *subFrm,
26789 RgSchUeCb                  *ue,
26790 uint32_t                        bo,
26791 uint32_t                        *effBo,
26792 RgSchDlHqProcCb            *proc,
26793 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26794 )
26795 #else
26796 static Void rgSCHCmnDlAllocTxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26797 RgSchCellCb                *cell;
26798 RgSchDlSf                  *subFrm;
26799 RgSchUeCb                  *ue;
26800 uint32_t                        bo;
26801 uint32_t                        *effBo;
26802 RgSchDlHqProcCb            *proc;
26803 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26804 #endif
26805 {
26806    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
26807    return;
26808 }
26809
26810 \f
26811 /**
26812  * @brief This function determines the RBs and Bytes required for BO
26813  *        retransmission for UEs configured with TM 2.
26814  *
26815  * @details
26816  *
26817  *     Function: rgSCHCmnDlAllocRetxRbTM2
26818  *     Purpose:
26819  *
26820  *               Reference Parameter effBo is filled with alloced bytes.
26821  *               Returns RFAILED if BO not satisfied at all.
26822  *
26823  *     Invoked by: rgSCHCmnDlAllocRetxRb
26824  *
26825  *  @param[in]  RgSchCellCb           *cell
26826  *  @param[in]  RgSchDlSf             *subFrm
26827  *  @param[in]  RgSchUeCb             *ue
26828  *  @param[in]  uint32_t                   bo
26829  *  @param[out] uint32_t                   *effBo
26830  *  @param[in]  RgSchDlHqProcCb       *proc
26831  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26832  *  @return Void
26833  *
26834  **/
26835 #ifdef ANSI
26836 static Void rgSCHCmnDlAllocRetxRbTM2
26837 (
26838 RgSchCellCb                *cell,
26839 RgSchDlSf                  *subFrm,
26840 RgSchUeCb                  *ue,
26841 uint32_t                        bo,
26842 uint32_t                        *effBo,
26843 RgSchDlHqProcCb            *proc,
26844 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26845 )
26846 #else
26847 static Void rgSCHCmnDlAllocRetxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26848 RgSchCellCb                *cell;
26849 RgSchDlSf                  *subFrm;
26850 RgSchUeCb                  *ue;
26851 uint32_t                        bo;
26852 uint32_t                        *effBo;
26853 RgSchDlHqProcCb            *proc;
26854 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26855 #endif
26856 {
26857    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
26858    return;
26859 }
26860
26861 \f
26862 /**
26863  * @brief This function determines the RBs and Bytes required for BO
26864  *        transmission for UEs configured with TM 3.
26865  *
26866  * @details
26867  *
26868  *     Function: rgSCHCmnDlAllocTxRbTM3
26869  *     Purpose:
26870  *
26871  *               Reference Parameter effBo is filled with alloced bytes.
26872  *               Returns RFAILED if BO not satisfied at all.
26873  *
26874  *     Invoked by: rgSCHCmnDlAllocTxRb
26875  *
26876  *  @param[in]  RgSchCellCb           *cell
26877  *  @param[in]  RgSchDlSf             *subFrm
26878  *  @param[in]  RgSchUeCb             *ue
26879  *  @param[in]  uint32_t                   bo
26880  *  @param[out] uint32_t                   *effBo
26881  *  @param[in]  RgSchDlHqProcCb       *proc
26882  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26883  *  @return Void
26884  *
26885  **/
26886 #ifdef ANSI
26887 static Void rgSCHCmnDlAllocTxRbTM3
26888 (
26889 RgSchCellCb                *cell,
26890 RgSchDlSf                  *subFrm,
26891 RgSchUeCb                  *ue,
26892 uint32_t                        bo,
26893 uint32_t                        *effBo,
26894 RgSchDlHqProcCb            *proc,
26895 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26896 )
26897 #else
26898 static Void rgSCHCmnDlAllocTxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26899 RgSchCellCb                *cell;
26900 RgSchDlSf                  *subFrm;
26901 RgSchUeCb                  *ue;
26902 uint32_t                        bo;
26903 uint32_t                        *effBo;
26904 RgSchDlHqProcCb            *proc;
26905 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26906 #endif
26907 {
26908
26909
26910    /* Both TBs free for TX allocation */
26911    rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo,\
26912          proc, cellWdAllocInfo);
26913
26914    return;
26915 }
26916
26917 \f
26918 /**
26919  * @brief This function determines the RBs and Bytes required for BO
26920  *        retransmission for UEs configured with TM 3.
26921  *
26922  * @details
26923  *
26924  *     Function: rgSCHCmnDlAllocRetxRbTM3
26925  *     Purpose:
26926  *
26927  *               Reference Parameter effBo is filled with alloced bytes.
26928  *               Returns RFAILED if BO not satisfied at all.
26929  *
26930  *     Invoked by: rgSCHCmnDlAllocRetxRb
26931  *
26932  *  @param[in]  RgSchCellCb           *cell
26933  *  @param[in]  RgSchDlSf             *subFrm
26934  *  @param[in]  RgSchUeCb             *ue
26935  *  @param[in]  uint32_t                   bo
26936  *  @param[out] uint32_t                   *effBo
26937  *  @param[in]  RgSchDlHqProcCb       *proc
26938  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
26939  *  @return Void
26940  *
26941  **/
26942 #ifdef ANSI
26943 static Void rgSCHCmnDlAllocRetxRbTM3
26944 (
26945 RgSchCellCb                *cell,
26946 RgSchDlSf                  *subFrm,
26947 RgSchUeCb                  *ue,
26948 uint32_t                        bo,
26949 uint32_t                        *effBo,
26950 RgSchDlHqProcCb            *proc,
26951 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
26952 )
26953 #else
26954 static Void rgSCHCmnDlAllocRetxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
26955 RgSchCellCb                *cell;
26956 RgSchDlSf                  *subFrm;
26957 RgSchUeCb                  *ue;
26958 uint32_t                        bo;
26959 uint32_t                        *effBo;
26960 RgSchDlHqProcCb            *proc;
26961 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
26962 #endif
26963 {
26964
26965
26966    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
26967          (proc->tbInfo[1].state == HQ_TB_NACKED))
26968    {
26969 #ifdef LAA_DBG_LOG
26970       printf ("RETX RB TM3 nack for both hqp %d cell %d \n", proc->procId, proc->hqE->cell->cellId);
26971 #endif
26972       /* Both TBs require RETX allocation */
26973       rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo,\
26974             proc, cellWdAllocInfo);
26975    }
26976    else
26977    {
26978       /* One of the TBs need RETX allocation. Other TB may/maynot
26979        * be available for new TX allocation. */
26980       rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo,\
26981             proc, cellWdAllocInfo);
26982    }
26983
26984    return;
26985 }
26986
26987 \f
26988 /**
26989  * @brief This function performs the DCI format selection in case of
26990  *        Transmit Diversity scheme where there can be more
26991  *        than 1 option for DCI format selection.
26992  *
26993  * @details
26994  *
26995  *     Function: rgSCHCmnSlctPdcchFrmt
26996  *     Purpose:  1. If DLFS is enabled, then choose TM specific
26997  *                  DCI format for Transmit diversity. All the
26998  *                  TM Specific DCI Formats support Type0 and/or
26999  *                  Type1 resource allocation scheme. DLFS
27000  *                  supports only Type-0&1 Resource allocation.
27001  *               2. If DLFS is not enabled, select a DCI format
27002  *                  which is of smaller size. Since Non-DLFS
27003  *                  scheduler supports all Resource allocation
27004  *                  schemes, selection is based on efficiency.
27005  *
27006  *     Invoked by: DL UE Allocation by Common Scheduler.
27007  *
27008  *  @param[in]  RgSchCellCb      *cell
27009  *  @param[in]  RgSchUeCb        *ue
27010  *  @param[out] uint8_t               *raType
27011  *  @return  TfuDciFormat
27012  *
27013  **/
27014 #ifdef ANSI
27015 TfuDciFormat rgSCHCmnSlctPdcchFrmt
27016 (
27017 RgSchCellCb                *cell,
27018 RgSchUeCb                  *ue,
27019 uint8_t                         *raType
27020 )
27021 #else
27022 TfuDciFormat rgSCHCmnSlctPdcchFrmt(cell, ue, raType)
27023 RgSchCellCb                *cell;
27024 RgSchUeCb                  *ue;
27025 uint8_t                         *raType;
27026 #endif
27027 {
27028    RgSchCmnCell   *cellSch = RG_SCH_CMN_GET_CELL(cell);
27029
27030
27031    /* ccpu00140894- Selective DCI Format and RA type should be selected only 
27032     * after TX Mode transition is completed*/
27033    if ((cellSch->dl.isDlFreqSel) && (ue->txModeTransCmplt))
27034    {
27035       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciRAType;
27036       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciFrmt);
27037    }
27038    else
27039    {
27040       *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciRAType;
27041       return (rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciFrmt);
27042    }
27043 }
27044
27045 \f
27046 /**
27047  * @brief This function handles Retx allocation in case of TM3 UEs
27048  *        where both the TBs were NACKED previously.
27049  *
27050  * @details
27051  *
27052  *     Function: rgSCHCmnDlTM3RetxRetx
27053  *     Purpose:  If forceTD flag enabled
27054  *                  TD for TB1 on CW1.
27055  *               Else
27056  *                  DCI Frmt 2A and RA Type 0
27057  *                  RI layered SM of both TBs on 2 CWs
27058  *               Add UE to cell Alloc Info.
27059  *               Fill UE alloc Info.
27060  *
27061  *
27062  *               Successful allocation is indicated by non-zero effBo value.
27063  *
27064  *     Invoked by: rgSCHCmnDlAllocRbTM3
27065  *
27066  *  @param[in]  RgSchCellCb           *cell
27067  *  @param[in]  RgSchDlSf             *subFrm
27068  *  @param[in]  RgSchUeCb             *ue
27069  *  @param[in]  uint32_t                   bo
27070  *  @param[out] uint32_t                   *effBo
27071  *  @param[in]  RgSchDlHqProcCb       *proc
27072  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27073  *  @return  Void
27074  *
27075  **/
27076 #ifdef ANSI
27077 static Void rgSCHCmnDlTM3RetxRetx
27078 (
27079 RgSchCellCb                *cell,
27080 RgSchDlSf                  *subFrm,
27081 RgSchUeCb                  *ue,
27082 uint32_t                        bo,
27083 uint32_t                        *effBo,
27084 RgSchDlHqProcCb            *proc,
27085 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27086 )
27087 #else
27088 static Void rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27089 RgSchCellCb                *cell;
27090 RgSchDlSf                  *subFrm;
27091 RgSchUeCb                  *ue;
27092 uint32_t                        bo;
27093 uint32_t                        *effBo;
27094 RgSchDlHqProcCb            *proc;
27095 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27096 #endif
27097 {
27098    S16           ret;
27099    RgSchDlRbAlloc *allocInfo;
27100    uint8_t            numRb;
27101    Bool          swpFlg;
27102    uint8_t            precInfo;
27103    uint8_t            noTxLyrs;
27104    uint8_t            precInfoAntIdx;
27105
27106
27107    ret = ROK;
27108    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
27109    swpFlg = FALSE;
27110 /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
27111    {
27112       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
27113       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
27114
27115       ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
27116             effBo);
27117       if (ret == RFAILED)
27118       {
27119          /* Allocation couldn't be made for Retx */
27120          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
27121          return;
27122       }
27123       /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */
27124       noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
27125 #ifdef FOUR_TX_ANTENNA
27126       /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 should
27127        * have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
27128       if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
27129       {
27130          swpFlg = TRUE;
27131          proc->cwSwpEnabled = TRUE;
27132       }
27133 #endif
27134       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27135       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
27136    }
27137
27138 #ifdef LTEMAC_SPS
27139    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
27140 #endif
27141    {
27142       /* Adding UE to allocInfo RETX Lst */
27143       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
27144    }
27145    /* Fill UE alloc Info scratch pad */
27146    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
27147          precInfo, noTxLyrs, subFrm);
27148
27149    return;
27150 }
27151
27152 \f
27153 /**
27154  * @brief This function handles Retx allocation in case of TM4 UEs
27155  *        where both the TBs were NACKED previously.
27156  *
27157  * @details
27158  *
27159  *     Function: rgSCHCmnDlTM4RetxRetx
27160  *     Purpose:  If forceTD flag enabled
27161  *                  TD for TB1 on CW1.
27162  *               Else
27163  *                  DCI Frmt 2 and RA Type 0
27164  *                  If RI == 1
27165  *                     1 layer SM of TB1 on CW1.
27166  *                  Else
27167  *                     RI layered SM of both TBs on 2 CWs
27168  *               Add UE to cell Alloc Info.
27169  *               Fill UE alloc Info.
27170  *
27171  *
27172  *               Successful allocation is indicated by non-zero effBo value.
27173  *
27174  *     Invoked by: rgSCHCmnDlAllocRbTM4
27175  *
27176  *  @param[in]  RgSchCellCb           *cell
27177  *  @param[in]  RgSchDlSf             *subFrm
27178  *  @param[in]  RgSchUeCb             *ue
27179  *  @param[in]  uint32_t                   bo
27180  *  @param[out] uint32_t                   *effBo
27181  *  @param[in]  RgSchDlHqProcCb       *proc
27182  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27183  *  @return  Void
27184  *
27185  **/
27186 #ifdef ANSI
27187 static Void rgSCHCmnDlTM4RetxRetx
27188 (
27189 RgSchCellCb                *cell,
27190 RgSchDlSf                  *subFrm,
27191 RgSchUeCb                  *ue,
27192 uint32_t                        bo,
27193 uint32_t                        *effBo,
27194 RgSchDlHqProcCb            *proc,
27195 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
27196 )
27197 #else
27198 static Void rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
27199 RgSchCellCb                *cell;
27200 RgSchDlSf                  *subFrm;
27201 RgSchUeCb                  *ue;
27202 uint32_t                        bo;
27203 uint32_t                        *effBo;
27204 RgSchDlHqProcCb            *proc;
27205 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
27206 #endif
27207 {
27208    S16            ret;
27209    RgSchDlRbAlloc *allocInfo;
27210    uint8_t             numRb;
27211    Bool           swpFlg = FALSE;
27212    uint8_t             precInfo;
27213 #ifdef FOUR_TX_ANTENNA
27214    uint8_t             precInfoAntIdx;
27215 #endif
27216    uint8_t             noTxLyrs;
27217
27218
27219    ret = ROK;
27220    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
27221                        
27222    /* Irrespective of RI Schedule both CWs */
27223    allocInfo->dciFormat = TFU_DCI_FORMAT_2;
27224    allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
27225
27226    ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\
27227          effBo);
27228    if (ret == RFAILED)
27229    {
27230       /* Allocation couldn't be made for Retx */
27231       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
27232       return;
27233    }
27234    noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs;
27235    precInfo = 0; 
27236 #ifdef FOUR_TX_ANTENNA
27237    /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1
27238     * should have 2-LyrTB as per Table 6.3.3.2-1 of 36.211  */
27239    if(noTxLyrs == 3 &&  proc->tbInfo[0].numLyrs==2)
27240    {
27241       swpFlg = TRUE;
27242       proc->cwSwpEnabled = TRUE;
27243 }
27244 precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27245 precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
27246 #endif
27247
27248 #ifdef LTEMAC_SPS
27249    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
27250 #endif
27251    {
27252       /* Adding UE to allocInfo RETX Lst */
27253       rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
27254    }
27255    /* Fill UE alloc Info scratch pad */
27256    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
27257          precInfo, noTxLyrs, subFrm);
27258
27259    return;
27260 }
27261
27262
27263 \f
27264 /**
27265  * @brief This function determines Transmission attributes
27266  *        incase of Spatial multiplexing for TX and RETX TBs.
27267  *
27268  * @details
27269  *
27270  *     Function: rgSCHCmnDlSMGetAttrForTxRetx
27271  *     Purpose:  1. Reached here for a TM3/4 UE's HqP whose one of the TBs is
27272  *                  NACKED and the other TB is either NACKED or WAITING.
27273  *               2. Select the NACKED TB for RETX allocation.
27274  *               3. Allocation preference for RETX TB by mapping it to a better
27275  *                  CW (better in terms of efficiency).
27276  *               4. Determine the state of the other TB.
27277  *                  Determine if swapFlag were to be set.
27278  *                  Swap flag would be set if Retx TB is cross
27279  *                  mapped to a CW.
27280  *               5. If UE has new data available for TX and if the other TB's state
27281  *                  is ACKED then set furtherScope as TRUE.
27282  *
27283  *     Invoked by: rgSCHCmnDlTM3[4]TxRetx
27284  *
27285  *  @param[in]  RgSchUeCb        *ue
27286  *  @param[in]  RgSchDlHqProcCb  *proc
27287  *  @param[out] RgSchDlHqTbCb    **retxTb
27288  *  @param[out] RgSchDlHqTbCb    **txTb
27289  *  @param[out] Bool             *frthrScp
27290  *  @param[out] Bool             *swpFlg
27291  *  @return  Void
27292  *
27293  **/
27294 #ifdef ANSI
27295 static Void rgSCHCmnDlSMGetAttrForTxRetx
27296 (
27297 RgSchUeCb                  *ue,
27298 RgSchDlHqProcCb            *proc,
27299 RgSchDlHqTbCb              **retxTb,
27300 RgSchDlHqTbCb              **txTb,
27301 Bool                       *frthrScp,
27302 Bool                       *swpFlg
27303 )
27304 #else
27305 static Void rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, frthrScp,\
27306         swpFlg)
27307 RgSchUeCb                  *ue;
27308 RgSchDlHqProcCb            *proc;
27309 RgSchDlHqTbCb              **retxTb;
27310 RgSchDlHqTbCb              **txTb;
27311 Bool                       *frthrScp;
27312 Bool                       *swpFlg;
27313 #endif
27314 {
27315    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,proc->hqE->cell);
27316    RgSchDlRbAlloc  *allocInfo;
27317
27318
27319    if (proc->tbInfo[0].state == HQ_TB_NACKED)
27320    {
27321       *retxTb = &proc->tbInfo[0];
27322       *txTb = &proc->tbInfo[1];
27323       /* TENB_BRDCM_TM4- Currently disabling swapflag for TM3/TM4, since 
27324        * HqFeedback processing does not consider a swapped hq feedback */
27325       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 1))
27326       {
27327          *swpFlg = TRUE;
27328          proc->cwSwpEnabled = TRUE;
27329       }
27330       if (proc->tbInfo[1].state == HQ_TB_ACKED)
27331       {
27332          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
27333          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
27334       }
27335    }
27336    else
27337    {
27338       *retxTb = &proc->tbInfo[1];
27339       *txTb = &proc->tbInfo[0];
27340       /* TENB_BRDCM_TM4 - Currently disabling swapflag for TM3/TM4, since 
27341        * HqFeedback processing does not consider a swapped hq feedback */
27342       if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 0))
27343       {
27344          *swpFlg = TRUE;
27345          proc->cwSwpEnabled = TRUE;
27346       }
27347       if (proc->tbInfo[0].state == HQ_TB_ACKED)
27348       {
27349          allocInfo =  RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell);
27350          *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData;
27351       }
27352    }
27353    return;
27354 }
27355
27356 \f
27357 /**
27358  * @brief Determine Precoding information for TM3 2 TX Antenna.
27359  *
27360  * @details
27361  *
27362  *     Function: rgSCHCmnDlTM3PrecInf2
27363  *     Purpose:
27364  *
27365  *     Invoked by: rgSCHCmnDlGetAttrForTM3
27366  *
27367  *  @param[in]  RgSchUeCb        *ue
27368  *  @param[in]  uint8_t               numTxLyrs
27369  *  @param[in]  Bool             bothCwEnbld
27370  *  @return  uint8_t
27371  *
27372  **/
27373 #ifdef ANSI
27374 static uint8_t rgSCHCmnDlTM3PrecInf2
27375 (
27376 RgSchCellCb                *cell,
27377 RgSchUeCb                  *ue,
27378 uint8_t                         numTxLyrs,
27379 Bool                       bothCwEnbld
27380 )
27381 #else
27382 static uint8_t rgSCHCmnDlTM3PrecInf2(ue, numTxLyrs, bothCwEnbld)
27383 RgSchCellCb                *cell;
27384 RgSchUeCb                  *ue;
27385 uint8_t                         numTxLyrs;
27386 Bool                       bothCwEnbld;
27387 #endif
27388 {
27389
27390    return (0);
27391 }
27392
27393 \f
27394 /**
27395  * @brief Determine Precoding information for TM4 2 TX Antenna.
27396  *
27397  * @details
27398  *
27399  *     Function: rgSCHCmnDlTM4PrecInf2
27400  *     Purpose:  To determine a logic of deriving precoding index
27401  *               information from 36.212 table 5.3.3.1.5-4
27402  *
27403  *     Invoked by: rgSCHCmnDlGetAttrForTM4
27404  *
27405  *  @param[in]  RgSchUeCb        *ue
27406  *  @param[in]  uint8_t               numTxLyrs
27407  *  @param[in]  Bool             bothCwEnbld
27408  *  @return  uint8_t
27409  *
27410  **/
27411 #ifdef ANSI
27412 static uint8_t rgSCHCmnDlTM4PrecInf2
27413 (
27414 RgSchCellCb                *cell,
27415 RgSchUeCb                  *ue,
27416 uint8_t                         numTxLyrs,
27417 Bool                       bothCwEnbld
27418 )
27419 #else
27420 static uint8_t rgSCHCmnDlTM4PrecInf2(ue, numTxLyrs, bothCwEnbld)
27421 RgSchCellCb                *cell;
27422 RgSchUeCb                  *ue;
27423 uint8_t                         numTxLyrs;
27424 Bool                       bothCwEnbld;
27425 #endif
27426 {
27427    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27428    uint8_t            precIdx;
27429
27430
27431    if (ueDl->mimoInfo.ri == numTxLyrs)
27432    {
27433       if (ueDl->mimoInfo.ri == 2)
27434       {
27435          /* PrecInfo corresponding to 2 CW
27436            Transmission */
27437          if (ue->mimoInfo.puschFdbkVld)
27438          {
27439             precIdx = 2;
27440          }
27441          else 
27442          {
27443             precIdx = ueDl->mimoInfo.pmi - 1;
27444          }
27445       }
27446       else
27447       {
27448          /* PrecInfo corresponding to 1 CW
27449           * Transmission */
27450          if (ue->mimoInfo.puschFdbkVld)
27451          {
27452             precIdx =  5;
27453          }
27454          else
27455          {
27456             precIdx =  ueDl->mimoInfo.pmi + 1;
27457          }
27458       }
27459    }
27460    else if (ueDl->mimoInfo.ri > numTxLyrs)
27461    {
27462       /* In case of choosing among the columns of a
27463        * precoding matrix, choose the column corresponding
27464        * to the MAX-CQI */
27465       if (ue->mimoInfo.puschFdbkVld)
27466       {
27467          precIdx = 5;
27468       }
27469       else
27470       {
27471          precIdx = (ueDl->mimoInfo.pmi- 1)* 2  + 1;
27472       }
27473    }
27474    else /* if RI < numTxLyrs */
27475    {
27476       precIdx = (ueDl->mimoInfo.pmi < 2)? 0:1;
27477    }
27478    return (precIdx);
27479 }
27480
27481 \f
27482 /**
27483  * @brief Determine Precoding information for TM3 4 TX Antenna.
27484  *
27485  * @details
27486  *
27487  *     Function: rgSCHCmnDlTM3PrecInf4
27488  *     Purpose:  To determine a logic of deriving precoding index
27489  *               information from 36.212 table 5.3.3.1.5A-2
27490  *
27491  *     Invoked by: rgSCHCmnDlGetAttrForTM3
27492  *
27493  *  @param[in]  RgSchUeCb        *ue
27494  *  @param[in]  uint8_t               numTxLyrs
27495  *  @param[in]  Bool             bothCwEnbld
27496  *  @return  uint8_t
27497  *
27498  **/
27499 #ifdef ANSI
27500 static uint8_t rgSCHCmnDlTM3PrecInf4
27501 (
27502 RgSchCellCb                *cell,
27503 RgSchUeCb                  *ue,
27504 uint8_t                         numTxLyrs,
27505 Bool                       bothCwEnbld
27506 )
27507 #else
27508 static uint8_t rgSCHCmnDlTM3PrecInf4(ue, numTxLyrs, bothCwEnbld)
27509 RgSchCellCb                *cell;
27510 RgSchUeCb                  *ue;
27511 uint8_t                         numTxLyrs;
27512 Bool                       bothCwEnbld;
27513 #endif
27514 {
27515    uint8_t            precIdx;
27516
27517
27518    if (bothCwEnbld)
27519    {
27520       precIdx = numTxLyrs - 2;
27521    }
27522    else /* one 1 CW transmission */
27523    {
27524       precIdx = 1;
27525    }
27526    return (precIdx);
27527 }
27528
27529 \f
27530 /**
27531  * @brief Determine Precoding information for TM4 4 TX Antenna.
27532  *
27533  * @details
27534  *
27535  *     Function: rgSCHCmnDlTM4PrecInf4
27536  *     Purpose:  To determine a logic of deriving precoding index
27537  *               information from 36.212 table 5.3.3.1.5-5
27538  *
27539  *     Invoked by: rgSCHCmnDlGetAttrForTM4
27540  *
27541  *  @param[in]  RgSchUeCb        *ue
27542  *  @param[in]  uint8_t               numTxLyrs
27543  *  @param[in]  Bool             bothCwEnbld
27544  *  @return  uint8_t
27545  *
27546  **/
27547 #ifdef ANSI
27548 static uint8_t rgSCHCmnDlTM4PrecInf4
27549 (
27550 RgSchCellCb                *cell,
27551 RgSchUeCb                  *ue,
27552 uint8_t                         numTxLyrs,
27553 Bool                       bothCwEnbld
27554 )
27555 #else
27556 static uint8_t rgSCHCmnDlTM4PrecInf4(cell, ue, numTxLyrs, bothCwEnbld)
27557 RgSchCellCb                *cell;
27558 RgSchUeCb                  *ue;
27559 uint8_t                         numTxLyrs;
27560 Bool                       bothCwEnbld;
27561 #endif
27562 {
27563    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27564    uint8_t            precInfoBaseIdx, precIdx;
27565
27566
27567    precInfoBaseIdx  = (ue->mimoInfo.puschFdbkVld)? (16):
27568       (ueDl->mimoInfo.pmi);
27569    if (bothCwEnbld)
27570    {
27571       precIdx = precInfoBaseIdx + (numTxLyrs-2)*17;
27572    }
27573    else /* one 1 CW transmission */
27574    {
27575       precInfoBaseIdx += 1;
27576       precIdx = precInfoBaseIdx + (numTxLyrs-1)*17;
27577    }
27578    return (precIdx);
27579 }
27580
27581 \f
27582 /**
27583  * @brief This function determines Transmission attributes
27584  *        incase of TM3 scheduling.
27585  *
27586  * @details
27587  *
27588  *     Function: rgSCHCmnDlGetAttrForTM3
27589  *     Purpose:  Determine retx TB and tx TB based on TB states.
27590  *               If forceTD enabled
27591  *                  perform only retx TB allocation.
27592  *                  If retxTB == TB2 then DCI Frmt = 2A, RA Type = 0.
27593  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
27594  *               If RI == 1
27595  *                  perform retxTB allocation on CW1.
27596  *               Else if RI > 1
27597  *                  Determine further Scope and Swap Flag attributes
27598  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
27599  *                  If no further scope for new TX allocation
27600  *                     Allocate only retx TB using 2 layers if
27601  *                     this TB was previously transmitted using 2 layers AND
27602  *                     number of Tx antenna ports == 4.
27603  *                     otherwise do single layer precoding.
27604  *
27605  *     Invoked by: rgSCHCmnDlTM3TxRetx
27606  *
27607  *  @param[in]  RgSchUeCb        *ue
27608  *  @param[in]  RgSchDlHqProcCb  *proc
27609  *  @param[out] uint8_t               *numTxLyrs
27610  *  @param[out] Bool             *isTraDiv
27611  *  @param[out] uint8_t               *prcdngInf
27612  *  @param[out] uint8_t               *raType
27613  *  @return  Void
27614  *
27615  **/
27616 #ifdef ANSI
27617 static Void rgSCHCmnDlGetAttrForTM3
27618 (
27619 RgSchCellCb                *cell,
27620 RgSchUeCb                  *ue,
27621 RgSchDlHqProcCb            *proc,
27622 uint8_t                         *numTxLyrs,
27623 TfuDciFormat               *dciFrmt,
27624 uint8_t                         *prcdngInf,
27625 RgSchDlHqTbCb              **retxTb,
27626 RgSchDlHqTbCb              **txTb,
27627 Bool                       *frthrScp,
27628 Bool                       *swpFlg,
27629 uint8_t                         *raType
27630 )
27631 #else
27632 static Void rgSCHCmnDlGetAttrForTM3(cell, ue, proc, numTxLyrs, dciFrmt,\
27633         prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType)
27634 RgSchCellCb                *cell;
27635 RgSchUeCb                  *ue;
27636 RgSchDlHqProcCb            *proc;
27637 uint8_t                         *numTxLyrs;
27638 TfuDciFormat               *dciFrmt;
27639 uint8_t                         *prcdngInf;
27640 RgSchDlHqTbCb              **retxTb;
27641 RgSchDlHqTbCb              **txTb;
27642 Bool                       *frthrScp;
27643 Bool                       *swpFlg;
27644 uint8_t                         *raType;
27645 #endif
27646 {
27647    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27648    uint8_t            precInfoAntIdx;
27649
27650
27651    /* Avoiding Tx-Retx for LAA cell as firstSchedTime is associated with 
27652       HQP */
27653    /* Integration_fix: SPS Proc shall always have only one Cw */
27654 #ifdef LTEMAC_SPS
27655    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
27656          (ueDl->mimoInfo.forceTD)) 
27657 #ifdef LTE_ADV
27658      ||(TRUE == rgSCHLaaSCellEnabled(cell))
27659 #endif
27660       )
27661 #else
27662    if ((ueDl->mimoInfo.forceTD) 
27663 #ifdef LTE_ADV
27664        || (TRUE == rgSCHLaaSCellEnabled(cell))
27665 #endif
27666       )
27667 #endif
27668    {
27669       /* Transmit Diversity. Format based on dlfsEnabled
27670        * No further scope */
27671       if (proc->tbInfo[0].state == HQ_TB_NACKED)
27672       {
27673          *retxTb = &proc->tbInfo[0];
27674          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
27675       }
27676       else
27677       {
27678          *retxTb = &proc->tbInfo[1];
27679          *dciFrmt = TFU_DCI_FORMAT_2A;
27680          *raType = RG_SCH_CMN_RA_TYPE0;
27681       }
27682       *numTxLyrs = 1;
27683       *frthrScp = FALSE;
27684       *prcdngInf = 0;
27685       return;
27686    }
27687
27688    /* Determine the 2 TB transmission attributes */
27689    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
27690          frthrScp, swpFlg);
27691    if (*frthrScp)
27692    {
27693       /* Prefer allocation of RETX TB over 2 layers rather than combining
27694        * it with a new TX. */
27695       if ((ueDl->mimoInfo.ri == 2)
27696             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
27697       {
27698          /* Allocate TB on CW1, using 2 Lyrs,
27699           * Format 2, precoding accordingly */
27700          *numTxLyrs = 2;
27701          *frthrScp = FALSE;
27702       }
27703       else
27704       {
27705          *numTxLyrs=  ((*retxTb)->numLyrs + ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)].noLyr);
27706
27707          if((*retxTb)->tbIdx == 0 && ((*retxTb)->numLyrs == 2 ) && *numTxLyrs ==3)
27708          {
27709             *swpFlg = TRUE;
27710             proc->cwSwpEnabled = TRUE;
27711          }
27712          else if((*retxTb)->tbIdx == 1 && ((*retxTb)->numLyrs == 1) && *numTxLyrs ==3)
27713          {
27714             *swpFlg = TRUE;
27715             proc->cwSwpEnabled = TRUE;
27716          }
27717       }
27718
27719       precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
27720       *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])\
27721                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
27722       *dciFrmt = TFU_DCI_FORMAT_2A;
27723       *raType = RG_SCH_CMN_RA_TYPE0;
27724    }
27725    else /* frthrScp == FALSE */
27726    {
27727       if (cell->numTxAntPorts == 2)
27728       {
27729          /*  Transmit Diversity  */
27730          *numTxLyrs = 1;
27731          if ((*retxTb)->tbIdx == 0)
27732          {
27733             *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
27734          }
27735          else
27736          {
27737             /* If retxTB is TB2 then use format 2A */
27738             *dciFrmt = TFU_DCI_FORMAT_2A;
27739             *raType = RG_SCH_CMN_RA_TYPE0;
27740          }
27741          *prcdngInf = 0;
27742          return;
27743       }
27744       else /* NumAntPorts == 4 */
27745       {
27746          if ((*retxTb)->numLyrs == 2)
27747          {
27748             /* Allocate TB on CW1, using 2 Lyrs,
27749              * Format 2A, precoding accordingly */
27750             *numTxLyrs = 2;
27751             *dciFrmt = TFU_DCI_FORMAT_2A;
27752             *raType = RG_SCH_CMN_RA_TYPE0;
27753             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27754             *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, *numTxLyrs, *frthrScp);
27755             return;
27756          }
27757          else
27758          {
27759             /*  Transmit Diversity  */
27760             *numTxLyrs = 1;
27761             if ((*retxTb)->tbIdx == 0)
27762             {
27763                *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
27764             }
27765             else
27766             {
27767                /* If retxTB is TB2 then use format 2A */
27768                *dciFrmt = TFU_DCI_FORMAT_2A;
27769                *raType = RG_SCH_CMN_RA_TYPE0;
27770             }
27771             *prcdngInf = 0;
27772             return;
27773          }
27774       }
27775    }
27776
27777    return;
27778 }
27779
27780
27781 \f
27782 /**
27783  * @brief This function determines Transmission attributes
27784  *        incase of TM4 scheduling.
27785  *
27786  * @details
27787  *
27788  *     Function: rgSCHCmnDlGetAttrForTM4
27789  *     Purpose:  Determine retx TB and tx TB based on TB states.
27790  *               If forceTD enabled
27791  *                  perform only retx TB allocation.
27792  *                  If retxTB == TB2 then DCI Frmt = 2, RA Type = 0.
27793  *                  Else DCI Frmt and RA Type based on cell->isDlfsEnbld
27794  *               If RI == 1
27795  *                  perform retxTB allocation on CW1.
27796  *               Else if RI > 1
27797  *                  Determine further Scope and Swap Flag attributes
27798  *                  assuming a 2 CW transmission of RetxTB and new Tx TB.
27799  *                  If no further scope for new TX allocation
27800  *                     Allocate only retx TB using 2 layers if
27801  *                     this TB was previously transmitted using 2 layers AND
27802  *                     number of Tx antenna ports == 4.
27803  *                     otherwise do single layer precoding.
27804  *
27805  *     Invoked by: rgSCHCmnDlTM4TxRetx
27806  *
27807  *  @param[in]  RgSchUeCb        *ue
27808  *  @param[in]  RgSchDlHqProcCb  *proc
27809  *  @param[out] uint8_t               *numTxLyrs
27810  *  @param[out] Bool             *isTraDiv
27811  *  @param[out] uint8_t               *prcdngInf
27812  *  @param[out] uint8_t               *raType
27813  *  @return  Void
27814  *
27815  **/
27816 #ifdef ANSI
27817 static Void rgSCHCmnDlGetAttrForTM4
27818 (
27819 RgSchCellCb                *cell,
27820 RgSchUeCb                  *ue,
27821 RgSchDlHqProcCb            *proc,
27822 uint8_t                         *numTxLyrs,
27823 TfuDciFormat               *dciFrmt,
27824 uint8_t                         *prcdngInf,
27825 RgSchDlHqTbCb              **retxTb,
27826 RgSchDlHqTbCb              **txTb,
27827 Bool                       *frthrScp,
27828 Bool                       *swpFlg,
27829 uint8_t                         *raType
27830 )
27831 #else
27832 static Void rgSCHCmnDlGetAttrForTM4(cell, ue, proc, numTxLyrs, dciFrmt,\
27833         prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType)
27834 RgSchCellCb                *cell;
27835 RgSchUeCb                  *ue;
27836 RgSchDlHqProcCb            *proc;
27837 uint8_t                         *numTxLyrs;
27838 TfuDciFormat               *dciFrmt;
27839 uint8_t                         *prcdngInf;
27840 RgSchDlHqTbCb              **retxTb;
27841 RgSchDlHqTbCb              **txTb;
27842 Bool                       *frthrScp;
27843 Bool                       *swpFlg;
27844 uint8_t                         *raType;
27845 #endif
27846 {
27847    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
27848    uint8_t precInfoAntIdx;
27849
27850
27851    *frthrScp = FALSE;
27852    /* Integration_fix: SPS Proc shall always have only one Cw */
27853 #ifdef LTEMAC_SPS
27854    if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
27855          (ueDl->mimoInfo.forceTD)) 
27856 #ifdef LTE_ADV
27857      ||(TRUE == rgSCHLaaSCellEnabled(cell))
27858 #endif
27859       )
27860 #else
27861    if ((ueDl->mimoInfo.forceTD) 
27862 #ifdef LTE_ADV
27863        || (TRUE == rgSCHLaaSCellEnabled(cell))
27864 #endif
27865       )
27866 #endif
27867    {
27868       /* Transmit Diversity. Format based on dlfsEnabled
27869        * No further scope */
27870       if (proc->tbInfo[0].state == HQ_TB_NACKED)
27871       {
27872          *retxTb = &proc->tbInfo[0];
27873          *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType);
27874       }
27875       else
27876       {
27877          *retxTb = &proc->tbInfo[1];
27878          *dciFrmt = TFU_DCI_FORMAT_2;
27879          *raType = RG_SCH_CMN_RA_TYPE0;
27880       }
27881       *numTxLyrs = 1;
27882       *frthrScp = FALSE;
27883       *prcdngInf = 0;
27884       return;
27885    }
27886
27887    if (ueDl->mimoInfo.ri == 1)
27888    {
27889       /* single layer precoding. Format 2.
27890        * No further scope */
27891       if (proc->tbInfo[0].state == HQ_TB_NACKED)
27892       {
27893          *retxTb = &proc->tbInfo[0];
27894       }
27895       else
27896       {
27897          *retxTb = &proc->tbInfo[1];
27898       }
27899       *numTxLyrs = 1;
27900       *dciFrmt = TFU_DCI_FORMAT_2;
27901       *raType = RG_SCH_CMN_RA_TYPE0;
27902       *frthrScp = FALSE;
27903       *prcdngInf = 0; /*When RI= 1*/
27904       return;
27905    }
27906
27907    /* Determine the 2 TB transmission attributes */
27908    rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \
27909          frthrScp, swpFlg);
27910    *dciFrmt = TFU_DCI_FORMAT_2;
27911    *raType = RG_SCH_CMN_RA_TYPE0;
27912    if (*frthrScp)
27913    {
27914       /* Prefer allocation of RETX TB over 2 layers rather than combining
27915        * it with a new TX. */
27916       if ((ueDl->mimoInfo.ri == 2)
27917             && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4))
27918       {
27919          /* Allocate TB on CW1, using 2 Lyrs,
27920           * Format 2, precoding accordingly */
27921          *numTxLyrs = 2;
27922          *frthrScp = FALSE;
27923       }
27924       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27925       *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])
27926                    (cell, ue, ueDl->mimoInfo.ri, *frthrScp);
27927    }
27928    else /* frthrScp == FALSE */
27929    {
27930       if (cell->numTxAntPorts == 2)
27931       {
27932          /* single layer precoding. Format 2. */
27933          *numTxLyrs = 1;
27934          *prcdngInf = (getPrecInfoFunc[1][cell->numTxAntPorts/2 - 1])\
27935                       (cell, ue, *numTxLyrs, *frthrScp);
27936          return;
27937       }
27938       else /* NumAntPorts == 4 */
27939       {
27940          if ((*retxTb)->numLyrs == 2)
27941          {
27942             /* Allocate TB on CW1, using 2 Lyrs,
27943              * Format 2, precoding accordingly */
27944             *numTxLyrs = 2;
27945             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27946             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
27947                          (cell, ue, *numTxLyrs, *frthrScp);
27948             return;
27949          }
27950          else
27951          {
27952             /* Allocate TB with 1 lyr precoding,
27953              * Format 2, precoding info accordingly */
27954             *numTxLyrs = 1;
27955             precInfoAntIdx = cell->numTxAntPorts/2 - 1;
27956             *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\
27957                          (cell, ue, *numTxLyrs, *frthrScp);
27958             return;
27959          }
27960       }
27961    }
27962
27963    return;
27964 }
27965
27966 \f
27967 /**
27968  * @brief This function handles Retx allocation in case of TM3 UEs
27969  *        where previously one of the TBs was NACKED and the other
27970  *        TB is either ACKED/WAITING.
27971  *
27972  * @details
27973  *
27974  *     Function: rgSCHCmnDlTM3TxRetx
27975  *     Purpose:  Determine the TX attributes for TM3 TxRetx Allocation.
27976  *               If futher Scope for New Tx Allocation on other TB
27977  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
27978  *                  Add UE to cell wide RetxTx List.
27979  *               Else
27980  *                  Perform only RETX alloc'n on CW1.
27981  *                  Add UE to cell wide Retx List.
27982  *
27983  *               effBo is set to a non-zero value if allocation is
27984  *               successful.
27985  *
27986  *     Invoked by: rgSCHCmnDlAllocRbTM3
27987  *
27988  *  @param[in]  RgSchCellCb           *cell
27989  *  @param[in]  RgSchDlSf             *subFrm
27990  *  @param[in]  RgSchUeCb             *ue
27991  *  @param[in]  uint32_t                   bo
27992  *  @param[out] uint32_t                   *effBo
27993  *  @param[in]  RgSchDlHqProcCb       *proc
27994  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
27995  *  @return  Void
27996  *
27997  **/
27998 #ifdef ANSI
27999 static Void rgSCHCmnDlTM3TxRetx
28000 (
28001 RgSchCellCb                *cell,
28002 RgSchDlSf                  *subFrm,
28003 RgSchUeCb                  *ue,
28004 uint32_t                        bo,
28005 uint32_t                        *effBo,
28006 RgSchDlHqProcCb            *proc,
28007 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28008 )
28009 #else
28010 static Void rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28011 RgSchCellCb                *cell;
28012 RgSchDlSf                  *subFrm;
28013 RgSchUeCb                  *ue;
28014 uint32_t                        bo;
28015 uint32_t                        *effBo;
28016 RgSchDlHqProcCb            *proc;
28017 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28018 #endif
28019 {
28020    S16              ret;
28021    RgSchDlRbAlloc   *allocInfo;
28022    uint8_t               numRb;
28023    RgSchDlHqTbCb    *retxTb, *txTb;
28024    Bool             frthrScp;
28025    Bool             swpFlg;
28026    uint8_t               prcdngInf;
28027    uint8_t               numTxLyrs;
28028
28029    frthrScp = FALSE;
28030
28031    ret = ROK;
28032    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28033    swpFlg = FALSE;
28034
28035    /* Determine the transmission attributes */
28036    rgSCHCmnDlGetAttrForTM3(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
28037          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
28038          &allocInfo->raType);
28039
28040    if (frthrScp)
28041    {
28042 #ifdef LAA_DBG_LOG
28043       printf ("TX RETX called from proc %d cell %d \n",proc->procId, cell->cellId);
28044 #endif
28045       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
28046             &numRb, effBo);
28047       if (ret == RFAILED)
28048       {
28049          /* Allocation couldn't be made for Retx */
28050          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28051          return;
28052       }
28053       /* Adding UE to RbAllocInfo RETX-TX Lst */
28054       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
28055    }
28056    else
28057    {
28058       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
28059             numTxLyrs, &numRb, effBo);
28060       if (ret == RFAILED)
28061       {
28062          /* Allocation couldn't be made for Retx */
28063          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28064          return;
28065       }
28066 #ifdef LTEMAC_SPS
28067       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28068 #endif
28069       {
28070          /* Adding UE to allocInfo RETX Lst */
28071          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
28072       }
28073    }
28074    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
28075          prcdngInf, numTxLyrs, subFrm);
28076
28077    return;
28078 }
28079
28080 \f
28081 /**
28082  * @brief This function handles Retx allocation in case of TM4 UEs
28083  *        where previously one of the TBs was NACKED and the other
28084  *        TB is either ACKED/WAITING.
28085  *
28086  * @details
28087  *
28088  *     Function: rgSCHCmnDlTM4TxRetx
28089  *     Purpose:  Determine the TX attributes for TM4 TxRetx Allocation.
28090  *               If futher Scope for New Tx Allocation on other TB
28091  *                  Perform RETX alloc'n on 1 CW and TX alloc'n on other.
28092  *                  Add UE to cell wide RetxTx List.
28093  *               Else
28094  *                  Perform only RETX alloc'n on CW1.
28095  *                  Add UE to cell wide Retx List.
28096  *
28097  *               effBo is set to a non-zero value if allocation is
28098  *               successful.
28099  *
28100  *     Invoked by: rgSCHCmnDlAllocRbTM4
28101  *
28102  *  @param[in]  RgSchCellCb           *cell
28103  *  @param[in]  RgSchDlSf             *subFrm
28104  *  @param[in]  RgSchUeCb             *ue
28105  *  @param[in]  uint32_t                   bo
28106  *  @param[out] uint32_t                   *effBo
28107  *  @param[in]  RgSchDlHqProcCb       *proc
28108  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28109  *  @return  Void
28110  *
28111  **/
28112 #ifdef ANSI
28113 static Void rgSCHCmnDlTM4TxRetx
28114 (
28115 RgSchCellCb                *cell,
28116 RgSchDlSf                  *subFrm,
28117 RgSchUeCb                  *ue,
28118 uint32_t                        bo,
28119 uint32_t                        *effBo,
28120 RgSchDlHqProcCb            *proc,
28121 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28122 )
28123 #else
28124 static Void rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28125 RgSchCellCb                *cell;
28126 RgSchDlSf                  *subFrm;
28127 RgSchUeCb                  *ue;
28128 uint32_t                        bo;
28129 uint32_t                        *effBo;
28130 RgSchDlHqProcCb            *proc;
28131 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28132 #endif
28133 {
28134    S16              ret;
28135    RgSchDlRbAlloc   *allocInfo;
28136    uint8_t               numRb;
28137    RgSchDlHqTbCb    *retxTb, *txTb;
28138    Bool             frthrScp;
28139    Bool             swpFlg;
28140    uint8_t               prcdngInf;
28141    uint8_t               numTxLyrs;
28142
28143
28144    ret = ROK;
28145    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28146    swpFlg = FALSE;
28147
28148    /* Determine the transmission attributes */
28149    rgSCHCmnDlGetAttrForTM4(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\
28150          &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\
28151          &allocInfo->raType);
28152
28153    if (frthrScp)
28154    {
28155       ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\
28156             &numRb, effBo);
28157       if (ret == RFAILED)
28158       {
28159          /* Fix : syed If TxRetx allocation failed then add the UE along 
28160           * with the proc to the nonSchdTxRetxUeLst and let spfc scheduler
28161           *  take care of it during finalization. */       
28162          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28163          return;
28164       }
28165       /* Adding UE to RbAllocInfo RETX-TX Lst */
28166       rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc);
28167    }
28168    else
28169    {
28170       ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb,
28171             numTxLyrs, &numRb, effBo);
28172       if (ret == RFAILED)
28173       {
28174          /* Allocation couldn't be made for Retx */
28175          rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28176          return;
28177       }
28178 #ifdef LTEMAC_SPS
28179       if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28180 #endif
28181       {
28182          /* Adding UE to allocInfo RETX Lst */
28183          rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
28184       }
28185    }
28186    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \
28187          prcdngInf, numTxLyrs, subFrm)
28188
28189       return;
28190 }
28191
28192 \f
28193 /**
28194  * @brief This function handles Retx allocation in case of TM4 UEs
28195  *        where previously both the TBs were ACKED and ACKED
28196  *        respectively.
28197  *
28198  * @details
28199  *
28200  *     Function: rgSCHCmnDlTM3TxTx
28201  *     Purpose:  Reached here for a TM3 UE's HqP's fresh allocation
28202  *                  where both the TBs are free for TX scheduling.
28203  *               If forceTD flag is set
28204  *                  perform TD on CW1 with TB1.
28205  *                  precInfo = 0
28206  *               else
28207  *                  DCI Format = 2A.
28208  *                  RA Type = Type0.
28209  *                  RI layered precoding 2 TB on 2 CW.
28210  *                  Set precoding info.
28211  *               Add UE to cellAllocInfo.
28212  *               Fill ueAllocInfo.
28213  *
28214  *              effBo is set to a non-zero value if allocation is
28215  *              successful.
28216  *
28217  *     Invoked by: rgSCHCmnDlAllocRbTM3
28218  *
28219  *  @param[in]  RgSchCellCb           *cell
28220  *  @param[in]  RgSchDlSf             *subFrm
28221  *  @param[in]  RgSchUeCb             *ue
28222  *  @param[in]  uint32_t                   bo
28223  *  @param[out] uint32_t                   *effBo
28224  *  @param[in]  RgSchDlHqProcCb       *proc
28225  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28226  *  @return  Void
28227  *
28228  **/
28229 #ifdef ANSI
28230 static Void rgSCHCmnDlTM3TxTx
28231 (
28232 RgSchCellCb                *cell,
28233 RgSchDlSf                  *subFrm,
28234 RgSchUeCb                  *ue,
28235 uint32_t                        bo,
28236 uint32_t                        *effBo,
28237 RgSchDlHqProcCb            *proc,
28238 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28239 )
28240 #else
28241 static Void rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28242 RgSchCellCb                *cell;
28243 RgSchDlSf                  *subFrm;
28244 RgSchUeCb                  *ue;
28245 uint32_t                        bo;
28246 uint32_t                        *effBo;
28247 RgSchDlHqProcCb            *proc;
28248 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28249 #endif
28250 {
28251    RgSchCmnDlUe     *ueDl;
28252    RgSchDlRbAlloc   *allocInfo;
28253    uint8_t               numRb;
28254    uint8_t               noTxLyrs;
28255    uint8_t               precInfo;
28256    S16              ret;
28257    uint8_t               precInfoAntIdx;
28258
28259
28260    ret = ROK;
28261    ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
28262    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28263
28264    /* Integration_fix: SPS Proc shall always have only one Cw */
28265 #ifdef LTEMAC_SPS
28266 #ifdef FOUR_TX_ANTENNA
28267       if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28268                      (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
28269 #else
28270    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28271          (ueDl->mimoInfo.forceTD))
28272 #endif
28273 #else
28274    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
28275 #endif
28276    {
28277       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
28278             &allocInfo->raType);
28279       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28280             bo, &numRb, effBo);
28281       if (ret == RFAILED)
28282       {
28283          /* If allocation couldn't be made then return */
28284          return;
28285       }
28286       noTxLyrs = 1;
28287       precInfo = 0; /* TD */
28288    }
28289    else /* Precoding */
28290    {
28291       allocInfo->dciFormat = TFU_DCI_FORMAT_2A;
28292       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
28293
28294       /* Spatial Multiplexing using 2 CWs */
28295       ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
28296       if (ret == RFAILED)
28297       {
28298          /* If allocation couldn't be made then return */
28299          return;
28300       }
28301       noTxLyrs = ueDl->mimoInfo.ri;
28302       precInfoAntIdx = cell->numTxAntPorts/2 - 1;
28303       RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, getPrecInfoFunc[0], precInfoAntIdx);
28304       precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
28305    }
28306
28307 #ifdef LTEMAC_SPS
28308    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28309 #endif
28310    {
28311       /* Adding UE to RbAllocInfo TX Lst */
28312       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
28313    }
28314    /* Fill UE allocInfo scrath pad */
28315    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
28316          precInfo, noTxLyrs, subFrm);
28317
28318    return;
28319 }
28320
28321 \f
28322 /**
28323  * @brief This function handles Retx allocation in case of TM4 UEs
28324  *        where previously both the TBs were ACKED and ACKED
28325  *        respectively.
28326  *
28327  * @details
28328  *
28329  *     Function: rgSCHCmnDlTM4TxTx
28330  *     Purpose:  Reached here for a TM4 UE's HqP's fresh allocation
28331  *                  where both the TBs are free for TX scheduling.
28332  *               If forceTD flag is set
28333  *                  perform TD on CW1 with TB1.
28334  *                  precInfo = 0
28335  *               else
28336  *                  DCI Format = 2.
28337  *                  RA Type = Type0.
28338  *                  If Rank == 1
28339  *                     Single layer precoding of TB1 on CW1.
28340  *                     Set precoding info.
28341  *                  else
28342  *                     RI layered precoding 2 TB on 2 CW.
28343  *                     Set precoding info.
28344  *               Add UE to cellAllocInfo.
28345  *               Fill ueAllocInfo.
28346  *
28347  *              effBo is set to a non-zero value if allocation is
28348  *              successful.
28349  *
28350  *     Invoked by: rgSCHCmnDlAllocRbTM4
28351  *
28352  *  @param[in]  RgSchCellCb           *cell
28353  *  @param[in]  RgSchDlSf             *subFrm
28354  *  @param[in]  RgSchUeCb             *ue
28355  *  @param[in]  uint32_t                   bo
28356  *  @param[out] uint32_t                   *effBo
28357  *  @param[in]  RgSchDlHqProcCb       *proc
28358  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28359  *  @return  Void
28360  *
28361  **/
28362 #ifdef ANSI
28363 static Void rgSCHCmnDlTM4TxTx
28364 (
28365 RgSchCellCb                *cell,
28366 RgSchDlSf                  *subFrm,
28367 RgSchUeCb                  *ue,
28368 uint32_t                        bo,
28369 uint32_t                        *effBo,
28370 RgSchDlHqProcCb            *proc,
28371 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28372 )
28373 #else
28374 static Void rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28375 RgSchCellCb                *cell;
28376 RgSchDlSf                  *subFrm;
28377 RgSchUeCb                  *ue;
28378 uint32_t                        bo;
28379 uint32_t                        *effBo;
28380 RgSchDlHqProcCb            *proc;
28381 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28382 #endif
28383 {
28384    RgSchCmnDlUe     *ueDl;
28385    RgSchDlRbAlloc   *allocInfo;
28386    uint8_t               numRb;
28387    uint8_t               precInfo;
28388    uint8_t               noTxLyrs;
28389    uint8_t               precInfoAntIdx;
28390    S16              ret;
28391
28392
28393    ret       = ROK;
28394    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
28395    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28396
28397    /* Integration_fix: SPS Proc shall always have only one Cw */
28398 #ifdef LTEMAC_SPS
28399 #ifdef FOUR_TX_ANTENNA
28400    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28401                   (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */
28402 #else
28403    if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) ||
28404          (ueDl->mimoInfo.forceTD))
28405 #endif
28406 #else
28407    if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */
28408 #endif
28409    {
28410       allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \
28411             &allocInfo->raType);
28412
28413       ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28414             bo, &numRb, effBo);
28415       if (ret == RFAILED)
28416       {
28417          /* If allocation couldn't be made then return */
28418          return;
28419       }
28420       noTxLyrs = 1;
28421       precInfo = 0; /* TD */
28422    }
28423    else /* Precoding */
28424    {
28425       allocInfo->dciFormat = TFU_DCI_FORMAT_2;
28426       allocInfo->raType    = RG_SCH_CMN_RA_TYPE0;
28427
28428       if (ueDl->mimoInfo.ri == 1)
28429       {
28430          /* Single Layer SM using FORMAT 2 */
28431          ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28432                bo, &numRb, effBo);
28433          if (ret == RFAILED)
28434          {
28435             /* If allocation couldn't be made then return */
28436             return;
28437          }
28438          noTxLyrs = 1;
28439          precInfo = 0; /* PrecInfo as 0 for RI=1*/
28440       }
28441       else
28442       {
28443          /* Spatial Multiplexing using 2 CWs */
28444          ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo);
28445          if (ret == RFAILED)
28446          {
28447             /* If allocation couldn't be made then return */
28448             return;
28449          }
28450          noTxLyrs = ueDl->mimoInfo.ri;
28451          precInfoAntIdx = cell->numTxAntPorts/2 - 1; 
28452          precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE);
28453       }
28454    }
28455
28456    
28457 #ifdef LTEMAC_SPS
28458    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28459 #endif
28460    {
28461       /* Adding UE to RbAllocInfo TX Lst */
28462       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
28463    }
28464
28465    /* Fill UE allocInfo scrath pad */
28466    RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \
28467          precInfo, noTxLyrs, subFrm);
28468
28469    return;
28470 }
28471
28472 \f
28473 /**
28474  * @brief This function determines the RBs and Bytes required for BO
28475  *        transmission for UEs configured with TM 4.
28476  *
28477  * @details
28478  *
28479  *     Function: rgSCHCmnDlAllocTxRbTM4
28480  *     Purpose:  Invokes the functionality particular to the
28481  *               current state of the TBs of the "proc".
28482  *
28483  *               Reference Parameter effBo is filled with alloced bytes.
28484  *               Returns RFAILED if BO not satisfied at all.
28485  *
28486  *     Invoked by: rgSCHCmnDlAllocTxRb
28487  *
28488  *  @param[in]  RgSchCellCb           *cell
28489  *  @param[in]  RgSchDlSf             *subFrm
28490  *  @param[in]  RgSchUeCb             *ue
28491  *  @param[in]  uint32_t                   bo
28492  *  @param[out] uint32_t                   *effBo
28493  *  @param[in]  RgSchDlHqProcCb       *proc
28494  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28495  *  @return  Void
28496  *
28497  **/
28498 #ifdef ANSI
28499 static Void rgSCHCmnDlAllocTxRbTM4
28500 (
28501 RgSchCellCb                *cell,
28502 RgSchDlSf                  *subFrm,
28503 RgSchUeCb                  *ue,
28504 uint32_t                        bo,
28505 uint32_t                        *effBo,
28506 RgSchDlHqProcCb            *proc,
28507 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28508 )
28509 #else
28510 static Void rgSCHCmnDlAllocTxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28511 RgSchCellCb                *cell;
28512 RgSchDlSf                  *subFrm;
28513 RgSchUeCb                  *ue;
28514 uint32_t                        bo;
28515 uint32_t                        *effBo;
28516 RgSchDlHqProcCb            *proc;
28517 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28518 #endif
28519 {
28520
28521    /* Both TBs free for TX allocation */
28522    rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo,\
28523          proc, cellWdAllocInfo);
28524
28525    return;
28526 }
28527
28528 \f
28529 /**
28530  * @brief This function determines the RBs and Bytes required for BO
28531  *        retransmission for UEs configured with TM 4.
28532  *
28533  * @details
28534  *
28535  *     Function: rgSCHCmnDlAllocRetxRbTM4
28536  *     Purpose:  Invokes the functionality particular to the
28537  *               current state of the TBs of the "proc".
28538  *
28539  *               Reference Parameter effBo is filled with alloced bytes.
28540  *               Returns RFAILED if BO not satisfied at all.
28541  *
28542  *     Invoked by: rgSCHCmnDlAllocRetxRb
28543  *
28544  *  @param[in]  RgSchCellCb           *cell
28545  *  @param[in]  RgSchDlSf             *subFrm
28546  *  @param[in]  RgSchUeCb             *ue
28547  *  @param[in]  uint32_t                   bo
28548  *  @param[out] uint32_t                   *effBo
28549  *  @param[in]  RgSchDlHqProcCb       *proc
28550  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28551  *  @return  Void
28552  *
28553  **/
28554 #ifdef ANSI
28555 static Void rgSCHCmnDlAllocRetxRbTM4
28556 (
28557 RgSchCellCb                *cell,
28558 RgSchDlSf                  *subFrm,
28559 RgSchUeCb                  *ue,
28560 uint32_t                        bo,
28561 uint32_t                        *effBo,
28562 RgSchDlHqProcCb            *proc,
28563 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28564 )
28565 #else
28566 static Void rgSCHCmnDlAllocRetxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28567 RgSchCellCb                *cell;
28568 RgSchDlSf                  *subFrm;
28569 RgSchUeCb                  *ue;
28570 uint32_t                        bo;
28571 uint32_t                        *effBo;
28572 RgSchDlHqProcCb            *proc;
28573 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28574 #endif
28575 {
28576
28577    if ((proc->tbInfo[0].state == HQ_TB_NACKED) &&
28578          (proc->tbInfo[1].state == HQ_TB_NACKED))
28579    {
28580       /* Both TBs require RETX allocation */
28581       rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo,\
28582             proc, cellWdAllocInfo);
28583    }
28584    else
28585    {
28586       /* One of the TBs need RETX allocation. Other TB may/maynot
28587        * be available for new TX allocation. */
28588       rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo,\
28589             proc, cellWdAllocInfo);
28590    }
28591
28592    return;
28593 }
28594
28595 #ifdef RG_UNUSED
28596 \f
28597 /**
28598  * @brief This function determines the RBs and Bytes required for BO
28599  *        transmission for UEs configured with TM 5.
28600  *
28601  * @details
28602  *
28603  *     Function: rgSCHCmnDlAllocTxRbTM5
28604  *     Purpose:
28605  *
28606  *               Reference Parameter effBo is filled with alloced bytes.
28607  *               Returns RFAILED if BO not satisfied at all.
28608  *
28609  *     Invoked by: rgSCHCmnDlAllocTxRb
28610  *
28611  *  @param[in]  RgSchCellCb           *cell
28612  *  @param[in]  RgSchDlSf             *subFrm
28613  *  @param[in]  RgSchUeCb             *ue
28614  *  @param[in]  uint32_t                   bo
28615  *  @param[out] uint32_t                   *effBo
28616  *  @param[in]  RgSchDlHqProcCb       *proc
28617  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28618  *  @return Void
28619  *
28620  **/
28621 #ifdef ANSI
28622 static Void rgSCHCmnDlAllocTxRbTM5
28623 (
28624 RgSchCellCb                *cell,
28625 RgSchDlSf                  *subFrm,
28626 RgSchUeCb                  *ue,
28627 uint32_t                        bo,
28628 uint32_t                        *effBo,
28629 RgSchDlHqProcCb            *proc,
28630 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28631 )
28632 #else
28633 static Void rgSCHCmnDlAllocTxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28634 RgSchCellCb                *cell;
28635 RgSchDlSf                  *subFrm;
28636 RgSchUeCb                  *ue;
28637 uint32_t                        bo;
28638 uint32_t                        *effBo;
28639 RgSchDlHqProcCb            *proc;
28640 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28641 #endif
28642 {
28643 #if (ERRCLASS & ERRCLS_DEBUG)
28644    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId);
28645 #endif
28646    return;
28647 }
28648
28649 \f
28650 /**
28651  * @brief This function determines the RBs and Bytes required for BO
28652  *        retransmission for UEs configured with TM 5.
28653  *
28654  * @details
28655  *
28656  *     Function: rgSCHCmnDlAllocRetxRbTM5
28657  *     Purpose:
28658  *
28659  *               Reference Parameter effBo is filled with alloced bytes.
28660  *               Returns RFAILED if BO not satisfied at all.
28661  *
28662  *     Invoked by: rgSCHCmnDlAllocRetxRb
28663  *
28664  *  @param[in]  RgSchCellCb           *cell
28665  *  @param[in]  RgSchDlSf             *subFrm
28666  *  @param[in]  RgSchUeCb             *ue
28667  *  @param[in]  uint32_t                   bo
28668  *  @param[out] uint32_t                   *effBo
28669  *  @param[in]  RgSchDlHqProcCb       *proc
28670  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28671  *  @return Void
28672  *
28673  **/
28674 #ifdef ANSI
28675 static Void rgSCHCmnDlAllocRetxRbTM5
28676 (
28677 RgSchCellCb                *cell,
28678 RgSchDlSf                  *subFrm,
28679 RgSchUeCb                  *ue,
28680 uint32_t                        bo,
28681 uint32_t                        *effBo,
28682 RgSchDlHqProcCb            *proc,
28683 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28684 )
28685 #else
28686 static Void rgSCHCmnDlAllocRetxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28687 RgSchCellCb                *cell;
28688 RgSchDlSf                  *subFrm;
28689 RgSchUeCb                  *ue;
28690 uint32_t                        bo;
28691 uint32_t                        *effBo;
28692 RgSchDlHqProcCb            *proc;
28693 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28694 #endif
28695 {
28696 #if (ERRCLASS & ERRCLS_DEBUG)
28697    RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId);
28698 #endif
28699    return;
28700 }
28701 #endif
28702
28703 \f
28704 /**
28705  * @brief This function determines the RBs and Bytes required for BO
28706  *        transmission for UEs configured with TM 6.
28707  *
28708  * @details
28709  *
28710  *     Function: rgSCHCmnDlAllocTxRbTM6
28711  *     Purpose:
28712  *
28713  *               Reference Parameter effBo is filled with alloced bytes.
28714  *               Returns RFAILED if BO not satisfied at all.
28715  *
28716  *     Invoked by: rgSCHCmnDlAllocTxRb
28717  *
28718  *  @param[in]  RgSchCellCb           *cell
28719  *  @param[in]  RgSchDlSf             *subFrm
28720  *  @param[in]  RgSchUeCb             *ue
28721  *  @param[in]  uint32_t                   bo
28722  *  @param[out] uint32_t                   *effBo
28723  *  @param[in]  RgSchDlHqProcCb       *proc
28724  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28725  *  @return Void
28726  *
28727  **/
28728 #ifdef ANSI
28729 static Void rgSCHCmnDlAllocTxRbTM6
28730 (
28731 RgSchCellCb                *cell,
28732 RgSchDlSf                  *subFrm,
28733 RgSchUeCb                  *ue,
28734 uint32_t                        bo,
28735 uint32_t                        *effBo,
28736 RgSchDlHqProcCb            *proc,
28737 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28738 )
28739 #else
28740 static Void rgSCHCmnDlAllocTxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28741 RgSchCellCb                *cell;
28742 RgSchDlSf                  *subFrm;
28743 RgSchUeCb                  *ue;
28744 uint32_t                        bo;
28745 uint32_t                        *effBo;
28746 RgSchDlHqProcCb            *proc;
28747 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28748 #endif
28749 {
28750    RgSchDlRbAlloc *allocInfo;
28751    RgSchCmnDlUe   *ueDl;
28752    S16            ret;
28753    uint8_t             numRb;
28754
28755
28756    ret       = ROK;
28757    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
28758    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28759
28760    if (ueDl->mimoInfo.forceTD)
28761    {
28762       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
28763       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
28764    }
28765    else
28766    {
28767       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
28768       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
28769       /* Fill precoding information for FORMAT 1B */
28770       /* First 4 least significant bits to indicate PMI.
28771        * 4th most significant corresponds to pmi Confirmation.
28772        */
28773       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
28774       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
28775    }
28776    ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\
28777          bo, &numRb, effBo);
28778    if (ret == RFAILED)
28779    {
28780       /* If allocation couldn't be made then return */
28781       return;
28782    }
28783    
28784 #ifdef LTEMAC_SPS
28785    if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc))
28786 #endif
28787    {
28788       /* Adding UE to RbAllocInfo TX Lst */
28789       rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc);
28790    }
28791    /* Fill UE alloc Info */
28792    allocInfo->rbsReq = numRb;
28793    allocInfo->dlSf   = subFrm;
28794    return;
28795 }
28796
28797 \f
28798 /**
28799  * @brief This function determines the RBs and Bytes required for BO
28800  *        retransmission for UEs configured with TM 6.
28801  *
28802  * @details
28803  *
28804  *     Function: rgSCHCmnDlAllocRetxRbTM6
28805  *     Purpose:
28806  *
28807  *               Reference Parameter effBo is filled with alloced bytes.
28808  *               Returns RFAILED if BO not satisfied at all.
28809  *
28810  *     Invoked by: rgSCHCmnDlAllocRetxRb
28811  *
28812  *  @param[in]  RgSchCellCb           *cell
28813  *  @param[in]  RgSchDlSf             *subFrm
28814  *  @param[in]  RgSchUeCb             *ue
28815  *  @param[in]  uint32_t                   bo
28816  *  @param[out] uint32_t                   *effBo
28817  *  @param[in]  RgSchDlHqProcCb       *proc
28818  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28819  *  @return Void
28820  *
28821  **/
28822 #ifdef ANSI
28823 static Void rgSCHCmnDlAllocRetxRbTM6
28824 (
28825 RgSchCellCb                *cell,
28826 RgSchDlSf                  *subFrm,
28827 RgSchUeCb                  *ue,
28828 uint32_t                        bo,
28829 uint32_t                        *effBo,
28830 RgSchDlHqProcCb            *proc,
28831 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28832 )
28833 #else
28834 static Void rgSCHCmnDlAllocRetxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28835 RgSchCellCb                *cell;
28836 RgSchDlSf                  *subFrm;
28837 RgSchUeCb                  *ue;
28838 uint32_t                        bo;
28839 uint32_t                        *effBo;
28840 RgSchDlHqProcCb            *proc;
28841 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28842 #endif
28843 {
28844    RgSchDlRbAlloc *allocInfo;
28845    RgSchCmnDlUe   *ueDl;
28846    S16            ret;
28847    uint8_t             numRb;
28848
28849
28850    ret       = ROK;
28851    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
28852    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
28853
28854    if (ueDl->mimoInfo.forceTD)
28855    {
28856       allocInfo->dciFormat = TFU_DCI_FORMAT_1A;
28857       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
28858    }
28859    else
28860    {
28861       allocInfo->dciFormat = TFU_DCI_FORMAT_1B;
28862       allocInfo->raType    = RG_SCH_CMN_RA_TYPE2;
28863       /* Fill precoding information for FORMAT 1B */
28864       /* First 4 least significant bits to indicate PMI.
28865        * 4th most significant corresponds to pmi Confirmation.
28866        */
28867       allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4;
28868       allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi;
28869    }
28870
28871    /* Get the Allocation in terms of RBs that are required for
28872     * this retx of TB1 */
28873    ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0],
28874          1, &numRb, effBo);
28875    if (ret == RFAILED)
28876    {
28877       /* Allocation couldn't be made for Retx */
28878       rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc);
28879       return;
28880    }
28881    /* Adding UE to allocInfo RETX Lst */
28882    rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc);
28883    /* Fill UE alloc Info */
28884    allocInfo->rbsReq = numRb;
28885    allocInfo->dlSf   = subFrm;
28886    return;
28887 }
28888
28889 \f
28890 /**
28891  * @brief This function determines the RBs and Bytes required for BO
28892  *        transmission for UEs configured with TM 7.
28893  *
28894  * @details
28895  *
28896  *     Function: rgSCHCmnDlAllocTxRbTM7
28897  *     Purpose:
28898  *
28899  *               Reference Parameter effBo is filled with alloced bytes.
28900  *               Returns RFAILED if BO not satisfied at all.
28901  *
28902  *     Invoked by: rgSCHCmnDlAllocTxRb
28903  *
28904  *  @param[in]  RgSchCellCb           *cell
28905  *  @param[in]  RgSchDlSf             *subFrm
28906  *  @param[in]  RgSchUeCb             *ue
28907  *  @param[in]  uint32_t                   bo
28908  *  @param[out] uint32_t                   *effBo
28909  *  @param[in]  RgSchDlHqProcCb       *proc
28910  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28911  *  @return Void
28912  *
28913  **/
28914 #ifdef ANSI
28915 static Void rgSCHCmnDlAllocTxRbTM7
28916 (
28917 RgSchCellCb                *cell,
28918 RgSchDlSf                  *subFrm,
28919 RgSchUeCb                  *ue,
28920 uint32_t                        bo,
28921 uint32_t                        *effBo,
28922 RgSchDlHqProcCb            *proc,
28923 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28924 )
28925 #else
28926 static Void rgSCHCmnDlAllocTxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28927 RgSchCellCb                *cell;
28928 RgSchDlSf                  *subFrm;
28929 RgSchUeCb                  *ue;
28930 uint32_t                        bo;
28931 uint32_t                        *effBo;
28932 RgSchDlHqProcCb            *proc;
28933 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28934 #endif
28935 {
28936    rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
28937    return;
28938 }
28939
28940 \f
28941 /**
28942  * @brief This function determines the RBs and Bytes required for BO
28943  *        retransmission for UEs configured with TM 7.
28944  *
28945  * @details
28946  *
28947  *     Function: rgSCHCmnDlAllocRetxRbTM7
28948  *     Purpose:
28949  *
28950  *               Reference Parameter effBo is filled with alloced bytes.
28951  *               Returns RFAILED if BO not satisfied at all.
28952  *
28953  *     Invoked by: rgSCHCmnDlAllocRetxRb
28954  *
28955  *  @param[in]  RgSchCellCb           *cell
28956  *  @param[in]  RgSchDlSf             *subFrm
28957  *  @param[in]  RgSchUeCb             *ue
28958  *  @param[in]  uint32_t                   bo
28959  *  @param[out] uint32_t                   *effBo
28960  *  @param[in]  RgSchDlHqProcCb       *proc
28961  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
28962  *  @return Void
28963  *
28964  **/
28965 #ifdef ANSI
28966 static Void rgSCHCmnDlAllocRetxRbTM7
28967 (
28968 RgSchCellCb                *cell,
28969 RgSchDlSf                  *subFrm,
28970 RgSchUeCb                  *ue,
28971 uint32_t                        bo,
28972 uint32_t                        *effBo,
28973 RgSchDlHqProcCb            *proc,
28974 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
28975 )
28976 #else
28977 static Void rgSCHCmnDlAllocRetxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
28978 RgSchCellCb                *cell;
28979 RgSchDlSf                  *subFrm;
28980 RgSchUeCb                  *ue;
28981 uint32_t                        bo;
28982 uint32_t                        *effBo;
28983 RgSchDlHqProcCb            *proc;
28984 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
28985 #endif
28986 {
28987    rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo);
28988    return;
28989 }
28990
28991 \f
28992 /**
28993  * @brief This function invokes the TM specific DL TX RB Allocation routine.
28994  *
28995  * @details
28996  *
28997  *     Function: rgSCHCmnDlAllocTxRb
28998  *     Purpose:  This function invokes the TM specific
28999  *               DL TX RB Allocation routine.
29000  *
29001  *     Invoked by: Specific Schedulers
29002  *
29003  *  @param[in]  RgSchCellCb           *cell
29004  *  @param[in]  RgSchDlSf             *subFrm
29005  *  @param[in]  RgSchUeCb             *ue
29006  *  @param[in]  uint32_t                   bo
29007  *  @param[out] uint32_t                   *effBo
29008  *  @param[in]  RgSchDlHqProcCb       *proc
29009  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29010  *  @return  S16
29011  *
29012  **/
29013 #ifdef ANSI
29014 S16 rgSCHCmnDlAllocTxRb
29015 (
29016 RgSchCellCb                *cell,
29017 RgSchDlSf                  *subFrm,
29018 RgSchUeCb                  *ue,
29019 uint32_t                        bo,
29020 uint32_t                        *effBo,
29021 RgSchDlHqProcCb            *proc,
29022 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29023 )
29024 #else
29025 S16 rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29026 RgSchCellCb                *cell;
29027 RgSchDlSf                  *subFrm;
29028 RgSchUeCb                  *ue;
29029 uint32_t                        bo;
29030 uint32_t                        *effBo;
29031 RgSchDlHqProcCb            *proc;
29032 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29033 #endif
29034 {
29035    uint32_t                     newSchBits = 0;
29036    uint32_t                     prevSchBits = 0;
29037    RgSchDlRbAlloc          *allocInfo;
29038
29039
29040    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
29041    {
29042       ue->dl.aggTbBits = 0;
29043    }
29044    *effBo = 0;
29045
29046    /* Calculate totals bits previously allocated */
29047    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29048    if (allocInfo->tbInfo[0].schdlngForTb)
29049    {
29050       prevSchBits += allocInfo->tbInfo[0].bytesReq;
29051    }
29052    if (allocInfo->tbInfo[1].schdlngForTb)
29053    {
29054       prevSchBits += allocInfo->tbInfo[1].bytesReq;
29055    }
29056
29057    /* Call TM specific RB allocation routine */
29058    (dlAllocTxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
29059          proc, cellWdAllocInfo);
29060
29061    if (*effBo)
29062    {
29063       /* Calculate totals bits newly allocated */
29064       if (allocInfo->tbInfo[0].schdlngForTb)
29065       {
29066          newSchBits += allocInfo->tbInfo[0].bytesReq;
29067       }
29068       if (allocInfo->tbInfo[1].schdlngForTb)
29069       {
29070          newSchBits += allocInfo->tbInfo[1].bytesReq;
29071       }
29072       if (newSchBits > prevSchBits)
29073       {
29074          ue->dl.aggTbBits += ((newSchBits - prevSchBits) * 8);
29075          RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
29076       }
29077    }
29078
29079    return ROK;
29080 }
29081
29082 /* DwPTS Scheduling Changes Start */
29083 #ifdef LTE_TDD
29084 /**
29085  * @brief Retransmit decision for TDD. Retx is avoided in below cases
29086  *        1) DL Sf       -> Spl Sf
29087  *        2) DL SF       -> DL SF 0 
29088  *
29089  * @details
29090  *
29091  *     Function: rgSCHCmnRetxAvoidTdd 
29092  *     Purpose: Avoid allocating RETX for cases 1, 2 
29093  * 
29094  *     Invoked by: rgSCHCmnRetxAvoidTdd 
29095  *
29096  *  @param[in]  RgSchDlSf             *curSf
29097  *  @param[in]  RgSchCellCb           *cell
29098  *  @param[in]  RgSchDlHqProcCb       *proc
29099  *  @return  Bool 
29100  *
29101  **/
29102 #ifdef ANSI
29103 Bool rgSCHCmnRetxAvoidTdd 
29104 (
29105 RgSchDlSf                  *curSf,
29106 RgSchCellCb                *cell,
29107 RgSchDlHqProcCb            *proc
29108 )
29109 #else
29110 Bool rgSCHCmnRetxAvoidTdd(curSf, cell, proc)
29111 RgSchDlSf                  *curSf;
29112 RgSchCellCb                *cell;
29113 RgSchDlHqProcCb            *proc;
29114 #endif
29115 {
29116    RgSchTddSfType   txSfType = 0;
29117
29118
29119    /* Get the RBs of TB that will be retransmitted */
29120    if (proc->tbInfo[0].state == HQ_TB_NACKED)
29121    {
29122       txSfType = proc->tbInfo[0].sfType;
29123
29124 #ifdef XEON_SPECIFIC_CHANGES
29125 #ifndef XEON_TDD_SPCL
29126       /* Avoid re-transmission on Normal SF when the corresponding TB wss transmitted on SPCL SF */
29127       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
29128       {
29129          return (TRUE);
29130       }
29131 #endif
29132 #endif
29133    }
29134    if (proc->tbInfo[1].state == HQ_TB_NACKED) 
29135    {
29136       /* Select the TxSf with the highest num of possible REs 
29137        * In ascending order -> 1) SPL SF 2) DL_SF_0 3) DL_SF */
29138       txSfType = RGSCH_MAX(txSfType, proc->tbInfo[1].sfType);
29139
29140 #ifdef XEON_SPECIFIC_CHANGES
29141 #ifndef XEON_TDD_SPCL
29142       /* Avoid re-transmission on Normal SF when the corresponding TB wss tranmitted on SPCL SF */
29143       if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0)
29144       {
29145          return (TRUE);
29146       }
29147 #endif
29148 #endif
29149    }
29150
29151    if (txSfType > curSf->sfType)
29152    {
29153       /* Avoid retx */
29154       return (TRUE);
29155    }
29156    
29157    /* Allow Retx */
29158    return (FALSE);
29159 }
29160
29161 #else
29162 /* DwPTS Scheduling Changes End */
29163 \f
29164 /**
29165  * @brief Avoid allocating RETX incase of collision
29166  * with reserved resources for BCH/PSS/SSS occassions.
29167  *
29168  * @details
29169  *
29170  *     Function: rgSCHCmnRetxAllocAvoid 
29171  *     Purpose: Avoid allocating RETX incase of collision
29172  * with reserved resources for BCH/PSS/SSS occassions 
29173  *
29174  *     Invoked by: rgSCHCmnDlAllocRetxRb 
29175  *
29176  *  @param[in]  RgSchDlSf             *subFrm
29177  *  @param[in]  RgSchUeCb             *ue
29178  *  @param[in]  RgSchDlHqProcCb       *proc
29179  *  @return  Bool 
29180  *
29181  **/
29182 #ifdef ANSI
29183 Bool rgSCHCmnRetxAllocAvoid 
29184 (
29185 RgSchDlSf                  *subFrm,
29186 RgSchCellCb                *cell,
29187 RgSchDlHqProcCb            *proc
29188 )
29189 #else
29190 Bool rgSCHCmnRetxAllocAvoid(subFrm, cell, proc)
29191 RgSchDlSf                  *subFrm;
29192 RgSchCellCb                *cell;
29193 RgSchDlHqProcCb            *proc;
29194 #endif
29195 {
29196    uint8_t          reqRbs;
29197
29198
29199    if (proc->tbInfo[0].state == HQ_TB_NACKED)
29200    {
29201       reqRbs = proc->tbInfo[0].dlGrnt.numRb;    
29202    }
29203    else
29204    {
29205       reqRbs = proc->tbInfo[1].dlGrnt.numRb;    
29206    }
29207    /* Consider the dlGrnt.numRb of the Retransmitting proc->tbInfo
29208     * and current available RBs to determine if this RETX TB
29209     * will collide with the BCH/PSS/SSS occassion */
29210    if (subFrm->sfNum % 5 == 0)
29211    {
29212       if ((subFrm->bwAssigned < cell->pbchRbEnd) &&
29213           (((subFrm->bwAssigned + reqRbs) - cell->pbchRbStart) > 0))
29214       {
29215          return (TRUE);
29216       }
29217    }
29218    return (FALSE);
29219 }
29220
29221 #endif
29222
29223 \f
29224 /**
29225  * @brief This function invokes the TM specific DL RETX RB Allocation routine.
29226  *
29227  * @details
29228  *
29229  *     Function: rgSCHCmnDlAllocRetxRb
29230  *     Purpose:  This function invokes the TM specific
29231  *               DL RETX RB Allocation routine.
29232  *
29233  *     Invoked by: Specific Schedulers
29234  *
29235  *  @param[in]  RgSchCellCb           *cell
29236  *  @param[in]  RgSchDlSf             *subFrm
29237  *  @param[in]  RgSchUeCb             *ue
29238  *  @param[in]  uint32_t                   bo
29239  *  @param[out] uint32_t                   *effBo
29240  *  @param[in]  RgSchDlHqProcCb       *proc
29241  *  @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo
29242  *  @return  S16
29243  *
29244  **/
29245 #ifdef ANSI
29246 S16 rgSCHCmnDlAllocRetxRb
29247 (
29248 RgSchCellCb                *cell,
29249 RgSchDlSf                  *subFrm,
29250 RgSchUeCb                  *ue,
29251 uint32_t                        bo,
29252 uint32_t                        *effBo,
29253 RgSchDlHqProcCb            *proc,
29254 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo
29255 )
29256 #else
29257 S16 rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo)
29258 RgSchCellCb                *cell;
29259 RgSchDlSf                  *subFrm;
29260 RgSchUeCb                  *ue;
29261 uint32_t                        bo;
29262 uint32_t                        *effBo;
29263 RgSchDlHqProcCb            *proc;
29264 RgSchCmnDlRbAllocInfo      *cellWdAllocInfo;
29265 #endif
29266 {
29267    uint32_t                     newSchBits = 0;
29268    RgSchDlRbAlloc          *allocInfo;
29269
29270
29271    if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) ))
29272    {
29273       ue->dl.aggTbBits = 0;
29274    }
29275  
29276    *effBo = 0;
29277    /* Check for DL BW exhaustion */
29278    if (subFrm->bw <= subFrm->bwAssigned)
29279    {
29280       return RFAILED;
29281    }
29282    /* Call TM specific RB allocation routine */
29283    (dlAllocRetxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \
29284          proc, cellWdAllocInfo);
29285
29286    if (*effBo)
29287    {
29288       allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29289       /* Calculate totals bits newly allocated */
29290       if (allocInfo->tbInfo[0].schdlngForTb)
29291       {
29292          newSchBits += allocInfo->tbInfo[0].bytesReq;
29293       }
29294       if (allocInfo->tbInfo[1].schdlngForTb)
29295       {
29296          newSchBits += allocInfo->tbInfo[1].bytesReq;
29297       }
29298       ue->dl.aggTbBits += (newSchBits * 8);
29299       RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime))
29300    }
29301    
29302    return ROK;
29303 }
29304
29305 \f
29306 /**
29307  * @brief This function determines the RBs and Bytes required for
29308  *        Transmission on 1 CW.
29309  *
29310  * @details
29311  *
29312  *     Function: rgSCHCmnDlAlloc1CwTxRb
29313  *     Purpose:  This function determines the RBs and Bytes required
29314  *               for Transmission of DL SVC BO on 1 CW.
29315  *               Also, takes care of SVC by SVC allocation by tracking
29316  *               previous SVCs allocations.
29317  *               Returns RFAILED if BO not satisfied at all.
29318  *
29319  *     Invoked by: DL UE Allocation
29320  *
29321  *  @param[in]  RgSchCellCb      *cell
29322  *  @param[in]  RgSchDlSf        *subFrm
29323  *  @param[in]  RgSchUeCb        *ue
29324  *  @param[in]  RgSchDlHqTbCb    *tbInfo
29325  *  @param[in]  uint32_t              bo
29326  *  @param[out] uint8_t               *numRb
29327  *  @param[out] uint32_t              *effBo
29328  *  @return  S16
29329  *
29330  **/
29331 #ifdef ANSI
29332 static S16 rgSCHCmnDlAlloc1CwTxRb
29333 (
29334 RgSchCellCb                *cell,
29335 RgSchDlSf                  *subFrm,
29336 RgSchUeCb                  *ue,
29337 RgSchDlHqTbCb              *tbInfo,
29338 uint32_t                        bo,
29339 uint8_t                         *numRb,
29340 uint32_t                        *effBo
29341 )
29342 #else
29343 static S16 rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, tbInfo, bo, numRb, effBo)
29344 RgSchCellCb                *cell;
29345 RgSchDlSf                  *subFrm;
29346 RgSchUeCb                  *ue;
29347 RgSchDlHqTbCb              *tbInfo;
29348 uint32_t                        bo;
29349 uint8_t                         *numRb;
29350 uint32_t                        *effBo;
29351 #endif
29352 {
29353    uint32_t                tbSz;
29354    uint8_t                 imcs;
29355    uint8_t                 iTbs;
29356    RgSchCmnDlUe       *ueDl;
29357    RgSchDlRbAlloc     *allocInfo;
29358    uint32_t                oldReq;
29359    uint32_t                reqBytes;
29360    /* Correcting wrap around issue.
29361     * This change has been done at mutliple places in this function.*/
29362    uint32_t                tempNumRb;
29363
29364    reqBytes  = bo;
29365    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29366    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29367    oldReq    = ueDl->outStndAlloc;
29368
29369 #ifdef RG_5GTF
29370    //TODO_SID: Currently setting max Tb size wrt to 5GTF TM3
29371    iTbs = ue->ue5gtfCb.mcs;
29372    ueDl->maxTbSz = MAX_5GTF_TB_SIZE * ue->ue5gtfCb.rank;
29373    ueDl->maxRb = MAX_5GTF_PRBS;
29374 #endif
29375    ueDl->outStndAlloc += bo;
29376    /* consider Cumulative amount of this BO and bytes so far allocated */
29377    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbSz/8);
29378    /* Get the number of REs needed for this bo. */
29379    //noRes = ((bo * 8 * 1024) / eff);
29380
29381    /* Get the number of RBs needed for this transmission */
29382    /* Number of RBs = No of REs / No of REs per RB       */
29383    //tempNumRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
29384    tempNumRb = MAX_5GTF_PRBS;
29385    tbSz = RGSCH_MIN(bo, (rgSch5gtfTbSzTbl[iTbs]/8) * ue->ue5gtfCb.rank);
29386
29387    /* DwPts Scheduling Changes End */
29388    *effBo = RGSCH_MIN(tbSz - oldReq, reqBytes);
29389
29390 #ifdef RG_5GTF
29391    //RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs);
29392    imcs = iTbs;
29393 #endif
29394
29395
29396    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbSz, \
29397          iTbs, imcs, tbInfo, ue->ue5gtfCb.rank);
29398    *numRb = (uint8_t) tempNumRb;
29399    
29400    /* Update the subframe Allocated BW field */
29401    subFrm->bwAssigned = subFrm->bwAssigned + tempNumRb - allocInfo->rbsReq;
29402    
29403    return ROK;
29404 }
29405
29406 \f
29407 /**
29408  * @brief This function is invoked in the event of any TB's allocation
29409  *  being underutilized by the specific scheduler. Here we reduce iMcs
29410  *  to increase redundancy and hence increase reception quality at UE.
29411  *
29412  * @details
29413  *
29414  *     Function: rgSCHCmnRdcImcsTxTb
29415  *     Purpose:  This function shall reduce the iMcs in accordance with
29416  *               the total consumed bytes by the UE at allocation
29417  *               finalization.
29418  *
29419  *     Invoked by: UE DL Allocation finalization routine
29420  *                 of specific scheduler.
29421  *
29422  *  @param[in]  RgSchDlRbAlloc   *allocInfo
29423  *  @param[in]  uint8_t               tbInfoIdx
29424  *  @param[in]  uint32_t              cnsmdBytes
29425  *  @return  Void
29426  *
29427  **/
29428 #ifdef ANSI
29429 Void rgSCHCmnRdcImcsTxTb
29430 (
29431 RgSchDlRbAlloc   *allocInfo,
29432 uint8_t               tbInfoIdx,
29433 uint32_t              cnsmdBytes
29434 )
29435 #else
29436 Void rgSCHCmnRdcImcsTxTb(allocInfo, tbInfoIdx, cnsmdBytes)
29437 RgSchDlRbAlloc   *allocInfo;
29438 uint8_t               tbInfoIdx;
29439 uint32_t              cnsmdBytes;
29440 #endif
29441 {
29442    return;
29443    /*The below functionality is not needed.*/
29444    uint8_t                 noLyr;
29445    uint8_t                 iTbs;
29446    uint16_t                numRb;
29447
29448
29449    iTbs = allocInfo->tbInfo[tbInfoIdx].iTbs;
29450    noLyr = allocInfo->tbInfo[tbInfoIdx].noLyr;
29451    numRb = allocInfo->rbsAlloc;
29452    if ( numRb > 0)
29453    {
29454       if ((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) == cnsmdBytes)
29455       {
29456          return;
29457       }
29458    }
29459    /* Get iTbs as suitable for the consumed bytes */
29460    while((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) > cnsmdBytes)
29461    {
29462       if (iTbs == 0)
29463       {
29464          RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].\
29465                tbCb->dlGrnt.iMcs);
29466          return;
29467       }
29468       iTbs--;
29469    }
29470    iTbs++;
29471    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].tbCb->dlGrnt.iMcs);
29472
29473    return;
29474 }
29475
29476 \f
29477 /**
29478  * @brief This function determines the RBs and Bytes required for
29479  *        Transmission on 2 CWs.
29480  *
29481  * @details
29482  *
29483  *     Function: rgSCHCmnDlAlloc2CwTxRb
29484  *     Purpose:  This function determines the RBs and Bytes required
29485  *               for Transmission of DL SVC BO on 2 CWs.
29486  *               Also, takes care of SVC by SVC allocation by tracking
29487  *               previous SVCs allocations.
29488  *               Returns RFAILED if BO not satisfied at all.
29489  *
29490  *     Invoked by: TM3 and TM4 DL UE Allocation
29491  *
29492  *  @param[in]  RgSchCellCb      *cell
29493  *  @param[in]  RgSchDlSf        *subFrm
29494  *  @param[in]  RgSchUeCb        *ue
29495  *  @param[in]  RgSchDlHqProcCb  *proc
29496  *  @param[in]  RgSchDlHqProcCb  bo
29497  *  @param[out] uint8_t               *numRb
29498  *  @param[out] uint32_t              *effBo
29499  *  @return  Void
29500  *
29501  **/
29502 #ifdef ANSI
29503 static S16 rgSCHCmnDlAlloc2CwTxRb
29504 (
29505 RgSchCellCb                *cell,
29506 RgSchDlSf                  *subFrm,
29507 RgSchUeCb                  *ue,
29508 RgSchDlHqProcCb            *proc,
29509 uint32_t                        bo,
29510 uint8_t                         *numRbRef,
29511 uint32_t                        *effBo
29512 )
29513 #else
29514 static S16 rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, numRbRef, effBo)
29515 RgSchCellCb                *cell;
29516 RgSchDlSf                  *subFrm;
29517 RgSchUeCb                  *ue;
29518 RgSchDlHqProcCb            *proc;
29519 uint32_t                        bo;
29520 uint8_t                         *numRbRef;
29521 uint32_t                        *effBo;
29522 #endif
29523 {
29524    uint32_t                noRes;
29525    uint32_t                eff1, eff2;
29526    uint32_t                tb1Sz, tb2Sz;
29527    uint8_t                 imcs1, imcs2;
29528    uint8_t                 noLyr1, noLyr2;
29529    uint8_t                 iTbs1, iTbs2;
29530    RgSchCmnDlCell     *cellDl;
29531    RgSchCmnDlUe       *ueDl;
29532    RgSchDlRbAlloc     *allocInfo;
29533    uint32_t                oldReq;
29534    uint32_t                reqBytes;
29535    /* Fix: MUE_PERTTI_DL */
29536    uint32_t                numRb;
29537    RgSchCmnCell       *cellSch = RG_SCH_CMN_GET_CELL(cell);
29538    uint8_t                 cfi = cellSch->dl.currCfi;
29539    S16                availBw; 
29540    uint32_t                availBits = 0;
29541 #ifdef LTE_ADV
29542    uint32_t                boTmp = bo;
29543 #endif
29544
29545
29546    reqBytes  = bo;
29547    cellDl    = RG_SCH_CMN_GET_DL_CELL(cell);
29548    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29549    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29550    oldReq    = ueDl->outStndAlloc;
29551
29552    
29553    if (ueDl->maxTbBits > ue->dl.aggTbBits)
29554    {
29555       availBits = ueDl->maxTbBits - ue->dl.aggTbBits;
29556    }
29557    /* check if we can further allocate to this UE */
29558    if ((ue->dl.aggTbBits >= ueDl->maxTbBits) ||
29559          (allocInfo->tbInfo[0].bytesReq >= ueDl->maxTbSz/8) ||
29560          (allocInfo->tbInfo[1].bytesReq >= ueDl->maxTbSz/8) ||
29561          (allocInfo->rbsReq >= ueDl->maxRb))
29562    {
29563       RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
29564             "rgSCHCmnDlAllocRb(): UEs max allocation exceed");
29565       return RFAILED;
29566    }
29567
29568    noLyr1 = ueDl->mimoInfo.cwInfo[0].noLyr;
29569    noLyr2 = ueDl->mimoInfo.cwInfo[1].noLyr;
29570
29571    /* If there is no CFI change, continue to use the BLER based
29572     * iTBS value */
29573    if (ueDl->lastCfi == cfi)
29574    {   
29575       iTbs1  = ueDl->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
29576       iTbs2  = ueDl->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
29577    }
29578    else
29579    {  
29580       uint8_t cqi = ueDl->mimoInfo.cwInfo[0].cqi;
29581 #ifdef LTE_TDD      
29582       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 0, noLyr1);
29583 #else      
29584       iTbs1 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 0, noLyr1);
29585 #endif         
29586
29587       cqi = ueDl->mimoInfo.cwInfo[1].cqi;
29588 #ifdef LTE_TDD      
29589       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 1, noLyr2);
29590 #else      
29591       iTbs2 = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 1, noLyr2);
29592 #endif         
29593    } 
29594
29595    /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure
29596     * issue for VoLTE call */
29597    //if ((proc->hasDcch)  || (TRUE == rgSCHLaaSCellEnabled(cell)))
29598    if (proc->hasDcch)
29599    {
29600       if (iTbs1 > 5)
29601       {
29602          iTbs1  = iTbs1 - 5;
29603       }
29604       else
29605       {
29606          iTbs1  = 0; 
29607       }
29608       if (iTbs2 > 5)
29609       {
29610          iTbs2  = iTbs2 - 5;
29611       }
29612       else
29613       {
29614          iTbs2  = 0; 
29615       }
29616    }
29617    else if(!cellSch->dl.isDlFreqSel)
29618    {
29619 #ifdef LTE_TDD
29620       /* for Tdd reduce iTbs only for SF0. SF5 contains only 
29621        * SSS and can be ignored */
29622       if (subFrm->sfNum == 0)
29623       {
29624          (iTbs1 > 1)? (iTbs1 -= 1) : (iTbs1 = 0);
29625          (iTbs2 > 1)? (iTbs2 -= 1) : (iTbs2 = 0);
29626       }
29627       /* For SF 3 and 8 CRC is getting failed in DL.
29628          Need to do proper fix after the replay from 
29629          BRCM PHY team*/
29630 #ifdef CA_PHY_BRDCM_61765      
29631       if ((subFrm->sfNum == 3) || (subFrm->sfNum == 8))
29632       {
29633          (iTbs1 > 2)? (iTbs1 -= 2) : (iTbs1 = 0);
29634          (iTbs2 > 2)? (iTbs2 -= 2) : (iTbs2 = 0);
29635       }
29636 #endif
29637 #else
29638 #endif
29639    }
29640
29641 #ifdef LTE_TDD
29642    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
29643    {
29644       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
29645    }
29646 #endif 
29647
29648    eff1 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
29649    eff2 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
29650
29651
29652    bo = RGSCH_MIN(bo,availBits/8);
29653    ueDl->outStndAlloc += bo;
29654    /* consider Cumulative amount of this BO and bytes so far allocated */
29655    bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbBits/8);
29656    bo = RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff1)/(eff1+eff2)), 
29657                   ueDl->maxTbSz/8) +
29658         RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff2)/(eff1+eff2)), 
29659                   (ueDl->maxTbSz)/8) +
29660         1; /* Add 1 to adjust the truncation at weighted averaging */
29661    /* Get the number of REs needed for this bo. */
29662    noRes = ((bo * 8 * 1024) / (eff1 + eff2));
29663
29664    /* Get the number of RBs needed for this transmission */
29665    /* Number of RBs = No of REs / No of REs per RB       */
29666    numRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]);
29667    /* Cannot exceed the maximum number of RBs per UE */
29668    if (numRb > ueDl->maxRb)
29669    {
29670       numRb = ueDl->maxRb;
29671    }
29672    else
29673    {
29674 #ifdef LTE_ADV
29675       if(RFAILED == rgSCHLaaCmn2CwAdjustPrb(allocInfo,  boTmp, &numRb, ueDl, noLyr1, noLyr2, iTbs1, iTbs2))
29676 #endif
29677       {
29678          while ((numRb <= ueDl->maxRb) &&
29679                (rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1] <= ueDl->maxTbSz) &&
29680                (rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1] <= ueDl->maxTbSz) &&
29681                ((rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8 +
29682                  rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8) <= bo))
29683          {
29684             (numRb)++;
29685          }
29686       }
29687    }
29688    availBw = subFrm->bw - subFrm->bwAssigned;
29689    /* Cannot exceed the total number of RBs in the cell */
29690    if ((S16)(numRb - allocInfo->rbsReq) > availBw)
29691    {
29692       numRb = availBw + allocInfo->rbsReq;
29693    }
29694    tb1Sz = rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8;
29695    tb2Sz = rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8;
29696    /* DwPts Scheduling Changes Start */
29697 #ifdef LTE_TDD
29698    if(subFrm->sfType == RG_SCH_SPL_SF_DATA)
29699    { 
29700       /* Max Rb for Special Sf is approximated as 4/3 of maxRb */
29701       rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, (uint8_t*)&numRb,  ueDl->maxRb*4/3, 
29702                                 &iTbs1, &iTbs2, noLyr1, 
29703                                 noLyr2, &tb1Sz, &tb2Sz, cfi);   
29704       /* Check for available Bw */
29705       if ((S16)numRb - allocInfo->rbsReq > availBw)
29706       {
29707          numRb = availBw + allocInfo->rbsReq;
29708          tb1Sz = rgTbSzTbl[noLyr1-1][iTbs1][RGSCH_MAX(numRb*3/4,1)-1]/8;
29709          tb2Sz = rgTbSzTbl[noLyr2-1][iTbs2][RGSCH_MAX(numRb*3/4,1)-1]/8;
29710       }
29711    }
29712 #endif
29713    /* DwPts Scheduling Changes End */
29714    /* Update the subframe Allocated BW field */
29715    subFrm->bwAssigned = subFrm->bwAssigned + numRb - \
29716                         allocInfo->rbsReq;
29717
29718    *effBo = RGSCH_MIN((tb1Sz + tb2Sz) - oldReq, reqBytes);
29719
29720 #ifdef LTE_ADV
29721    if (ROK != rgSCHLaaCmn2TBPrbCheck(allocInfo, tb1Sz, tb2Sz, boTmp, effBo, iTbs1, iTbs2, numRb, proc))
29722    {
29723       return RFAILED;
29724    }
29725 #endif
29726
29727    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs1, imcs1);
29728    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs2, imcs2);
29729    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tb1Sz, \
29730          iTbs1, imcs1, &proc->tbInfo[0], noLyr1);
29731    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
29732          iTbs2, imcs2, &proc->tbInfo[1], noLyr2);
29733    *numRbRef = (uint8_t)numRb;
29734
29735
29736    return ROK;
29737 }
29738
29739 \f
29740 /**
29741  * @brief This function determines the RBs and Bytes required for
29742  *        Transmission & Retransmission on 2 CWs.
29743  *
29744  * @details
29745  *
29746  *     Function: rgSCHCmnDlAlloc2CwTxRetxRb
29747  *     Purpose:  This function determines the RBs and Bytes required
29748  *               for Transmission & Retransmission on 2 CWs. Allocate
29749  *               RETX TB on a better CW and restrict new TX TB by
29750  *               RETX allocation.
29751  *               Returns RFAILED if BO not satisfied at all.
29752  *
29753  *     Invoked by: TM3 and TM4 DL UE Allocation
29754  *
29755  *  @param[in]  RgSchCellCb      *cell
29756  *  @param[in]  RgSchDlSf        *subFrm
29757  *  @param[in]  RgSchUeCb        *ue
29758  *  @param[in]  RgSchDlHqTbCb    *reTxTb
29759  *  @param[in]  RgSchDlHqTbCb    *txTb
29760  *  @param[out] uint8_t               *numRb
29761  *  @param[out] uint32_t              *effBo
29762  *  @return  Void
29763  *
29764  **/
29765 #ifdef ANSI
29766 static S16 rgSCHCmnDlAlloc2CwTxRetxRb
29767 (
29768 RgSchCellCb                *cell,
29769 RgSchDlSf                  *subFrm,
29770 RgSchUeCb                  *ue,
29771 RgSchDlHqTbCb              *reTxTb,
29772 RgSchDlHqTbCb              *txTb,
29773 uint8_t                         *numRb,
29774 uint32_t                        *effBo
29775 )
29776 #else
29777 static S16 rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, reTxTb, txTb, numRb,\
29778         effBo)
29779 RgSchCellCb                *cell;
29780 RgSchDlSf                  *subFrm;
29781 RgSchUeCb                  *ue;
29782 RgSchDlHqTbCb              *reTxTb;
29783 RgSchDlHqTbCb              *txTb;
29784 uint8_t                         *numRb;
29785 uint32_t                        *effBo;
29786 #endif
29787 {
29788    RgSchCmnDlUe       *ueDl;
29789    RgSchDlRbAlloc     *allocInfo;
29790    uint8_t                 imcs1, imcs2;
29791    uint8_t                  noLyr2;
29792    uint16_t                 tb2Sz;
29793    RgSchCmnDlUeCwInfo *otherCw;
29794    S16                 availBw;
29795    RgSchCmnDlCell     *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
29796    uint8_t                 cfi = cellDl->currCfi; 
29797    uint8_t                 iTbs;
29798
29799
29800    ueDl      = RG_SCH_CMN_GET_DL_UE(ue,cell);
29801    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29802    otherCw   = &ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)];
29803
29804
29805    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
29806     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
29807     * MCS.  */
29808    availBw = subFrm->bw - subFrm->bwAssigned; 
29809    *numRb = reTxTb->dlGrnt.numRb;
29810
29811 #ifdef XEON_TDD_SPCL
29812    *numRb = (reTxTb->initTxNumRbs);
29813    if(reTxTb->sfType == RG_SCH_SPL_SF_DATA && subFrm->sfType != RG_SCH_SPL_SF_DATA)
29814    {
29815       *numRb = (reTxTb->initTxNumRbs*3/4);
29816
29817       if(*numRb <= 3)
29818       {
29819          RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb);
29820          return RFAILED;
29821       }
29822    }
29823 #endif
29824
29825    if ((S16)*numRb > availBw)
29826    {
29827       return RFAILED;
29828    }
29829    /* Update the subframe Allocated BW field */
29830    subFrm->bwAssigned += *numRb;
29831    noLyr2 = otherCw->noLyr;
29832    RG_SCH_CMN_GET_MCS_FOR_RETX(reTxTb, imcs1);
29833
29834    /* If there is no CFI change, continue to use the BLER based
29835     * iTBS value */
29836    if (ueDl->lastCfi == cfi)
29837    {   
29838       iTbs = otherCw->iTbs[noLyr2-1];
29839    }
29840    else
29841    {  
29842 #ifdef LTE_TDD      
29843       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, subFrm, otherCw->cqi, cfi, 
29844                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
29845 #else      
29846       iTbs = (uint8_t) rgSchCmnFetchItbs(cell, ueDl, otherCw->cqi, cfi, 
29847                                       !(ueDl->mimoInfo.btrCwIdx), noLyr2);
29848 #endif 
29849    } 
29850    tb2Sz = rgTbSzTbl[noLyr2-1][iTbs][*numRb-1]/8;
29851    /* DwPts Scheduling Changes Start */
29852 #ifdef LTE_TDD
29853 #endif
29854    /* DwPts Scheduling Changes End */
29855    RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs2);
29856    
29857    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], reTxTb->tbSz, \
29858                               0, imcs1, reTxTb, reTxTb->numLyrs);
29859    
29860    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \
29861                               iTbs, imcs2, txTb, noLyr2);
29862    
29863    *effBo = reTxTb->tbSz + tb2Sz;
29864
29865    return ROK;
29866 }
29867
29868 \f
29869 /**
29870  * @brief This function determines the RBs and Bytes required for BO
29871  *        Retransmission on 2 CWs.
29872  *
29873  * @details
29874  *
29875  *     Function: rgSCHCmnDlAlloc2CwRetxRb
29876  *     Purpose:  This function determines the RBs and Bytes required
29877  *               for BO Retransmission on 2 CWs. Allocate larger TB
29878  *               on a better CW and check if the smaller TB can be
29879  *               accomodated on the other CW.
29880  *               Returns RFAILED if BO not satisfied at all.
29881  *
29882  *     Invoked by: Common Scheduler
29883  *
29884  *  @param[in]  RgSchCellCb      *cell
29885  *  @param[in]  RgSchDlSf        *subFrm
29886  *  @param[in]  RgSchUeCb        *ue
29887  *  @param[in]  RgSchDlHqProcCb  *proc
29888  *  @param[out] uint8_t               *numRb
29889  *  @param[out] Bool             *swpFlg
29890  *  @param[out] uint32_t              *effBo
29891  *  @return  Void
29892  *
29893  **/
29894 #ifdef ANSI
29895 static S16 rgSCHCmnDlAlloc2CwRetxRb
29896 (
29897 RgSchCellCb                *cell,
29898 RgSchDlSf                  *subFrm,
29899 RgSchUeCb                  *ue,
29900 RgSchDlHqProcCb            *proc,
29901 uint8_t                         *numRb,
29902 Bool                       *swpFlg,
29903 uint32_t                        *effBo
29904 )
29905 #else
29906 static S16 rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc,\
29907         numRb, swpFlg, effBo)
29908 RgSchCellCb                *cell;
29909 RgSchDlSf                  *subFrm;
29910 RgSchUeCb                  *ue;
29911 RgSchDlHqProcCb            *proc;
29912 uint8_t                         *numRb;
29913 Bool                       *swpFlg;
29914 uint32_t                        *effBo;
29915 #endif
29916 {
29917    RgSchDlRbAlloc     *allocInfo;
29918    uint8_t                 imcs1;
29919    uint8_t                 imcs2;
29920    RgSchDlHqTbCb      *lrgTbInfo, *othrTbInfo;
29921
29922
29923    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
29924
29925
29926    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
29927     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
29928     * MCS.  */
29929    lrgTbInfo  = &proc->tbInfo[0];
29930    othrTbInfo = &proc->tbInfo[1];
29931    *numRb = lrgTbInfo->dlGrnt.numRb;
29932 #ifdef XEON_TDD_SPCL
29933    if((lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA || othrTbInfo->sfType == RG_SCH_SPL_SF_DATA))
29934    {
29935       if(lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA)
29936       {       
29937           *numRb = (lrgTbInfo->initTxNumRbs);
29938       }
29939       else
29940       {
29941           *numRb = (othrTbInfo->initTxNumRbs);
29942       }
29943
29944       if(subFrm->sfType != RG_SCH_SPL_SF_DATA)
29945       {
29946          *numRb = (*numRb)*3/4;
29947       }
29948        
29949       if(*numRb <= 3)
29950       {
29951          RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb);
29952          return RFAILED;
29953       }
29954    }
29955 #endif
29956    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
29957    {
29958       return RFAILED;
29959    }
29960    /* Update the subframe Allocated BW field */
29961    subFrm->bwAssigned += *numRb;
29962    RG_SCH_CMN_GET_MCS_FOR_RETX(lrgTbInfo, imcs1);
29963    RG_SCH_CMN_GET_MCS_FOR_RETX(othrTbInfo, imcs2);
29964    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], lrgTbInfo->tbSz, \
29965          0, imcs1, lrgTbInfo, lrgTbInfo->numLyrs);
29966    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], othrTbInfo->tbSz, \
29967          0, imcs2, othrTbInfo, othrTbInfo->numLyrs);
29968    *effBo = lrgTbInfo->tbSz + othrTbInfo->tbSz;
29969
29970
29971
29972    return ROK;
29973 }
29974
29975 \f
29976 /**
29977  * @brief This function determines the RBs and Bytes required for BO
29978  *        Retransmission on 1 CW.
29979  *
29980  * @details
29981  *
29982  *     Function: rgSCHCmnDlAlloc1CwRetxRb
29983  *     Purpose:  This function determines the RBs and Bytes required
29984  *               for BO Retransmission on 1 CW, the first CW.
29985  *               Returns RFAILED if BO not satisfied at all.
29986  *
29987  *     Invoked by: Common Scheduler
29988  *
29989  *  @param[in]  RgSchCellCb      *cell
29990  *  @param[in]  RgSchDlSf        *subFrm
29991  *  @param[in]  RgSchUeCb        *ue
29992  *  @param[in]  RgSchDlHqTbCb    *tbInfo
29993  *  @param[in]  uint8_t               noLyr
29994  *  @param[out] uint8_t               *numRb
29995  *  @param[out] uint32_t              *effBo
29996  *  @return  S16
29997  *
29998  **/
29999 #ifdef ANSI
30000 static S16 rgSCHCmnDlAlloc1CwRetxRb
30001 (
30002 RgSchCellCb                *cell,
30003 RgSchDlSf                  *subFrm,
30004 RgSchUeCb                  *ue,
30005 RgSchDlHqTbCb              *tbInfo,
30006 uint8_t                         noLyr,
30007 uint8_t                         *numRb,
30008 uint32_t                        *effBo
30009 )
30010 #else
30011 static S16 rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, tbInfo, noLyr,\
30012         numRb, effBo)
30013 RgSchCellCb                *cell;
30014 RgSchDlSf                  *subFrm;
30015 RgSchUeCb                  *ue;
30016 RgSchDlHqTbCb              *tbInfo;
30017 uint8_t                         noLyr;
30018 uint8_t                         *numRb;
30019 uint32_t                        *effBo;
30020 #endif
30021 {
30022    RgSchDlRbAlloc  *allocInfo;
30023    uint8_t              imcs;
30024
30025
30026    allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell);
30027
30028
30029    /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB
30030     * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and
30031     * MCS.  */
30032    *numRb = tbInfo->dlGrnt.numRb;
30033    if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned))
30034    {
30035       return RFAILED;
30036    }
30037    /* Update the subframe Allocated BW field */
30038    subFrm->bwAssigned += *numRb;
30039    imcs = tbInfo->dlGrnt.iMcs;
30040    allocInfo->dciFormat = tbInfo->dlGrnt.dciFormat; 
30041    /* Fix: For a RETX TB the iTbs is irrelevant, hence setting 0 */
30042    RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbInfo->tbSz, \
30043          0, imcs, tbInfo, tbInfo->numLyrs);
30044    *effBo = tbInfo->tbSz;
30045
30046    return ROK;
30047 }
30048
30049 #ifdef LTEMAC_SPS
30050
30051 /**
30052  * @brief This function is called to handle Release PDCCH feedback for SPS UE
30053  *
30054  * @details
30055  *
30056  *     Function: rgSCHCmnDlRelPdcchFbk
30057  *     Purpose:  Invokes SPS module to handle release PDCCH feedback
30058  *
30059  *     Invoked by: DHM
30060  *
30061  *  @param[in]   RgSchCellCb     *cell
30062  *  @param[in]   RgSchUeCb       *ue
30063  *  @param[in]   Bool            isAck
30064  *  @return  Void
30065  *
30066  **/
30067 #ifdef ANSI
30068 Void rgSCHCmnDlRelPdcchFbk
30069 (
30070 RgSchCellCb        *cell,
30071 RgSchUeCb          *ue,
30072 Bool               isAck
30073 )
30074 #else
30075 Void rgSCHCmnDlRelPdcchFbk(cell, ue, isAck)
30076 RgSchCellCb        *cell;
30077 RgSchUeCb          *ue;
30078 Bool               isAck;
30079 #endif
30080 {
30081
30082    rgSCHCmnSpsDlRelPdcchFbk(cell, ue, isAck);
30083    return;
30084
30085 }
30086
30087
30088 /**
30089  * @brief This function is invoked to handle Ack processing for a HARQ proc.
30090  *
30091  * @details
30092  *
30093  *     Function: rgSCHCmnDlProcAck
30094  *     Purpose:  DTX processing for HARQ proc
30095  *
30096  *     Invoked by: DHM
30097  *
30098  *  @param[in]   RgSchCellCb     *cell
30099  *  @param[in]   RgSchDlHqProcCb *hqP
30100  *  @return  Void
30101  *
30102  **/
30103 #ifdef ANSI
30104 Void rgSCHCmnDlProcAck
30105 (
30106 RgSchCellCb        *cell,
30107 RgSchDlHqProcCb    *hqP
30108 )
30109 #else
30110 Void rgSCHCmnDlProcAck(cell, hqP)
30111 RgSchCellCb        *cell;
30112 RgSchDlHqProcCb    *hqP;
30113 #endif
30114 {
30115
30116
30117    if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))
30118    {
30119       /* Invoke SPS module if SPS service was scheduled for this HARQ proc */
30120       rgSCHCmnSpsDlProcAck(cell, hqP);
30121    }
30122    return;
30123 }
30124 #ifdef RGSCH_SPS_STATS
30125 uint32_t rgSchStatCrntiCeRcvCnt;
30126 #endif
30127 /**
30128  * @brief This function is invoked to handle CRNTI CE reception for an UE
30129  *
30130  * @details
30131  *
30132  *     Function: rgSCHCmnHdlCrntiCE
30133  *     Purpose:  Handle CRNTI CE reception
30134  *
30135  *     Invoked by: DHM
30136  *
30137  *  @param[in]   RgSchCellCb     *cell
30138  *  @param[in]   RgSchDlHqProcCb *hqP
30139  *  @return  Void
30140  *
30141  **/
30142 #ifdef ANSI
30143 Void rgSCHCmnHdlCrntiCE
30144 (
30145 RgSchCellCb        *cell,
30146 RgSchUeCb          *ue
30147 )
30148 #else
30149 Void rgSCHCmnHdlCrntiCE(cell, ue)
30150 RgSchCellCb        *cell;
30151 RgSchUeCb          *ue;
30152 #endif
30153 {
30154
30155 #ifdef RGSCH_SPS_STATS   
30156    rgSchStatCrntiCeRcvCnt++;
30157 #endif
30158
30159    /* When UL sync lost happened due to TA timer expiry UE is being moved to 
30160       PDCCH order inactivity list.But when CRNTI CE received in msg3 from UE
30161       we are not moving UE into active state due to that RRC Reconfiguration is
30162       not happening.
30163       So here we are moving UE to active list whenever we receive the CRNTI CE and
30164       UE is inactive */
30165    /* CR ccpu00144525 */      
30166    if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue))
30167    {
30168        /* Activate this UE if it was inactive */
30169        RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
30170        RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE);
30171    }
30172
30173    /* Handling is same as reception of UE RESET for both DL and UL */
30174    if (ue->dl.dlSpsCfg.isDlSpsEnabled)
30175    {
30176       rgSCHCmnSpsDlUeReset(cell, ue);
30177    }
30178    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30179    {
30180       rgSCHCmnSpsUlUeReset(cell, ue);
30181    }
30182    
30183    return;
30184 }
30185
30186
30187 /**
30188  * @brief This function is called to handle relInd from MAC for a UE
30189  *
30190  * @details
30191  *
30192  *     Function: rgSCHCmnUlSpsRelInd
30193  *     Purpose:  Invokes SPS module to handle UL SPS release for a UE
30194  *
30195  *     Invoked by: SCH_UTL
30196  *
30197  *  @param[in]   RgSchCellCb        *cell
30198  *  @param[in]   RgSchUeCb          *ue
30199  *  @param[in]   Bool               isExplRel
30200  *  @return  Void
30201  *
30202  **/
30203 #ifdef ANSI
30204 Void rgSCHCmnUlSpsRelInd
30205 (
30206 RgSchCellCb        *cell,
30207 RgSchUeCb          *ue,
30208 Bool               isExplRel
30209 )
30210 #else
30211 Void rgSCHCmnUlSpsRelInd(cell, ue, isExplRel)
30212 RgSchCellCb        *cell;
30213 RgSchUeCb          *ue;
30214 Bool               isExplRel;
30215 #endif
30216 {
30217
30218    rgSCHCmnSpsUlProcRelInd(cell, ue, isExplRel);
30219    return;
30220
30221 } /* end of rgSCHCmnUlSpsRelInd */
30222
30223 /**
30224  * @brief This function is called to handle SPS Activate Ind from MAC for a UE
30225  *
30226  * @details
30227  *
30228  *     Function: rgSCHCmnUlSpsActInd
30229  *     Purpose:  Invokes SPS module to handle UL SPS activate for a UE
30230  *
30231  *     Invoked by: SCH_UTL
30232  *
30233  *  @param[in]   RgSchCellCb        *cell
30234  *  @param[in]   RgSchUeCb          *ue
30235  *  @return  Void
30236  *
30237  **/
30238 #ifdef ANSI
30239 Void rgSCHCmnUlSpsActInd
30240 (
30241 RgSchCellCb        *cell,
30242 RgSchUeCb          *ue,
30243 uint16_t                spsSduSize
30244 )
30245 #else
30246 Void rgSCHCmnUlSpsActInd(cell, ue,spsSduSize)
30247 RgSchCellCb        *cell;
30248 RgSchUeCb          *ue;
30249 uint16_t                spsSduSize;
30250 #endif
30251 {
30252
30253
30254    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30255    {
30256       rgSCHCmnSpsUlProcActInd(cell, ue,spsSduSize);
30257    }
30258    return;
30259
30260 } /* end of rgSCHCmnUlSpsActInd */
30261
30262 /**
30263  * @brief This function is called to handle CRC in UL for UEs
30264  * undergoing SPS release
30265  *
30266  * @details
30267  *
30268  *     Function: rgSCHCmnUlCrcInd
30269  *     Purpose:  Invokes SPS module to handle CRC in UL for SPS UE
30270  *
30271  *     Invoked by: SCH_UTL
30272  *
30273  *  @param[in]   RgSchCellCb        *cell
30274  *  @param[in]   RgSchUeCb          *ue
30275  *  @param[in]   CmLteTimingInfo    crcTime
30276  *  @return  Void
30277  *
30278  **/
30279 #ifdef ANSI
30280 Void rgSCHCmnUlCrcInd
30281 (
30282 RgSchCellCb        *cell,
30283 RgSchUeCb          *ue,
30284 CmLteTimingInfo    crcTime
30285 )
30286 #else
30287 Void rgSCHCmnUlCrcInd(cell, ue, crcTime)
30288 RgSchCellCb        *cell;
30289 RgSchUeCb          *ue;
30290 CmLteTimingInfo    crcTime;
30291 #endif
30292 {
30293
30294    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30295    {
30296       rgSCHCmnSpsUlProcCrcInd(cell, ue, crcTime);
30297    }
30298    return;
30299
30300 } /* end of rgSCHCmnUlCrcFailInd */
30301
30302 /**
30303  * @brief This function is called to handle CRC failure in UL
30304  *
30305  * @details
30306  *
30307  *     Function: rgSCHCmnUlCrcFailInd
30308  *     Purpose:  Invokes SPS module to handle CRC failure in UL for SPS UE
30309  *
30310  *     Invoked by: SCH_UTL
30311  *
30312  *  @param[in]   RgSchCellCb        *cell
30313  *  @param[in]   RgSchUeCb          *ue
30314  *  @param[in]   CmLteTimingInfo    crcTime
30315  *  @return  Void
30316  *
30317  **/
30318 #ifdef ANSI
30319 Void rgSCHCmnUlCrcFailInd
30320 (
30321 RgSchCellCb        *cell,
30322 RgSchUeCb          *ue,
30323 CmLteTimingInfo    crcTime
30324 )
30325 #else
30326 Void rgSCHCmnUlCrcFailInd(cell, ue, crcTime)
30327 RgSchCellCb        *cell;
30328 RgSchUeCb          *ue;
30329 CmLteTimingInfo    crcTime;
30330 #endif
30331 {
30332
30333    if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE)
30334    {
30335       rgSCHCmnSpsUlProcDtxInd(cell, ue, crcTime);
30336    }
30337    return;
30338
30339 } /* end of rgSCHCmnUlCrcFailInd */
30340
30341 #endif /* LTEMAC_SPS */
30342
30343 /**
30344  * @brief BCH,BCCH,PCCH Dowlink Scheduling Handler.
30345  *
30346  * @details
30347  *
30348  *     Function: rgSCHCmnDlBcchPcchAlloc
30349  *     Purpose:  This function calls common scheduler APIs to
30350  *     schedule for BCCH/PCCH.
30351  *     It then invokes Allocator for actual RB
30352  *     allocations. It processes on the actual resources allocated
30353  *     against requested to the allocator module.
30354  *
30355  *     Invoked by: Common Scheduler
30356  *
30357  *  @param[in]  RgSchCellCb *cell
30358  *  @return  Void
30359  **/
30360 #ifdef ANSI
30361 static Void rgSCHCmnDlBcchPcchAlloc
30362 (
30363 RgSchCellCb  *cell
30364 )
30365 #else
30366 static Void rgSCHCmnDlBcchPcchAlloc(cell)
30367 RgSchCellCb  *cell;
30368 #endif
30369 {
30370 #ifdef LTE_TDD
30371    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE;
30372 #else
30373 #ifdef LTEMAC_HDFDD
30374    uint8_t           nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES;
30375 #else
30376    uint8_t           nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES;
30377 #endif
30378 #endif
30379    RgInfSfAlloc *nextsfAlloc = &(cell->sfAllocArr[nextSfIdx]);
30380    RgSchCmnCell           *cellSch   = RG_SCH_CMN_GET_CELL(cell);
30381    RgSchCmnDlRbAllocInfo  *allocInfo = &cellSch->allocInfo;  
30382    
30383
30384
30385    /*Reset the bitmask for BCCH/PCCH*/
30386    rgSCHUtlResetSfAlloc(nextsfAlloc,TRUE,FALSE);
30387 #ifndef DISABLE_MIB_SIB /* Not sending MIB and SIB to CL */
30388 #ifdef RGR_SI_SCH
30389    rgSCHChkNUpdSiCfg(cell);
30390    rgSCHSelectSi(cell);
30391 #endif
30392
30393    /*Perform the scheduling for BCCH,PCCH*/
30394    rgSCHCmnDlBcchPcch(cell, allocInfo, nextsfAlloc);
30395
30396    /* Call common allocator for RB Allocation */
30397    rgSCHBcchPcchDlRbAlloc(cell, allocInfo);
30398
30399    /* Finalize the Allocations for reqested Against alloced */
30400    rgSCHCmnDlBcchPcchFnlz(cell, allocInfo);
30401 #endif /* DISABLE_MIB_SIB */
30402    return;
30403 }
30404
30405 /**
30406  * @brief Handles RB allocation for BCCH/PCCH for downlink.
30407  *
30408  * @details
30409  *
30410  *     Function : rgSCHBcchPcchDlRbAlloc
30411  *
30412  *     Invoking Module Processing:
30413  *     - This function is invoked for DL RB allocation of BCCH/PCCH
30414  *
30415  *     Processing Steps:
30416  *     - If cell is frequency selecive,
30417  *       - Call rgSCHDlfsBcchPcchAllocRb().
30418  *     - else,
30419  *       - Do the processing
30420  *
30421  *  @param[in]  RgSchCellCb        *cell
30422  *  @param[in]  RgSchDlRbAllocInfo *allocInfo
30423  *  @return  Void
30424  **/
30425
30426 #ifdef ANSI
30427 static Void rgSCHBcchPcchDlRbAlloc
30428 (
30429 RgSchCellCb           *cell,
30430 RgSchCmnDlRbAllocInfo *allocInfo
30431 )
30432 #else
30433 static Void rgSCHBcchPcchDlRbAlloc(cell, allocInfo)
30434 RgSchCellCb           *cell;
30435 RgSchCmnDlRbAllocInfo *allocInfo;
30436 #endif
30437 {
30438    RgSchCmnCell      *cellSch = RG_SCH_CMN_GET_CELL(cell);
30439
30440
30441
30442    if (cellSch->dl.isDlFreqSel)
30443    {
30444       cellSch->apisDlfs->rgSCHDlfsBcchPcchAllocRb(cell, allocInfo);
30445    }
30446    else
30447    {
30448       rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo);
30449    }
30450
30451    return;
30452 }
30453
30454 /**
30455  * @brief Handles RB allocation for BCCH,PCCH for frequency
30456  *  non-selective cell.
30457  *
30458  * @details
30459  *
30460  *     Function : rgSCHCmnNonDlfsBcchPcchRbAlloc
30461  *
30462  *     Invoking Module Processing:
30463  *      - SCH shall invoke this if downlink frequency selective is disabled for
30464  *        the cell for RB allocation.
30465  *      - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs
30466  *        estimate and subframe for each allocation to be made to SCH.
30467  *
30468  *     Processing Steps:
30469  *     - Allocate sequentially for BCCH,PCCH common channels.
30470  *
30471  *  @param[in]  RgSchCellCb        *cell
30472  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
30473  *  @return  Void
30474  **/
30475
30476 #ifdef ANSI
30477 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc
30478 (
30479 RgSchCellCb           *cell,
30480 RgSchCmnDlRbAllocInfo *allocInfo
30481 )
30482 #else
30483 static Void rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo)
30484 RgSchCellCb           *cell;
30485 RgSchCmnDlRbAllocInfo *allocInfo;
30486 #endif
30487 {
30488    RgSchDlRbAlloc     *reqAllocInfo;
30489
30490
30491    /* 143473 */
30492    /* Allocate for PCCH */
30493    reqAllocInfo = &(allocInfo->pcchAlloc);
30494    if (reqAllocInfo->rbsReq)
30495    {
30496       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
30497    }
30498    /* Allocate for BCCH on DLSCH */
30499    reqAllocInfo = &(allocInfo->bcchAlloc);
30500    if (reqAllocInfo->rbsReq)
30501    {
30502       rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo);
30503    }
30504    return;
30505 }
30506
30507
30508 #ifdef RGR_SI_SCH
30509 /**
30510  * @brief This function implements the handling to check and
30511  *        update the SI cfg at the start of the modificiation period.
30512  *
30513  * @details
30514  *
30515  *     Function: rgSCHChkNUpdSiCfg
30516  *     Purpose:  This function implements handling for update of SI Cfg
30517  *               at the start of modification period.
30518  *
30519  *     Invoked by: Scheduler
30520  *
30521  *  @param[in]  RgSchCellCb*     cell
30522  *  @return  S16
30523  *      -# ROK
30524  *      -# RFAILED
30525  **/
30526 #ifdef ANSI
30527 static Void rgSCHChkNUpdSiCfg
30528 (
30529 RgSchCellCb             *cell
30530 )
30531 #else
30532 static Void rgSCHChkNUpdSiCfg(cell)
30533 RgSchCellCb             *cell;
30534 #endif
30535 {
30536    CmLteTimingInfo   pdSchTmInfo;
30537
30538
30539
30540    pdSchTmInfo   = cell->crntTime;
30541 #ifdef LTEMAC_HDFDD
30542    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
30543       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
30544    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
30545 #else
30546    RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA);
30547 #endif
30548
30549
30550    /* Updating the SIB1 for Warning SI message immediately after it is received 
30551     * from application. No need to wait for next modification period.
30552     */
30553    if((pdSchTmInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
30554          && (RGSCH_SIB1_TX_SF_NUM == (pdSchTmInfo.slot % RGSCH_NUM_SUB_FRAMES)))
30555    {   
30556       /*Check whether SIB1 with PWS has been updated*/
30557       if(cell->siCb.siBitMask & RGSCH_SI_SIB1_PWS_UPD)
30558       {
30559          RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
30560                cell->siCb.newSiInfo.sib1Info.sib1);
30561          cell->siCb.crntSiInfo.sib1Info.mcs = 
30562             cell->siCb.newSiInfo.sib1Info.mcs;
30563          cell->siCb.crntSiInfo.sib1Info.nPrb = 
30564              cell->siCb.newSiInfo.sib1Info.nPrb;
30565          cell->siCb.crntSiInfo.sib1Info.msgLen = 
30566             cell->siCb.newSiInfo.sib1Info.msgLen;
30567          cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_PWS_UPD;
30568       }
30569    }
30570
30571    /*Check if this SFN and SF No marks the start of next modification
30572      period. If current SFN,SF No doesn't marks the start of next
30573      modification period, then return. */
30574    if(!((pdSchTmInfo.sfn % cell->siCfg.modPrd == 0)
30575             && (0 == pdSchTmInfo.slot)))
30576    /*if(!((((pdSchTmInfo.hSfn * 1024) + pdSchTmInfo.sfn) % cell->siCfg.modPrd == 0)
30577             && (0 == pdSchTmInfo.slot)))*/
30578    {
30579       return;
30580    }
30581
30582    /*Check whether MIB has been updated*/
30583    if(cell->siCb.siBitMask & RGSCH_SI_MIB_UPD)
30584    {
30585       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.mib,
30586             cell->siCb.newSiInfo.mib);
30587       cell->siCb.siBitMask &= ~RGSCH_SI_MIB_UPD;
30588    }
30589
30590    /*Check whether SIB1 has been updated*/
30591    if(cell->siCb.siBitMask & RGSCH_SI_SIB1_UPD)
30592    {
30593       RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1,
30594             cell->siCb.newSiInfo.sib1Info.sib1);
30595       cell->siCb.crntSiInfo.sib1Info.mcs = cell->siCb.newSiInfo.sib1Info.mcs;
30596       cell->siCb.crntSiInfo.sib1Info.nPrb = cell->siCb.newSiInfo.sib1Info.nPrb;
30597       cell->siCb.crntSiInfo.sib1Info.msgLen = 
30598          cell->siCb.newSiInfo.sib1Info.msgLen;
30599       cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_UPD;
30600    }
30601
30602    /*Check whether SIs have been updated*/
30603    if(cell->siCb.siBitMask & RGSCH_SI_SI_UPD)
30604    {
30605       uint8_t  idx;
30606
30607       /*Check if SI cfg have been modified And Check if numSi have
30608         been changed, if yes then we would need to update the
30609         pointers for all the SIs */
30610       if((cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) &&
30611             (cell->siCfg.numSi != cell->siCb.newSiCfg.numSi))
30612       {
30613          for(idx = 0;idx < cell->siCb.newSiCfg.numSi;idx++)
30614          {
30615             RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
30616                   cell->siCb.newSiInfo.siInfo[idx].si);
30617             cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
30618             cell->siCb.siArray[idx].isWarningSi = FALSE;
30619
30620             cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
30621             cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
30622             cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
30623          }
30624
30625          /*If numSi have been reduced then we need to free the
30626            pointers at the indexes in crntSiInfo which haven't
30627            been exercised. If numSi has increased then nothing
30628            additional is requires as above handling has taken
30629            care.*/
30630          if(cell->siCfg.numSi > cell->siCb.newSiCfg.numSi)
30631          {
30632             for(idx = cell->siCb.newSiCfg.numSi;
30633                   idx < cell->siCfg.numSi;idx++)
30634             {
30635                RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si);
30636                cell->siCb.siArray[idx].si = NULLP;
30637             }
30638          }
30639       }
30640       else
30641       {
30642          /*numSi has not been updated, we just need to update the
30643            pointers for the SIs which are set to NON NULLP */
30644          /*ccpu00118260 - Correct Update of SIB2 */
30645          for(idx = 0;idx < cell->siCfg.numSi;idx++)
30646          {
30647             if(NULLP != cell->siCb.newSiInfo.siInfo[idx].si)
30648             {
30649                RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si,
30650                      cell->siCb.newSiInfo.siInfo[idx].si);
30651
30652                cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si;
30653                cell->siCb.siArray[idx].isWarningSi = FALSE;
30654                cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs;
30655                cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb;
30656                cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen;
30657             }
30658          }
30659       }
30660       cell->siCb.siBitMask &= ~RGSCH_SI_SI_UPD;
30661    }
30662
30663    /*Check whether SI cfg have been updated*/
30664    if(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD)
30665    {
30666       cell->siCfg = cell->siCb.newSiCfg;
30667       cell->siCb.siBitMask &= ~RGSCH_SI_SICFG_UPD;
30668    }
30669
30670    return;
30671 }
30672
30673
30674 /**
30675  * @brief This function implements the selection of the SI
30676  *        that is to be scheduled.
30677  *
30678  * @details
30679  *
30680  *     Function: rgSCHSelectSi
30681  *     Purpose:  This function implements the selection of SI
30682  *               that is to be scheduled.
30683  *
30684  *     Invoked by: Scheduler
30685  *
30686  *  @param[in]  RgSchCellCb*     cell
30687  *  @return  S16
30688  *      -# ROK
30689  *      -# RFAILED
30690  **/
30691 #ifdef ANSI
30692 static Void rgSCHSelectSi
30693 (
30694 RgSchCellCb             *cell
30695 )
30696 #else
30697 static Void rgSCHSelectSi(cell)
30698 RgSchCellCb             *cell;
30699 #endif
30700 {
30701    CmLteTimingInfo        crntTmInfo;
30702    uint8_t                     siWinSize;
30703    uint16_t                    x; 
30704    uint16_t                    windowId; 
30705
30706
30707
30708    crntTmInfo  = cell->crntTime;
30709 #ifdef LTEMAC_HDFDD
30710    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
30711       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
30712    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
30713 #else
30714    RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA);
30715 #endif
30716
30717    siWinSize    = cell->siCfg.siWinSize;
30718
30719    /* Select SI only once at the starting of the new window */
30720    if(cell->siCb.inWindow)
30721    {
30722       if ((crntTmInfo.sfn % cell->siCfg.minPeriodicity) == 0 && 
30723           crntTmInfo.slot == 0)
30724       {
30725          /* Reinit inWindow at the beginning of every SI window */
30726          cell->siCb.inWindow = siWinSize - 1;
30727       }
30728       else
30729       {
30730          cell->siCb.inWindow--;
30731          return;
30732       }
30733    }
30734    else /* New window. Re-init the winSize counter with the window length */
30735    {
30736       if((cell->siCb.siArray[cell->siCb.siCtx.siId - 1].isWarningSi == TRUE)&&
30737             (cell->siCb.siCtx.retxCntRem != 0))   
30738       {
30739          rgSCHUtlFreeWarningSiPdu(cell);
30740          cell->siCb.siCtx.warningSiFlag  = FALSE;
30741       }
30742
30743       cell->siCb.inWindow = siWinSize - 1;
30744    }
30745
30746    x = rgSCHCmnGetSiSetId(crntTmInfo.sfn, crntTmInfo.slot, 
30747                                   cell->siCfg.minPeriodicity); 
30748
30749    /* Window Id within a SI set. This window Id directly maps to a
30750     * unique SI Id */
30751    windowId = (((crntTmInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + 
30752             crntTmInfo.slot) - (x * (cell->siCfg.minPeriodicity * 10))) 
30753                                                                / siWinSize;
30754
30755    if(windowId >= RGR_MAX_NUM_SI)
30756       return;
30757
30758    /* Update the siCtx if there is a valid SI and its periodicity
30759     * has occurred */
30760    if (NULLP != cell->siCb.siArray[windowId].si)
30761    {
30762       /* Warning SI Periodicity is same as SIB2 Periodicity */
30763       if(((cell->siCb.siArray[windowId].isWarningSi == FALSE) && 
30764                (x % (cell->siCfg.siPeriodicity[windowId]
30765                      /cell->siCfg.minPeriodicity) == 0)) || 
30766             ((cell->siCb.siArray[windowId].isWarningSi == TRUE) &&
30767              (x % (cell->siCfg.siPeriodicity[0]
30768                    /cell->siCfg.minPeriodicity) == 0)))
30769       {
30770          cell->siCb.siCtx.siId = windowId+1;
30771          cell->siCb.siCtx.retxCntRem = cell->siCfg.retxCnt;
30772          cell->siCb.siCtx.warningSiFlag = cell->siCb.siArray[windowId].
30773                                                            isWarningSi;
30774          cell->siCb.siCtx.timeToTx.sfn = crntTmInfo.sfn;
30775          cell->siCb.siCtx.timeToTx.slot = crntTmInfo.slot;
30776
30777          RG_SCH_ADD_TO_CRNT_TIME(cell->siCb.siCtx.timeToTx,
30778                cell->siCb.siCtx.maxTimeToTx, (siWinSize - 1))
30779       }
30780    }
30781    else
30782    {/* Update the siCtx with invalid si Id */
30783       cell->siCb.siCtx.siId = 0;
30784    }
30785
30786    return;
30787 }
30788
30789
30790 /**
30791  * @brief This function implements scheduler DL allocation for
30792  *        SI.
30793  *
30794  * @details
30795  *
30796  *     Function: rgSCHDlSiSched
30797  *     Purpose:  This function implements scheduler for DL allocation
30798  *               for SI.
30799  *
30800  *     Invoked by: Scheduler
30801  *
30802  *  @param[in]  RgSchCellCb*     cell
30803  *  @return  S16
30804  *      -# ROK
30805  *      -# RFAILED
30806  **/
30807 #ifdef ANSI
30808 static Void rgSCHDlSiSched
30809 (
30810 RgSchCellCb             *cell,
30811 RgSchCmnDlRbAllocInfo   *allocInfo,
30812 RgInfSfAlloc            *subfrmAlloc
30813 )
30814 #else
30815 static Void rgSCHDlSiSched(cell, allocInfo, subfrmAlloc)
30816 RgSchCellCb             *cell;
30817 RgSchCmnDlRbAllocInfo   *allocInfo;
30818 RgInfSfAlloc            *subfrmAlloc;
30819 #endif
30820 {
30821    CmLteTimingInfo   crntTimInfo;
30822    RgSchDlSf         *sf;
30823    uint8_t                nPrb = 0;
30824    uint8_t                mcs  = 0;
30825    MsgLen            msgLen = 0;
30826    uint32_t               rb=0;
30827    RgSchCmnDlCell    *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
30828    /* DwPTS Scheduling Changes Start */
30829 #ifdef LTE_TDD   
30830    uint16_t                lostRe;  
30831    uint8_t                 cfi = cellDl->currCfi;      
30832 #endif
30833    /* DwPTS Scheduling Changes End */
30834
30835
30836
30837    crntTimInfo   = cell->crntTime;
30838 #ifdef LTEMAC_HDFDD
30839    /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA
30840       + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */
30841    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL);
30842 #else
30843    RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA);
30844 #endif
30845
30846    /* Compute the subframe for which allocation is being made.
30847       Essentially, we need pointer to the dl frame for this subframe */
30848    sf = rgSCHUtlSubFrmGet(cell, crntTimInfo);
30849
30850    /*Check if scheduling of MIB is required */
30851 #ifdef EMTC_ENABLE
30852    /* since we are adding the MIB repetition logic for EMTC UEs, checking if
30853     * emtcEnabled or not,  If enabled MIB would be repeted at as part of EMTC
30854     * feature, otherwise scheduling at (n,0) */
30855    if(0 == cell->emtcEnable)
30856    {
30857 #endif
30858    if((crntTimInfo.sfn % RGSCH_MIB_PERIODICITY == 0)
30859          && (RGSCH_MIB_TX_SF_NUM == crntTimInfo.slot))
30860    {
30861       MsgLen  mibLen = 0;
30862       uint8_t      sfnOctet, mibOct2 = 0;
30863       uint8_t      mibOct1 = 0;
30864       /*If MIB has not been yet setup by Application, return*/
30865       if(NULLP == cell->siCb.crntSiInfo.mib)
30866          return;
30867
30868       SFndLenMsg(cell->siCb.crntSiInfo.mib, &mibLen);
30869       sf->bch.tbSize = mibLen;
30870       /*Fill the interface information */
30871       rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, NULLD, NULLD);
30872
30873       /*Set the bits of MIB to reflect SFN */
30874       /*First get the Most signficant 8 bits of SFN */
30875       sfnOctet = (uint8_t)(crntTimInfo.sfn >> 2);
30876       /*Get the first two octets of MIB, and then update them
30877         using the SFN octet value obtained above.*/
30878       if(ROK != SExamMsg((Data *)(&mibOct1),
30879                cell->siCb.crntSiInfo.mib, 0))
30880          return;
30881
30882       if(ROK != SExamMsg((Data *)(&mibOct2),
30883                cell->siCb.crntSiInfo.mib, 1))
30884          return;
30885
30886       /* ccpu00114572- Fix for improper way of MIB Octet setting for SFN */
30887       mibOct1 = (mibOct1 & 0xFC) | (sfnOctet >> 6);
30888       mibOct2 = (mibOct2 & 0x03) | (sfnOctet << 2);
30889       /* ccpu00114572- Fix ends*/
30890
30891       /*Now, replace the two octets in MIB */
30892       if(ROK != SRepMsg((Data)(mibOct1),
30893                cell->siCb.crntSiInfo.mib, 0))
30894          return;
30895
30896       if(ROK != SRepMsg((Data)(mibOct2),
30897                cell->siCb.crntSiInfo.mib, 1))
30898          return;
30899
30900       /*Copy the MIB msg buff into interface buffer */
30901       SCpyMsgMsg(cell->siCb.crntSiInfo.mib,
30902             rgSchCb[cell->instIdx].rgSchInit.region,
30903             rgSchCb[cell->instIdx].rgSchInit.pool,
30904             &subfrmAlloc->cmnLcInfo.bchInfo.pdu);
30905       /* Added Dl TB count for MIB message transmission
30906        * This counter is incremented 4 times to consider 
30907        * the retransmission at the PHY level on PBCH channel*/
30908 #ifdef LTE_L2_MEAS
30909       cell->dlUlTbCnt.tbTransDlTotalCnt += RG_SCH_MIB_CNT;
30910 #endif      
30911    }
30912 #ifdef EMTC_ENABLE
30913    }
30914 #endif
30915
30916    allocInfo->bcchAlloc.schdFirst = FALSE;
30917    /*Check if scheduling of SIB1 is required.
30918      Check of (crntTimInfo.sfn % RGSCH_SIB1_PERIODICITY == 0)
30919      is not required here since the below check takes care
30920      of SFNs applicable for this one too.*/
30921    if((crntTimInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0)
30922          && (RGSCH_SIB1_TX_SF_NUM == crntTimInfo.slot))
30923    {
30924       /*If SIB1 has not been yet setup by Application, return*/
30925       if(NULLP == (cell->siCb.crntSiInfo.sib1Info.sib1))
30926       {
30927          return;
30928       }
30929
30930       allocInfo->bcchAlloc.schdFirst = TRUE;
30931       mcs =  cell->siCb.crntSiInfo.sib1Info.mcs;
30932       nPrb =  cell->siCb.crntSiInfo.sib1Info.nPrb;
30933       msgLen =  cell->siCb.crntSiInfo.sib1Info.msgLen;
30934    }
30935    else
30936    {
30937       /*Check if scheduling of SI can be performed.*/
30938       Bool    invalid = FALSE;
30939
30940       if(cell->siCb.siCtx.siId == 0)
30941          return;
30942
30943       /*Check if the Si-Window for the current Si-Context is completed*/
30944       invalid = rgSCHCmnChkPastWin(crntTimInfo, cell->siCb.siCtx.maxTimeToTx);
30945       if(invalid)
30946       {
30947          /* LTE_ADV_FLAG_REMOVED_START */
30948          if(cell->siCb.siCtx.retxCntRem)
30949          { 
30950             RGSCHLOGERROR(cell->instIdx,ERRCLS_INT_PAR,ERG011,(ErrVal)cell->siCb.siCtx.siId,
30951                                 "rgSCHDlSiSched(): SI not scheduled and window expired");
30952          }
30953          /* LTE_ADV_FLAG_REMOVED_END */
30954          if(cell->siCb.siCtx.warningSiFlag == TRUE)
30955          {
30956             rgSCHUtlFreeWarningSiPdu(cell);
30957             cell->siCb.siCtx.warningSiFlag  = FALSE;
30958          }
30959          return;
30960       }
30961
30962       /*Check the timinginfo of the current SI-Context to see if its
30963         transmission can be scheduled. */
30964       if(FALSE == (rgSCHCmnChkInWin(crntTimInfo,
30965                   cell->siCb.siCtx.timeToTx,
30966                   cell->siCb.siCtx.maxTimeToTx)))
30967       {
30968          return;
30969
30970       }
30971       /*Check if retransmission count has become 0*/
30972       if(0 == cell->siCb.siCtx.retxCntRem)
30973       {
30974          return;
30975       }
30976
30977       /* LTE_ADV_FLAG_REMOVED_START */
30978       /* Check if ABS is enabled/configured  */
30979       if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
30980       {
30981          /* The pattern type is RGR_ABS_MUTE, then eNB need to blank the subframe */
30982          if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE)
30983          {
30984             /* Determine next scheduling subframe is ABS or not */
30985             if(RG_SCH_ABS_ENABLED_ABS_SF == (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern
30986                   [((crntTimInfo.sfn*RGSCH_NUM_SUB_FRAMES) + crntTimInfo.slot) % RGR_ABS_PATTERN_LEN]))
30987             {
30988                /* Skip the SI scheduling to next tti */
30989                return;
30990             }
30991          }
30992       }
30993       /* LTE_ADV_FLAG_REMOVED_END */
30994
30995       /*Schedule the transmission of the current SI-Context */
30996       /*Find out the messg length for the SI message */
30997       /* warningSiFlag is to differentiate between Warning SI
30998        * and Other SI */
30999         if((rgSCHUtlGetMcsAndNPrb(cell, &nPrb, &mcs, &msgLen)) != ROK)
31000         {
31001            return; 
31002         }
31003
31004       cell->siCb.siCtx.i = RGSCH_CALC_SF_DIFF(crntTimInfo,
31005             cell->siCb.siCtx.timeToTx);
31006    } 
31007
31008
31009    /*Get the number of rb required */
31010    /*rgSCHCmnClcRbAllocForFxdTb(cell, msgLen, cellDl->ccchCqi, &rb);*/
31011    if(cellDl->bitsPerRb==0)
31012    {
31013       while ((rgTbSzTbl[0][0][rb]) < (uint32_t) (msgLen*8))
31014       {
31015          rb++;
31016       }
31017       rb = rb+1;
31018    }
31019    else
31020    {
31021       rb = RGSCH_CEIL((msgLen*8), cellDl->bitsPerRb);
31022    }
31023    /* DwPTS Scheduling Changes Start */   
31024 #ifdef LTE_TDD
31025    if (sf->sfType == RG_SCH_SPL_SF_DATA) 
31026    {
31027       RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi);
31028
31029       /* Calculate the less RE's because of DwPTS */
31030        lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]);
31031
31032        /* Increase number of RBs in Spl SF to compensate for lost REs */
31033        rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); 
31034    }
31035 #endif
31036    /* DwPTS Scheduling Changes End */   
31037    /*ccpu00115595- end*/
31038    /* Additional check to see if required RBs
31039     * exceeds the available */
31040    if (rb > sf->bw - sf->bwAssigned)
31041    {
31042       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,  "rgSCHDlSiSched(): "
31043          "BW allocation failed CRNTI:%d",RGSCH_SI_RNTI);
31044       return;
31045    }
31046
31047    /* Update the subframe Allocated BW field */
31048    sf->bwAssigned = sf->bwAssigned + rb;
31049
31050    /*Fill the parameters in allocInfo */
31051    allocInfo->bcchAlloc.rnti = RGSCH_SI_RNTI;
31052    allocInfo->bcchAlloc.dlSf = sf;
31053    allocInfo->bcchAlloc.rbsReq = rb;
31054    /*ccpu00116710- MCS is not getting assigned */
31055    allocInfo->bcchAlloc.tbInfo[0].imcs = mcs;
31056
31057    /* ccpu00117510 - ADD - Assignment of nPrb and other information */
31058    allocInfo->bcchAlloc.nPrb = nPrb;
31059    allocInfo->bcchAlloc.tbInfo[0].bytesReq = msgLen;
31060    allocInfo->bcchAlloc.tbInfo[0].noLyr = 1;
31061    return;
31062 }
31063 #endif /*RGR_SI_SCH*/
31064
31065 \f
31066 /* ccpu00117452 - MOD - Changed macro name from
31067    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
31068 #ifdef RGR_CQI_REPT
31069 /**
31070  * @brief This function Updates the DL CQI for the UE.
31071  *
31072  * @details
31073  *
31074  *     Function: rgSCHCmnUeDlPwrCtColltCqiRept
31075  *     Purpose:  Manages PUSH N CQI reporting
31076  *         Step 1: Store the CQI in collation array
31077  *         Step 2: Increament the tracking count
31078  *         Step 3: Check is it time to to send the report
31079  *         Step 4: if yes, Send StaInd to RRM
31080  *         Step 4.1: Fill StaInd for sending collated N CQI rpeorts
31081  *         Step 4.2: Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM
31082  *         Step 4.2.1: If sending was not sucessful, return RFAILED
31083  *         Step 4.2.2: If sending was sucessful, return ROK
31084  *         Step 5: If no, return
31085  *     Invoked by: rgSCHCmnDlCqiInd
31086  *
31087  *  @param[in]  RgSchCellCb        *cell
31088  *  @param[in]  RgSchUeCb          *ue
31089  *  @param[in]  RgrUeCqiRept        *ueCqiRpt
31090  *  @return  Void
31091  *
31092  **/
31093 #ifdef ANSI
31094 static S16 rgSCHCmnUeDlPwrCtColltCqiRept
31095 (
31096 RgSchCellCb        *cell,
31097 RgSchUeCb          *ue,
31098 RgrUeCqiRept        *ueCqiRpt
31099 )
31100 #else
31101 static S16 rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, ueCqiRpt)
31102 RgSchCellCb        *cell;
31103 RgSchUeCb          *ue;
31104 RgrUeCqiRept        *ueCqiRpt;
31105 #endif
31106 {
31107    uint8_t    *cqiCount = NULLP;
31108    S16   retVal;
31109    RgrStaIndInfo *staInfo = NULLP;
31110
31111
31112    /* Step 1: Store the CQI in collation array */
31113    /* Step 2: Increament the tracking count */
31114    cqiCount = &(ue->schCqiInfo.cqiCount);
31115    ue->schCqiInfo.cqiRept[(*cqiCount)++] =
31116                   *ueCqiRpt;
31117
31118
31119    /* Step 3: Check is it time to to send the report */
31120    if(RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(ue))
31121    {
31122    /* Step 4: if yes, Send StaInd to RRM */
31123       retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo,
31124                sizeof(RgrStaIndInfo));
31125       if (retVal != ROK)
31126       {
31127          RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not "
31128             "allocate memory for sending StaInd CRNTI:%d",ue->ueId);
31129          return (retVal);
31130       }
31131
31132    /* Step 4.1: Fill StaInd for sending collated N CQI rpeorts */
31133 #ifdef CA_DBG
31134       {
31135          uint32_t gCqiReptToAppCount;
31136          gCqiReptToAppCount++;
31137       
31138       }
31139
31140 #endif
31141       retVal = rgSCHUtlFillSndStaInd(cell, ue, staInfo,
31142             ue->cqiReptCfgInfo.numColltdCqiRept);
31143       return (retVal);
31144
31145    }
31146
31147    return ROK;
31148 } /* End of rgSCHCmnUeDlPwrCtColltCqiRept */
31149
31150 #endif /* End of RGR_CQI_REPT */
31151
31152 /**
31153  * @brief This function checks for the retransmisson
31154  *        for a DTX scenario.
31155  * @details
31156  *
31157  *     Function:
31158  *     Purpose:
31159  *     Invoked by:
31160  *
31161  *  @param[in]  RgSchCellCb        *cell
31162  *  @param[in]  RgSchUeCb          *ue
31163  *  @param[in]
31164  *  @return  Void
31165  *
31166  **/
31167 #ifdef ANSI
31168 Void rgSCHCmnChkRetxAllowDtx
31169 (
31170 RgSchCellCb        *cell,
31171 RgSchUeCb          *ueCb,
31172 RgSchDlHqProcCb    *proc,
31173 Bool               *reTxAllwd
31174 )
31175 #else
31176 Void rgSCHCmnChkRetxAllowDtx(cell, ueCb, proc, reTxAllwd)
31177 RgSchCellCb        *cell;
31178 RgSchUeCb          *ueCb;
31179 RgSchDlHqProcCb    *proc;
31180 Bool               *reTxAllwd;
31181 #endif
31182 {
31183
31184
31185    *reTxAllwd = TRUE;
31186    /* Fix */
31187    if ((proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX))
31188    {
31189        *reTxAllwd = FALSE;
31190    }
31191
31192    return;
31193 }
31194
31195 /**
31196  * @brief API for calculating the SI Set Id 
31197  *
31198  * @details
31199  *
31200  *     Function: rgSCHCmnGetSiSetId
31201  *
31202  *     This API is used for calculating the SI Set Id, as shown below
31203  *     
31204  *          siSetId = 0        siSetId = 1
31205  *     |******************|******************|---------------->
31206  *   (0,0)              (8,0)              (16,0)          (SFN, SF)
31207  *    
31208  *
31209  *  @param[in]  uint16_t     sfn                   
31210  *  @param[in]  uint8_t      sf
31211  *  @return     uint16_t     siSetId
31212  **/
31213 #ifdef ANSI
31214 uint16_t rgSCHCmnGetSiSetId
31215 (
31216 uint16_t    sfn,
31217 uint8_t     sf,
31218 uint16_t    minPeriodicity
31219 )
31220 #else
31221 uint16_t rgSCHCmnGetSiSetId(sfn, sf, minPeriodicity)
31222 uint16_t    sfn;
31223 uint8_t     sf
31224 uint16_t    minPeriodicity;
31225 #endif
31226 {
31227    /* 80 is the minimum SI periodicity in sf. Also
31228     * all other SI periodicities are multiples of 80 */
31229     return  (((sfn * RGSCH_NUM_SUB_FRAMES_5G) + sf) / (minPeriodicity * 10));
31230 }
31231 #ifdef LTE_TDD
31232 /**
31233  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
31234  *
31235  * @details
31236  *
31237  *     Function: rgSCHCmnCalcDwPtsTbSz
31238  *
31239  *  @param[in]     RgSchCellCb    *cell                   
31240  *  @param[in]     uint32_t             bo
31241  *  @param[in/out] uint8_t             *rb
31242  *  @param[in/out] uint8_t             *iTbs
31243  *  @param[in]     uint8_t              lyr
31244  *  @param[in]     uint8_t              cfi
31245  *  @return        uint32_t             tbSz
31246  **/
31247 #ifdef ANSI
31248 static uint32_t rgSCHCmnCalcDwPtsTbSz
31249 (
31250 RgSchCellCb    *cell,
31251 uint32_t             bo,
31252 uint8_t             *rb,
31253 uint8_t             *iTbs,
31254 uint8_t              lyr,
31255 uint8_t              cfi
31256 )
31257 #else
31258 static uint32_t rgSCHCmnCalcDwPtsTbSz(cell, bo, rb, iTbs, lyr, cfi)
31259 RgSchCellCb    *cell;
31260 uint32_t             bo;
31261 uint8_t             *rb;
31262 uint8_t             *iTbs;
31263 uint8_t              lyr;
31264 uint8_t              cfi;
31265 #endif
31266 {
31267     uint32_t             tbSz;
31268     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
31269     uint32_t             numRE      = *rb * cellDl->noResPerRb[cfi];
31270     uint32_t             numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
31271
31272
31273     /* DwPts Rb cannot exceed the cell Bw */
31274     numDwPtsRb = RGSCH_MIN(numDwPtsRb, cellDl->maxDlBwPerUe);
31275     
31276     /* Adjust the iTbs for optimum usage of the DwPts region. 
31277      * Using the same iTbs adjustment will not work for all 
31278      * special subframe configurations and iTbs levels. Hence use the 
31279      * static iTbs Delta table for adjusting the iTbs  */
31280     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs);
31281     
31282     if (bo)
31283     {
31284        while(rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1] < bo*8 &&
31285              numDwPtsRb < cellDl->maxDlBwPerUe) 
31286        {
31287           (numDwPtsRb)++;
31288        }
31289
31290        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
31291     }
31292     else
31293     {
31294        tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1];
31295     }
31296     *rb = numDwPtsRb;
31297
31298     return (tbSz/8);
31299 }
31300
31301 /**
31302  * @brief API for calculating the DwPts Rb, Itbs and  tbSz 
31303  *
31304  * @details
31305  *
31306  *     Function: rgSCHCmnCalcDwPtsTbSz2Cw
31307  *
31308  *  @param[in]      RgSchCellCb    *cell                   
31309  *  @param[in]      uint32_t             bo
31310  *  @param[in/out]  uint8_t             *rb
31311  *  @param[in]      uint8_t              maxRb
31312  *  @param[in/out]  uint8_t             *iTbs1
31313  *  @param[in/out]  uint8_t             *iTbs2
31314  *  @param[in]      uint8_t              lyr1
31315  *  @param[in]      uint8_t              lyr2
31316  *  @return[in/out] uint32_t            *tb1Sz
31317  *  @return[in/out] uint32_t            *tb2Sz
31318  *  @param[in]      uint8_t              cfi 
31319  **/
31320 #ifdef ANSI
31321 static Void rgSCHCmnCalcDwPtsTbSz2Cw
31322 (
31323 RgSchCellCb    *cell,
31324 uint32_t             bo,
31325 uint8_t             *rb,
31326 uint8_t              maxRb,
31327 uint8_t             *iTbs1,
31328 uint8_t             *iTbs2,
31329 uint8_t              lyr1,
31330 uint8_t              lyr2,
31331 uint32_t            *tb1Sz, 
31332 uint32_t            *tb2Sz,
31333 uint8_t              cfi
31334 )
31335 #else
31336 static Void rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, rb, maxRb, iTbs1, iTbs2, 
31337       lyr1, lyr2, tb1Sz, tb2Sz, cfi)
31338 RgSchCellCb    *cell;
31339 uint32_t             bo;
31340 uint8_t             *rb;
31341 uint8_t              maxRb;
31342 uint8_t             *iTbs1;
31343 uint8_t             *iTbs2;
31344 uint8_t              lyr1;
31345 uint8_t              lyr2;
31346 uint32_t            *tb1Sz; 
31347 uint32_t            *tb2Sz;
31348 uint8_t              cfi;
31349 #endif
31350 {
31351     RgSchCmnDlCell *cellDl     = RG_SCH_CMN_GET_DL_CELL(cell);
31352     uint32_t             numRE      = *rb * cellDl->noResPerRb[cfi];
31353     uint32_t             numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]);   
31354
31355
31356     /* DwPts Rb cannot exceed the cell Bw */
31357     numDwPtsRb = RGSCH_MIN(numDwPtsRb, maxRb);
31358     
31359     /* Adjust the iTbs for optimum usage of the DwPts region. 
31360      * Using the same iTbs adjustment will not work for all 
31361      * special subframe configurations and iTbs levels. Hence use the 
31362      * static iTbs Delta table for adjusting the iTbs  */
31363     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs1);
31364     RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs2);
31365     
31366     while((rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1] +
31367            rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1])< bo*8 &&
31368           numDwPtsRb < maxRb) 
31369     {
31370        (numDwPtsRb)++;
31371     }
31372
31373     *tb1Sz = rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
31374     *tb2Sz = rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8;
31375
31376     *rb = numDwPtsRb;
31377
31378     return;    
31379 }
31380
31381 #endif
31382
31383 /**
31384  * @brief Updates the GBR LCGs when datInd is received from MAC
31385  * 
31386  * @details
31387  *
31388  *     Function: rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
31389  *     Purpose:  This function updates the GBR LCGs 
31390  *               when datInd is received from MAC.
31391  *
31392  *     Invoked by: TOM
31393  *
31394  *  @param[in]  RgSchCellCb      *cell
31395  *  @param[in]  RgSchUeCb        *ue
31396  *  @param[in]  RgInfUeDatInd    *datInd
31397  *  @return Void
31398  **/
31399 #ifdef ANSI
31400 Void rgSCHCmnUpdUeDataIndLcg 
31401 (
31402 RgSchCellCb    *cell,
31403 RgSchUeCb      *ue,
31404 RgInfUeDatInd  *datInd
31405 )
31406 #else
31407 Void rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd)
31408 RgSchCellCb    *cell;
31409 RgSchUeCb      *ue;
31410 RgInfUeDatInd  *datInd;
31411 #endif
31412 {
31413    uint32_t idx = 0;
31414    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
31415 #ifdef DEBUGP
31416    Inst                inst = cell->instIdx;
31417 #endif
31418
31419
31420    for (idx = 0; (idx < RGINF_MAX_LCG_PER_UE - 1); idx++)
31421    {
31422       if (datInd->lcgInfo[idx].bytesRcvd != 0)
31423       {
31424          uint8_t  lcgId     = datInd->lcgInfo[idx].lcgId;
31425          uint32_t bytesRcvd = datInd->lcgInfo[idx].bytesRcvd;
31426
31427          if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId]))
31428          {
31429             RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch));
31430             if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr))
31431             {
31432                if(bytesRcvd > cmnLcg->effGbr)
31433                {
31434                   bytesRcvd -= cmnLcg->effGbr;
31435                   cmnLcg->effDeltaMbr = (cmnLcg->effDeltaMbr > bytesRcvd) ? \
31436                                         (cmnLcg->effDeltaMbr - bytesRcvd) : (0);
31437                   cmnLcg->effGbr = 0;
31438                }
31439                else
31440                {
31441                   cmnLcg->effGbr -= bytesRcvd;
31442                }
31443                /* To keep BS updated with the amount of data received for the GBR */
31444                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31445                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31446                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr+cmnLcg->effDeltaMbr);
31447             }
31448             else if(lcgId != 0)
31449             {
31450                ue->ul.effAmbr = (ue->ul.effAmbr > datInd->lcgInfo[idx].bytesRcvd) ? \
31451                                (ue->ul.effAmbr - datInd->lcgInfo[idx].bytesRcvd) : (0);
31452                cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31453                                     (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31454                cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr);
31455                ue->ul.nonGbrLcgBs = (ue->ul.nonGbrLcgBs > datInd->lcgInfo[idx].bytesRcvd) ? \
31456                                    (ue->ul.nonGbrLcgBs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31457             }
31458             ue->ul.nonLcg0Bs = (ue->ul.nonLcg0Bs > datInd->lcgInfo[idx].bytesRcvd) ? \
31459                               (ue->ul.nonLcg0Bs - datInd->lcgInfo[idx].bytesRcvd) : (0);
31460          }
31461       }
31462       else
31463       {
31464          break;
31465       }
31466    }
31467 #ifdef EMTC_ENABLE
31468    if(TRUE == ue->isEmtcUe)
31469    {
31470       if (cellSch->apisEmtcUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
31471       {
31472          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure"));
31473       }
31474
31475    }
31476    else
31477 #endif
31478    {
31479       if (cellSch->apisUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK)
31480       {
31481          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure"));
31482       }
31483    }
31484 }
31485
31486
31487 /** @brief This function initializes DL allocation lists and prepares
31488  *         for scheduling  
31489  *
31490  * @details
31491  *
31492  *     Function: rgSCHCmnInitRbAlloc
31493  *
31494  * @param  [in] RgSchCellCb    *cell
31495  *
31496  * Returns: Void
31497  *
31498  */
31499 #ifdef ANSI
31500 static Void  rgSCHCmnInitRbAlloc 
31501 (
31502 RgSchCellCb        *cell
31503 )
31504 #else
31505 static Void  rgSCHCmnInitRbAlloc (cell)
31506 RgSchCellCb        *cell;
31507 #endif
31508 {
31509    RgSchCmnCell           *cellSch = RG_SCH_CMN_GET_CELL(cell);
31510    CmLteTimingInfo        frm;
31511    RgSchDlSf              *dlSf;
31512         uint8_t                     idx;
31513    
31514
31515 /* Initializing RgSchCmnUlRbAllocInfo structure.*/
31516    rgSCHCmnInitDlRbAllocInfo(&cellSch->allocInfo);
31517
31518    frm = cellSch->dl.time;
31519
31520    dlSf = rgSCHUtlSubFrmGet(cell, frm);
31521 #ifdef RG_5GTF
31522    dlSf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
31523    dlSf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
31524         for(idx = 0; idx < MAX_5GTF_BEAMS; idx++)
31525    {
31526       dlSf->sfBeamInfo[idx].totVrbgAllocated = 0;
31527       dlSf->sfBeamInfo[idx].totVrbgRequired = 0;
31528       dlSf->sfBeamInfo[idx].vrbgStart = 0;
31529    }
31530 #endif
31531    dlSf->remUeCnt = cellSch->dl.maxUePerDlSf;
31532    /* Updating the Subframe information in RBAllocInfo */
31533    cellSch->allocInfo.dedAlloc.dedDlSf   = dlSf;
31534    cellSch->allocInfo.msg4Alloc.msg4DlSf = dlSf;
31535
31536    /* LTE_ADV_FLAG_REMOVED_START */
31537    /* Determine next scheduling subframe is ABS or not */
31538    if(RGR_ENABLE == cell->lteAdvCb.absCfg.status)
31539    {
31540       cell->lteAdvCb.absPatternDlIdx = 
31541          ((frm.sfn*RGSCH_NUM_SUB_FRAMES_5G) + frm.slot) % RGR_ABS_PATTERN_LEN;
31542       cell->lteAdvCb.absDlSfInfo = (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern[
31543             cell->lteAdvCb.absPatternDlIdx]);
31544
31545    }
31546    else
31547    {
31548       cell->lteAdvCb.absDlSfInfo = RG_SCH_ABS_DISABLED;
31549    }
31550    /* LTE_ADV_FLAG_REMOVED_END */
31551
31552 #ifdef RGR_V1
31553    cellSch->allocInfo.ccchSduAlloc.ccchSduDlSf = dlSf;
31554 #endif
31555 #ifdef LTEMAC_SPS
31556    /* Update subframe-wide allocation information with SPS allocation */
31557    rgSCHCmnSpsDlUpdDlSfAllocWithSps(cell, frm, dlSf);
31558 #endif
31559    return;
31560 }
31561
31562
31563
31564 #ifdef DL_LA
31565 /**
31566  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
31567  * actual iTbs
31568  * 
31569  * @details
31570  *
31571  *     Function: rgSCHCmnSendTxModeInd(cell, ueUl, newTxMode)
31572  *     Purpose:  This function sends the TX mode Change 
31573  *               indication to RRM
31574  *     change
31575  *
31576  *     Invoked by: CMN
31577  *
31578  *  @param[in]  RgSchCellCb      *cell
31579  *  @param[in]  RgSchUeCb        *ue
31580  *  @param[in]  uint8_t               newTxMode
31581  *  @return Void
31582  **/
31583 #ifdef ANSI
31584 static Void rgSCHCmnSendTxModeInd 
31585 (
31586 RgSchCellCb    *cell,
31587 RgSchUeCb      *ue,
31588 uint8_t             newTxMode
31589 )
31590 #else
31591 static Void rgSCHCmnSendTxModeInd(cell, ue, newTxMode)
31592 RgSchCellCb    *cell;
31593 RgSchUeCb      *ue;
31594 uint8_t             newTxMode;
31595 #endif
31596
31597    RgmTransModeInd   *txModeChgInd;
31598    RgSchCmnDlUe      *ueDl =  RG_SCH_CMN_GET_DL_UE(ue,cell);
31599
31600
31601    if(!(ueDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG))
31602    {
31603       /* Mem Alloc */
31604       if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
31605                cell->rgmSap->sapCfg.sapPst.pool, (Data**)&txModeChgInd,
31606                sizeof(RgmTransModeInd)) != ROK)
31607       {
31608          return;
31609       }
31610       RG_SCH_FILL_RGM_TRANSMODE_IND(ue->ueId, cell->cellId, newTxMode, txModeChgInd);
31611       RgUiRgmChangeTransModeInd(&(cell->rgmSap->sapCfg.sapPst),
31612             cell->rgmSap->sapCfg.suId, txModeChgInd);
31613    }
31614
31615    ue->mimoInfo.txModUpChgFactor = 0;
31616    ue->mimoInfo.txModDownChgFactor = 0;
31617    ueDl->laCb[0].deltaiTbs = 0;
31618
31619    return;
31620 }
31621
31622 /**
31623  * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and
31624  * actual iTbs
31625  * 
31626  * @details
31627  *
31628  *     Function: rgSchCheckAndTriggerModeChange(cell, ueUl, iTbsNew)
31629  *     Purpose:  This function update and check for threashold for TM mode
31630  *     change
31631  *
31632  *     Invoked by: CMN
31633  *
31634  *  @param[in]  RgSchCellCb      *cell
31635  *  @param[in]  RgSchUeCb        *ue
31636  *  @param[in]  uint8_t               iTbs
31637  *  @return Void
31638  **/
31639 #ifdef ANSI
31640 Void rgSchCheckAndTriggerModeChange
31641 (
31642 RgSchCellCb    *cell,
31643 RgSchUeCb      *ue,
31644 uint8_t             reportediTbs,
31645 uint8_t             previTbs,
31646 uint8_t             maxiTbs
31647 )
31648 #else
31649 Void rgSchCheckAndTriggerModeChange(cell, ue, reportediTbs, previTbs, maxiTbs)
31650 RgSchCellCb    *cell;
31651 RgSchUeCb      *ue;
31652 uint8_t             reportediTbs;
31653 uint8_t             previTbs;
31654 uint8_t             maxiTbs;
31655 #endif
31656 {
31657    RgrTxMode          txMode;       /*!< UE's Transmission Mode */
31658    RgrTxMode          modTxMode;       /*!< UE's Transmission Mode */
31659
31660
31661    txMode = ue->mimoInfo.txMode;
31662
31663    /* Check for Step down */
31664    /* Step down only when TM4 is configured. */
31665    if(RGR_UE_TM_4 == txMode)
31666    {
31667       if((previTbs <= reportediTbs) && ((reportediTbs - previTbs) >= RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR))
31668       {
31669          ue->mimoInfo.txModDownChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
31670       }
31671       else
31672       {
31673          ue->mimoInfo.txModDownChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
31674       }
31675
31676       ue->mimoInfo.txModDownChgFactor =  
31677          RGSCH_MAX(ue->mimoInfo.txModDownChgFactor, -(RG_SCH_MODE_CHNG_STEPDOWN_THRSHD));
31678
31679       if(ue->mimoInfo.txModDownChgFactor >= RG_SCH_MODE_CHNG_STEPDOWN_THRSHD)
31680       {
31681          /* Trigger Mode step down */
31682          modTxMode = RGR_UE_TM_3;
31683          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
31684       }
31685    }
31686
31687    /* Check for Setup up */
31688    /* Step Up only when TM3 is configured, Max possible Mode is TM4*/
31689    if(RGR_UE_TM_3 == txMode)
31690    {
31691       if((previTbs > reportediTbs) || (maxiTbs == previTbs))
31692       {
31693          ue->mimoInfo.txModUpChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR;
31694       }
31695       else
31696       {
31697          ue->mimoInfo.txModUpChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR;
31698       }
31699
31700       ue->mimoInfo.txModUpChgFactor = 
31701          RGSCH_MAX(ue->mimoInfo.txModUpChgFactor, -(RG_SCH_MODE_CHNG_STEPUP_THRSHD));
31702
31703       /* Check if TM step up need to be triggered */
31704       if(ue->mimoInfo.txModUpChgFactor >= RG_SCH_MODE_CHNG_STEPUP_THRSHD)
31705       {
31706          /* Trigger mode chnage */
31707          modTxMode =  RGR_UE_TM_4;
31708          rgSCHCmnSendTxModeInd(cell, ue, modTxMode);
31709       }
31710    }
31711
31712    return;
31713 }
31714 #endif
31715
31716 /**
31717 * @brief Updates the GBR LCGs when datInd is received from MAC
31718  * 
31719  * @details
31720  *
31721  *     Function: rgSCHCmnIsDlCsgPrio (cell)
31722  *     Purpose:  This function returns if csg UEs are
31723  *               having priority at current time
31724  *
31725  *     Invoked by: Scheduler
31726  *
31727  *  @param[in]  RgSchCellCb      *cell
31728  *  @param[in]  RgSchUeCb        *ue
31729  *  @param[in]  RgInfUeDatInd    *datInd
31730  *  @return Void
31731  **/
31732 #ifdef ANSI
31733 Bool rgSCHCmnIsDlCsgPrio
31734 (
31735 RgSchCellCb    *cell
31736 )
31737 #else
31738 Bool rgSCHCmnIsDlCsgPrio(cell)
31739 RgSchCellCb    *cell;
31740 #endif
31741 {
31742   
31743    RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell);
31744  
31745    /* Calculating the percentage resource allocated */
31746    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
31747    {
31748       return (FALSE);
31749    }
31750    else
31751    {
31752       if(((cmnDlCell->ncsgPrbCnt * 100) / cmnDlCell->totPrbCnt) < cell->minDlResNonCsg)
31753       {
31754          return (FALSE);
31755       }
31756       else
31757       {
31758          return (TRUE);
31759       }
31760    }
31761 }
31762
31763 /**
31764 * @brief Updates the GBR LCGs when datInd is received from MAC
31765  * 
31766  * @details
31767  *
31768  *     Function: rgSCHCmnIsUlCsgPrio (cell)
31769  *     Purpose:  This function returns if csg UEs are
31770  *               having priority at current time
31771  *
31772  *     Invoked by: Scheduler
31773  *
31774  *  @param[in]  RgSchCellCb      *cell
31775  *  @param[in]  RgSchUeCb        *ue
31776  *  @param[in]  RgInfUeDatInd    *datInd
31777  *  @return Void
31778  **/
31779 #ifdef ANSI
31780 Bool rgSCHCmnIsUlCsgPrio
31781 (
31782 RgSchCellCb    *cell
31783 )
31784 #else
31785 Bool rgSCHCmnIsUlCsgPrio(cell)
31786 RgSchCellCb    *cell;
31787 #endif
31788 {
31789    RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell);
31790  
31791
31792    /* Calculating the percentage resource allocated */
31793    if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode)
31794    {
31795       return (FALSE);
31796    }
31797    else
31798    {
31799       if (((cmnUlCell->ncsgPrbCnt * 100) /cmnUlCell->totPrbCnt) < cell->minUlResNonCsg)
31800       {
31801          return (FALSE);
31802       }
31803       else
31804       {
31805          return (TRUE);
31806       }
31807    }
31808 }
31809
31810 /** @brief DL scheduler for SPS, and all other downlink data
31811  *
31812  * @details
31813  *
31814  *      Function: rgSchCmnPreDlSch
31815  *
31816  *  @param  [in] Inst               schInst;
31817  *   Returns: Void
31818  *
31819  */
31820 #ifdef ANSI
31821    Void rgSchCmnPreDlSch
31822 (
31823  RgSchCellCb        **cell,
31824  uint8_t                 nCell,
31825  RgSchCellCb        **cellLst
31826  )
31827 #else
31828 Void rgSchCmnPreDlSch(cell, nCell, cellLst)
31829    RgSchCellCb        **cell;
31830    uint8_t                 nCell;
31831    RgSchCellCb        **cellLst;
31832 #endif
31833 {
31834    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell[0]);
31835    RgSchDlSf     *sf;
31836    uint8_t            idx;
31837
31838
31839    if(nCell > CM_LTE_MAX_CELLS)
31840    {
31841       return;
31842    }
31843
31844    if (cell[0]->isDlDataAllwd && (cell[0]->stopDlSch == FALSE))
31845    {
31846       /* Specific DL scheduler to perform UE scheduling */
31847       cellSch->apisDl->rgSCHDlPreSched(cell[0]);
31848
31849       /* Rearranging the cell entries based on their remueCnt in SF.
31850        * cells will be processed in the order of number of ue scheduled
31851        * in that cell */
31852       for (idx = 0; idx < nCell; idx++)
31853       {
31854          uint8_t    j;
31855          cellSch = RG_SCH_CMN_GET_CELL(cell[idx]);
31856          sf = cellSch->allocInfo.dedAlloc.dedDlSf;
31857
31858          if(idx == 0)
31859          {
31860             cellLst[idx] = cell[idx];
31861             continue;
31862          }
31863
31864          for(j = 0; j < idx; j++)
31865          {
31866             RgSchCmnCell *cmnCell = RG_SCH_CMN_GET_CELL(cellLst[j]);
31867             RgSchDlSf    *subfrm = cmnCell->allocInfo.dedAlloc.dedDlSf;
31868
31869             if(sf->remUeCnt < subfrm->remUeCnt)
31870             {
31871                uint8_t  k;
31872                for(k = idx; k > j; k--)
31873                {
31874                   cellLst[k] = cellLst[k-1];
31875                }
31876                break;
31877             }
31878          }
31879          cellLst[j] = cell[idx];
31880       }
31881    }
31882    else
31883    {
31884       for (idx = 0; idx < nCell; idx++)
31885       {
31886          cellLst[idx] = cell[idx];
31887       }
31888    }
31889    return;
31890 }
31891
31892 /** @brief DL scheduler for SPS, and all other downlink data
31893  *  @details
31894  *
31895  *       Function: rgSchCmnPstDlSch
31896  *
31897  *        @param  [in] Inst               schInst;
31898  *        Returns: Void
31899  *
31900  */
31901 #ifdef ANSI
31902 Void rgSchCmnPstDlSch
31903 (
31904  RgSchCellCb       *cell
31905 )
31906 #else
31907 Void rgSchCmnPstDlSch(cell)
31908    RgSchCellCb        *cell
31909 #endif
31910 {
31911    RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
31912
31913
31914    if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE))
31915    {
31916       cellSch->apisDl->rgSCHDlPstSched(cell->instIdx);
31917    }
31918 }
31919
31920 #ifdef ANSI
31921 uint8_t rgSCHCmnCalcPcqiBitSz
31922 (
31923  RgSchUeCb    *ueCb, 
31924  uint8_t           numTxAnt
31925 )
31926 #else
31927 uint8_t rgSCHCmnCalcPcqiBitSz(ueCb, numTxAnt)
31928    RgSchUeCb     *ueCb;
31929    uint8_t            numTxAnt;
31930 #endif
31931 {
31932    uint8_t confRepMode;
31933    uint8_t pcqiSz;
31934    uint8_t ri;
31935    RgSchUePCqiCb *cqiCb = ueCb->nPCqiCb;
31936
31937
31938    confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
31939    if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && 
31940          (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
31941    {
31942       ri =1;
31943    }
31944    else
31945    {
31946       ri = cqiCb->perRiVal;
31947    }
31948    switch(confRepMode)
31949    {
31950       case RGR_PRD_CQI_MOD10:
31951          {
31952             pcqiSz = 4;
31953          }
31954          break;
31955
31956       case RGR_PRD_CQI_MOD11:
31957          {
31958             if(numTxAnt == 2)
31959             {
31960                if (ri ==1)
31961                {
31962                   pcqiSz = 6;
31963                }
31964                else
31965                {
31966                   pcqiSz = 8;
31967                }
31968             }
31969             else if(numTxAnt == 4)
31970             {
31971                if (ri ==1)
31972                {
31973                   pcqiSz = 8;
31974                }
31975                else
31976                {
31977                   pcqiSz = 11;
31978                }
31979             }
31980             else
31981             {
31982                /* This is number of antenna case 1.
31983                 * This is not applicable for Mode 1-1. 
31984                 * So setting it to invalid value */
31985                pcqiSz = 0;
31986             }
31987          }
31988          break;
31989
31990       case RGR_PRD_CQI_MOD20:
31991          {
31992             if(cqiCb->isWb)
31993             {
31994                pcqiSz = 4;
31995             }
31996             else
31997             {
31998                pcqiSz = 4 + cqiCb->label;
31999             }
32000          }
32001          break;
32002
32003       case RGR_PRD_CQI_MOD21:
32004          {
32005             if(cqiCb->isWb)
32006             {
32007                if(numTxAnt == 2)
32008                {
32009                   if (ri ==1)
32010                   {
32011                      pcqiSz = 6;
32012                   }
32013                   else
32014                   {
32015                      pcqiSz = 8;
32016                   }
32017                }
32018                else if(numTxAnt == 4)
32019                {
32020                   if (ri ==1)
32021                   {
32022                      pcqiSz = 8;
32023                   }
32024                   else
32025                   {
32026                      pcqiSz = 11;
32027                   }
32028                }
32029                else
32030                {
32031                   /* This might be number of antenna case 1.
32032                    * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
32033                    * So setting invalid value.*/
32034                   pcqiSz = 0;
32035                }
32036             }
32037             else
32038             {
32039                if (ri ==1)
32040                {
32041                   pcqiSz = 4 + cqiCb->label;
32042                }
32043                else
32044                {
32045                   pcqiSz = 7 + cqiCb->label;
32046                }
32047             }
32048          }
32049          break;
32050       default:
32051           pcqiSz = 0;
32052           break;
32053    }
32054    
32055    return (pcqiSz);
32056 }
32057
32058 /** @brief DL scheduler for SPS, and all other downlink data
32059  *
32060  * @details
32061  *
32062  *     Function: rgSCHCmnDlSch
32063  *
32064  * @param  [in] RgSchCellCb    *cell
32065  *
32066  * Returns: Void
32067  *
32068  */
32069 #ifdef ANSI
32070 Void rgSCHCmnDlSch
32071 (
32072  RgSchCellCb        *cell
32073  )
32074 #else
32075 Void rgSCHCmnDlSch (cell)
32076    RgSchCellCb        *cell;
32077 #endif
32078 {
32079    RgSchDlSf *dlSf;
32080    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
32081 #ifdef RG_5GTF
32082    RgSchDynTddCb  *rgSchDynTddInfo = &(rgSchCb[cell->instIdx].rgSchDynTdd);
32083    uint16_t dlCntrlSfIdx;
32084 #endif
32085
32086
32087    dlSf = rgSCHUtlSubFrmGet(cell, cellSch->dl.time);
32088 #ifdef RG_5GTF
32089         if (rgSchDynTddInfo->isDynTddEnbld)
32090    {
32091       RG_SCH_DYN_TDD_GET_SFIDX(dlCntrlSfIdx, rgSchDynTddInfo->crntDTddSfIdx, 
32092                                             RG_SCH_CMN_DL_DELTA);
32093                 if(RG_SCH_DYNTDD_DLC_ULD == rgSchDynTddInfo->sfInfo[dlCntrlSfIdx].sfType)
32094                 {
32095                    if(1 == cell->cellId)
32096          {
32097                       ul5gtfsidDlAlreadyMarkUl++;
32098             /*
32099                       printf("ul5gtfsidDlAlreadyMarkUl: %d, [sfn:sf] [%04d:%02d]\n", 
32100                     ul5gtfsidDlAlreadyMarkUl, cellSch->dl.time.sfn, 
32101                     cellSch->dl.time.slot);
32102             */
32103          }
32104                    return;
32105                 }
32106    }
32107 #endif
32108
32109    /* Specific DL scheduler to perform UE scheduling */
32110    cellSch->apisDl->rgSCHDlNewSched(cell, &cellSch->allocInfo);      
32111    /* LTE_ADV_FLAG_REMOVED_END */
32112
32113    /* call common allocator for RB Allocation */
32114    rgSCHCmnDlRbAlloc(cell, &cellSch->allocInfo);
32115
32116    /* Finalize the Allocations for reqested Against alloced */
32117    rgSCHCmnDlAllocFnlz(cell);
32118
32119    /* Perform Pdcch allocations for PDCCH Order Q.
32120     * As of now, giving this the least preference.
32121     * This func call could be moved above other allocations
32122     * as per need */
32123    rgSCHCmnGenPdcchOrder(cell, dlSf);
32124
32125    /* Do group power control for PUCCH */
32126    rgSCHCmnGrpPwrCntrlPucch(cell, dlSf);
32127
32128    return;
32129 }
32130
32131 /**********************************************************************
32132
32133   End of file
32134 **********************************************************************/