[Epic-ID: ODUHIGH-464][Task-ID: ODUHIGH-483] Memeory related fix in FDD and TDD mode
[o-du/l2.git] / src / 5gnrmac / rg_tom.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_tom.c 
28   
29 **********************************************************************/
30
31 /** @file rg_tom.c 
32 @brief This module does processing related to handling of lower interface APIs 
33 invoked by PHY towards MAC
34 */
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "rgu.h"           /* RGU defines */
38 #include "tfu.h"           /* RGU defines */
39 #include "lrg.h"           /* layer management defines for LTE-MAC */
40 #include "crg.h"           /* layer management defines for LTE-MAC */
41 #include "rg_sch_inf.h"           /* layer management defines for LTE-MAC */
42 #include "rg.h"            /* defines and macros for MAC */
43 #include "rg_env.h"            /* defines and macros for MAC */
44 #include "rg_err.h"            /* defines and macros for MAC */
45 #include "rgm.h"           /* layer management typedefs for MAC */
46
47 /* header/extern include files (.x) */
48 #include "crg.x"           /* CRG interface typedefs */
49 #include "rgu.x"           /* RGU types */
50 #include "tfu.x"           /* RGU types */
51 #include "lrg.x"           /* layer management typedefs for MAC */
52 #include "rg_sch_inf.x"    /* SCH interface typedefs */
53 #include "rg_prg.x"        /* PRG interface typedefs */
54 #include "rgm.x"           /* layer management typedefs for MAC */
55 #include "rg.x"            /* typedefs for MAC */
56 #ifdef MAC_RLC_UL_RBUF
57 #include "ss_rbuf.h"
58 #include "ss_rbuf.x"
59 #endif
60
61 /* ADD Changes for Downlink UE Timing Optimization */
62 #ifndef LTEMAC_DLUE_TMGOPTMZ 
63 static S16 rgTOMUtlProcDlSf ARGS(( RgDlSf *dlSf, RgCellCb   *cellCb,
64                                     RgErrInfo  *err));
65 #else
66 S16 rgTOMUtlProcDlSf ARGS((RgDlSf *dlSf, RgCellCb *cellCb,
67                                   RgErrInfo  *err));
68 #endif
69 static S16 rgTOMProcCrntiCEInDatInd ARGS((
70 RgMacPdu          *pdu,
71 RgUeCb            *prevUeCb,
72 RgCellCb          *cellCb,
73 TfuDatInfo        *datInfo,
74 RgInfCeInfo       *ceInfo,
75 uint16_t          slot
76 ));
77
78 static S16 rgTOMProcCCCHSduInDatInd ARGS((
79 RgMacPdu          *pdu,
80 RgUeCb            *prevUeCb,
81 RgCellCb          *cellCb,
82 TfuDatInfo        *datInfo,
83 RgInfCeInfo       *ceInfo,
84 uint16_t           slot
85 ));
86
87 S16 rgHndlFlowCntrl
88 (
89 RgCellCb       *cell,
90 RgInfSfAlloc        *sfInfo
91 );
92
93 S16 RgUiRguFlowCntrlInd(Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd);
94 #ifdef EMTC_ENABLE
95 S16 rgEmtcHndl(RgCellCb *cell,RgInfSfAlloc  *sfInfo);  
96 S16 rgTOMEmtcUtlFillDatReqPdus(TfuDatReqInfo *datInfo, RgDlSf *dlSf, RgCellCb *cell, RgErrInfo *err);  
97 Void rgTOMEmtcRlsSf(RgDlSf *dlSf);  
98 #endif
99 #ifdef LTE_L2_MEAS
100 static Void rgTOML2MCompileActiveLCs ARGS
101 ((
102  RgCellCb      *cellCb, 
103  RgUeCb        *ueCb,
104  RgMacPdu      *pdu,
105  RgInfCeInfo   *ceInfo 
106  ));
107 static S16 rgTOMUtlL2MStoreBufSz ARGS
108 ((
109  RgUeCb      *ueCb,
110  RgInfCeInfo *ceInfo
111  ));
112
113 static S16 rgTomUtlPrepareL2MUlThrpInfo ARGS
114 ((
115    RgCellCb *cellCb,
116    RgUeCb  *ueCb,
117    RgRguDedDatInd  *dDatInd
118 ));
119
120
121 /* The below table takes lower values of BSR Range for a BSR value
122      This is to ensure that outstanding can be decrease to zero upon reception of
123      TB, which is not guaranteed if higher Range values are used */
124    /* Note: taking value 10 for BSR index 1 */
125 #ifndef MAC_5GTF_UPDATE
126 static uint32_t rgLwrBsrTbl[64] = {
127    0, 10, 10, 12, 14, 17, 19, 22, 26,
128    31, 36, 42, 49, 57, 67, 78, 91,
129    107, 125, 146, 171, 200, 234, 274, 321,
130    376, 440, 515, 603, 706, 826, 967, 1132,
131    1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
132    4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
133    16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
134    58255, 68201, 79846, 93479, 109439, 128125, 150000
135 };
136 #else
137
138 static uint32_t rgLwrBsrTbl[64] = {
139 0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181,223,274,337,414,
140 509,625,769,945,1162,1429,1757,2161,2657,3267,4017,4940,6074,7469,
141 9185,11294,13888,17077,20999,25822,31752,39045,48012,59039,72598,
142 89272,109774,134986,165989,204111,250990,308634,379519,466683,
143 573866,705666,867737,1067031,1312097,1613447,1984009,2439678,
144 3000000};
145
146 #endif
147
148 #endif
149
150 /* local defines */
151 #define RG_TOM_INF_ALLOC(_pdu, _size, _dataPtr, _ret) {\
152    _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
153 }
154
155 /* global variables */
156 uint32_t rgUlrate_tfu;
157 #ifdef EMTC_ENABLE
158 uint32_t grgUlrate_tfu;
159 #endif
160
161 /** @brief This function fills the PDSCH data of a downlink subframe 
162  *
163  * @details
164  *
165  *     Function: rgTOMUtlFillDatReqPdus 
166  *
167  *         Processing steps:
168  *         - Fill BCCH on DLSCH data using datInfo
169  *         - Fill PCCH on DLSCH data using datInfo
170  *         - Fill Dedicated data on DLSCH data using datInfo
171  *         - Fill RA RSP data using datInfo
172  *
173  * @param  [out] TfuDatReqInfo *datInfo 
174  * @param  [in]  RgDlSf     *dlSf
175  * @param  [in]  RgCellCb   *cellCb
176  * @param  [out] RgErrInfo *err
177  * @return  S16
178  *      -# ROK 
179  *      -# RFAILED 
180  */
181 static S16 rgTOMUtlFillDatReqPdus (TfuDatReqInfo *datInfo,RgDlSf *dlSf,RgCellCb *cellCb, RgErrInfo *err)
182 {
183    S16              ret;
184    TfuDatReqPduInfo *datReq=NULLP;
185    /* Moving node declaration to limited scope for optimization */
186    RgDlHqProcCb     *hqCb;
187    uint8_t               idx;
188    Inst             inst = cellCb->macInst - RG_INST_START;
189
190
191    /* first lets send the BCCH data down to PHY */
192    if (dlSf->bcch.tb != NULLP)
193    {
194       if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
195                   &(datInfo->memCp))) != ROK)
196       {
197          err->errCause = RGERR_TOM_MEM_EXHAUST;
198          DU_LOG("\nERROR  -->  MAC : Memory Exhaustion ");
199          return (ret);
200       }
201 #ifdef TFU_ALLOC_EVENT_NO_INIT
202 #ifndef L2_OPTMZ      
203       datReq->mBuf[1] = 0;
204 #else 
205       datReq->tbInfo[0].lchInfo[0].mBuf[0]=NULLP;
206 #endif
207 #endif
208       datReq->rnti                   =  RG_SI_RNTI;
209       datReq->dciInfo                =  dlSf->bcch.pdcch.dci;
210       /* Note: SCpyMsgMsg is not done since free of unsent buffer 
211        * has been taken care through cell delete by invoking rgTomRlsSf
212        * during shutdown */
213       datReq->nmbOfTBs               =  1;
214 #ifndef L2_OPTMZ
215       datReq->mBuf[0]                =  dlSf->bcch.tb;
216 #else
217       SFndLenMsg((Buffer *)dlSf->bcch.tb, &(datReq->tbInfo[0].tbSize));
218       datReq->tbInfo[0].tbPres             = TRUE;
219       datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->bcch.tb;
220       datReq->tbInfo[0].numLch             = 1;
221       datReq->tbInfo[0].lchInfo[0].numPdu  = 1;
222
223 #ifdef TFU_ALLOC_EVENT_NO_INIT
224       datReq->tbInfo[1].tbPres             = FALSE;
225       datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
226 #endif
227 #endif
228       cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
229       datReq->lnk.node = (PTR)datReq;
230 #ifdef TFU_UPGRADE      
231       /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
232       datReq->txPwrOffset            = dlSf->bcch.txPwrOffset;
233 #endif      
234       /* Setting the pointer to NULL post transmission */
235       dlSf->bcch.tb = NULLP;
236    }
237    /* Fill PCCH data */
238    if (dlSf->pcch.tb != NULLP)
239    {
240       if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
241                   &(datInfo->memCp))) != ROK)
242       {
243          err->errCause = RGERR_TOM_MEM_EXHAUST;
244          DU_LOG("\nERROR  -->  MAC : Memory Exhaustion CRNTI:%d",datReq->rnti);
245          return (ret);
246       }
247 #ifdef TFU_ALLOC_EVENT_NO_INIT
248 #ifndef L2_OPTMZ      
249       datReq->mBuf[1] = 0;
250 #endif     
251 #endif     
252       datReq->rnti                   =  RG_P_RNTI;
253       datReq->dciInfo                = dlSf->pcch.pdcch.dci;
254       datReq->nmbOfTBs               =  1;
255 #ifndef L2_OPTMZ
256       datReq->mBuf[0]                =  dlSf->pcch.tb;
257 #else
258       SFndLenMsg((Buffer *)dlSf->pcch.tb, &datReq->tbInfo[0].tbSize);
259       datReq->tbInfo[0].tbPres             = TRUE;
260       datReq->tbInfo[0].lchInfo[0].mBuf[0] =  dlSf->pcch.tb;
261 #ifdef TFU_ALLOC_EVENT_NO_INIT
262       datReq->tbInfo[1].tbPres             = FALSE;
263       datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
264 #endif
265       datReq->tbInfo[0].numLch             = 1;
266       datReq->tbInfo[0].lchInfo[0].numPdu  = 1;
267 #endif
268       cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
269       datReq->lnk.node = (PTR)datReq;
270 #ifdef TFU_UPGRADE      
271       /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
272       datReq->txPwrOffset            = dlSf->pcch.txPwrOffset;
273 #endif      
274       dlSf->pcch.tb = NULLP;
275    }
276
277    for(idx=0; idx < dlSf->numRaRsp; idx++)
278    {
279       if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
280                   &(datInfo->memCp))) != ROK)
281       {
282          err->errCause = RGERR_TOM_MEM_EXHAUST;
283          DU_LOG("\nERROR  -->  MAC : Memory Exhaustion CRNTI:%d",
284                datReq->rnti);
285          return (ret);
286       }
287 #ifdef TFU_ALLOC_EVENT_NO_INIT
288 #ifndef L2_OPTMZ      
289       datReq->mBuf[1] = 0;
290 #endif    
291 #endif    
292       datReq->rnti                   =  dlSf->raRsp[idx].pdcch.rnti;
293       datReq->dciInfo                = dlSf->raRsp[idx].pdcch.dci;
294       datReq->nmbOfTBs               =  1;
295 #ifndef L2_OPTMZ
296       datReq->mBuf[0]                =  dlSf->raRsp[idx].rar;
297 #else
298       SFndLenMsg((Buffer *)dlSf->raRsp[idx].rar, &datReq->tbInfo[0].tbSize);
299       datReq->tbInfo[0].tbPres             = TRUE;
300       datReq->tbInfo[0].lchInfo[0].mBuf[0] =  dlSf->raRsp[idx].rar;
301 #ifdef TFU_ALLOC_EVENT_NO_INIT
302       datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
303       datReq->tbInfo[1].tbPres             = FALSE;
304 #endif
305       datReq->tbInfo[0].numLch             = 1;
306       datReq->tbInfo[0].lchInfo[0].numPdu  = 1;
307       //   prc_trace_format_string(0x40,3,"UE Id=(%d) tbSz=(%d)",datReq->rnti, datReq->tbInfo[0].tbSize);
308 #endif
309       cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
310       datReq->lnk.node = (PTR)datReq;
311 #ifdef TFU_UPGRADE      
312       /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
313       datReq->txPwrOffset            = dlSf->raRsp[idx].txPwrOffset;
314 #endif
315       dlSf->raRsp[idx].rar = NULLP;
316    }
317
318    /* Fill Dedicated UE data */
319    if (dlSf->tbs.count != 0) 
320    {
321       CmLList          *node;
322       while (dlSf->tbs.first)
323       {
324          node = dlSf->tbs.first;
325          hqCb = (RgDlHqProcCb*)node->node;
326          if ((ret = rgDHMSndDatReq (cellCb, dlSf, datInfo, hqCb, err)) != ROK)
327          {
328             DU_LOG("\nERROR  -->  MAC : DHM unable to fill DATA request");
329             err->errType = RGERR_TOM_TTIIND;
330             continue;
331          }
332       } /* end of while */
333    } 
334
335    return ROK;
336 } /* end of rgTOMUtlFillDatReqPdus*/ 
337
338 /** @brief This function does all the processing related to a single downlink
339  * subframe.
340  *
341  * @details 
342  *
343  *     Function: rgTOMUtlProcDlSf
344  *
345  *         Processing steps:
346  *         - collate control data for all UEs and send to PHY 
347  *         - collate data buffers for all UEs and send to PHY 
348  *
349  * @param  [in] RgDlSf     *dlSf
350  * @param  [in] RgCellCb   *cellCb
351  * @param  [out] RgErrInfo *err
352  * @return S16
353  */
354 /* ADD Changes for Downlink UE Timing Optimization */
355 #ifndef LTEMAC_DLUE_TMGOPTMZ 
356 static S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
357 #else
358 S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
359 #endif
360 {
361    S16               ret;
362    TfuDatReqInfo     *datInfo;
363    Inst              inst = cellCb->macInst - RG_INST_START;
364
365
366    /* Fill Data Request Info from scheduler to PHY */   
367    if ((ret = rgAllocEventMem(inst,(Ptr *)&datInfo, 
368                sizeof(TfuDatReqInfo))) != ROK)
369    {
370       DU_LOG("\nERROR  -->  MAC : Unable to Allocate TfuDatReqInfo");
371       return (ret);
372    }
373    else
374    {
375       cmLListInit(&datInfo->pdus);
376 #ifdef LTE_TDD
377       RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DELTA);
378 #else
379       RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DLDATA_DLDELTA);
380 #endif
381       datInfo->cellId = cellCb->cellId;
382       if((0 == (datInfo->timingInfo.sfn % 30)) && (0 == datInfo->timingInfo.slot))
383       {
384          //DU_LOG("5GTF_CHECK rgTOMUtlProcDlSf dat (%d : %d)\n", datInfo->timingInfo.sfn, datInfo->timingInfo.slot);
385       }
386 #ifdef TFU_ALLOC_EVENT_NO_INIT
387       datInfo->bchDat.pres = 0;
388 #endif
389
390       /* Fill BCH data */
391       if (dlSf->bch.tb != NULLP)
392       {
393          datInfo->bchDat.pres = PRSNT_NODEF;
394          datInfo->bchDat.val  = dlSf->bch.tb;
395          dlSf->bch.tb = NULLP;
396       }
397 #ifdef EMTC_ENABLE
398       /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
399       if ((ret = rgTOMEmtcUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
400       {
401          RG_FREE_MEM(datInfo);
402          return (ret);
403       }
404 #endif 
405       /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
406       if ((ret = rgTOMUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
407       {
408          DU_LOG("\nERROR  -->  MAC : Unable to send data for cell");
409          RG_FREE_MEM(datInfo);
410          return (ret);
411       }
412       if((datInfo->pdus.count) || (datInfo->bchDat.pres == TRUE))
413       {
414          /* sending the data to Phy */
415          //if (rgLIMTfuDatReq(inst,datInfo) != ROK)
416          {
417             DU_LOG("\nERROR  -->  MAC : Unable to send data info for cell");               
418          }
419       }
420       else
421       {
422          /* Nothing to send: free the allocated datInfo */
423          RG_FREE_MEM(datInfo);
424       }
425    }
426    return ROK;
427 } /* end of */
428
429 uint32_t  rgMacGT;
430
431 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
432  * with the SubHeaders list and the values of the Control elements.
433  *
434  * @details
435  *
436  *     Function: rgTOMUtlAllocPduEvnt
437  *
438  *         Processing steps:
439  *  @param[in]  Inst        inst
440  * @param  [out] RgMacPdu   **pdu
441  *
442  *  @return  S16
443  *      -# ROK 
444  *      -# RFAILED 
445  */
446 static S16 rgTOMUtlAllocPduEvnt (Inst inst,RgMacPdu **pdu)
447 {
448
449    Mem               evntMem;
450    RgUstaDgn         dgn;      /* Alarm diagnostics structure */
451    volatile uint32_t startTime=0;
452
453
454    evntMem.region = rgCb[inst].rgInit.region;
455    evntMem.pool   = rgCb[inst].rgInit.pool;
456
457    /*starting Task*/
458    SStartTask(&startTime, PID_TOMUTL_CMALLCEVT);
459
460 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
461    MS_BUF_ADD_ALLOC_CALLER();
462 #endif /* */
463
464    if (cmAllocEvnt (sizeof (RgMacPdu), RG_BLKSZ, &evntMem, (Ptr*)pdu) != ROK)
465    {
466       rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
467       rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
468             LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
469       DU_LOG("\nERROR  -->  MAC : Allocation of DUX event failed");
470       return RFAILED;
471    }
472
473    /*stoping Task*/
474    SStopTask(startTime, PID_TOMUTL_CMALLCEVT);
475
476    return ROK;
477 } /* end of */ 
478
479 /** @brief This function frees up the RgMacPdu structure that has been
480  * populated by demux.
481  *
482  * @details
483  *
484  *     Function: rgTOMUtlFreePduEvnt
485  *       - Function frees up the RgMacPdu structure, in case of error it shall
486  *       free up the buffer's present in the different sdu.
487  *
488  *         Processing steps:
489  * @param  [in]  Inst        inst
490  * @param  [in] RgMacPdu   *pdu
491  * @param  [in] Bool       *error
492  * @return 
493  */
494 static Void rgTOMUtlFreePduEvnt( RgMacPdu *pdu,Bool  error)
495 {
496
497    RgMacSdu       *sdu;
498    CmLList        *node;
499
500    /* Steps of freeing up the PDU.
501     * 1. loop through the subHdrLst and free up all the buffers.
502     * 2. free up the whole event
503     */
504    if ((error == TRUE) && (pdu->sduLst.count > 0))
505    {
506       node =  pdu->sduLst.first;
507       while (node)
508       {
509          sdu = (RgMacSdu*)node->node;
510          RG_FREE_MSG(sdu->mBuf);
511          node = node->next;
512       }
513    }
514    RG_FREE_MEM(pdu);
515    return;
516 } /* end of rgTOMUtlFreePduEvnt */ 
517
518 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
519  * with the SubHeaders list and the values of the Control elements.
520  *
521  * @details
522  *
523  *     Function: rgTOMInfAllocPduEvnt
524  *
525  *         Processing steps:
526  * @param  [in] Inst        inst
527  * @param  [out] RgMacPdu   **pdu
528  *
529  *  @return  S16
530  *      -# ROK 
531  *      -# RFAILED 
532  */
533 static S16 rgTOMInfAllocPduEvnt (Inst inst,RgInfSfDatInd **sfInfo)
534 {
535
536    Mem               evntMem;
537    RgUstaDgn         dgn;      /* Alarm diagnostics structure */
538    volatile uint32_t      startTime=0;
539
540
541    evntMem.region = rgCb[inst].rgInit.region;
542    evntMem.pool   = rgCb[inst].rgInit.pool;
543
544    /*starting Task*/
545    SStartTask(&startTime, PID_TOMINF_CMALLCEVT);
546
547 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
548    MS_BUF_ADD_ALLOC_CALLER();
549 #endif /* */
550    if (cmAllocEvnt (sizeof (RgInfSfDatInd), RG_BLKSZ, &evntMem, (Ptr*)sfInfo) != ROK)
551    {
552       rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
553       rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
554             LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
555       DU_LOG("\nERROR  -->  MAC : Allocation failed");
556       return RFAILED;
557    }
558
559    /*stoping Task*/
560    SStopTask(startTime, PID_TOMINF_CMALLCEVT);
561
562    return ROK;
563 } /* end of */ 
564
565 /** @brief This function frees up the RgMacPdu structure that has been
566  * populated by demux.
567  *
568  * @details
569  *
570  *     Function: rgTOMInfFreePduEvnt
571  *       - Function frees up the RgMacPdu structure, in case of error it shall
572  *       free up the buffer's present in the different sdu.
573  *
574  *         Processing steps:
575  * @param  [in] RgMacPdu   *pdu
576  * @param  [in] Bool       *error
577  * @return 
578  */
579 static Void rgTOMInfFreePduEvnt(RgInfSfDatInd *sfInfo)
580 {
581
582    RG_FREE_MEM(sfInfo);
583    return;
584 } /* end of rgTOMUtlFreePduEvnt */
585
586 #ifdef LTE_L2_MEAS
587
588 /** @brief This function performs the preparation of information needed to set
589  * L2M Scheduled UL Throughput Information for a particular UE.
590  *
591  * @details
592  *
593  *     Function: rgTomUtlPrepareL2MUlThrpInfo
594  *      This function performs the preparation of information needed to set
595  *       L2M Scheduled UL Throughput Information for a particular UE.
596  *
597  *
598  *         Processing steps:
599  * @param  [in] RgCellCb   *cellCb
600  * @param  [in] RgUeCb       *ueCb
601  * @param  [out] RgRguDedDatInd *dDatInd
602  * @return 
603  */
604 static S16 rgTomUtlPrepareL2MUlThrpInfo(RgCellCb *cellCb,RgUeCb *ueCb,RgRguDedDatInd *dDatInd)
605 {
606    uint8_t lcId;
607    uint8_t lcgId;
608    uint8_t loop;
609
610    dDatInd->burstInd = RGU_L2M_UL_BURST_END;
611    for(loop=0;loop<dDatInd->numLch;loop++)
612    {
613       lcId=dDatInd->lchData[loop].lcId;
614       if (lcId)
615       {
616          lcgId = ueCb->ul.lcCb[lcId - 1].lcgId;
617          if(ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs > 0)
618          {
619             dDatInd->burstInd = RGU_L2M_UL_BURST_START;
620             break;
621          }
622       }
623    }
624
625    return ROK;
626 }
627
628 #endif
629
630 /** @brief This function is called by rgTOMDatInd. This function invokes the
631  * scheduler with the information of the received Data and any Control Elements
632  * if present. Also it generates Data indications towards the higher layers.
633  *
634  * @details
635  *
636  *     Function: 
637  *
638  *         Processing steps:
639  *         - Retrieves the RaCb with the rnti provided, if it doesnt exist
640  *         return failure. 
641  *         - If UE exists then update the Schduler with any MAC CEs if present. 
642  *         - Invoke RAM module to do Msg3 related processing rgRAMProcMsg3
643  *         - Loop through the SDU subheaders and invoke either a common data
644  *         indication (rgUIMSndCmnDatInd) or dedicated data indication
645  *         (rgUIMSndDedDatInd) towards the higher layers. 
646  *
647  * @param  [in] RgCellCb   *cellCb
648  * @param  [in] RgUeCb     *ueCb
649  * @param  [in] CmLteRnti  rnti
650  * @param  [in] RgMacPdu   *pdu
651  * @param  [out] uint32_t       *lcgBytes
652  *  
653  *  @return  S16
654  *      -# ROK 
655  *      -# RFAILED 
656  */
657 RgUeCb  *glblueCb4;
658 RgUeCb  *glblueCb5;
659
660 #ifdef LTEMAC_SPS
661    static S16 rgTOMUtlProcMsg
662 (
663  RgCellCb      *cellCb, 
664  RgUeCb        *ueCb,
665  RgMacPdu      *pdu,
666  Bool          isSpsRnti,
667  Bool          *spsToBeActvtd,
668  uint16_t      *sduSize,
669  uint16_t      slot,
670  uint32_t      *lcgBytes
671  )
672 #else /* LTEMAC_SPS */
673    static S16 rgTOMUtlProcMsg
674 (
675  RgCellCb      *cellCb, 
676  RgUeCb        *ueCb,
677  RgMacPdu      *pdu,
678  uint16_t      slot,
679  uint32_t      *lcgBytes
680  )
681 #endif
682 {
683    Inst              inst = cellCb->macInst - RG_INST_START;
684    S16               ret;
685    RgRguCmnDatInd    *cDatInd;
686    RgRguDedDatInd    *dDatInd;
687    CmLList           *node;
688    RgMacSdu          *sdu;
689    MsgLen            ccchSz;
690    MsgLen            cpySz;
691 #ifdef LTEMAC_SPS
692    Pst               schPst1;  
693    //   RgInfSpsRelInfo   relInfo;
694 #endif
695
696 #ifdef LTE_L2_MEAS
697    uint8_t                idx1;
698    uint8_t                idx2;
699    RgUlSf                 *ulSf;
700    uint16_t               totalBytesRcvd = 0;
701    uint16_t               sduLen[RGU_MAX_LC] = {0};
702    uint8_t                qciVal[RGU_MAX_LC] = {0};
703    uint8_t                numPrb = 0;
704
705 #endif
706    uint8_t                lcgId;
707    MsgLen                 bufSz;
708
709    /* Moved outside of LTE_L2_MEAS
710     *          scope as this pointer will now be used to 
711     *          check for valid Logical Channel ID
712     */
713    RgUlLcCb          *ulLcCb;
714
715    cDatInd  = NULLP;
716    dDatInd  = NULLP;
717 #ifdef LTE_L2_MEAS
718    ulSf   = NULLP;
719    idx1   = 0;
720    idx2   = 0;
721 #endif
722 #ifdef SS_RBUF 
723    Void *elem = NULLP;
724 #endif
725
726    ulLcCb = NULLP;
727
728
729 #ifndef LTE_L2_MEAS      
730    UNUSED(slot);
731 #endif
732
733    if(pdu->sduLst.first)
734    {
735       sdu = (RgMacSdu*)(pdu->sduLst.first->node);
736       glblueCb4 = ueCb;
737       if ((sdu->lcId == RG_CCCH_LCID))
738       {
739          /* code for common channel dat indications */
740          if ((ret = rgAllocShrablSBuf (inst,(Data**)&cDatInd, sizeof(RgRguCmnDatInd))) != ROK)
741          {
742             return RFAILED;
743          }
744          cDatInd->cellId   = cellCb->cellId;
745          cDatInd->rnti     = ueCb->ueId;
746          /* rg001.101: Corrected lcId value for common data indication */
747          cDatInd->lcId     = cellCb->ulCcchId;
748          cDatInd->pdu      = sdu->mBuf;
749          SFndLenMsg (sdu->mBuf, &ccchSz);
750          /* Fix : syed Contention resolution ID copy should consider only
751           * 6 bytes of information from sdu->mBuf. Incase of CCCH sdu for reest
752           * message/psuedo reest message, ccchSz can go beyond 6 and can corrupt 
753           * other fields of ueCb. */
754          if (ccchSz >= RG_CRES_LEN)
755          {
756             SCpyMsgFix (sdu->mBuf, (MsgLen)0, RG_CRES_LEN, ueCb->contResId.resId,
757                   &cpySz);
758          }
759 #ifdef XEON_SPECIFIC_CHANGES
760          CM_LOG_DEBUG(CM_LOG_ID_MAC, "CCCH SDU of size(%d) received for UE(%d) CRES[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x] Time[%d %d]\n",  ((S16)ccchSz), ueCb->ueId,ueCb->contResId.resId[0], ueCb->contResId.resId[1], ueCb->contResId.resId[2], ueCb->contResId.resId[3], ueCb->contResId.resId[4], ueCb->contResId.resId[5], cellCb->crntTime.sfn,  cellCb->crntTime.slot);
761 #endif
762          sdu->mBuf = NULLP;
763          rgUIMSndCmnDatInd(inst,cellCb->rguUlSap,cDatInd);
764          return ROK;
765       } /* end of common channel processing */
766 #ifndef SS_RBUF 
767       if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
768       {
769          return RFAILED;
770       }
771 #else
772       glblueCb5 = ueCb;
773       elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
774       if (NULLP == elem)
775       { 
776          return RFAILED;
777       }
778       dDatInd = (RgRguDedDatInd *)elem;
779       memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
780 #endif
781       dDatInd->cellId   = cellCb->cellId;
782       dDatInd->rnti     = ueCb->ueId;
783       dDatInd->numLch   = 0;
784    }
785 #ifdef LTE_L2_MEAS
786    ulSf = &cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)];
787    if(ulSf->ueUlAllocInfo != NULLP)
788    {
789       for(idx1 = 0; idx1 < ulSf->numUe; idx1++)
790       {
791          if(ulSf->ueUlAllocInfo[idx1].rnti == ueCb->ueId)
792          {
793             numPrb = ulSf->ueUlAllocInfo[idx1].numPrb;
794             break;
795          }
796       }
797    }
798 #endif
799    node =  pdu->sduLst.first;
800    while (node)
801    {
802       sdu = (RgMacSdu*)node->node;
803
804       ulLcCb = rgDBMGetUlDedLcCb (ueCb, sdu->lcId);
805
806       if(ulLcCb == NULLP)
807       {
808          DU_LOG("\nERROR  -->  MAC : Unconfigured LCID:%d CRNTI:%d"
809                ,sdu->lcId,ueCb->ueId);
810          /* ccpu00128443: Fix for memory leak */
811          /* Fix : syed Neccessary to set sdu->mBuf = NULLP */
812          RG_FREE_MSG(sdu->mBuf);         
813          node = node->next;
814          continue;
815       }
816 #ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */
817       {
818          S16 rlcProcDlStatusPdu(Pst       *udxPst,SuId      suId,
819                CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu);
820
821          if(ROK == rlcProcDlStatusPdu(&(cellCb->rguDlSap->sapCfg.sapPst),
822                   cellCb->rguDlSap->sapCfg.suId,
823                   cellCb->cellId,ueCb->ueId,sdu->lcId,sdu->mBuf))
824          {
825             RG_FREE_MSG(sdu->mBuf);           
826             node = node->next;
827             continue;
828          }
829       }
830 #endif
831
832       /* ccpu00116477- Fixed the rgUIMSndDedDatInd condition when we receive 11 sdus in the 
833        * list we are losing 11th sdu and sending the first 10 sdus again which
834        * is causing the duplicate packets and eNB crashing due to access
835        * of the freed memory */
836       if (dDatInd->numLch >= RGU_MAX_LC)
837       {
838          if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
839          {
840             DU_LOG("\nERROR  -->  MAC : Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
841             return (ret);
842          }
843 #ifndef SS_RBUF
844          if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
845          {
846             return RFAILED;
847          }
848 #else
849          elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
850          if (NULLP == elem)
851          { 
852             return RFAILED;
853          }
854          dDatInd = (RgRguDedDatInd *)elem;
855          memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
856 #endif
857          dDatInd->cellId   = cellCb->cellId;
858          dDatInd->rnti     = ueCb->ueId;
859          dDatInd->numLch   = 0;
860       }
861       dDatInd->lchData[dDatInd->numLch].lcId = sdu->lcId;
862       dDatInd->lchData[dDatInd->numLch].pdu.mBuf[dDatInd->lchData[dDatInd->numLch].pdu.numPdu] = sdu->mBuf;
863       dDatInd->lchData[dDatInd->numLch].pdu.numPdu++;
864       lcgId = ulLcCb->lcgId;
865       SFndLenMsg(sdu->mBuf, &bufSz);
866 #ifdef LTE_L2_MEAS
867       if(ulLcCb->measOn)
868       {
869          ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs -= bufSz; 
870       }
871 #endif
872       //if ((lcgBytes != NULLP) && (ueCb->ul.lcgArr[lcgId].isGbr == TRUE))
873       if (lcgBytes != NULLP)
874       {
875          lcgBytes[lcgId] += bufSz;
876       }
877       sdu->mBuf = NULLP;
878       dDatInd->numLch++;
879 #ifdef LTEMAC_SPS
880       /* Check if data has come on SPS LC */
881       /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */
882       if (ueCb->ul.spsLcId[sdu->lcId-1] == TRUE)
883       {
884          ueCb->ul.spsDatRcvd++;
885       }
886
887       if(isSpsRnti)
888       {
889          /* Data rcvd on CRNTI*/
890          /* Retrieve the LCG ID of the LCID*/
891          /* SPS LCG has data whose size > SID Size */
892          /* Activate SPS if data recvd on SPS LCID and size > SID Packet Size */
893          if((ueCb->ul.spsLcId[sdu->lcId-1] == TRUE) &&
894                (sdu->len > RG_SPS_SID_PACKET_SIZE))
895          {
896             *spsToBeActvtd = TRUE;
897             *sduSize = sdu->len;
898          }
899       }
900
901 #endif  
902
903 #ifdef LTE_L2_MEAS
904       if(cellCb->qciArray[ulLcCb->qci].mask == TRUE)
905       {
906          sduLen[ulLcCb->qci] = sdu->len;
907          totalBytesRcvd += sdu->len;
908          qciVal[ulLcCb->qci] = ulLcCb->qci;
909       }
910 #endif
911       node = node->next;
912    } /* end of while for SubHeaders */
913 #ifdef LTE_L2_MEAS
914    for(idx2 = 0; idx2 < RGU_MAX_LC; idx2++)
915    {
916       if((cellCb->qciArray[qciVal[idx2]].mask == TRUE) &&
917             totalBytesRcvd > 0)
918       {
919          cellCb->qciArray[qciVal[idx2]].prbCount += 
920             ((numPrb * sduLen[idx2]) / totalBytesRcvd);
921       }
922
923       /* RRM_RBC_X */
924       if(totalBytesRcvd > 0 && qciVal[idx2] > 0)
925       {
926          RG_UPD_GBR_PRB(cellCb, qciVal[idx2], ((numPrb * sduLen[idx2])/totalBytesRcvd));
927       }
928       /* RRM_RBC_Y */
929    }
930 #endif
931    /*Added for explicit release - start*/
932 #ifdef LTEMAC_SPS
933
934    if(isSpsRnti && dDatInd && dDatInd->numLch)
935    {
936       if(ueCb->ul.spsDatRcvd != 0)
937       {
938          ueCb->ul.explRelCntr = 0;
939          ueCb->ul.spsDatRcvd = 0;
940       }
941       else
942       {
943          ueCb->ul.explRelCntr++;
944          if (ueCb->ul.explRelCntr == ueCb->ul.explRelCnt)
945          {
946             ueCb->ul.explRelCntr = 0;
947             /* Indicate scheduler for explicit release */
948             memset(&schPst1, 0, sizeof(Pst));
949             rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
950             //TODO: commented for compilation without SCH 
951 #if 0
952             relInfo.cellSapId = cellCb->schInstMap.cellSapId;
953             relInfo.cRnti = ueCb->ueId;
954             relInfo.isExplRel = TRUE;
955             /* Release indicator is called now through the matrix in the function below */
956             //TODO: commented for compilation without SCH RgMacSchSpsRel( &schPst1, &relInfo );
957 #endif
958             ueCb->ul.implRelCntr = 0;
959          }
960       }
961    } 
962    else
963    {
964       /* SPS_FIX */
965       if(ueCb->ul.spsDatRcvd != 0)
966       {
967          //ueCb->ul.implRelCntr = 0;
968          ueCb->ul.explRelCntr = 0;
969          ueCb->ul.spsDatRcvd = 0;
970       }
971    }
972 #endif
973    /*Added for explicit release - end */
974
975    if((dDatInd) && (dDatInd->numLch))
976    {
977 #ifdef LTE_L2_MEAS
978       rgTomUtlPrepareL2MUlThrpInfo(cellCb, ueCb,dDatInd);
979
980       RG_CALC_TTI_CNT(cellCb, dDatInd->ttiCnt); 
981 #endif
982       if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
983       {
984          DU_LOG("\nERROR  -->  MAC : Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
985          return (ret);
986       }
987    }
988 #ifndef SS_RBUF
989    else if((dDatInd) && (0 == dDatInd->numLch))
990    {
991       /* Free the memory allocated for dDatInd if we 
992        * have no valid LCH PDU to send to RLC.*/
993       rgFreeSharableSBuf(inst,(Data **)&dDatInd,sizeof(RgRguDedDatInd)); 
994    }
995 #endif
996    return ROK;
997 } /* end of */ 
998
999 /** @brief This function frees up the RgMacPdu structure that has been
1000  * populated by demux.
1001  *
1002  * @details
1003  *
1004  *     Function: rgTOMUtlInsSchInfo
1005  *       - Function frees up the RgMacPdu structure, in case of error it shall
1006  *       free up the buffer's present in the different sdu.
1007  *
1008  *         Processing steps:
1009  * @param  [in] RgMacPdu   *pdu
1010  * @param  [in] Bool       *error
1011  * @return 
1012  */
1013 #ifdef LTEMAC_SPS
1014    static S16 rgTOMUtlInsSchInfo
1015 (
1016  RgMacPdu *pdu,
1017  RgInfSfDatInd *sfInfo,
1018  RgInfCeInfo   *ceInfo,
1019  CmLteRnti      rnti,
1020  Bool           spsToBeActvtd,
1021  uint16_t       sduSize,
1022  uint32_t       *lcgBytes
1023  )
1024 #else
1025    static S16 rgTOMUtlInsSchInfo
1026 (
1027  RgMacPdu *pdu,
1028  RgInfSfDatInd *sfInfo,
1029  RgInfCeInfo *ceInfo,
1030  CmLteRnti   rnti,
1031  uint32_t    *lcgBytes
1032  )
1033 #endif
1034 {
1035    S16            ret;
1036    RgInfUeDatInd *ueInfo;
1037    uint32_t       lcgId = 0;
1038    uint32_t       idx = 0;
1039
1040
1041    RG_TOM_INF_ALLOC(sfInfo, sizeof(RgInfUeDatInd), ueInfo, ret);
1042
1043    if(ROK != ret)
1044    {
1045       return RFAILED;
1046    }
1047
1048    ueInfo->rnti = rnti; 
1049
1050    ueInfo->ceInfo = *ceInfo;
1051    ueInfo->ueLstEnt.node = (PTR)ueInfo;
1052    for (lcgId = 1, idx = 0; lcgId < RGINF_MAX_LCG_PER_UE; lcgId++)
1053    {
1054       if (lcgBytes[lcgId] != 0)
1055       {
1056          /* Only GBR bytes */
1057          ueInfo->lcgInfo[idx].lcgId     = lcgId;
1058          ueInfo->lcgInfo[idx++].bytesRcvd = lcgBytes[lcgId];
1059          lcgBytes[lcgId] = 0;
1060       }
1061    }
1062    cmLListAdd2Tail(&sfInfo->ueLst, &ueInfo->ueLstEnt);
1063    return ROK;
1064 } /* end of rgTOMUtlInsSchInfo */
1065
1066 #include <stdlib.h>
1067 /**
1068  * @brief Handler for processing data indication recieved from PHY for UEs.
1069  *
1070  * @details
1071  *
1072  *     Function: rgTOMDatInd
1073  *
1074  *     Handler for processing data indication recieved from PHY for UEs.
1075  *
1076  *     Invoked by: RgLiTfuDatInd of LIM 
1077  *
1078  *     Processing Steps: 
1079  *     For each DataInfo recieved
1080  *      - Validate the information received and retrieve cellCb 
1081  *        Validate cellId, rnti 
1082  *      - Call De-Mux module to decode the data rgDUXDemuxData
1083  *      - If  received a CRNTI control element 
1084  *          - Check if a CCCH SDU is present, if it is return failure
1085  *          - Check for the existence of UE, if its isnt present return failure.
1086  *          - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1087  *          primarily informs the scheduler about the data received and
1088  *          generates Data indications towards the higher layer.
1089  *      - If only CCCH SDU is present
1090  *        - Invoke rgTOMUtlProcMsg3 for further processing.
1091  *      - If its a non-Msg3 PDU i.e. received outside of a RA procedure
1092  *        - Retrieve the UeCB 
1093  *        - Validate that the received PDU contains only configured Logical
1094  *        Channels.
1095  *        - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
1096  *        scheduler with the information of the received Data and generates
1097  *        DatIndications towards the higher layers. 
1098  *           
1099  * @param  [in] Inst        inst
1100  *  @param[in]  TfuDatIndInfo *datInd
1101  *  @return  S16
1102  *      -# ROK 
1103  *      -# RFAILED 
1104  **/
1105 S16 rgTOMDatInd(Inst inst, TfuDatIndInfo *datInd)
1106 {
1107    S16               ret = ROK;
1108    RgErrInfo         err;
1109    RgUeCb            *ueCb;
1110    RgUeCb            *prevUeCb = NULLP;
1111    RgCellCb          *cellCb;
1112    RgMacPdu          *pdu;
1113    RgInfSfDatInd     *sfInfo;
1114    RgInfCeInfo       ceInfo; 
1115    Pst               schPst;
1116    CmLList           *node;
1117    TfuDatInfo        *datInfo;
1118    RgLowSapCb        *tfuSap;
1119    uint16_t          slot;
1120 #ifdef LTEMAC_SPS
1121    Bool              isSpsRnti=FALSE;
1122    Pst               schPst1;  
1123    // RgInfSpsRelInfo   relInfo;
1124    Bool              spsToBeActvtd = FALSE;
1125    uint16_t          sduSize = 0;
1126 #endif
1127    uint32_t          lcgBytes[RGINF_MAX_LCG_PER_UE];
1128
1129
1130 #ifdef STUB_TTI_HANDLING_5GTF 
1131    node =  datInd->datIndLst.first;
1132    for (;node; node=node->next)
1133    {
1134       datInfo = (TfuDatInfo*)node->node;
1135       {
1136          MsgLen len;
1137          SFndLenMsg(datInfo->mBuf, &len);
1138          rgUlrate_tfu += len;
1139          if (rgUlrate_tfu > 100000)
1140          {
1141             DU_LOG("\nINFO  -->  MAC : rgTOMDatInd datInfo->mBuf len =%d rgUlrate_tfu=%d",len,rgUlrate_tfu);
1142             rgUlrate_tfu = 0;
1143          }
1144       }
1145    }
1146    return(RFAILED);
1147 #endif      
1148
1149    memset(&lcgBytes, 0, sizeof(lcgBytes));
1150
1151    tfuSap = &(rgCb[inst].tfuSap);
1152    ueCb = NULLP;
1153    cellCb = rgCb[inst].cell;
1154    if((cellCb == NULLP) ||
1155          (cellCb->cellId != datInd->cellId))   
1156    {
1157
1158       DU_LOG("\nERROR  -->  MAC : Unable to get the cellCb for cell");
1159       return RFAILED;
1160    }
1161    /* Avoiding memset as all the fields are getting initialized further */
1162
1163    if (rgTOMInfAllocPduEvnt (inst,&sfInfo) != ROK)
1164    {
1165       err.errType = RGERR_TOM_DATIND;
1166       DU_LOG("\nERROR  -->  MAC : Unable to Allocate PDU for DUX cell");
1167       node =  datInd->datIndLst.first;
1168       return RFAILED;
1169    }
1170    cmLListInit(&sfInfo->ueLst);
1171    sfInfo->cellId = datInd->cellId;
1172    sfInfo->timingInfo = datInd->timingInfo;
1173    slot = datInd->timingInfo.slot;
1174
1175    node =  datInd->datIndLst.first;
1176    for (;node; node=node->next)
1177    {
1178       datInfo = (TfuDatInfo*)node->node;
1179       {
1180          //uint32_t ulrate_tfu;
1181          MsgLen len;
1182          SFndLenMsg(datInfo->mBuf, &len);
1183 #ifdef STUB_TTI_HANDLING_5GTF         
1184          //  DU_LOG(":rgTOMDatInd datInfo->mBuf len =%d",len);
1185 #endif
1186          rgUlrate_tfu += len;
1187 #ifdef EMTC_ENABLE
1188          grgUlrate_tfu += len;
1189 #endif
1190       }
1191 #ifdef STUB_TTI_HANDLING_5GTF         
1192       rgLIMUtlFreeDatIndEvnt(datInd,TRUE);
1193 #endif
1194       /* We shall call De-Mux to process the received buffer. We shall try and find
1195        * out the RaCb based on the following - 
1196        * 1. If the incoming PDU contained a CCCH SDU i.e. this is message 3.
1197        * 2. If the incoming PDU contained a CRNTI control element, i.e. we should
1198        * have a ueCb also for this 
1199        */
1200       /* Lets allocate the event that needs to be passed to DUX */
1201       if (rgTOMUtlAllocPduEvnt (inst,&pdu) != ROK)
1202       {
1203          err.errType = RGERR_TOM_DATIND;
1204          DU_LOG("\nERROR  -->  MAC : Unable to Allocate PDU for DUX cell");
1205          rgTOMInfFreePduEvnt (sfInfo);
1206          return RFAILED;
1207       }
1208
1209       if ((ret = rgDUXDemuxData (inst,pdu, &ceInfo, 
1210                   &datInfo->mBuf, &err)) != ROK)
1211       {
1212          //exit(1);
1213          /* Fix: sriky memory corruption precautions */
1214          rgTOMUtlFreePduEvnt (pdu, TRUE);
1215          err.errType = RGERR_TOM_DATIND;
1216          DU_LOG("\nERROR  -->  MAC : DUX processing failed");
1217          tfuSap->sapSts.numPduDrop++;
1218          continue; 
1219       }
1220       /* It could be that a non-msg3 pdu contains a CRNTI Control element. We
1221        * should check for CRNTI CE and if it exists the UECb must exist, also an
1222        * if the CRNTI in the CE and the one with which the message came in are
1223        * different we shall look for an raCb as well. 
1224        */
1225
1226       if (ceInfo.bitMask & RG_CCCH_SDU_PRSNT)
1227       {
1228          ret = rgTOMProcCCCHSduInDatInd(pdu, prevUeCb, \
1229                cellCb, datInfo, &ceInfo, slot);
1230          if (ret == RFAILED)
1231          {
1232             rgTOMUtlFreePduEvnt (pdu, TRUE);
1233             err.errType = RGERR_TOM_DATIND;
1234             tfuSap->sapSts.numPduDrop++;
1235             continue; 
1236          }
1237       } /* end of Msg3 processing */
1238
1239       else if (ceInfo.bitMask & RG_CRNTI_CE_PRSNT)
1240       {
1241          ret = rgTOMProcCrntiCEInDatInd(pdu, prevUeCb, \
1242                cellCb, datInfo, &ceInfo, slot);
1243          if (ret == RFAILED)
1244          {
1245             rgTOMUtlFreePduEvnt (pdu, TRUE);
1246             err.errType = RGERR_TOM_DATIND;
1247             tfuSap->sapSts.numPduDrop++;
1248             continue; 
1249          }
1250
1251       } /* end of CRNTI based message */
1252       else
1253       {
1254          ueCb = rgDBMGetUeCb (cellCb, datInfo->rnti);
1255          if (ueCb == NULLP)
1256          {
1257 #ifdef LTEMAC_SPS
1258             /* Try getting the UE using SPS-RNTI. */
1259             ueCb = rgDBMGetSpsUeCb (cellCb, datInfo->rnti);
1260             if (ueCb != NULLP)
1261             {
1262                isSpsRnti = TRUE;
1263                /* Increment implrelCntr for an empty transmission */
1264                if (pdu->sduLst.count == 0)
1265                {
1266                   ueCb->ul.implRelCntr++;
1267                   if (ueCb->ul.implRelCntr == ueCb->ul.implRelCnt)
1268                   {
1269                      /* Indicate scheduler for implicit release */
1270                      memset(&schPst1, 0, sizeof(Pst));
1271                      rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
1272
1273                      ueCb->ul.implRelCntr = 0;
1274                      ueCb->ul.explRelCntr = 0;
1275 #if 0                     
1276                      relInfo.cellSapId = cellCb->schInstMap.cellSapId;
1277                      relInfo.cRnti = ueCb->ueId;
1278                      relInfo.isExplRel= FALSE;
1279                      //TODO: commented for compilation without SCH RgMacSchSpsRel(&schPst1, &relInfo);
1280 #endif  
1281                   }
1282                }
1283                else
1284                {
1285                   /* Reset the implrelCntr */
1286                   ueCb->ul.implRelCntr = 0;
1287                }
1288             }
1289             else
1290 #endif 
1291             {
1292                /* Perform failure if ueCb is still NULLP */
1293                rgTOMUtlFreePduEvnt (pdu, TRUE);
1294                err.errType = RGERR_TOM_DATIND;
1295                DU_LOG("\nERROR  -->  MAC : RNTI:%d Unable to get the UE CB", 
1296                      datInfo->rnti);
1297                tfuSap->sapSts.numPduDrop++;
1298                continue;
1299             }
1300          }
1301 #ifdef LTE_L2_MEAS         
1302          rgTOMUtlL2MStoreBufSz(ueCb, &ceInfo);
1303          rgTOML2MCompileActiveLCs (cellCb, ueCb, pdu, &ceInfo);
1304 #endif
1305 #ifdef LTEMAC_SPS
1306          if ((ret = rgTOMUtlProcMsg(cellCb, ueCb, pdu, isSpsRnti,&spsToBeActvtd,&sduSize, slot, (uint32_t *)&lcgBytes)) != ROK)
1307 #else
1308             if ((ret = rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, (uint32_t *)&lcgBytes)) != ROK)
1309 #endif /* LTEMAC_SPS */
1310             {
1311                rgTOMUtlFreePduEvnt (pdu, TRUE);
1312                err.errType = RGERR_TOM_DATIND;
1313                DU_LOG("\nERROR  -->  MAC : Unable to handle Data Indication CRNTI:%d",ueCb->ueId);
1314                tfuSap->sapSts.numPduDrop++;
1315                continue;
1316             }
1317       }
1318
1319
1320 #ifdef LTEMAC_SPS
1321       if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti,spsToBeActvtd,sduSize, (uint32_t *)&lcgBytes) != ROK)
1322 #else
1323          if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti, (uint32_t *)&lcgBytes) != ROK)
1324 #endif
1325
1326          {
1327             rgTOMInfFreePduEvnt (sfInfo);
1328             rgTOMUtlFreePduEvnt (pdu, FALSE);
1329             return RFAILED;
1330          }
1331       /* free up the PDU memory */
1332       rgTOMUtlFreePduEvnt (pdu, FALSE);
1333    }
1334    /* Free the allocated memory for ueUlAllocInfo here */
1335 #ifdef LTE_L2_MEAS
1336    if(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo != NULLP)
1337    {
1338       /*ccpu00117052 - MOD - Passing double for proper NULLP
1339         assignment */
1340       rgFreeSBuf(inst,(Data **)&(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo), 
1341             ((cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].numUe) * sizeof(RgUeUlAlloc)));
1342    }
1343 #endif
1344    /* RRM_RBC_X */
1345    /* Update PRB used for all GBR QCIs to scheduler */
1346    memcpy( &sfInfo->qcisUlPrbCnt[0],
1347          &cellCb->qcisUlPrbCnt[0],
1348          (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1349    /* clear the cellCb ul prb value */
1350    memset(&cellCb->qcisUlPrbCnt[0], 0, 
1351          (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1352
1353    /* RRM_RBC_Y */
1354
1355    rgGetPstToInst(&schPst, inst,cellCb->schInstMap.schInst);
1356    sfInfo->cellSapId = cellCb->schInstMap.cellSapId;
1357    //TODO: commented for compilation without SCH RgMacSchSfRecp(&schPst, sfInfo);
1358    return ROK;
1359 }  /* rgTOMDatInd */
1360
1361 /**
1362  * @brief Function handles allocation for common channels i.e. BCCH-BCH,
1363  * BCCH-DLSCH, PCCH-DLSCH.
1364  *
1365  * @details
1366  *
1367  *     Function : rgHndlCmnChnl
1368  *     
1369  *     This function is invoked from RgSchMacSfAllocReq. This function handles
1370  *     allocations made for common channels like BCCH and PCCH. 
1371  *
1372  *     Processing steps:
1373  *     1. If BCCH on BCH has been scheduled, send StatusIndication on RGU.
1374  *     2. If PCCH is scheduled, send StatusIndication on RGU.
1375  *     3. If BCCH on DLSCH has been scheduled and sndStatInd is TRUE, send
1376  *     StatusIndication on RGU, else copy the bcch buffer onto the downlink
1377  *     subframe. 
1378  *     
1379  *           
1380  *  @param[in] RgCellCb          *cell,
1381  *  @param[in] CmLteTimingInfo   timingInfo,
1382  *  @param[in] RgInfCmnLcInfo    *cmnLcInfo,
1383  *  @param[in/out] RgErrInfo     *err,
1384  *  @return  S16
1385  *      -# ROK 
1386  *      -# RFAILED
1387  **/
1388    static S16 rgHndlCmnChnl
1389 (
1390  RgCellCb            *cell,
1391  CmLteTimingInfo     timingInfo,
1392  RgInfCmnLcInfo      *cmnLcInfo,
1393  RgErrInfo           *err
1394  )
1395 {
1396 #if (ERRCLASS & ERRCLS_DEBUG)
1397    RgPcchLcCb           *pcch;
1398 #endif
1399 #ifndef RGR_SI_SCH
1400    RgBcchDlschLcCb      *bcch;
1401 #if (ERRCLASS & ERRCLS_DEBUG)
1402    RgBcchBchLcCb        *bch;
1403 #endif
1404 #endif/*RGR_SI_SCH*/
1405    RguCStaIndInfo       *staInd;
1406    RgDlSf               *dlSf;
1407    Inst                 inst = cell->macInst - RG_INST_START;
1408
1409
1410    dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
1411
1412    if(cmnLcInfo->bitMask & RGINF_BCH_INFO)
1413    {
1414 #ifndef RGR_SI_SCH
1415 #if (ERRCLASS & ERRCLS_DEBUG) 
1416       if(NULLP == (bch = rgDBMGetBcchOnBch(cell)))
1417       {
1418          return RFAILED;
1419       }
1420       if(cmnLcInfo->bchInfo.lcId != bch->lcId)
1421       {
1422          return RFAILED;
1423       }
1424 #endif
1425
1426       if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1427       {
1428          err->errCause = RGERR_TOM_MEM_EXHAUST;
1429          return RFAILED;
1430       }
1431       staInd->cellId = cell->cellId;
1432       staInd->rnti   = RG_INVALID_RNTI;
1433       staInd->lcId   = cmnLcInfo->bchInfo.lcId;
1434       staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1435       /* ADD Changes for Downlink UE Timing Optimization */
1436 #ifdef LTEMAC_DLUE_TMGOPTMZ
1437       dlSf->remDatReqCnt++;
1438 #endif
1439       if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1440       {
1441          return RFAILED;
1442       }
1443 #else
1444       /*Store the received BCH Data in the scheduled subframe*/
1445       dlSf->bch.tb = cmnLcInfo->bchInfo.pdu;
1446 #endif/*RGR_SI_SCH*/
1447    }
1448
1449    if(cmnLcInfo->bitMask & RGINF_PCCH_INFO)
1450    {
1451 #if (ERRCLASS & ERRCLS_DEBUG) 
1452       if(NULLP == (pcch = rgDBMGetPcch(cell)))
1453       {
1454          return RFAILED;
1455       }
1456       if(cmnLcInfo->pcchInfo.lcId != pcch->lcId)
1457       {
1458          return RFAILED;
1459       }
1460 #endif
1461
1462       dlSf->pcch.pdcch.rnti = 
1463          cmnLcInfo->pcchInfo.rnti;
1464       dlSf->pcch.pdcch.dci = 
1465          cmnLcInfo->pcchInfo.dciInfo;
1466 #ifdef TFU_UPGRADE               
1467       /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */         
1468       dlSf->pcch.txPwrOffset = cmnLcInfo->pcchInfo.txPwrOffset;         
1469 #endif
1470       if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1471       {
1472          err->errCause = RGERR_TOM_MEM_EXHAUST;
1473          return RFAILED;
1474       }
1475       staInd->cellId = cell->cellId;
1476       staInd->rnti   = RG_INVALID_RNTI;
1477       staInd->lcId   = cmnLcInfo->pcchInfo.lcId;
1478       staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1479       /* ADD Changes for Downlink UE Timing Optimization */
1480 #ifdef LTEMAC_DLUE_TMGOPTMZ
1481       dlSf->remDatReqCnt++;
1482 #endif
1483       /* for consolidated CmnStaInd calling below function from function 
1484        * rgHndlSchedUe once CmnStaInd prepared for all UEs
1485        */
1486       if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1487       {
1488          return RFAILED;
1489       }
1490    }
1491
1492    if(cmnLcInfo->bitMask & RGINF_BCCH_INFO)
1493    {
1494       dlSf->bcch.pdcch.rnti = 
1495          cmnLcInfo->bcchInfo.rnti;
1496       dlSf->bcch.pdcch.dci = 
1497          cmnLcInfo->bcchInfo.dciInfo;
1498 #ifdef TFU_UPGRADE               
1499       /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */         
1500       dlSf->bcch.txPwrOffset = cmnLcInfo->bcchInfo.txPwrOffset;         
1501 #endif      
1502 #ifndef RGR_SI_SCH
1503       if(NULLP == 
1504             (bcch=rgDBMGetBcchOnDlsch(cell,cmnLcInfo->bcchInfo.lcId)))
1505       {
1506          return RFAILED;
1507       }
1508       if(TRUE == cmnLcInfo->bcchInfo.sndStatInd)
1509       {
1510          RG_FREE_MSG(bcch->tb);
1511          if (rgAllocShrablSBuf (inst,(Data**)&staInd, 
1512                   sizeof(RguCStaIndInfo)) != ROK)
1513          {
1514             err->errCause = RGERR_TOM_MEM_EXHAUST;
1515             return RFAILED;
1516          }
1517          staInd->cellId = cell->cellId;
1518          staInd->rnti   = RG_INVALID_RNTI;
1519          staInd->lcId   = cmnLcInfo->bcchInfo.lcId;
1520          staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1521          /* ADD Changes for Downlink UE Timing Optimization */
1522 #ifdef LTEMAC_DLUE_TMGOPTMZ
1523          dlSf->remDatReqCnt++;
1524 #endif
1525          if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1526          {
1527             return RFAILED;
1528          }
1529       }
1530       else
1531       {
1532          SCpyMsgMsg(bcch->tb, RG_GET_MEM_REGION(rgCb[inst]),
1533                RG_GET_MEM_POOL(rgCb[inst]), &dlSf->bcch.tb);
1534       }
1535 #else
1536       /*Store the received BCCH Data in the scheduled subframe*/
1537       dlSf->bcch.tb = cmnLcInfo->bcchInfo.pdu;
1538 #endif/*RGR_SI_SCH*/
1539    }
1540
1541    return ROK;
1542 } /* end of rgHndlCmnChnl */
1543
1544 /**
1545  * @brief Function for handling allocations for dedicated channels for a
1546  * subframe.
1547  *
1548  * @details
1549  *
1550  *     Function : rgHndlSchdUe
1551  *     
1552  *     This function shall be invoked whenever scheduler is done with the
1553  *     allocations of dedicated channels for a subframe. Invoked by the function
1554  *     RgSchMacSfAllocReq.
1555  *
1556  *     Processing steps :
1557  *     1. Loops through the list of UE's scheduled looking for the corresponding
1558  *     ueCb/raCb. 
1559  *     2. Finds the corresponding HARQ process.
1560  *     3. Invokes the DHM function to issue StatusIndications on RGU.
1561  *
1562  *           
1563  *  @param[in] RgCellCb            *cell,
1564  *  @param[in] CmLteTimingInfo     timingInfo,
1565  *  @param[in] RgInfUeInfo         *ueInfo
1566  *  @param[in/out] RgErrInfo       *err
1567  *  @return  S16
1568  *      -# ROK 
1569  *      -# RFAILED 
1570  **/
1571    static S16 rgHndlSchdUe
1572 (
1573  RgCellCb            *cell,
1574  CmLteTimingInfo     timingInfo,
1575  RgInfUeInfo         *ueInfo,
1576  RgErrInfo           *err
1577  )
1578 {
1579
1580
1581    if(NULLP == ueInfo->allocInfo)
1582    {
1583       return RFAILED;
1584    }
1585
1586    rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err);
1587
1588    return ROK;
1589 } /* end of rgHndlSchdUe */
1590
1591 #ifdef LTE_L2_MEAS
1592 /**
1593  * @brief Function for handling Uplink allocations for Ue for a
1594  * subframe.
1595  *
1596  * @details
1597  *
1598  *     Function : rgHndlUlUeInfo
1599  *     
1600  *  @param[in] RgCellCb            *cell,
1601  *  @param[in] CmLteTimingInfo     timingInfo,
1602  *  @param[in] RgInfUlUeInfo       *ueInfo
1603  *  @return  S16
1604  *      -# ROK 
1605  *      -# RFAILED 
1606  **/
1607    static S16 rgHndlUlUeInfo
1608 (
1609  RgCellCb            *cell,
1610  CmLteTimingInfo     timingInfo,
1611  RgInfUlUeInfo       *ueInfo
1612  )
1613 {
1614    Inst           inst = cell->macInst - RG_INST_START;
1615    uint8_t        idx;
1616    RgUlSf         *ulSf;
1617    S16            ret;
1618
1619
1620    ulSf = &cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)];
1621
1622    /* rg003.301-MOD- Corrected the purifier memory leak */
1623    if (ulSf->numUe != ueInfo->numUes)
1624    {
1625       if (ulSf->ueUlAllocInfo)
1626       {
1627          rgFreeSBuf(inst,(Data **)&(ulSf->ueUlAllocInfo),
1628                ulSf->numUe * sizeof(RgUeUlAlloc));
1629       }
1630    }
1631 #ifdef XEON_SPECIFIC_CHANGES
1632    CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_FREE);
1633    CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES),  CM_DBG_MEAS_FREE, ulSf->numUe);
1634 #endif
1635    ulSf->numUe         = ueInfo->numUes;
1636    if((ulSf->ueUlAllocInfo == NULLP) && (ueInfo->numUes > 0))
1637    {
1638       /* Allocate memory for ulAllocInfo */
1639       if((ret = rgAllocSBuf(inst,(Data**)&(cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)].
1640                      ueUlAllocInfo), ueInfo->numUes *  sizeof(RgUeUlAlloc))) != ROK)
1641       {
1642          return (ret);
1643       }
1644    }
1645 #ifdef XEON_SPECIFIC_CHANGES
1646    CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_ALLOC);
1647    CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_ALLOC, ueInfo->numUes);
1648 #endif
1649    if (ulSf->ueUlAllocInfo != NULLP)
1650    {
1651       for(idx = 0; idx < ueInfo->numUes; idx++)
1652       {
1653          ulSf->ueUlAllocInfo[idx].rnti   = ueInfo->ulAllocInfo[idx].rnti;
1654          ulSf->ueUlAllocInfo[idx].numPrb = ueInfo->ulAllocInfo[idx].numPrb;
1655       }
1656    }
1657    RGCPYTIMEINFO(timingInfo, ulSf->schdTime);
1658    return ROK;
1659 } /* end of rgHndlUlUeInfo */
1660 #endif
1661 /**
1662  * @brief Function for handling RaResp request received from scheduler to MAC
1663  *
1664  * @details
1665  *
1666  *     Function : rgTOMRlsSf
1667  *     
1668  *     This function shall be invoked whenever scheduler is done with the
1669  *     allocations of random access responses for a subframe.
1670  *     This shall invoke RAM to create ueCbs for all the rapIds allocated and 
1671  *     shall invoke MUX to create RAR PDUs for raRntis allocated.
1672  *     
1673  *           
1674  *  @param[in] Inst        inst
1675  *  @param[in] CmLteCellId         cellId,
1676  *  @param[in] CmLteTimingInfo     timingInfo,
1677  *  @param[in] RaRespInfo          *rarInfo
1678  *  @return  S16
1679  *      -# ROK 
1680  **/
1681 Void rgTOMRlsSf(Inst inst,RgDlSf *dlSf)
1682 {
1683    uint8_t          idx;
1684
1685
1686    if(dlSf->txDone == FALSE)
1687    {
1688       DU_LOG("\nERROR  -->  MAC : SUBFRAME Not pushed to the PHY");
1689
1690       if (dlSf->bch.tb != NULLP)
1691       {
1692          RG_FREE_MSG(dlSf->bch.tb);
1693       }
1694       if (dlSf->bcch.tb != NULLP)
1695       {
1696          RG_FREE_MSG(dlSf->bcch.tb);
1697       }
1698       if (dlSf->pcch.tb != NULLP)
1699       {
1700          RG_FREE_MSG(dlSf->pcch.tb);
1701       }
1702 #ifdef EMTC_ENABLE
1703       rgTOMEmtcRlsSf(dlSf);
1704 #endif
1705       for(idx=0; idx < dlSf->numRaRsp; idx++)
1706       {
1707          RG_FREE_MSG(dlSf->raRsp[idx].rar);
1708       }
1709    }
1710    /* ADD Changes for Downlink UE Timing Optimization */
1711 #ifdef LTEMAC_DLUE_TMGOPTMZ
1712    dlSf->remDatReqCnt = 0;
1713    /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled 
1714       RLC-MAC */
1715    dlSf->statIndDone = FALSE;
1716 #endif
1717    if (dlSf->tbs.count)
1718    {
1719       uint8_t      i;
1720       CmLList      *node;
1721       RgDlHqProcCb *hqP;
1722       DU_LOG("\nERROR  -->  MAC : Error Stale TBs in Subframes TBS list\n");
1723       node = dlSf->tbs.first;
1724       while(node)
1725       {
1726          hqP = (RgDlHqProcCb*)node->node;
1727          node = node->next;
1728          if (hqP)
1729          {
1730             for(i=0;i< RG_MAX_TB_PER_UE;i++)
1731             {
1732                if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
1733                {
1734                   cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
1735                   hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
1736                   DU_LOG("\nERROR  -->  MAC : rgTOMRlsSf:: hqP %p \n", (Void *)hqP);
1737                }
1738                hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
1739             }
1740          }
1741       }
1742    }
1743    /*arjun: check if dlSf laaTb list has to be freed???*/
1744    cmLListInit(&dlSf->tbs);
1745    dlSf->txDone = FALSE;
1746    dlSf->numRaRsp = 0;
1747    return;
1748 }
1749
1750 /**
1751  * @brief Function is called by the scheduler once it has completed the
1752  * allocation for the subframe. 
1753  *
1754  * @details
1755  *
1756  *     Function : rgHndlFlowCntrl
1757  *     This function should fill and send Flow control 
1758  *     indication to RLC
1759  *
1760  *           
1761  *  @param[in] Pst                 *cell       
1762  *  @param[in] RgInfSfAlloc        *sfInfo   Carries all the allocation
1763  *  information.
1764  *  @return  S16
1765  *      -# ROK 
1766  **/
1767 S16 rgHndlFlowCntrl(RgCellCb *cell,RgInfSfAlloc *sfInfo)
1768 {
1769    RguFlowCntrlInd  *flowCntrlInd;
1770    Pst              *pst;
1771    uint32_t         ueIdx;
1772    uint32_t         lcIdx;
1773
1774    pst = &cell->rguDlSap->sapCfg.sapPst;
1775    /* flowCntrlInd is alloced in cell init time and will be re-used throughout */
1776    flowCntrlInd = cell->flowCntrlInd;
1777    flowCntrlInd->cellId = sfInfo->cellId;
1778    flowCntrlInd->numUes = sfInfo->flowCntrlInfo.numUes; 
1779
1780    for (ueIdx = 0; ueIdx < sfInfo->flowCntrlInfo.numUes; ueIdx++)
1781    {
1782       flowCntrlInd->ueFlowCntrlInfo[ueIdx].ueId = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].ueId;
1783       flowCntrlInd->ueFlowCntrlInfo[ueIdx].numLcs = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].numLcs;
1784
1785       for (lcIdx = 0; lcIdx < RGINF_MAX_NUM_DED_LC; lcIdx++)
1786       {
1787          flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId =
1788             sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId;
1789          flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt = 
1790             sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt;
1791
1792          flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl = 
1793             sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl;
1794       }
1795    }
1796    RgUiRguFlowCntrlInd(pst, cell->rguDlSap->sapCfg.spId,flowCntrlInd); /* TODO: Rishi confirm if the suId and pst pointer is correct */
1797    return ROK;
1798 }
1799 /**
1800  * @brief Function is called by the scheduler once it has completed the
1801  * allocation for the subframe. 
1802  *
1803  * @details
1804  *
1805  *     Function : RgSchMacSfAllocReq
1806  *     
1807  *     This function shall be invoked whenever scheduler is done with the
1808  *     allocations of for a subframe. The sfInfo carries all the allocation
1809  *     details for the common channels, RA responses and dedicated channel
1810  *     allocations. 
1811  *
1812  *     Processing steps :
1813  *     1. Reset the information present in the downlink subframe that is
1814  *     scheduled.
1815  *     2. Handle common channel allocations
1816  *     3. Handle RA Response allocations
1817  *     4. Handle dedicated channel allocations.
1818  *           
1819  *  @param[in] Pst                 *pst       
1820  *  @param[in] RgInfSfAlloc        *sfInfo   Carries all the allocation
1821  *  information.
1822  *  @return  S16
1823  *      -# ROK 
1824  **/
1825 S16 RgSchMacSfAllocReq(Pst *pst,RgInfSfAlloc *sfInfo)
1826 {
1827    RgCellCb       *cell;
1828    RgDlSf         *dlSf;
1829    RgErrInfo      err;
1830    volatile uint32_t   startTime=0;
1831    Inst           inst;
1832
1833
1834    RG_IS_INST_VALID(pst->dstInst);
1835    inst = pst->dstInst - RG_INST_START;
1836    /*starting Task*/
1837    SStartTask(&startTime, PID_MAC_SF_ALLOC_REQ);
1838
1839    if(NULLP == sfInfo)
1840    {
1841       return RFAILED;
1842    }
1843
1844    if((cell = rgCb[inst].cell) == NULLP)
1845    {
1846       DU_LOG("\nERROR  -->  MAC : No cellCb found with cell");
1847       return RFAILED;
1848    }
1849
1850    dlSf = &cell->subFrms[(sfInfo->timingInfo.slot % RG_NUM_SUB_FRAMES)];
1851
1852    rgTOMRlsSf(inst,dlSf);
1853    dlSf->schdTime = sfInfo->timingInfo;
1854
1855 #ifdef LTE_ADV
1856    rgLaaInitTbInfoLst(cell);
1857 #endif
1858
1859    /* Fix : syed Ignore Failure Returns and continue processing.
1860     * Incomplete processing results in state sync loss between MAC-SCH. */
1861 #ifdef EMTC_ENABLE
1862    if(TRUE == cell->emtcEnable)
1863    {
1864       rgEmtcHndl(cell, sfInfo);
1865    }
1866 #endif
1867    rgHndlCmnChnl(cell, sfInfo->timingInfo, &sfInfo->cmnLcInfo, &err);
1868
1869    rgHndlRaResp(cell, sfInfo->timingInfo, &sfInfo->rarInfo, &err);
1870
1871 #ifdef LTE_ADV
1872 #ifdef XEON_SPECIFIC_CHANGES
1873    CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_B4_UE_SCHD);
1874 #endif
1875    rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1876 #ifdef XEON_SPECIFIC_CHANGES
1877    CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_UE_SCHD);
1878 #endif
1879    rgLaaChkAndReqTbs(dlSf,cell, inst);
1880
1881 #else
1882    rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1883 #endif
1884
1885 #ifdef LTE_L2_MEAS
1886    if(rgHndlUlUeInfo(cell, sfInfo->ulUeInfo.timingInfo, 
1887             &sfInfo->ulUeInfo) != ROK)
1888    {
1889       return RFAILED;
1890    }
1891 #endif
1892 #ifdef XEON_SPECIFIC_CHANGES
1893    CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_MEAS);
1894 #endif
1895    /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled 
1896       RLC-MAC */
1897
1898
1899    /* Added the handling for pushing down
1900     * TFU Data request in the retransmission only scenario.*/ 
1901 #ifdef LTEMAC_DLUE_TMGOPTMZ
1902    dlSf->statIndDone = TRUE;
1903    /* Fix [ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled 
1904       RLC-MAC */
1905    if(!(dlSf->txDone) && 
1906 #ifdef LTE_ADV
1907          (TRUE == rgLaaChkAllRxTbs(dlSf)) && 
1908 #endif
1909          (0 == dlSf->remDatReqCnt) && (dlSf->statIndDone) && 
1910          (RG_TIMEINFO_SAME(cell->crntTime, dlSf->schdTime)))
1911    {
1912       /*This is the case of rettransmission, so no need
1913        * to wait for TTI Ind to push TFU Data Request. Send
1914        * it right away.*/
1915       if (ROK != rgTOMUtlProcDlSf (dlSf, cell, &err))
1916       {
1917          DU_LOG("\nERROR  -->  MAC : Unable to process downlink subframe for cell");
1918          err.errType = RGERR_ROM_DEDDATREQ;
1919       }
1920       /* Mark this frame as sent */
1921       dlSf->txDone = TRUE;
1922    }
1923 #endif
1924    if (sfInfo->flowCntrlInfo.numUes > 0)
1925    {
1926       rgHndlFlowCntrl(cell,sfInfo);
1927    }
1928    /*stoping Task*/
1929    SStopTask(startTime, PID_MAC_SF_ALLOC_REQ);
1930    return ROK;
1931 } /* end of RgSchMacSfAllocReq */
1932 /**
1933  * @brief Handler for processing data indication recieved from PHY for UEs.
1934  *
1935  * @details
1936  *
1937  *     Function: rgTOMProcCrntiCEInDatInd
1938  *
1939  *     Handler for processing data indication recieved from PHY for UEs.
1940  *
1941  *     Invoked by: RgLiTfuDatInd of LIM 
1942  *
1943  *     Processing Steps: 
1944  *     For each DataInfo recieved
1945  *      - If  received a CRNTI control element 
1946  *          - Check if a CCCH SDU is present, if it is return failure
1947  *          - Check for the existence of UE, if its isnt present return failure.
1948  *          - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1949  *          primarily informs the scheduler about the data received and
1950  *          generates Data indications towards the higher layer.
1951  *           
1952  *  @param      RgMacPdu          *pdu,
1953  *  @param      RgUeCb            *prevUeCb,
1954  *  @param      RgCellCb          *cellCb,
1955  *  @param      TfuDatInfo        *datInfo,
1956  *  @param      RgInfCeInfo       *ceInfo
1957  *  @return  S16
1958  *      -# ROK 
1959  *      -# RFAILED 
1960  **/
1961    static S16 rgTOMProcCrntiCEInDatInd
1962 (
1963  RgMacPdu          *pdu,
1964  RgUeCb            *prevUeCb,
1965  RgCellCb          *cellCb,
1966  TfuDatInfo        *datInfo,
1967  RgInfCeInfo       *ceInfo,
1968  uint16_t               slot
1969  )
1970 {
1971    RgUeCb *ueCb = NULLP;
1972    Inst   inst  = cellCb->macInst - RG_INST_START;
1973
1974
1975 #ifdef LTEMAC_SPS
1976    Bool spsToBeActvtd;
1977    uint16_t  sduSize;
1978 #endif
1979
1980
1981 #ifndef LTE_L2_MEAS      
1982    UNUSED(slot);
1983 #endif
1984
1985    ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
1986
1987    if (ueCb == NULLP)
1988    {
1989       DU_LOG("\nERROR  -->  MAC : RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
1990       return RFAILED;
1991    }
1992
1993    prevUeCb = rgDBMGetUeCb (cellCb, ceInfo->ces.cRnti);
1994    if (prevUeCb == NULLP)
1995    {
1996       DU_LOG("\nERROR  -->  MAC : RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
1997       return RFAILED;
1998    }
1999    DU_LOG("\nERROR  -->  MAC : CRNTI CE(%d) received through tmpCrnti(%d)",
2000          ceInfo->ces.cRnti, datInfo->rnti);
2001    rgDBMDelUeCbFromRachLst(cellCb, ueCb);
2002    rgRAMFreeUeCb(inst,ueCb);
2003    ueCb = prevUeCb;
2004 #ifdef LTEMAC_SPS
2005    if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2006 #else
2007       if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2008 #endif /* LTEMAC_SPS */
2009       {
2010          DU_LOG("\nERROR  -->  MAC : RNTI:%d Processing for MSG3 failed",datInfo->rnti);
2011          return RFAILED;
2012       }
2013    return ROK;
2014 }
2015 /**
2016  * @brief Handler for processing data indication recieved from PHY for UEs.
2017  *
2018  * @details
2019  *
2020  *     Function: rgTOMProcCCCHSduInDatInd
2021  *
2022  *     Handler for processing data indication recieved from PHY for UEs.
2023  *
2024  *     Invoked by: RgLiTfuDatInd of LIM 
2025  *
2026  *     Processing Steps: 
2027  *     For each DataInfo recieved
2028  *      - If only CCCH SDU is present
2029  *        - Invoke rgTOMUtlProcMsg3 for further processing.
2030  *      - If its a non-Msg3 PDU i.e. received outside of a RA procedure
2031  *        - Retrieve the UeCB 
2032  *        - Validate that the received PDU contains only configured Logical
2033  *        Channels.
2034  *        - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
2035  *        scheduler with the information of the received Data and generates
2036  *        DatIndications towards the higher layers. 
2037  *           
2038  *  @param  TfuDatIndInfo *datInd
2039  *  @param  RgMacPdu          *pdu,
2040  *  @param  RgUeCb            *prevUeCb,
2041  *  @param  RgCellCb          *cellCb,
2042  *  @param  TfuDatInfo        *datInfo,
2043  *  @param  RgInfCeInfo       *ceInfo
2044  *  @return  S16
2045  *      -# ROK 
2046  *      -# RFAILED 
2047  **/
2048    static S16 rgTOMProcCCCHSduInDatInd
2049 (
2050  RgMacPdu          *pdu,
2051  RgUeCb            *prevUeCb,
2052  RgCellCb          *cellCb,
2053  TfuDatInfo        *datInfo,
2054  RgInfCeInfo       *ceInfo,
2055  uint16_t               slot 
2056  )
2057 {
2058    RgUeCb *ueCb = NULLP;
2059    Inst   inst  = cellCb->macInst - RG_INST_START;
2060
2061 #ifdef LTEMAC_SPS
2062    Bool spsToBeActvtd;
2063    uint16_t  sduSize;
2064 #endif
2065
2066
2067
2068 #ifndef LTE_L2_MEAS      
2069    UNUSED(slot);
2070 #endif
2071
2072    if (ceInfo->bitMask & RG_CRNTI_CE_PRSNT)
2073    {
2074       DU_LOG("\nERROR  -->  MAC : CRNTI:%d Received MSG3 with CCCH",ceInfo->ces.cRnti);
2075       return RFAILED;
2076    }
2077
2078    ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
2079
2080    if (ueCb == NULLP)
2081    {
2082       DU_LOG("\nERROR  -->  MAC : RNTI:%d Processing for MSG3 failed", datInfo->rnti);
2083       return RFAILED;
2084    }
2085    /* Fix: syed Drop any duplicate Msg3(CCCH Sdu) */
2086    if (ueCb->dl.hqEnt.numHqProcs)
2087    {
2088       /* HqE is already initialized by a previuos Msg3 */ 
2089       DU_LOG("\nERROR  -->  MAC : RNTI:%d Processing for MSG3 failed. Duplicate "
2090             "MSG3 received. Dropping", datInfo->rnti);
2091       return RFAILED;
2092    }
2093
2094    if(rgDHMHqEntInit(inst,&ueCb->dl.hqEnt,
2095             cellCb->maxDlHqProcPerUe) != ROK)
2096    {
2097       DU_LOG("\nERROR  -->  MAC : RNTI:%d Harq Initialization failed ", 
2098             datInfo->rnti);
2099       return RFAILED;
2100    }
2101    DU_LOG("\nDEBUG  -->  MAC : CCCH SDU received through tmpCrnti(%d)",datInfo->rnti);
2102 #ifdef LTEMAC_SPS
2103    if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2104 #else
2105       if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2106 #endif /* LTEMAC_SPS */
2107       {
2108          DU_LOG("\nERROR  -->  MAC : RNTI:%d Processing for MSG3 failed", 
2109                datInfo->rnti);
2110          return RFAILED;
2111       }
2112    return ROK;
2113 }
2114
2115 #ifdef LTE_L2_MEAS
2116
2117 /** @brief This function captures the BSR value from Control Element
2118  *  Info structure and updates the effective Buffer size into the 
2119  *  corresponding LCG ID. 
2120  *
2121  * @details 
2122  *
2123  *     Function: rgTOMUtlL2MStoreBufSz
2124  *
2125  *         Processing steps:
2126  *         - update/append the Data structure based on BSR type 
2127  *
2128  * @param  [in] RgUeCb     *ueCb
2129  * @param  [in] RgInfCeInfo *ceInfo
2130  * @return S16
2131  */
2132
2133 static S16 rgTOMUtlL2MStoreBufSz( RgUeCb *ueCb, RgInfCeInfo *ceInfo )
2134 {
2135    uint8_t lcgId;
2136    uint8_t bsr;
2137
2138    if(ceInfo->bitMask & RG_TRUNC_BSR_CE_PRSNT)
2139    {
2140       lcgId = ((ceInfo->ces.bsr.truncBsr >> 6) & 0x03);
2141       bsr = ceInfo->ces.bsr.truncBsr & 0x3F;
2142       ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2143    }
2144    else if(ceInfo->bitMask & RG_SHORT_BSR_CE_PRSNT)
2145    {
2146       lcgId = ((ceInfo->ces.bsr.shortBsr >> 6) & 0x03);
2147       bsr = ceInfo->ces.bsr.shortBsr & 0x3F;
2148       ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2149
2150    }
2151    else if(ceInfo->bitMask & RG_LONG_BSR_CE_PRSNT)
2152    {
2153       ueCb->ul.lcgArr[0].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs1];
2154       ueCb->ul.lcgArr[1].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs2];
2155       ueCb->ul.lcgArr[2].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs3];
2156       ueCb->ul.lcgArr[3].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs4];
2157    }
2158    return ROK;
2159 } /* end of rgTOMUtlL2MStoreBufSz*/
2160
2161 /** @brief : Compiles list of LCs received in UL data for DTCH RBs
2162  *
2163  * @details
2164  *
2165  * @param  [in] RgCellCb   *cellCb
2166  * @param  [in] RgUeCb     *ueCb
2167  * @param  [in] CmLteRnti  rnti
2168  * @param  [in] RgMacPdu   *pdu
2169  * @param 
2170  *  @return  S16
2171  *      -# ROK 
2172  *      -# RFAILED 
2173  */
2174 static Void rgTOML2MCompileActiveLCs(RgCellCb *cellCb,RgUeCb *ueCb,RgMacPdu *pdu,RgInfCeInfo *ceInfo)
2175 {
2176    CmLList           *node;
2177    RgMacSdu          *sdu;
2178    RgUlLcCb          *ulLcCb;
2179
2180
2181    node =  pdu->sduLst.first;
2182    while (node)
2183    {
2184       sdu = (RgMacSdu*)node->node;
2185
2186       if ((ulLcCb = rgDBMGetUlDedLcCb(ueCb, sdu->lcId)), ulLcCb != NULLP)
2187       {
2188          if (ulLcCb->lcgId != 0)
2189          {
2190             ceInfo->bitMask |= RG_ACTIVE_LC_PRSNT;
2191             ceInfo->ulActLCs[ulLcCb->lcId - 1] = TRUE;
2192          }
2193       }
2194       node = node->next;
2195    }
2196
2197 } /* end of */ 
2198
2199
2200
2201 #endif
2202 /**********************************************************************
2203
2204   End of file
2205  **********************************************************************/