fbc659e22f08ad6b111316ef940a1c64448f891f
[o-du/l2.git] / src / 5gnrmac / rg_utl.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_utl.c
28   
29 **********************************************************************/
30
31 /** @file rg_utl.c
32 @brief This file implements utility functions for LTE MAC
33 */
34
35
36 /* header include files (.h) */
37 #include "common_def.h"
38 #include "rg_env.h"        /* MAC Environment Defines */
39 #include "crg.h"           /* CRG Interface defines */
40 #include "rgu.h"           /* RGU Interface defines */
41 #include "tfu.h"           /* TFU Interface defines */
42 #include "rg_sch_inf.h"    /* RGR Interface defines */
43 #include "lrg.h"           /* LRG Interface defines */
44 #include  "mac_utils.h"
45
46 #include "rg_prg.h"        /* PRG(MAC-MAC) Interface includes */
47 #include "rg.h"            /* MAC defines */
48 #include "rg_err.h"        /* MAC error defines */
49
50 /* header/extern include files (.x) */
51 #include "cm5.x"           /* Timer */
52
53 #include "crg.x"           /* CRG Interface includes */
54 #include "rgu.x"           /* RGU Interface includes */
55 #include "tfu.x"           /* TFU Interface includes */
56 #include "rg_sch_inf.x"    /* RGR Interface includes */
57 #include "lrg.x"           /* LRG Interface includes */
58 #include "rg_prg.x"        /* PRG(MAC-MAC) Interface includes */
59
60 #include "du_app_mac_inf.h"
61 #include "rg.x"            /* MAC includes */
62
63 /* local defines */
64 #define RG_NON_MIMO_IDX 0
65
66 /* local typedefs */
67  
68 /* local externs */
69  
70 /* forward references */
71 static S16 rgUtlHndlCrntiChng ARGS((
72          Inst            inst,
73          RgCellCb        *cell,
74          CmLteRnti       rnti,
75          CmLteRnti       newRnti
76          ));
77 static Void rgUtlHndlCrntiRls ARGS((
78          RgCellCb        *cell,
79          RgInfRlsRnti    *rlsRnti
80          ));
81
82 S16 rgDelUeFrmAllSCell ARGS((
83          RgCellCb       *cell,
84          RgUeCb         *ue
85          ));
86
87 #ifdef LTE_ADV
88 static S16 rgUtlSndCrntiChngReq2AllSMacs ARGS((
89          RgCellCb        *cell,
90          CmLteRnti       rnti,
91          CmLteRnti       newRnti
92          ));
93 #endif
94 /***********************************************************
95  *
96  *     Func : rgAllocShrablSBuf
97  *
98  *     Desc : Utility Function to Allocate static buffer which is 
99  *            sharable among different layers if YYYY flag is enabled. 
100  *            else it allocates from normal static region
101  *            Memory allocated is assumed contiguous.
102  *            
103  *
104  *     Ret  : ROK
105  *            RFAILED
106  *
107  *     Notes: Caller doesnt need to raise the alarm in case of memory
108  *            allocation gets failed. 
109  *
110  *     File : rg_utl.c
111  *
112  **********************************************************/
113 S16 rgAllocShrablSBuf
114 (
115 Inst    inst,
116 Data    **pData,            /* Pointer of the data to be returned */
117 Size    size                /* size */
118 )
119 {
120    RgUstaDgn dgn;      /* Alarm diagnostics structure */
121
122    /* Initialize the param to NULLP */
123    *pData = NULLP;
124
125    if (size == 0)
126    {
127       return RFAILED;
128    }
129
130    /* allocate buffer */
131    MAC_ALLOC_SHRABL_BUF(pData, size);
132    if(pData == NULLP)
133    {
134      dgn.type = LRG_USTA_DGNVAL_MEM;
135      dgn.u.mem.region = rgCb[inst].rgInit.region;
136      dgn.u.mem.pool = rgCb[inst].rgInit.pool;
137      /*  Send an alarm to Layer Manager */
138      rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
139                                        LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
140       DU_LOG("\nERROR  -->  MAC : Unable to Allocate Buffer");
141       return RFAILED;
142    }
143
144 #ifndef ALIGN_64BIT
145    DU_LOG("\nDEBUG  -->  MAC : MAC_ALLOC(Region (%d), Pool (%d), Size (%ld)), Data (0x%p))\n",
146              rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData);
147 #else
148    DU_LOG("\nDEBUG  -->  MAC : MAC_ALLOC(Region (%d), Pool (%d), Size (%d)), Data (0x%p))\n",
149              rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData);
150 #endif
151
152    /* zero out the allocated memory */
153    memset(*pData, 0x00, size);
154
155    return ROK;
156
157 } /* end of rgAllocSBuf */
158
159
160 /***********************************************************
161  *
162  *     Func : rgAllocSBuf
163  *
164  *     Desc : Utility Function to Allocate static buffer. 
165  *            Memory allocated is assumed contiguous.
166  *            
167  *
168  *     Ret  : ROK
169  *            RFAILED
170  *
171  *     Notes: Caller doesnt need to raise the alarm in case of memory
172  *            allocation gets failed. 
173  *
174  *     File : rg_utl.c
175  *
176  **********************************************************/
177 S16 rgAllocSBuf
178 (
179 Inst    inst,
180 Data    **pData,            /* Pointer of the data to be returned */
181 Size    size                /* size */
182 )
183 {
184    RgUstaDgn dgn;      /* Alarm diagnostics structure */
185
186    /* Initialize the param to NULLP */
187    *pData = NULLP;
188
189    if (size == 0)
190    {
191       return RFAILED;
192    }
193
194    /* allocate buffer */
195 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
196    MS_BUF_ADD_ALLOC_CALLER();
197 #endif /* */
198    MAC_ALLOC(pData, size);
199    if(pData == NULLP)
200    {
201      dgn.type = LRG_USTA_DGNVAL_MEM;
202      dgn.u.mem.region = rgCb[inst].rgInit.region;
203      dgn.u.mem.pool = rgCb[inst].rgInit.pool;
204      /*  Send an alarm to Layer Manager */
205      rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
206                                        LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
207       DU_LOG("\nERROR  -->  MAC : Unable to Allocate Buffer");
208       return RFAILED;
209    }
210
211    /* zero out the allocated memory */
212    memset(*pData, 0x00, size);
213
214    return ROK;
215
216 } /* end of rgAllocSBuf */
217
218 /*
219 *
220 *       Fun:   rgFreeSharableSBuf
221 *
222 *       Desc:  The argument to rgFreeSBuf() is a pointer to a block
223 *              previously allocated by rgAllocSBuf() and size. It 
224 *              deallocates the memory. 
225 *
226 *       Ret:   void
227 *
228 *       Notes: ccpu00117052 - MOD- changed the Data parameter from 
229 *                             pointer to address of pointer so that
230 *                             the freed memory could be set to NULLP
231 *
232 *       File:  rg_utl.c
233 */
234 Void rgFreeSharableSBuf
235 (
236 Inst inst,
237 Data **data,         /* address of pointer to data */
238 Size size            /* size */
239 )
240 {
241
242    if ((data == NULLP) || (*data == NULLP) || (size == 0))
243    {
244       return;
245    }
246
247    /* Deallocate buffer */
248    MAC_FREE_SHRABL_BUF(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, *data, size);
249    
250    if (data != NULLP)
251    {
252       return;
253    }
254
255    *data = NULLP;
256
257    return;
258
259 } /* end of rgFreeSharableBuf */
260
261
262
263 /*
264 *
265 *       Fun:   rgFreeSBuf
266 *
267 *       Desc:  The argument to rgFreeSBuf() is a pointer to a block
268 *              previously allocated by rgAllocSBuf() and size. It 
269 *              deallocates the memory. 
270 *
271 *       Ret:   void
272 *
273 *       Notes: ccpu00117052 - MOD- changed the Data parameter from 
274 *                             pointer to address of pointer so that
275 *                             the freed memory could be set to NULLP
276 *
277 *       File:  rg_utl.c
278 */
279 Void rgFreeSBuf
280 (
281 Inst inst,
282 Data **data,         /* address of pointer to data */
283 Size size            /* size */
284 )
285 {
286
287    if ((data == NULLP) || (*data == NULLP) || (size == 0))
288    {
289       return;
290    }
291
292
293 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
294    MS_BUF_ADD_CALLER();
295 #endif /* */
296    /* Deallocate buffer */
297    MAC_FREE(data, size);
298
299    if (data != NULLP)
300    {
301       DU_LOG("\nERROR  -->  MAC : rgFreeSBuf failed.\n");
302       return;
303    }
304
305    *data = NULLP;
306
307    return;
308
309 } /* end of rgFreeSBuf */
310
311
312 /***********************************************************
313  *
314  *     Func : rgGetMsg
315  *
316  *     Desc : Utility Function to Allocate message buffer. 
317  *            
318  *
319  *     Ret  : ROK
320  *            RFAILED
321  *
322  *     Notes: Caller doesnt need to raise the alarm in case of memory
323  *            allocation gets failed. 
324  *
325  *     File : rg_utl.c
326  *
327  **********************************************************/
328 S16 rgGetMsg
329 (
330 Inst    inst,
331 Buffer  **mBuf            /* Message Buffer pointer be returned */
332 )
333 {
334    S16         ret;
335
336 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
337    MS_BUF_ADD_ALLOC_CALLER();
338 #endif /* */
339    ret = ODU_GET_MSG_BUF(RG_GET_MEM_REGION(rgCb[inst]), RG_GET_MEM_POOL(rgCb[inst]), mBuf);
340
341    if (ROK != ret) 
342    {
343       /* Moving diagnostics structure to limited scope for optimization */
344       RgUstaDgn   dgn;      /* Alarm diagnostics structure */
345
346       rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
347
348       /*  Send an alarm to Layer Manager */
349       rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
350                                        LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
351       DU_LOG("\nERROR  -->  MAC : Unable to Allocate Buffer");
352       return RFAILED;
353    }
354
355    return ROK;
356
357 } /* end of rgGetMsg */
358
359
360 /***********************************************************
361  *
362  *     Func : rgFillDgnParams
363  *
364  *     Desc : Utility Function to Fill Diagonostic params. 
365  *
366  *     Ret  : None.
367  *
368  *     Notes: None.
369  *
370  *     File : rg_utl.c
371  *
372  **********************************************************/
373 Void rgFillDgnParams
374 (
375 Inst        inst,
376 RgUstaDgn   *dgn,
377 uint8_t     dgnType
378 )
379 {
380
381    switch(dgnType)
382    {
383       case LRG_USTA_DGNVAL_MEM:
384          dgn->type = (uint8_t) LRG_USTA_DGNVAL_MEM;
385          dgn->u.mem.region  = rgCb[inst].rgInit.region;
386          dgn->u.mem.pool    = rgCb[inst].rgInit.pool;
387       break;
388
389       default:
390       break;
391    }
392
393    return;
394 } /* end of rgFillDgnParams */
395
396
397 /***********************************************************
398  *
399  *     Func : rgUpdtRguDedSts
400  *
401  *     Desc : Utility Function to update rgu sap statistics for dedicated
402  *            DatReqs.
403  *            
404  *
405  *     Ret  : ROK
406  *            RFAILED
407  *
408  *     Notes: 
409  *
410  *     File : rg_utl.c
411  *
412  **********************************************************/
413 Void rgUpdtRguDedSts
414 (
415 Inst           inst,
416 RgUpSapCb      *rguDlSap,
417 uint8_t        stsType,   /* Statistics type to update */
418 RgRguDedDatReq *datReq    /* DatReq pointer */
419 )
420 {
421    uint8_t idx1,idx2;
422    uint32_t idx;
423
424    switch(stsType)
425    {
426       case RG_RGU_SDU_RCVD:
427       for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++)
428       {
429          RguDDatReqPerUe *datReqPerUe = &datReq->datReq[idx];
430          for (idx1 = 0; idx1 < datReqPerUe->nmbOfTbs; idx1++) 
431          {
432             for(idx2 = 0; idx2 < datReqPerUe->datReqTb[idx1].nmbLch; idx2++) 
433             {
434                rguDlSap->sapSts.numPduRcvd +=
435                   datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu;
436             }
437          }
438       }
439
440          break;
441       case RG_RGU_SDU_DROP:
442       for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++)
443       {
444          RguDDatReqPerUe *datReqPerUe = &datReq->datReq[idx];
445          for (idx1 = 0; idx1 < datReqPerUe->nmbOfTbs; idx1++) 
446          {
447             for(idx2 = 0; idx2 < datReqPerUe->datReqTb[idx1].nmbLch; idx2++) 
448             {
449                rguDlSap->sapSts.numPduRcvd +=
450                   datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu;
451                rguDlSap->sapSts.numPduDrop +=
452                   datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu;
453             }
454          }
455       }
456
457          break;
458    }
459    
460    return;
461 } /* rgUpdtRguDedSts */
462
463
464 /***********************************************************
465  *
466  *     Func : rgUpdtRguCmnSts
467  *
468  *     Desc : Utility Function to update rgu sap statistics for common
469  *            DatReqs.
470  *            
471  *
472  *     Ret  : ROK
473  *            RFAILED
474  *
475  *     Notes: 
476  *
477  *     File : rg_utl.c
478  *
479  **********************************************************/
480 Void rgUpdtRguCmnSts
481 (
482 Inst           inst,
483 RgUpSapCb     *rguDlSap,
484 uint8_t       stsType   /* Statistics type to update */
485 )
486 {
487
488    switch(stsType)
489    {
490       case RG_RGU_SDU_RCVD:
491          rguDlSap->sapSts.numPduRcvd ++;
492          break;
493       case RG_RGU_SDU_DROP:
494          rguDlSap->sapSts.numPduRcvd ++;
495          rguDlSap->sapSts.numPduDrop ++;
496          break;
497    }
498    
499    return;
500 } /* rgUpdtRguCmnSts */
501
502
503 /***********************************************************
504  *
505  *     Func : rgUpdtCellCnt
506  *
507  *     Desc : Utility Function to update cell count. It gives number of active
508  *     cells
509  *            
510  *
511  *     Ret  : ROK
512  *            RFAILED
513  *
514  *     Notes: This function should be called only after cell is added/deleted 
515  *     from the globlal hashlist
516  *
517  *     File : rg_utl.c
518  *
519  **********************************************************/
520 Void rgUpdtCellCnt(Inst inst,uint8_t updtType)
521 {
522
523    switch (updtType)
524    {
525       case RG_CFG_ADD:
526          rgCb[inst].genSts.numCellCfg++;
527          break;
528       case RG_CFG_DEL:
529          rgCb[inst].genSts.numCellCfg--;
530          break;
531       default:
532          break;
533    }
534
535    return;
536 } /* rgUpdtCellCnt */
537
538
539 /***********************************************************
540  *
541  *     Func : rgUpdtUeCnt
542  *
543  *     Desc : Utility Function to update ue count. It gives number of active
544  *     Ues.
545  *            
546  *
547  *     Ret  : ROK
548  *            RFAILED
549  *
550  *     Notes: This function should be called only after ue is added/deleted 
551  *     from the globlal hashlist
552  *
553  *     File : rg_utl.c
554  *
555  **********************************************************/
556 Void rgUpdtUeCnt(Inst inst,uint8_t updtType)
557 {
558    switch (updtType)
559    {
560       case RG_CFG_ADD:
561          rgCb[inst].genSts.numUeCfg++;
562          break;
563       case RG_CFG_DEL:
564          rgCb[inst].genSts.numUeCfg--;
565          break;
566       default:
567          break;
568    }
569    return;
570 } /* rgUpdtUeCnt */
571
572 /*
573 *
574 *       Fun:   rgAllocEventMem
575 *
576 *       Desc:  This function allocates event memory 
577 *
578 *       Ret:   ROK      - on success
579 *              RFAILED  - on failure
580 *
581 *       Notes: None
582 *
583 *       File:  rg_utl.c
584 *
585 */
586 S16 rgAllocEventMem
587 (
588 Inst     inst,
589 Ptr       *memPtr,
590 Size      memSize
591 )
592 {
593    Mem               sMem;
594    volatile uint32_t startTime=0;
595
596
597    sMem.region = rgCb[inst].rgInit.region;
598    sMem.pool = rgCb[inst].rgInit.pool;
599
600 #if (ERRCLASS & ERRCLS_DEBUG)
601    if (memSize<= 0)
602    {
603       DU_LOG("\nERROR  -->  MAC : rgAllocEventMem(): memSize invalid\n");
604       return  (RFAILED);
605    }
606 #endif /* ERRCLASS & ERRCLS_DEBUG */
607
608
609    /*starting Task*/
610    SStartTask(&startTime, PID_MACUTL_CMALLCEVT);
611
612 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
613    MS_BUF_ADD_ALLOC_CALLER();
614 #endif /* */
615 #ifdef TFU_ALLOC_EVENT_NO_INIT
616    if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
617 #else
618    if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
619 #endif /* */
620    {
621       DU_LOG("\nERROR  -->  MAC : cmAllocEvnt Failed"); 
622       return RFAILED;
623    }
624
625    /*stoping Task*/
626    SStopTask(startTime, PID_MACUTL_CMALLCEVT);
627
628    return ROK;
629 } /* end of rgAllocEventMem*/
630
631 /*
632 *
633 *       Fun:   rgGetEventMem
634 *
635 *       Desc:  This function allocates event memory 
636 *
637 *       Ret:   ROK      - on success
638 *              RFAILED  - on failure
639 *
640 *       Notes: None
641 *
642 *       File:  rg_utl.c
643 *
644 */
645 S16 rgGetEventMem
646 (
647 Inst      inst,
648 Ptr       *ptr,
649 Size      len,
650 Ptr       memCp
651 )
652 {
653    S16   ret;
654
655 #ifdef TFU_ALLOC_EVENT_NO_INIT
656    ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
657 #else
658    ret = cmGetMem(memCp, len, (Ptr *)ptr);
659 #endif /* */
660    return (ret);
661 } /* end of rgGetEventMem*/
662
663 /***********************************************************
664  *
665  *     Func : rgGetPstToInst
666  *
667  *     Desc : Utility Function to get the pst structure to post a message to
668  *     scheduler instance
669  *            
670  *
671  *     Ret  : ROK
672  *            RFAILED
673  *
674  *     Notes: This function should be called while sending a msg from 
675  *     MAC to a scheduler instance
676  *
677  *     File : rg_utl.c
678  *
679  **********************************************************/
680 Void rgGetPstToInst
681 (
682 Pst           *pst,
683 Inst          srcInst,
684 Inst          dstInst
685 )
686 {
687
688    pst->srcEnt = rgCb[srcInst].rgInit.ent; 
689    pst->srcInst = rgCb[srcInst].rgInit.inst;
690    pst->srcProcId = rgCb[srcInst].rgInit.procId;
691    pst->region = rgCb[srcInst].rgInit.region;
692    pst->pool = rgCb[srcInst].rgInit.pool;
693
694    pst->dstProcId = rgCb[dstInst].rgInit.procId;
695    pst->dstEnt = rgCb[dstInst].rgInit.ent; 
696    pst->dstInst = dstInst;
697    pst->selector = 0;
698    pst->prior     = PRIOR0;
699    pst->intfVer   = 0;
700    pst->route   = RTESPEC;
701
702    return; 
703 } /* end of rgGetPstToInst */
704
705 /***********************************************************
706  *
707  *     Func : RgSchMacLcgRegReq
708  *
709  *     Desc : Utility Function to register the set of GBR LCG.
710  *        Invoked at the time of LCG configuration/Reconfiguration at Schedular.
711  * 
712  *     Processing Steps: 
713  *           - Fetch the ueCb using the crnti given in lcInfo            
714  *           - Store the if LCG is GBR or not.
715  *
716  *     Ret  : ROK
717  *            RFAILED
718  *
719  *     Notes: This function should be called at the time of LCG 
720  *     configuration/Reconfiguration at Schedular. 
721  *     
722  *
723  *     File : rg_utl.c
724  *
725  **********************************************************/
726 S16 RgSchMacLcgRegReq(Pst *pst,RgInfLcgRegReq *lcgRegReq)
727 {
728    Inst       inst;
729    RgCellCb   *cell = NULLP;
730    RgUeCb     *ue;
731
732    RG_IS_INST_VALID(pst->dstInst);
733    inst   = pst->dstInst - RG_INST_START;
734    cell   = rgCb[inst].cell;
735    /* Fetch the cell and then the UE */
736    if((cell == NULLP) ||
737       (cell->cellId != lcgRegReq->cellId))
738    {
739       
740       DU_LOG("\nERROR  -->  MAC : Cell does not exist ");
741       return RFAILED;
742    }
743
744    if ((ue = rgDBMGetUeCb(cell, lcgRegReq->crnti)) == NULLP)
745    {
746      DU_LOG("\nERROR  -->  MAC : CRNTI:%d does not exist", 
747                          lcgRegReq->crnti);
748       return RFAILED;
749    }
750    ue->ul.lcgArr[lcgRegReq->lcgId].isGbr = lcgRegReq->isGbr;
751
752    return ROK; 
753 } /* end of RgSchMacLcgRegReq */
754
755 #ifdef LTEMAC_SPS
756
757 /***********************************************************
758  *
759  *     Func : RgSchMacUlSpsResetReq
760  *
761  *     Desc : Utility Function to reset SPS params for a UE
762  * 
763  *     Processing Steps: 
764  *           - Fetch the ueCb using the crnti 
765  *           - reset implRelCnt and explRelCnt
766  *
767  *     Ret  : ROK
768  *            RFAILED
769  *
770  *     File : rg_utl.c
771  *
772  **********************************************************/
773 S16 RgSchMacUlSpsResetReq(Pst *pst,RgInfUlSpsReset *ulSpsResetInfo)
774 {
775    Inst       inst;
776    RgCellCb   *cell = NULLP;
777    RgUeCb     *ue;
778
779    RG_IS_INST_VALID(pst->dstInst);
780    inst   = pst->dstInst - RG_INST_START;
781    cell   = rgCb[inst].cell;
782    /* Fetch the cell and then the UE */
783    if((cell == NULLP)||
784       (cell->cellId != ulSpsResetInfo->cellId))
785    {
786       
787       DU_LOG("\nERROR  -->  MAC : Cell does not exist ");
788       return RFAILED;
789    }
790
791    if ((ue = rgDBMGetUeCb(cell, ulSpsResetInfo->crnti)) == NULLP)
792    {
793       DU_LOG("\nERROR  -->  MAC : CRNTI:%d does not exist", 
794                       ulSpsResetInfo->crnti);
795       return RFAILED;
796    }
797
798    ue->ul.implRelCntr = 0;
799    ue->ul.explRelCntr = 0;
800
801    return ROK; 
802 } /* end of RgSchMacUlSpsResetReq */
803
804
805
806
807 /***********************************************************
808  *
809  *     Func : RgSchMacSpsLcRegReq
810  *
811  *     Desc : Utility Function to register the set of uplink SPS logical
812  *        channels for a SPS UE.
813  *        Invoked at the time of activation of a UE for UL-SPS.
814  *        Whenever there is data on these LCs MAC shall inform scheduler
815  * 
816  *     Processing Steps: 
817  *           - Fetch the ueCb using the crnti given in lcInfo            
818  *           - Store the sps-rnti and set the bits corresponding to the
819  *             logical channel ids in ueUlCb->spsLcMask.
820  *
821  *     Ret  : ROK
822  *            RFAILED
823  *
824  *     Notes: This function should be called at the time UL SPS is activated 
825  *     for a UE at scheduler
826  *     
827  *
828  *     File : rg_utl.c
829  *
830  **********************************************************/
831 S16 RgSchMacSpsLcRegReq(Pst *pst,RgInfSpsLcInfo *lcInfo)
832 {
833    Inst       inst;
834    RgCellCb   *cell= NULLP;
835    RgUeCb     *ue;
836    uint8_t    idx;
837
838    RG_IS_INST_VALID(pst->dstInst);
839    inst   = pst->dstInst - RG_INST_START;
840    cell   = rgCb[inst].cell;
841    /* Fetch the cell and then the UE */
842    if((cell == NULLP) ||
843       (cell->cellId != lcInfo->cellId))
844    {
845       
846       DU_LOG("\nERROR  -->  MAC : Cell does not exist ");
847       return RFAILED;
848    }
849
850    if ((ue = rgDBMGetUeCb(cell, lcInfo->crnti)) == NULLP)
851    {
852       DU_LOG("\nERROR  -->  MAC : CRNTI:%d does not exist", 
853                       lcInfo->crnti);
854       return RFAILED;
855    }
856
857    /* Store the sps-rnti and SPS LC information in the UE */ 
858    ue->spsRnti = lcInfo->spsRnti;
859    for (idx=0; idx < lcInfo->spsLcCnt; idx++)
860    {
861       /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */
862       ue->ul.spsLcId[(lcInfo->spsLcId[idx])-1] = TRUE;
863    }
864    ue->ul.implRelCnt = lcInfo->implRelCnt;
865    ue->ul.explRelCnt = ue->ul.implRelCnt + 1; /*(lcInfo->implRelCnt * lcInfo->spsPrd);*/
866
867    /* Insert the UE into SPS UE List */
868    if (rgDBMInsSpsUeCb(cell, ue) == RFAILED)
869    {
870       DU_LOG("\nERROR  -->  MAC : Ue insertion into SPS list failed SPS CRNTI:%d", ue->spsRnti);
871       return RFAILED;
872    } 
873
874    return ROK; 
875 } /* end of RgSchMacSpsLcRegReq */
876
877
878 /***********************************************************
879  *
880  *     Func : RgSchMacSpsLcDeregReq
881  *
882  *     Desc : Utility Function to deregister the set of uplink SPS 
883  *        logical channels for a UE.
884  *        Invoked at the time of release of UL-SPS for an activated UE.
885  * 
886  *     Processing Steps: 
887  *           - Fetch the ueCb using the crnti given
888  *           - Reset the bits corresponding to the logical channel ids in
889  *             ueUlCb->spsLcMask.
890  *
891  *     Ret  : ROK
892  *            RFAILED
893  *
894  *     Notes: This function should be called at the time UL SPS is released 
895  *     for a UE at scheduler
896  *     
897  *
898  *     File : rg_utl.c
899  *
900  **********************************************************/
901 S16 RgSchMacSpsLcDeregReq(Pst  *pst,CmLteCellId cellId,CmLteRnti crnti)
902 {
903    Inst       inst;
904    RgCellCb   *cell = NULLP;
905    RgUeCb      *ue;
906
907    RG_IS_INST_VALID(pst->dstInst);
908    inst   = pst->dstInst - RG_INST_START;
909    cell   = rgCb[inst].cell;
910    /* Fetch the cell and then the UE */
911    if((cell == NULLP) ||
912       (cell->cellId != cellId))
913    {
914       
915       DU_LOG("\nERROR  -->  MAC : Cell does not exist ");
916       return RFAILED;
917    }
918
919    if ((ue = rgDBMGetUeCb(cell, crnti)) == NULLP)
920    {
921       DU_LOG("\nERROR  -->  MAC : CRNTI:%d Ue does not exist", crnti);
922       return RFAILED;
923    }
924
925    /* No need to reset the SPS LC Ids as they will not be looked at*/
926
927    /* Delete UE from the SPS UE List */
928    rgDBMDelSpsUeCb(cell, ue);
929    
930    return ROK; 
931 } /* end of RgSchMacSpsLcDeregReq */
932
933 #endif /* LTEMAC_SPS */
934
935 /**
936  * @brief Function for handling CRNTI change request 
937  * received from scheduler to MAC.
938  *
939  * @details
940  *
941  *     Function : rgUtlHndlCrntiChng
942  *     
943  *        - Delete old UE from the list.
944  *        - Update the new rnti and re-insert the UE in the list.
945  *     
946  *           
947  *  @param[in] Inst        inst
948  *  @param[in] RgCellCb      *cell,
949  *  @param[in] CmLteRnti     rnti,
950  *  @param[in] CmLteRnti     newRnti
951  *  @return  S16
952  *      -# ROK 
953  *      -# RFAILED
954  **/
955 static S16 rgUtlHndlCrntiChng 
956 (
957 Inst            inst,
958 RgCellCb        *cell,
959 CmLteRnti       rnti,
960 CmLteRnti       newRnti
961 )
962 {
963    RgUeCb         *ue = NULLP;
964    RgUeCb         *newUe = NULLP;
965
966    ue = rgDBMGetUeCb(cell, rnti);
967    newUe = rgDBMGetUeCbFromRachLst(cell, newRnti);
968    if ((ue == NULLP) || (newUe == NULLP))
969    {
970       DU_LOG("\nERROR  -->  MAC : RNTI:%d Failed to get UECB[%lu:%lu] or NEW RNTI:%d", 
971                rnti, ((PTR)ue), ((PTR)newUe), newRnti);
972       return RFAILED;
973    }
974 #ifdef XEON_SPECIFIC_CHANGES
975    DU_LOG("\nDEBUG  -->  MAC : MAC:UE[%d] id changed to %d\n", rnti, newRnti);
976 #endif
977    rgDBMDelUeCb(cell, ue);
978
979    ue->ueId = newRnti;
980
981    memcpy(&(ue->contResId), &(newUe->contResId), 
982                    sizeof(newUe->contResId));
983    /* Fix : syed MSG4 might be RETXing need to store the
984     * HARQ context. */
985    rgDHMFreeUe(inst,&ue->dl.hqEnt);
986    ue->dl.hqEnt = newUe->dl.hqEnt;
987        
988    rgDBMInsUeCb(cell, ue);
989
990    rgDBMDelUeCbFromRachLst(cell, newUe);
991    rgFreeSBuf(inst,(Data **)&newUe, sizeof(*newUe));
992
993    return ROK;
994 } /* end of rgUtlHndlCrntiChng */
995
996 #ifdef LTE_ADV
997 /**
998  * @brief Function for handling UE  release for SCELL
999  * triggered from SCH to MAC.
1000  *
1001  * @details
1002  *
1003  *     Function : rgDelUeFrmAllSCell
1004  *     
1005  *        - This Function should be invoked by PCell of UE
1006  *        - Remove the UE context from SCELL corresponding to rnti.
1007  *           
1008  *  @param[in] Inst      *macInst,
1009  *  @param[in] RgUeCb    *ue
1010  *  @return  ROK is SUCCESS 
1011  **/
1012 S16 rgDelUeFrmAllSCell(RgCellCb *cell,RgUeCb *ue)
1013 {
1014    Inst        inst     = cell->macInst - RG_INST_START;
1015    uint8_t     idx      = 0;
1016    Inst        sCellInstIdx;
1017    Pst         dstInstPst;
1018    RgPrgUeSCellDelInfo ueSCellDelInfo;
1019
1020    /* To Delete the SCells if exisits for that UE */
1021    for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
1022    {
1023       if(TRUE == ue->sCelInfo[idx].isSCellAdded)
1024       {
1025          sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START;
1026
1027          rgGetPstToInst(&dstInstPst, inst, sCellInstIdx);
1028          ueSCellDelInfo.ueId = ue->ueId;
1029          ueSCellDelInfo.sCellId = ue->sCelInfo[idx].sCellId;
1030
1031          /* Filling same ueId in newRnti so that SMAC will check if newRnti
1032           *and old UeId is same that means its a UeSCell delete request*/
1033          ueSCellDelInfo.newRnti = ue->ueId;
1034
1035          RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueSCellDelInfo);
1036          ue->sCelInfo[idx].isSCellAdded = FALSE;
1037       } /* loop of if */
1038    } /* loop of for */
1039
1040    return ROK;
1041 } /* rgDelUeFrmAllSCell */
1042
1043 /**
1044  * @brief Function to validate AddSCellCfg.
1045  *
1046  * @details
1047  *
1048  *     Function : rgUtlVltdAddSCellCfg
1049  *     
1050  *           
1051  *  @param[in] ueSCellCb   secondary cell CB for validation
1052  *  @param[in] cell        cell control block
1053  *  @param[in] inst        instance number to fetch rgCb instance
1054  *  @return  S16
1055  *      -# ROK 
1056  **/
1057 S16 rgUtlVltdAddSCellCfg(RgPrgUeSCellCfgInfo *ueSCellCb,RgCellCb *cell,Inst inst)
1058 {
1059   S16 ret = ROK; 
1060   
1061   /* To Validate the CellID presence */
1062   if((cell == NULLP) ||
1063         (cell->cellId != ueSCellCb->cellId))
1064   {
1065      DU_LOG("\nERROR  -->  MAC : [%d]Sec Cell does not exit %d\n",
1066               ueSCellCb->ueId, ueSCellCb->cellId);
1067      ret = RFAILED;
1068   }
1069 #ifdef TENB_MULT_CELL_SUPPRT
1070    if((ueSCellCb->rguDlSapId > rgCb[inst].numRguSaps) ||
1071       (ueSCellCb->rguUlSapId > rgCb[inst].numRguSaps))
1072    {
1073       DU_LOG("\nERROR  -->  MAC : Invald Sap Id: DL %d UL %d for ueId %d failed\n",
1074                ueSCellCb->rguDlSapId,
1075                ueSCellCb->rguUlSapId,
1076                ueSCellCb->cellId);
1077      ret = RFAILED;
1078    }
1079 #endif
1080    return (ret);
1081 } /* rgUtlVltdAddSCellCfg */
1082
1083 /**
1084  * @brief Function to build CrntiChangeReq and send to all SMACs.
1085  *
1086  * @details
1087  *
1088  *     Function : rgUtlSndCrntiChngReq2AllSMacs
1089  *     
1090  *        - This Function should be invoked by PCell of UE
1091  *        - It sends RgPrgPMacSMacUeSCellDelReq to all SMACs with newRnti sent
1092  *          by SCH. SMAC will check if newRnti is not equal to old UeId then it
1093  *          do only UeId change else it will delete the UeScell context
1094  *           
1095  *  @param[in] cell    Cell CB to get Ue control block
1096  *  @param[in] rnti    Ue Identifier used to fill in UeId Change req
1097  *  @param[in] newRnti UE new identifier, to be used in UeId Change req
1098  *  @return  S16
1099  *      -# ROK 
1100  **/
1101 static S16 rgUtlSndCrntiChngReq2AllSMacs
1102 (
1103 RgCellCb        *cell,
1104 CmLteRnti       rnti,
1105 CmLteRnti       newRnti
1106 )
1107 {
1108    Inst                inst = cell->macInst - RG_INST_START;
1109    Inst                sCellInstIdx;
1110    Pst                 dstInstPst;
1111    RgPrgUeSCellDelInfo ueIdChngReq;
1112    RgUeCb              *ue;
1113    uint8_t                  idx;
1114 #ifdef L2_OPTMZ
1115 TfuDelDatReqInfo delDatReq;
1116 #endif
1117
1118    /* use newRnti to get UeCb in PMac because rnti is already changed in PMac*/
1119    ue = rgDBMGetUeCb(cell, newRnti);
1120    if (ue == NULLP)
1121    {
1122       DU_LOG("\nERROR  -->  MAC : [%d]RNTI:Failed to get ueCb \
1123                newRnti=%d\n", rnti, newRnti);
1124       return RFAILED;
1125    }
1126    /* For all added SCells, prepare and send ueIdChngReq */
1127    for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
1128    {
1129       if(TRUE == ue->sCelInfo[idx].isSCellAdded)
1130       {
1131          sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START;
1132
1133          rgGetPstToInst(&dstInstPst, inst, sCellInstIdx);
1134          /* fill old rnti*/
1135          ueIdChngReq.ueId = rnti;
1136          ueIdChngReq.sCellId = ue->sCelInfo[idx].sCellId;
1137          
1138          /* Filling newRnti so that SMAC can check if old ueId and new UeId
1139           *(newRnti) is different then its a UeId change request from PMAC.
1140           * RgPrgPMacSMacUeSCellDelReq is being reused for UeId change req
1141           * from PMAC to SMAC*/
1142          ueIdChngReq.newRnti = newRnti;
1143          
1144          /* Re-using UeSCellDelReq API for UeId change*/
1145          RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueIdChngReq);
1146 #ifdef L2_OPTMZ
1147       /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/
1148       delDatReq.cellId = ueIdChngReq.sCellId;
1149       delDatReq.ueId = ueIdChngReq.ueId;
1150       rgLIMTfuDelDatReq(sCellInstIdx, &delDatReq);
1151 #endif
1152
1153       } /* loop of if */
1154    } /* loop of for */
1155
1156    return ROK;
1157 } /* rgUtlSndCrntiChngReq2AllSMacs */
1158
1159 #endif /* LTE_ADV */
1160
1161 /**
1162  * @brief Function for handling CRNTI Context release 
1163  * triggered from SCH to MAC.
1164  *
1165  * @details
1166  *
1167  *     Function : rgUtlHndlCrntiRls
1168  *     
1169  *        - Remove the UE context from MAC corresponding to rnti.
1170  *     
1171  *           
1172  *  @param[in] RgCellCb      *cell,
1173  *  @param[in] CmLteRnti     rnti
1174  *  @return  Void 
1175  **/
1176 static Void rgUtlHndlCrntiRls(RgCellCb *cell,RgInfRlsRnti *rlsRnti)
1177 {
1178    Inst           inst = cell->macInst - RG_INST_START;
1179    RgUeCb        *ue = NULLP;
1180 #ifdef LTEMAC_SPS
1181    RgUeCb         *spsUeCb = NULLP;
1182 #endif
1183
1184    if ((ue = rgDBMGetUeCb(cell, rlsRnti->rnti)) == NULLP)
1185    {
1186       /* Check in RachLst */
1187       if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP)
1188       {
1189          /* Delete Ue from the UE list */
1190          rgDBMDelUeCbFromRachLst(cell, ue);
1191
1192          /* Free Ue */
1193          rgRAMFreeUeCb(inst,ue);
1194       }
1195       else
1196       {
1197           DU_LOG("\nERROR  -->  MAC : RNTI:%d No ueCb found in RachLst",rlsRnti->rnti);
1198       }
1199    }
1200    else
1201    {
1202 #ifdef LTE_ADV
1203       if(FALSE == rlsRnti->isUeSCellDel)
1204       {
1205          rgDelUeFrmAllSCell(cell, ue);
1206       }
1207 #endif /* LTE_ADV */
1208
1209       /* Delete Ue from the UE list */
1210       rgDBMDelUeCb(cell, ue);
1211 #ifdef LTEMAC_SPS
1212       spsUeCb = rgDBMGetSpsUeCb (cell, ue->spsRnti);
1213       if (spsUeCb)
1214       {
1215          rgDBMDelSpsUeCb(cell, spsUeCb);
1216       }
1217 #endif
1218
1219       /* Free Ue */
1220       rgCFGFreeUeCb(cell, ue);     
1221       /* MS_REMOVE : syed Check in RachLst */
1222       {
1223          if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP)
1224          {
1225              DU_LOG("\nERROR  -->  MAC : RNTI:%d STALE UE is still present", rlsRnti->rnti);         
1226          }
1227       }
1228    }
1229
1230    return;
1231 } /* end of rgUtlHndlCrntiRls */
1232
1233 /**
1234  * @brief Function for handling RaResp request received from scheduler to MAC.
1235  *
1236  * @details
1237  *
1238  *     Function : RgSchMacRlsRntiReq
1239  *     
1240  *     This function shall be invoked whenever scheduler is done with the
1241  *     allocations of random access responses for a subframe.
1242  *     This shall invoke RAM to create ueCbs for all the rapIds allocated and 
1243  *     shall invoke MUX to create RAR PDUs for raRntis allocated.
1244  *     
1245  *           
1246  *  @param[in] CmLteCellId         cellId,
1247  *  @param[in] CmLteTimingInfo     timingInfo,
1248  *  @param[in] RaRespInfo          *rarInfo
1249  *  @return  S16
1250  *      -# ROK 
1251  **/
1252 S16 RgSchMacRlsRntiReq(Pst *pst,RgInfRlsRnti *rlsRnti)
1253 {
1254 //   Pst            schPst;
1255 //   RgInfUeDelInd  ueDelInd;
1256    Inst           macInst;
1257    RgCellCb       *cell;
1258 #ifdef L2_OPTMZ
1259 TfuDelDatReqInfo delDatReq;
1260 #endif
1261
1262    RG_IS_INST_VALID(pst->dstInst);
1263    macInst   = pst->dstInst - RG_INST_START;
1264    cell   = rgCb[macInst].cell;
1265
1266    if(NULLP == rlsRnti)
1267    {
1268       return RFAILED;
1269    }
1270
1271    if((cell == NULLP) ||
1272       (cell->cellId != rlsRnti->cellId))
1273    {
1274       
1275       DU_LOG("\nERROR  -->  MAC : No cellCb found with cellId for RNTI:%d", 
1276                          rlsRnti->rnti);
1277       return RFAILED;
1278    }
1279    /* Fix : syed Clearing UE context when SCH indicates to do so
1280     * UE DEL from CRG interface is now dummy. */
1281    if (rlsRnti->ueIdChng)
1282    {
1283       /* Fix : syed ueId change as part of reestablishment.
1284        * Now SCH to trigger this. CRG ueRecfg for ueId change 
1285        * is dummy */       
1286       if (rgUtlHndlCrntiChng(macInst,cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK)        
1287       {
1288           DU_LOG("\nERROR  -->  MAC : CRNTI change failed for RNTI:%d new RNTI:%d",
1289                    rlsRnti->rnti,rlsRnti->newRnti);
1290          return RFAILED;
1291       }
1292
1293 #ifdef LTE_ADV
1294       /*PMAC_Reest: Prepare CrntiChngReq and then send to all SMACs to change
1295        *rnti in all Scells
1296        */
1297       if(rgUtlSndCrntiChngReq2AllSMacs(cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK)
1298       {
1299          /* TODO: do we need to send DelInd to SCH in failure case*/ 
1300          return RFAILED;
1301       }
1302 #endif
1303 #ifdef L2_OPTMZ
1304       /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/
1305       delDatReq.cellId = cell->cellId;
1306       delDatReq.ueId = rlsRnti->rnti;
1307       rgLIMTfuDelDatReq(macInst, &delDatReq);
1308 #endif
1309    }
1310    else
1311    {
1312       rgUtlHndlCrntiRls(cell, rlsRnti);
1313    }
1314    /* Fix : syed Send delete confirmation to SCH */
1315    /* Send RgMacSchUeDelInd to SCH only if it is Rnti release to PMAC.
1316     * Basically dont send DelInd to SCH incase of Ue SCell Del*/
1317 #ifdef LTE_ADV
1318    if(FALSE == rlsRnti->isUeSCellDel)
1319 #endif
1320    {
1321       //TODO: commented for compilation without SCH 
1322 #if 0
1323       ueDelInd.cellSapId  = cell->schInstMap.cellSapId;
1324       ueDelInd.cellId  = rlsRnti->cellId;
1325       ueDelInd.rnti    = rlsRnti->rnti; 
1326       rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst);
1327       RgMacSchUeDel(&schPst, &ueDelInd);
1328 #endif
1329    }
1330
1331    return ROK;
1332 } /* end of RgSchMacRlsRntiReq */
1333
1334 #ifdef L2_OPTMZ
1335 Bool RgUtlIsTbMuxed(TfuDatReqTbInfo *tb)
1336 {
1337    MsgLen len = 0;
1338    SFndLenMsg(tb->macHdr, &len);
1339    return (len?TRUE : FALSE);
1340 }
1341 #endif
1342
1343 /**********************************************************************
1344  
1345          End of file
1346 **********************************************************************/