Moving all common header file into common_def.h file
[o-du/l2.git] / src / 5gnrmac / rg_l2m.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  L2 Measurements in MAC
26   
27      File:     rg_l2m.c
28   
29 **********************************************************************/
30
31 /** @file rg_l2m.c
32 @brief This file implements the schedulers main access to MAC layer code.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "lrg.h"
38 #include "crg.h"        
39 #include "rgr.h"
40 #include "rgu.h"           
41 #include "tfu.h"
42 #include "rg_env.h"
43 #include "rg_err.h"
44 #include "rg_sch_inf.h"
45 #include "rg.h"
46
47 /* header/extern include files (.x) */
48 #include "rgu.x"           /* RGU types */
49 #include "tfu.x"           /* TFU types */
50 #include "lrg.x"           /* layer management typedefs for MAC */
51 #include "rgr.x"           /* layer management typedefs for MAC */
52 #include "crg.x"           /* layer management typedefs for MAC */
53 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
54 #include "rg_prg.x"        /* typedefs for PRG interface */
55 #include "du_app_mac_inf.h"
56 #include "rg.x"            /* MAC types */
57
58 #ifdef LTE_L2_MEAS
59 static const char* RLOG_MODULE_NAME="MAC";
60 static int RLOG_FILE_ID=183;
61 static int RLOG_MODULE_ID=4096;
62 #endif 
63
64 /* local defines */
65 #ifdef LTE_L2_MEAS
66 PRIVATE S16 rgL2mInsertMeasCb ARGS((
67          RgCellCb       *cell,
68          RgL2MeasCb     *measCb,
69          RgInfL2MeasReq *measInfo ));
70
71 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb ARGS((
72          RgCellCb       *cell,
73          RgInfL2MeasReq *measInfo,
74          RgErrInfo      *err));
75
76 /* Function definitions */
77
78 /** @brief This function creates the measCb
79  *
80  * @details
81  *
82  *     Function: rgL2mCreateMeasCb
83  *         Processing steps:
84  *         - Check the measType
85  *         - Create measCb for every qci
86  *
87  * @param  [in] RgCellCb       *cell
88  * @param  [in] RgInfL2MeasReq *measInfo
89  * @param  [in] U8             measType
90  * @param  [out] RgErrInfo      *err
91  * @return  S16
92  *      -# ROK 
93  *      -# RFAILED 
94  *
95  */
96 #ifdef ANSI
97 PUBLIC S16 rgL2mCreateMeasCb 
98 (
99 RgCellCb       *cell,
100 RgInfL2MeasReq *measInfo, 
101 U8              measType,
102 RgErrInfo      *err
103 )
104 #else
105 PUBLIC S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
106 RgCellCb       *cell;
107 RgInfL2MeasReq *measInfo; 
108 U8              measType;
109 RgErrInfo      *err;
110 #endif    
111 {
112   // Inst    inst = cell->macInst - RG_INST_START;
113    U32     idx;
114    RgL2MeasCb       *measCb = NULLP;
115    U8            qciVal = 0;
116
117    UNUSED(measType);
118    UNUSED(err);
119
120    TRC3(rgL2mCreateMeasCb)
121
122       if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
123       {
124          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
125          RETVALUE(RFAILED);
126       }
127    //Memcpy is already done in rgL2mAllocMeasCb
128    /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\
129      sizeof(RgInfL2MeasReq));*/
130    rgL2mInsertMeasCb(cell, measCb, measInfo);
131    measCb->measReq.timePrd = measInfo->timePrd;
132
133    if(measInfo->timePrd == 0)
134    {
135       cell->sndL2Meas = FALSE;
136    }
137
138    for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
139    {
140       if(measInfo->timePrd == 0)
141       {
142          qciVal = measInfo->t.prbReq.qci[idx];
143          cell->qciArray[qciVal].qci = qciVal;
144       }
145       cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
146    }
147    RETVALUE(ROK);
148 } /* rgL2mCreateMeasCb */
149
150
151 /**
152  * @brief Layer Manager Measurement request handler. 
153  *
154  * @details
155  *
156  *     Function : rgL2mMeasReq
157  *     
158  *     This function handles  measurement request received at MAC
159  *     from the Scheduler.
160  *     -# Measurement request will be stored in the list in descending order of
161  *     there time period.
162  *     
163  *  @param[in]  Pst *pst, the post structure     
164  *  @param[in]  RgInfL2MeasReq *measInfo, the measurement request structure
165  *  @param[out] RgErrInfo   *err, error information
166  *  @return  S16
167  *      -# ROK
168  **/
169 #ifdef ANSI
170 PUBLIC S16 rgL2mMeasReq 
171 (
172 RgCellCb       *cell,
173 RgInfL2MeasReq *measInfo,
174 RgErrInfo      *err
175 )
176 #else
177 PUBLIC S16 rgL2mMeasReq(cell, measInfo, err)
178 RgCellCb       *cell;
179 RgInfL2MeasReq *measInfo; 
180 RgErrInfo      *err;
181 #endif    
182 {
183    S16  ret=RFAILED;
184
185    TRC3(rgL2mMeasReq)
186    /* Creaet MeasCb Insert in cell->l2mList and return*/
187    if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
188                LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
189    {
190       /* Clear Downlink MeasCb created Above If exists*/
191       RETVALUE(ret);
192    }
193    RETVALUE(ROK);
194 } /* rgL2mMeasReq */
195 /** @brief This function sends the measurement confirm
196  *  from mac to scheduler
197  *
198  * @details
199  *
200  *     Function: rgSndL2MeasCfm
201  *
202  * @param  [in] RgCellCb          *cell
203  * @param  [in] RgInfL2MeasCfm    *measCfm
204  */
205 #ifdef ANSI
206 PRIVATE Void rgSndL2MeasCfm
207 (
208 RgCellCb          *cell, 
209 RgInfL2MeasCfm    *measCfm
210 )
211 #else
212 PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
213 RgCellCb          *cell; 
214 RgInfL2MeasCfm    *measCfm;   
215 #endif
216 {
217    Pst             pst;
218    Inst            macInst = cell->macInst - RG_INST_START;
219    TRC3(rgSndL2MeasCfm)
220
221       cmMemset((U8 *)&pst, 0, sizeof(Pst));
222    rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
223    RgMacSchL2Meas(&pst, measCfm);
224
225    RETVOID;
226 }/* rgSndL2MeasCfm */
227
228 /** @brief This function sends the measurement stop confirm
229  *  from mac to scheduler
230  *
231  * @details
232  *
233  *     Function: rgSndL2MeasStopCfm
234  *
235  * @param  [in] RgCellCb          *cell
236  * @param  [in] RgInfL2MeasCfm    *measCfm
237  */
238 #ifdef ANSI
239 PRIVATE Void rgSndL2MeasStopCfm
240 (
241 RgCellCb          *cell,
242 RgInfL2MeasCfm    *measCfm
243 )
244 #else
245 PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
246 RgCellCb          *cell;
247 RgInfL2MeasCfm    *measCfm;
248 #endif
249 {
250    Pst             pst;
251    Inst            macInst = cell->macInst - RG_INST_START;
252
253    TRC3(rgSndL2MeasStopCfm)
254       cmMemset((U8 *)&pst, 0, sizeof(Pst));
255    rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
256    RgMacSchL2MeasStop(&pst, measCfm);
257
258    RETVOID;
259 }/* rgSndL2MeasStopCfm */
260
261 /**
262  * @brief  L2 Measurement request handler.This function shall be called by
263  *  scheduler to calculate average PRB usage Per Qci in Uplink
264  *
265  * @details
266  *
267  *     Function : RgSchMacL2MeasReq
268  *     
269  *  @param[in]  Pst *pst, the post structure     
270  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
271  *  @return  S16
272  *      -# ROK
273  *      -# RFAILED
274  **/
275 #ifdef ANSI
276 PUBLIC S16 RgSchMacL2MeasReq
277 (
278 Pst               *pst,          /* post structure  */
279 RgInfL2MeasReq    *measInfo      /* Meas Req Info */
280 )
281 #else
282 PUBLIC S16 RgSchMacL2MeasReq(pst, measInfo)
283 Pst               *pst;          /* post structure  */
284 RgInfL2MeasReq    *measInfo;      /* Meas Req Info */
285 #endif    
286 {
287    Inst            inst;
288    RgCellCb        *cellCb = NULLP;
289    RgErrInfo       err;
290    S16             ret = ROK;
291    RgInfL2MeasCfm   measCfm;
292
293    TRC3(RgSchMacL2MeasReq)
294
295
296    RG_IS_INST_VALID(pst->dstInst);
297    inst   = pst->dstInst - RG_INST_START;
298    cellCb = rgCb[inst].cell;
299    /* Get the  cell using cellId */
300    if ((cellCb == NULLP) ||
301        (cellCb->cellId != measInfo->cellId))
302    {
303       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
304       RETVALUE(RFAILED);
305    }
306    /* Call L2M Function to store Meas req */
307    ret = rgL2mMeasReq(cellCb, measInfo, &err);
308    if (ret != ROK)
309    {
310       cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
311       measCfm.transId     = measInfo->transId;
312       measCfm.cellId      = measInfo->cellId;
313       measCfm.measType    = measInfo->measType;
314       measCfm.cfm.reason   = LCM_REASON_INVALID_PAR_VAL;
315       measCfm.cfm.status  = LCM_PRIM_NOK;
316       rgSndL2MeasCfm(cellCb, &measCfm);
317       RLOG_ARG2(L_ERROR,DBG_CELLID,measInfo->cellId,
318                "Meas req Failed  errType(%d) errCause(%d)",
319                err.errType, err.errCause);
320       RETVALUE(RFAILED);
321    }
322    RETVALUE(ret);
323 } /* -- RgSchMacL2MeasReq-- */
324
325 /**
326  * @brief  L2 Measurement request handler.This function shall be called by
327  *         sch to to stop l2 measurement in MAC,
328  *
329  * @details
330  *
331  *     Function : RgSchMacL2MeasStopReq
332  *     
333  *  @param[in]  Pst *pst, the post structure     
334  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
335  *  @return  S16
336  *      -# ROK
337  *      -# RFAILED
338  **/
339 #ifdef ANSI
340 PUBLIC S16 RgSchMacL2MeasStopReq
341 (
342 Pst               *pst,          /* post structure  */
343 RgInfL2MeasStopReq *measInfo      /* Meas Req Info */
344 )
345 #else
346 PUBLIC S16 RgSchMacL2MeasStopReq(pst, measInfo)
347 Pst               *pst;          /* post structure  */
348 RgInfL2MeasStopReq *measInfo;      /* Meas Req Info */
349 #endif
350 {
351    S16             ret = ROK;   
352    CmLList         *node   = NULLP;
353    RgL2MeasCb      *measCb = NULLP;
354    U8               idx;
355    U8               qciVal;
356    Inst             inst;
357    RgCellCb        *cellCb = NULLP;
358
359    RgInfL2MeasCfm  measCfm;
360
361    TRC3(RgSchMacL2MeasStopReq)
362
363
364    RG_IS_INST_VALID(pst->dstInst);
365    inst   = pst->dstInst - RG_INST_START;
366    cellCb = rgCb[inst].cell;
367       /* Get the  cell using cellId */
368    if ((cellCb == NULLP) ||
369        (cellCb->cellId != measInfo->cellId))
370    {
371       
372       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
373             "Unable to get the cellCb");
374       RETVALUE(RFAILED);
375    }
376    node = cellCb->l2mList.first; 
377    while(node != NULLP)
378    {
379       measCb = (RgL2MeasCb *)(node)->node;
380       node = (node)->next;
381       /*L2 Meas off for qci in cell */
382       for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
383       {
384          qciVal = measCb->measReq.t.prbReq.qci[idx];
385          cellCb->qciArray[qciVal].mask = FALSE;
386       }
387       cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
388       rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
389    }
390    cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
391    measCfm.transId     = measInfo->transId;
392    measCfm.cellId      = measInfo->cellId;
393    measCfm.measType    = measInfo->measType;
394    measCfm.cfm.status  = LCM_PRIM_OK;
395    rgSndL2MeasStopCfm(cellCb, &measCfm);
396    RETVALUE(ret);
397 } /* -- RgSchMacL2MeasStopReq-- */
398
399 /**
400  * @brief  L2 Measurement request handler.This function shall be called by
401  *  scheduler for  sending L2 meas 
402  *
403  * @details
404  *
405  *     Function : RgSchMacL2MeasSendReq
406  *     
407  *  @param[in]  Pst *pst, the post structure     
408  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
409  *  @return  S16
410  *      -# ROK
411  *      -# RFAILED
412  **/
413 #ifdef ANSI
414 PUBLIC S16 RgSchMacL2MeasSendReq
415 (
416 Pst               *pst,          /* post structure  */
417 RgInfL2MeasSndReq *measInfo      /* Meas Req Info */
418 )
419 #else
420 PUBLIC S16 RgSchMacL2MeasSendReq(pst, measInfo)
421 Pst               *pst;          /* post structure  */
422 RgInfL2MeasSndReq *measInfo;      /* Meas Req Info */
423 #endif
424 {
425    Inst            inst;
426    RgCellCb       *cellCb = NULLP;
427    S16             ret    = ROK;
428
429    TRC3(RgSchMacL2MeasSendReq)
430
431
432    RG_IS_INST_VALID(pst->dstInst);
433    inst   = pst->dstInst - RG_INST_START;
434    cellCb = rgCb[inst].cell;
435       /* Get the  cell using cellId */
436    if ((cellCb == NULLP) ||
437        (cellCb->cellId != measInfo->cellId))
438    {
439       
440       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
441             "Unable to get the cellCb");
442       RETVALUE(RFAILED);
443    }
444    /*set sndL2Meas as applicatoin sent l2 meas info request*/
445    cellCb->sndL2Meas = TRUE;
446
447    RETVALUE(ret);
448 }/*RgSchMacL2MeasSendReq*/ 
449
450 /** @brief This function inserts the MeasCb in to data base
451  *
452  * @details
453  *
454  *     Function: rgL2mInsertMeasCb
455  *
456  * @param  [in] RgCellCb       *cell
457  * @param  [in] RgL2MeasCb     *measCb
458  * @param  [in] RgInfMeasReq   *measInfo
459  * @return  S16
460  *      -# ROK 
461  *      -# RFAILED 
462  */
463 #ifdef ANSI
464 PRIVATE S16 rgL2mInsertMeasCb
465 (
466 RgCellCb       *cell,
467 RgL2MeasCb     *measCb,
468 RgInfL2MeasReq *measInfo
469 )
470 #else
471 PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
472 RgCellCb       *cell;
473 RgL2MeasCb     *measCb;
474 RgInfL2MeasReq *measInfo;
475 #endif
476 {
477    CmLList   *lnk, *node;
478    RgL2MeasCb  *oldMeasCb;
479    U16         diffTime;
480
481    TRC3(rgL2mInsertMeasCb)
482
483       /* 
484        * 1. Check if l2mList has any entries.
485        * 2. If yes 
486        *       1. Take the first entrie's time period and find the diff with
487        *       cell->crntTime.
488        *       2. If the diff is > measInfo->timePeriod then insert before this
489        *       entry.
490        *       3. Else take the next entry in list
491        *       4. If reached without adding to list . Append at the end of list.
492        * 3. If no entries in l2mList add at the first.
493        */
494       lnk = cell->l2mList.first;
495
496    node = &measCb->measLnk;
497    node->node = (PTR)measCb;
498    while(lnk != NULLP )
499    {
500       oldMeasCb = (RgL2MeasCb *)lnk->node;
501       diffTime = (oldMeasCb->measReq.timePrd - 
502             (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
503       if (diffTime > measInfo->timePrd)
504       {
505          cell->l2mList.crnt = lnk;
506          cmLListInsCrnt(&(cell->l2mList), node);
507          RETVALUE(ROK);
508       }
509       else
510       {
511          lnk = lnk->next;
512       }
513    }  /* End of While */
514
515    cmLListAdd2Tail(&(cell->l2mList), node);
516    RETVALUE(ROK);
517 } /* rgL2mInsertMeasCb */
518
519 /** @brief This function allocates memory from the heap
520  *
521  * @details
522  *
523  *     Function: rgL2mAllocMeasCb
524  *
525  * @param  [in] RgCellCb       *cell
526  * @param  [in] RgInfL2MeasReq *measInfo
527  * @param  [out] RgErrInfo      *err
528  * @return  RgSchL2MeasCb *
529  */
530 #ifdef ANSI
531 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
532 (
533 RgCellCb       *cell,
534 RgInfL2MeasReq *measInfo,
535 RgErrInfo      *err
536 )
537 #else
538 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
539 RgCellCb       *cell;
540 RgInfL2MeasReq *measInfo;
541 RgErrInfo      *err;
542 #endif
543 {
544    RgL2MeasCb       *measCb = NULLP;
545    Inst             inst = cell->macInst - RG_INST_START;
546
547    TRC3(rgL2mAllocMeasCb)
548
549       if((rgAllocSBuf(inst,(Data **)&(measCb),
550                   sizeof(RgL2MeasCb))) == RFAILED)
551       {
552          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
553                    "Allocation of RgL2MeasCb failed");
554          err->errType  = RGERR_L2M_MEASREQ;
555          err->errCause = RGERR_RAM_MEM_EXHAUST;
556          RETVALUE(NULLP);
557       }
558    cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(RgInfL2MeasReq));
559    RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
560
561    RETVALUE(measCb);
562 } /* rgL2mAllocMeasCb */
563
564
565 /**
566  * @brief This function calculates the measurement for measType 
567  * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the 
568  * MAC Scheduler.
569  *
570  * @details
571  *
572  *  Function : rgL2Meas
573  *     
574  *  @param[in] RgCellCb  *cell
575  *  @return  S16
576  *      -# ROK
577  *      -# RFAILED
578  **/
579 #ifdef ANSI
580 PUBLIC S16 rgL2Meas
581 (
582 RgCellCb  *cell
583 )
584 #else
585 PUBLIC S16 rgL2Meas(cell)
586 RgCellCb  *cell;
587 #endif
588 {
589    CmLList         *node   = NULLP;
590    RgL2MeasCb      *measCb = NULLP;
591    RgInfL2MeasCfm  measCfm;
592    U8              idx = 0;
593    U8              qciVal = 0;
594    U32             measPrd; /*LTE_L2_MEAS_PHASE2*/
595    CmLteTimingInfo  crntTime;
596    Inst           inst = cell->macInst - RG_INST_START;
597    
598    TRC3(rgL2Meas)
599
600    node = cell->l2mList.first;
601
602    while(node != NULLP)
603    {
604       measCb = (RgL2MeasCb *)node->node;
605       node = node->next;
606       crntTime = cell->crntTime;
607
608       if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
609       {
610          measCb->sfnCycle++;
611       }
612
613       measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime, 
614                         measCb->sfnCycle, measCb->startTime);
615       
616       /*LTE_L2_MEAS_PHASE2*/
617       if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
618       {
619          cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
620          for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
621          {
622             qciVal = measCb->measReq.t.prbReq.qci[idx];
623             measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
624
625             measCfm.transId  = measCb->measReq.transId;
626             measCfm.measType = measCb->measReq.measType;
627             measCfm.cellId    = measCb->measReq.cellId;
628
629             measCfm.u.prbCfm.prbUsage[idx].prbUsage = 
630                cell->qciArray[qciVal].prbCount;
631
632             cell->qciArray[qciVal].prbCount = 0;
633             measCfm.u.prbCfm.numQci++;
634             if(measCb->measReq.timePrd > 0)
635             {
636                cell->qciArray[qciVal].mask = FALSE;
637             }
638          }
639          rgSndL2MeasCfm(cell, &measCfm);
640
641          if(measCb->measReq.timePrd > 0) 
642          {
643             cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
644             rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
645          }
646          else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
647          { 
648             measCb->startTime = crntTime;
649             measCb->measReq.timePrd = 0;
650             cell->sndL2Meas = FALSE;
651          }
652          continue;
653       } 
654    }
655    RETVALUE(ROK);
656 } /* rgL2MEas */
657
658 #endif /* LTE_L2_MEAS */
659 /**********************************************************************
660  
661          End of file
662 **********************************************************************/