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