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