5736fc8b2cd476e1a287fb0a4ef8bec855912e5c
[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 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=179;
38
39 /* header include files (.h) */
40 #include "common_def.h"
41 #include "rg_env.h"        /* MAC Environment Defines */
42 #include "crg.h"           /* CRG Interface defines */
43 #include "rgu.h"           /* RGU Interface defines */
44 #include "tfu.h"           /* TFU Interface defines */
45 #include "rg_sch_inf.h"    /* RGR Interface defines */
46 #include "lrg.h"           /* LRG Interface defines */
47
48 #include "rg_prg.h"        /* PRG(MAC-MAC) Interface includes */
49 #include "rg.h"            /* MAC defines */
50 #include "rg_err.h"        /* MAC error defines */
51
52 /* header/extern include files (.x) */
53 #include "cm5.x"           /* Timer */
54
55 #include "crg.x"           /* CRG Interface includes */
56 #include "rgu.x"           /* RGU Interface includes */
57 #include "tfu.x"           /* TFU Interface includes */
58 #include "rg_sch_inf.x"    /* RGR Interface includes */
59 #include "lrg.x"           /* LRG Interface includes */
60 #include "rg_prg.x"        /* PRG(MAC-MAC) Interface includes */
61
62 #include "du_app_mac_inf.h"
63 #include "rg.x"            /* MAC includes */
64
65 /* local defines */
66 #define RG_NON_MIMO_IDX 0
67
68 /* local typedefs */
69  
70 /* local externs */
71  
72 /* forward references */
73 static S16 rgUtlHndlCrntiChng ARGS((
74          Inst            inst,
75          RgCellCb        *cell,
76          CmLteRnti       rnti,
77          CmLteRnti       newRnti
78          ));
79 static Void rgUtlHndlCrntiRls ARGS((
80          RgCellCb        *cell,
81          RgInfRlsRnti    *rlsRnti
82          ));
83
84 S16 rgDelUeFrmAllSCell ARGS((
85          RgCellCb       *cell,
86          RgUeCb         *ue
87          ));
88
89 #ifdef LTE_ADV
90 static S16 rgUtlSndCrntiChngReq2AllSMacs ARGS((
91          RgCellCb        *cell,
92          CmLteRnti       rnti,
93          CmLteRnti       newRnti
94          ));
95 #endif
96 /***********************************************************
97  *
98  *     Func : rgAllocShrablSBuf
99  *
100  *     Desc : Utility Function to Allocate static buffer which is 
101  *            sharable among different layers if YYYY flag is enabled. 
102  *            else it allocates from normal static region
103  *            Memory allocated is assumed contiguous.
104  *            
105  *
106  *     Ret  : ROK
107  *            RFAILED
108  *
109  *     Notes: Caller doesnt need to raise the alarm in case of memory
110  *            allocation gets failed. 
111  *
112  *     File : rg_utl.c
113  *
114  **********************************************************/
115 S16 rgAllocShrablSBuf
116 (
117 Inst    inst,
118 Data    **pData,            /* Pointer of the data to be returned */
119 Size    size                /* size */
120 )
121 {
122    RgUstaDgn dgn;      /* Alarm diagnostics structure */
123
124    /* Initialize the param to NULLP */
125    *pData = NULLP;
126
127    if (size == 0)
128    {
129       return RFAILED;
130    }
131
132    /* allocate buffer */
133    if (SGetStaticBuffer(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, pData, size, 0) != ROK)
134    {
135      dgn.type = LRG_USTA_DGNVAL_MEM;
136      dgn.u.mem.region = rgCb[inst].rgInit.region;
137      dgn.u.mem.pool = rgCb[inst].rgInit.pool;
138      /*  Send an alarm to Layer Manager */
139      rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
140                                        LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
141       RGLOGERROR(inst,ERRCLS_DEBUG, ERG028, 0, "Unable to Allocate Buffer");
142       return RFAILED;
143    }
144
145 #ifndef ALIGN_64BIT
146    RGDBGINFO(inst,(rgPBuf(inst), "SGetSBuf(Region (%d), Pool (%d), Size (%ld)), Data (0x%p))\n",
147              rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData));
148 #else
149    RGDBGINFO(inst,(rgPBuf(inst), "SGetSBuf(Region (%d), Pool (%d), Size (%d)), Data (0x%p))\n",
150              rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData));
151 #endif
152
153    /* zero out the allocated memory */
154    memset(*pData, 0x00, size);
155
156    return ROK;
157
158 } /* end of rgAllocSBuf */
159
160
161 /***********************************************************
162  *
163  *     Func : rgAllocSBuf
164  *
165  *     Desc : Utility Function to Allocate static buffer. 
166  *            Memory allocated is assumed contiguous.
167  *            
168  *
169  *     Ret  : ROK
170  *            RFAILED
171  *
172  *     Notes: Caller doesnt need to raise the alarm in case of memory
173  *            allocation gets failed. 
174  *
175  *     File : rg_utl.c
176  *
177  **********************************************************/
178 S16 rgAllocSBuf
179 (
180 Inst    inst,
181 Data    **pData,            /* Pointer of the data to be returned */
182 Size    size                /* size */
183 )
184 {
185    RgUstaDgn dgn;      /* Alarm diagnostics structure */
186
187    /* Initialize the param to NULLP */
188    *pData = NULLP;
189
190    if (size == 0)
191    {
192       return RFAILED;
193    }
194
195    /* allocate buffer */
196 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
197    MS_BUF_ADD_ALLOC_CALLER();
198 #endif /* */
199    if (SGetSBuf(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, pData, size) != ROK)
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       RGLOGERROR(inst,ERRCLS_DEBUG, ERG028, 0, "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    ret = SPutStaticBuffer(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, *data, size, SS_SHARABLE_MEMORY);
251
252    if (ret != ROK)
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    ret = SPutSBuf(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, *data, size);
302
303    if (ret != ROK)
304    {
305       RGLOGERROR(inst,ERRCLS_DEBUG, ERG029, (ErrVal) 0, "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 = SGetMsg(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       RGLOGERROR(inst,ERRCLS_DEBUG, ERG030, 0, "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       RGLOGERROR(inst,ERRCLS_INT_PAR, ERG031, memSize,
608                    "rgAllocEventMem(): memSize invalid\n");
609       return  (RFAILED);
610    }
611 #endif /* ERRCLASS & ERRCLS_DEBUG */
612
613
614    /*starting Task*/
615    SStartTask(&startTime, PID_MACUTL_CMALLCEVT);
616
617 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
618    MS_BUF_ADD_ALLOC_CALLER();
619 #endif /* */
620 #ifdef TFU_ALLOC_EVENT_NO_INIT
621    if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
622 #else
623    if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
624 #endif /* */
625    {
626       RLOG0(L_ERROR,"cmAllocEvnt Failed"); 
627       return RFAILED;
628    }
629
630    /*stoping Task*/
631    SStopTask(startTime, PID_MACUTL_CMALLCEVT);
632
633    return ROK;
634 } /* end of rgAllocEventMem*/
635
636 /*
637 *
638 *       Fun:   rgGetEventMem
639 *
640 *       Desc:  This function allocates event memory 
641 *
642 *       Ret:   ROK      - on success
643 *              RFAILED  - on failure
644 *
645 *       Notes: None
646 *
647 *       File:  rg_utl.c
648 *
649 */
650 S16 rgGetEventMem
651 (
652 Inst      inst,
653 Ptr       *ptr,
654 Size      len,
655 Ptr       memCp
656 )
657 {
658    S16   ret;
659
660 #ifdef TFU_ALLOC_EVENT_NO_INIT
661    ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
662 #else
663    ret = cmGetMem(memCp, len, (Ptr *)ptr);
664 #endif /* */
665    return (ret);
666 } /* end of rgGetEventMem*/
667
668 /***********************************************************
669  *
670  *     Func : rgGetPstToInst
671  *
672  *     Desc : Utility Function to get the pst structure to post a message to
673  *     scheduler instance
674  *            
675  *
676  *     Ret  : ROK
677  *            RFAILED
678  *
679  *     Notes: This function should be called while sending a msg from 
680  *     MAC to a scheduler instance
681  *
682  *     File : rg_utl.c
683  *
684  **********************************************************/
685 Void rgGetPstToInst
686 (
687 Pst           *pst,
688 Inst          srcInst,
689 Inst          dstInst
690 )
691 {
692
693    pst->srcEnt = rgCb[srcInst].rgInit.ent; 
694    pst->srcInst = rgCb[srcInst].rgInit.inst;
695    pst->srcProcId = rgCb[srcInst].rgInit.procId;
696    pst->region = rgCb[srcInst].rgInit.region;
697    pst->pool = rgCb[srcInst].rgInit.pool;
698
699    pst->dstProcId = rgCb[dstInst].rgInit.procId;
700    pst->dstEnt = rgCb[dstInst].rgInit.ent; 
701    pst->dstInst = dstInst;
702    pst->selector = 0;
703    pst->prior     = PRIOR0;
704    pst->intfVer   = 0;
705    pst->route   = RTESPEC;
706
707    return; 
708 } /* end of rgGetPstToInst */
709
710 /***********************************************************
711  *
712  *     Func : RgSchMacLcgRegReq
713  *
714  *     Desc : Utility Function to register the set of GBR LCG.
715  *        Invoked at the time of LCG configuration/Reconfiguration at Schedular.
716  * 
717  *     Processing Steps: 
718  *           - Fetch the ueCb using the crnti given in lcInfo            
719  *           - Store the if LCG is GBR or not.
720  *
721  *     Ret  : ROK
722  *            RFAILED
723  *
724  *     Notes: This function should be called at the time of LCG 
725  *     configuration/Reconfiguration at Schedular. 
726  *     
727  *
728  *     File : rg_utl.c
729  *
730  **********************************************************/
731 S16 RgSchMacLcgRegReq(Pst *pst,RgInfLcgRegReq *lcgRegReq)
732 {
733    Inst       inst;
734    RgCellCb   *cell = NULLP;
735    RgUeCb     *ue;
736
737    RG_IS_INST_VALID(pst->dstInst);
738    inst   = pst->dstInst - RG_INST_START;
739    cell   = rgCb[inst].cell;
740    /* Fetch the cell and then the UE */
741    if((cell == NULLP) ||
742       (cell->cellId != lcgRegReq->cellId))
743    {
744       
745       RLOG_ARG0(L_ERROR,DBG_CELLID,lcgRegReq->cellId,"Cell does not exist ");
746       return RFAILED;
747    }
748
749    if ((ue = rgDBMGetUeCb(cell, lcgRegReq->crnti)) == NULLP)
750    {
751       RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", 
752                          lcgRegReq->crnti);
753       return RFAILED;
754    }
755    ue->ul.lcgArr[lcgRegReq->lcgId].isGbr = lcgRegReq->isGbr;
756
757    return ROK; 
758 } /* end of RgSchMacLcgRegReq */
759
760 #ifdef LTEMAC_SPS
761
762 /***********************************************************
763  *
764  *     Func : RgSchMacUlSpsResetReq
765  *
766  *     Desc : Utility Function to reset SPS params for a UE
767  * 
768  *     Processing Steps: 
769  *           - Fetch the ueCb using the crnti 
770  *           - reset implRelCnt and explRelCnt
771  *
772  *     Ret  : ROK
773  *            RFAILED
774  *
775  *     File : rg_utl.c
776  *
777  **********************************************************/
778 S16 RgSchMacUlSpsResetReq(Pst *pst,RgInfUlSpsReset *ulSpsResetInfo)
779 {
780    Inst       inst;
781    RgCellCb   *cell = NULLP;
782    RgUeCb     *ue;
783
784    RG_IS_INST_VALID(pst->dstInst);
785    inst   = pst->dstInst - RG_INST_START;
786    cell   = rgCb[inst].cell;
787    /* Fetch the cell and then the UE */
788    if((cell == NULLP)||
789       (cell->cellId != ulSpsResetInfo->cellId))
790    {
791       
792       RLOG_ARG0(L_ERROR, DBG_CELLID,ulSpsResetInfo->cellId,"Cell does not exist ");
793       return RFAILED;
794    }
795
796    if ((ue = rgDBMGetUeCb(cell, ulSpsResetInfo->crnti)) == NULLP)
797    {
798       RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", 
799                       ulSpsResetInfo->crnti);
800       return RFAILED;
801    }
802
803    ue->ul.implRelCntr = 0;
804    ue->ul.explRelCntr = 0;
805
806    return ROK; 
807 } /* end of RgSchMacUlSpsResetReq */
808
809
810
811
812 /***********************************************************
813  *
814  *     Func : RgSchMacSpsLcRegReq
815  *
816  *     Desc : Utility Function to register the set of uplink SPS logical
817  *        channels for a SPS UE.
818  *        Invoked at the time of activation of a UE for UL-SPS.
819  *        Whenever there is data on these LCs MAC shall inform scheduler
820  * 
821  *     Processing Steps: 
822  *           - Fetch the ueCb using the crnti given in lcInfo            
823  *           - Store the sps-rnti and set the bits corresponding to the
824  *             logical channel ids in ueUlCb->spsLcMask.
825  *
826  *     Ret  : ROK
827  *            RFAILED
828  *
829  *     Notes: This function should be called at the time UL SPS is activated 
830  *     for a UE at scheduler
831  *     
832  *
833  *     File : rg_utl.c
834  *
835  **********************************************************/
836 S16 RgSchMacSpsLcRegReq(Pst *pst,RgInfSpsLcInfo *lcInfo)
837 {
838    Inst       inst;
839    RgCellCb   *cell= NULLP;
840    RgUeCb     *ue;
841    uint8_t    idx;
842
843    RG_IS_INST_VALID(pst->dstInst);
844    inst   = pst->dstInst - RG_INST_START;
845    cell   = rgCb[inst].cell;
846    /* Fetch the cell and then the UE */
847    if((cell == NULLP) ||
848       (cell->cellId != lcInfo->cellId))
849    {
850       
851       RLOG_ARG0(L_ERROR,DBG_CELLID,lcInfo->cellId, "Cell does not exist ");
852       return RFAILED;
853    }
854
855    if ((ue = rgDBMGetUeCb(cell, lcInfo->crnti)) == NULLP)
856    {
857       RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", 
858                       lcInfo->crnti);
859       return RFAILED;
860    }
861
862    /* Store the sps-rnti and SPS LC information in the UE */ 
863    ue->spsRnti = lcInfo->spsRnti;
864    for (idx=0; idx < lcInfo->spsLcCnt; idx++)
865    {
866       /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */
867       ue->ul.spsLcId[(lcInfo->spsLcId[idx])-1] = TRUE;
868    }
869    ue->ul.implRelCnt = lcInfo->implRelCnt;
870    ue->ul.explRelCnt = ue->ul.implRelCnt + 1; /*(lcInfo->implRelCnt * lcInfo->spsPrd);*/
871
872    /* Insert the UE into SPS UE List */
873    if (rgDBMInsSpsUeCb(cell, ue) == RFAILED)
874    {
875       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
876                     "Ue insertion into SPS list failed SPS CRNTI:%d", ue->spsRnti);
877       return RFAILED;
878    } 
879
880    return ROK; 
881 } /* end of RgSchMacSpsLcRegReq */
882
883
884 /***********************************************************
885  *
886  *     Func : RgSchMacSpsLcDeregReq
887  *
888  *     Desc : Utility Function to deregister the set of uplink SPS 
889  *        logical channels for a UE.
890  *        Invoked at the time of release of UL-SPS for an activated UE.
891  * 
892  *     Processing Steps: 
893  *           - Fetch the ueCb using the crnti given
894  *           - Reset the bits corresponding to the logical channel ids in
895  *             ueUlCb->spsLcMask.
896  *
897  *     Ret  : ROK
898  *            RFAILED
899  *
900  *     Notes: This function should be called at the time UL SPS is released 
901  *     for a UE at scheduler
902  *     
903  *
904  *     File : rg_utl.c
905  *
906  **********************************************************/
907 S16 RgSchMacSpsLcDeregReq(Pst  *pst,CmLteCellId cellId,CmLteRnti crnti)
908 {
909    Inst       inst;
910    RgCellCb   *cell = NULLP;
911    RgUeCb      *ue;
912
913    RG_IS_INST_VALID(pst->dstInst);
914    inst   = pst->dstInst - RG_INST_START;
915    cell   = rgCb[inst].cell;
916    /* Fetch the cell and then the UE */
917    if((cell == NULLP) ||
918       (cell->cellId != cellId))
919    {
920       
921       RLOG_ARG0(L_ERROR,DBG_CELLID,cellId, "Cell does not exist ");
922       return RFAILED;
923    }
924
925    if ((ue = rgDBMGetUeCb(cell, crnti)) == NULLP)
926    {
927       RLOG_ARG1(L_ERROR, DBG_CELLID,cellId,"CRNTI:%d Ue does not exist", crnti);
928       return RFAILED;
929    }
930
931    /* No need to reset the SPS LC Ids as they will not be looked at*/
932
933    /* Delete UE from the SPS UE List */
934    rgDBMDelSpsUeCb(cell, ue);
935    
936    return ROK; 
937 } /* end of RgSchMacSpsLcDeregReq */
938
939 #endif /* LTEMAC_SPS */
940
941 /**
942  * @brief Function for handling CRNTI change request 
943  * received from scheduler to MAC.
944  *
945  * @details
946  *
947  *     Function : rgUtlHndlCrntiChng
948  *     
949  *        - Delete old UE from the list.
950  *        - Update the new rnti and re-insert the UE in the list.
951  *     
952  *           
953  *  @param[in] Inst        inst
954  *  @param[in] RgCellCb      *cell,
955  *  @param[in] CmLteRnti     rnti,
956  *  @param[in] CmLteRnti     newRnti
957  *  @return  S16
958  *      -# ROK 
959  *      -# RFAILED
960  **/
961 static S16 rgUtlHndlCrntiChng 
962 (
963 Inst            inst,
964 RgCellCb        *cell,
965 CmLteRnti       rnti,
966 CmLteRnti       newRnti
967 )
968 {
969    RgUeCb         *ue = NULLP;
970    RgUeCb         *newUe = NULLP;
971
972    ue = rgDBMGetUeCb(cell, rnti);
973    newUe = rgDBMGetUeCbFromRachLst(cell, newRnti);
974    if ((ue == NULLP) || (newUe == NULLP))
975    {
976       RLOG_ARG4(L_ERROR,DBG_CELLID,cell->cellId,
977                         "RNTI:%d Failed to get UECB[%lu:%lu] or NEW RNTI:%d", 
978                rnti, ((PTR)ue), ((PTR)newUe), newRnti);
979       return RFAILED;
980    }
981 #ifdef XEON_SPECIFIC_CHANGES
982    CM_LOG_DEBUG(CM_LOG_ID_MAC, "MAC:UE[%d] id changed to %d\n", rnti, newRnti);
983 #endif
984    rgDBMDelUeCb(cell, ue);
985
986    ue->ueId = newRnti;
987
988    memcpy(&(ue->contResId), &(newUe->contResId), 
989                    sizeof(newUe->contResId));
990    /* Fix : syed MSG4 might be RETXing need to store the
991     * HARQ context. */
992    rgDHMFreeUe(inst,&ue->dl.hqEnt);
993    ue->dl.hqEnt = newUe->dl.hqEnt;
994        
995    rgDBMInsUeCb(cell, ue);
996
997    rgDBMDelUeCbFromRachLst(cell, newUe);
998    rgFreeSBuf(inst,(Data **)&newUe, sizeof(*newUe));
999
1000    return ROK;
1001 } /* end of rgUtlHndlCrntiChng */
1002
1003 #ifdef LTE_ADV
1004 /**
1005  * @brief Function for handling UE  release for SCELL
1006  * triggered from SCH to MAC.
1007  *
1008  * @details
1009  *
1010  *     Function : rgDelUeFrmAllSCell
1011  *     
1012  *        - This Function should be invoked by PCell of UE
1013  *        - Remove the UE context from SCELL corresponding to rnti.
1014  *           
1015  *  @param[in] Inst      *macInst,
1016  *  @param[in] RgUeCb    *ue
1017  *  @return  ROK is SUCCESS 
1018  **/
1019 S16 rgDelUeFrmAllSCell(RgCellCb *cell,RgUeCb *ue)
1020 {
1021    Inst        inst     = cell->macInst - RG_INST_START;
1022    uint8_t     idx      = 0;
1023    Inst        sCellInstIdx;
1024    Pst         dstInstPst;
1025    RgPrgUeSCellDelInfo ueSCellDelInfo;
1026
1027    /* To Delete the SCells if exisits for that UE */
1028    for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
1029    {
1030       if(TRUE == ue->sCelInfo[idx].isSCellAdded)
1031       {
1032          sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START;
1033
1034          rgGetPstToInst(&dstInstPst, inst, sCellInstIdx);
1035          ueSCellDelInfo.ueId = ue->ueId;
1036          ueSCellDelInfo.sCellId = ue->sCelInfo[idx].sCellId;
1037
1038          /* Filling same ueId in newRnti so that SMAC will check if newRnti
1039           *and old UeId is same that means its a UeSCell delete request*/
1040          ueSCellDelInfo.newRnti = ue->ueId;
1041
1042          RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueSCellDelInfo);
1043          ue->sCelInfo[idx].isSCellAdded = FALSE;
1044       } /* loop of if */
1045    } /* loop of for */
1046
1047    return ROK;
1048 } /* rgDelUeFrmAllSCell */
1049
1050 /**
1051  * @brief Function to validate AddSCellCfg.
1052  *
1053  * @details
1054  *
1055  *     Function : rgUtlVltdAddSCellCfg
1056  *     
1057  *           
1058  *  @param[in] ueSCellCb   secondary cell CB for validation
1059  *  @param[in] cell        cell control block
1060  *  @param[in] inst        instance number to fetch rgCb instance
1061  *  @return  S16
1062  *      -# ROK 
1063  **/
1064 S16 rgUtlVltdAddSCellCfg(RgPrgUeSCellCfgInfo *ueSCellCb,RgCellCb *cell,Inst inst)
1065 {
1066   S16 ret = ROK; 
1067   
1068   /* To Validate the CellID presence */
1069   if((cell == NULLP) ||
1070         (cell->cellId != ueSCellCb->cellId))
1071   {
1072      RGDBGERRNEW(inst, (rgPBuf(inst),
1073               "[%d]Sec Cell does not exit %d\n",
1074               ueSCellCb->ueId, ueSCellCb->cellId));
1075      ret = RFAILED;
1076   }
1077 #ifdef TENB_MULT_CELL_SUPPRT
1078    if((ueSCellCb->rguDlSapId > rgCb[inst].numRguSaps) ||
1079       (ueSCellCb->rguUlSapId > rgCb[inst].numRguSaps))
1080    {
1081       RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for ueId %d failed\n",
1082                ueSCellCb->rguDlSapId,
1083                ueSCellCb->rguUlSapId,
1084                ueSCellCb->cellId));
1085      ret = RFAILED;
1086    }
1087 #endif
1088    return (ret);
1089 } /* rgUtlVltdAddSCellCfg */
1090
1091 /**
1092  * @brief Function to build CrntiChangeReq and send to all SMACs.
1093  *
1094  * @details
1095  *
1096  *     Function : rgUtlSndCrntiChngReq2AllSMacs
1097  *     
1098  *        - This Function should be invoked by PCell of UE
1099  *        - It sends RgPrgPMacSMacUeSCellDelReq to all SMACs with newRnti sent
1100  *          by SCH. SMAC will check if newRnti is not equal to old UeId then it
1101  *          do only UeId change else it will delete the UeScell context
1102  *           
1103  *  @param[in] cell    Cell CB to get Ue control block
1104  *  @param[in] rnti    Ue Identifier used to fill in UeId Change req
1105  *  @param[in] newRnti UE new identifier, to be used in UeId Change req
1106  *  @return  S16
1107  *      -# ROK 
1108  **/
1109 static S16 rgUtlSndCrntiChngReq2AllSMacs
1110 (
1111 RgCellCb        *cell,
1112 CmLteRnti       rnti,
1113 CmLteRnti       newRnti
1114 )
1115 {
1116    Inst                inst = cell->macInst - RG_INST_START;
1117    Inst                sCellInstIdx;
1118    Pst                 dstInstPst;
1119    RgPrgUeSCellDelInfo ueIdChngReq;
1120    RgUeCb              *ue;
1121    uint8_t                  idx;
1122 #ifdef L2_OPTMZ
1123 TfuDelDatReqInfo delDatReq;
1124 #endif
1125
1126    /* use newRnti to get UeCb in PMac because rnti is already changed in PMac*/
1127    ue = rgDBMGetUeCb(cell, newRnti);
1128    if (ue == NULLP)
1129    {
1130       RGDBGERRNEW(inst,(rgPBuf(inst),"[%d]RNTI:Failed to get ueCb \
1131                newRnti=%d\n", rnti, newRnti));
1132       return RFAILED;
1133    }
1134    /* For all added SCells, prepare and send ueIdChngReq */
1135    for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
1136    {
1137       if(TRUE == ue->sCelInfo[idx].isSCellAdded)
1138       {
1139          sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START;
1140
1141          rgGetPstToInst(&dstInstPst, inst, sCellInstIdx);
1142          /* fill old rnti*/
1143          ueIdChngReq.ueId = rnti;
1144          ueIdChngReq.sCellId = ue->sCelInfo[idx].sCellId;
1145          
1146          /* Filling newRnti so that SMAC can check if old ueId and new UeId
1147           *(newRnti) is different then its a UeId change request from PMAC.
1148           * RgPrgPMacSMacUeSCellDelReq is being reused for UeId change req
1149           * from PMAC to SMAC*/
1150          ueIdChngReq.newRnti = newRnti;
1151          
1152          /* Re-using UeSCellDelReq API for UeId change*/
1153          RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueIdChngReq);
1154 #ifdef L2_OPTMZ
1155       /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/
1156       delDatReq.cellId = ueIdChngReq.sCellId;
1157       delDatReq.ueId = ueIdChngReq.ueId;
1158       rgLIMTfuDelDatReq(sCellInstIdx, &delDatReq);
1159 #endif
1160
1161       } /* loop of if */
1162    } /* loop of for */
1163
1164    return ROK;
1165 } /* rgUtlSndCrntiChngReq2AllSMacs */
1166
1167 #endif /* LTE_ADV */
1168
1169 /**
1170  * @brief Function for handling CRNTI Context release 
1171  * triggered from SCH to MAC.
1172  *
1173  * @details
1174  *
1175  *     Function : rgUtlHndlCrntiRls
1176  *     
1177  *        - Remove the UE context from MAC corresponding to rnti.
1178  *     
1179  *           
1180  *  @param[in] RgCellCb      *cell,
1181  *  @param[in] CmLteRnti     rnti
1182  *  @return  Void 
1183  **/
1184 static Void rgUtlHndlCrntiRls(RgCellCb *cell,RgInfRlsRnti *rlsRnti)
1185 {
1186    Inst           inst = cell->macInst - RG_INST_START;
1187    RgUeCb        *ue = NULLP;
1188 #ifdef LTEMAC_SPS
1189    RgUeCb         *spsUeCb = NULLP;
1190 #endif
1191
1192    if ((ue = rgDBMGetUeCb(cell, rlsRnti->rnti)) == NULLP)
1193    {
1194       /* Check in RachLst */
1195       if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP)
1196       {
1197          /* Delete Ue from the UE list */
1198          rgDBMDelUeCbFromRachLst(cell, ue);
1199
1200          /* Free Ue */
1201          rgRAMFreeUeCb(inst,ue);
1202       }
1203       else
1204       {
1205          RLOG_ARG1(L_WARNING,DBG_CELLID,cell->cellId,
1206                    "RNTI:%d No ueCb found in RachLst",rlsRnti->rnti);
1207       }
1208    }
1209    else
1210    {
1211 #ifdef LTE_ADV
1212       if(FALSE == rlsRnti->isUeSCellDel)
1213       {
1214          rgDelUeFrmAllSCell(cell, ue);
1215       }
1216 #endif /* LTE_ADV */
1217
1218       /* Delete Ue from the UE list */
1219       rgDBMDelUeCb(cell, ue);
1220 #ifdef LTEMAC_SPS
1221       spsUeCb = rgDBMGetSpsUeCb (cell, ue->spsRnti);
1222       if (spsUeCb)
1223       {
1224          rgDBMDelSpsUeCb(cell, spsUeCb);
1225       }
1226 #endif
1227
1228       /* Free Ue */
1229       rgCFGFreeUeCb(cell, ue);     
1230       /* MS_REMOVE : syed Check in RachLst */
1231       {
1232          if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP)
1233          {
1234             RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
1235                         "RNTI:%d STALE UE is still present", rlsRnti->rnti);         
1236          }
1237       }
1238    }
1239
1240    return;
1241 } /* end of rgUtlHndlCrntiRls */
1242
1243 /**
1244  * @brief Function for handling RaResp request received from scheduler to MAC.
1245  *
1246  * @details
1247  *
1248  *     Function : RgSchMacRlsRntiReq
1249  *     
1250  *     This function shall be invoked whenever scheduler is done with the
1251  *     allocations of random access responses for a subframe.
1252  *     This shall invoke RAM to create ueCbs for all the rapIds allocated and 
1253  *     shall invoke MUX to create RAR PDUs for raRntis allocated.
1254  *     
1255  *           
1256  *  @param[in] CmLteCellId         cellId,
1257  *  @param[in] CmLteTimingInfo     timingInfo,
1258  *  @param[in] RaRespInfo          *rarInfo
1259  *  @return  S16
1260  *      -# ROK 
1261  **/
1262 S16 RgSchMacRlsRntiReq(Pst *pst,RgInfRlsRnti *rlsRnti)
1263 {
1264 //   Pst            schPst;
1265 //   RgInfUeDelInd  ueDelInd;
1266    Inst           macInst;
1267    RgCellCb       *cell;
1268 #ifdef L2_OPTMZ
1269 TfuDelDatReqInfo delDatReq;
1270 #endif
1271
1272    RG_IS_INST_VALID(pst->dstInst);
1273    macInst   = pst->dstInst - RG_INST_START;
1274    cell   = rgCb[macInst].cell;
1275
1276    if(NULLP == rlsRnti)
1277    {
1278       return RFAILED;
1279    }
1280
1281    if((cell == NULLP) ||
1282       (cell->cellId != rlsRnti->cellId))
1283    {
1284       
1285       RLOG_ARG1(L_ERROR,DBG_CELLID,rlsRnti->cellId,
1286                "No cellCb found with cellId for RNTI:%d", 
1287                          rlsRnti->rnti);
1288       return RFAILED;
1289    }
1290    /* Fix : syed Clearing UE context when SCH indicates to do so
1291     * UE DEL from CRG interface is now dummy. */
1292    if (rlsRnti->ueIdChng)
1293    {
1294       /* Fix : syed ueId change as part of reestablishment.
1295        * Now SCH to trigger this. CRG ueRecfg for ueId change 
1296        * is dummy */       
1297       if (rgUtlHndlCrntiChng(macInst,cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK)        
1298       {
1299          RLOG_ARG2(L_ERROR,DBG_CELLID,rlsRnti->cellId,
1300                         "CRNTI change failed for RNTI:%d new RNTI:%d",
1301                    rlsRnti->rnti,rlsRnti->newRnti);
1302          return RFAILED;
1303       }
1304
1305 #ifdef LTE_ADV
1306       /*PMAC_Reest: Prepare CrntiChngReq and then send to all SMACs to change
1307        *rnti in all Scells
1308        */
1309       if(rgUtlSndCrntiChngReq2AllSMacs(cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK)
1310       {
1311          /* TODO: do we need to send DelInd to SCH in failure case*/ 
1312          return RFAILED;
1313       }
1314 #endif
1315 #ifdef L2_OPTMZ
1316       /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/
1317       delDatReq.cellId = cell->cellId;
1318       delDatReq.ueId = rlsRnti->rnti;
1319       rgLIMTfuDelDatReq(macInst, &delDatReq);
1320 #endif
1321    }
1322    else
1323    {
1324       rgUtlHndlCrntiRls(cell, rlsRnti);
1325    }
1326    /* Fix : syed Send delete confirmation to SCH */
1327    /* Send RgMacSchUeDelInd to SCH only if it is Rnti release to PMAC.
1328     * Basically dont send DelInd to SCH incase of Ue SCell Del*/
1329 #ifdef LTE_ADV
1330    if(FALSE == rlsRnti->isUeSCellDel)
1331 #endif
1332    {
1333       //TODO: commented for compilation without SCH 
1334 #if 0
1335       ueDelInd.cellSapId  = cell->schInstMap.cellSapId;
1336       ueDelInd.cellId  = rlsRnti->cellId;
1337       ueDelInd.rnti    = rlsRnti->rnti; 
1338       rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst);
1339       RgMacSchUeDel(&schPst, &ueDelInd);
1340 #endif
1341    }
1342
1343    return ROK;
1344 } /* end of RgSchMacRlsRntiReq */
1345
1346 #ifdef L2_OPTMZ
1347 Bool RgUtlIsTbMuxed(TfuDatReqTbInfo *tb)
1348 {
1349    MsgLen len = 0;
1350    SFndLenMsg(tb->macHdr, &len);
1351    return (len?TRUE : FALSE);
1352 }
1353 #endif
1354
1355 /**********************************************************************
1356  
1357          End of file
1358 **********************************************************************/