1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for L2 Measurements in MAC
29 **********************************************************************/
32 @brief This file implements the schedulers main access to MAC layer code.
35 /* header include files -- defines (.h) */
36 #include "envopt.h" /* environment options */
37 #include "envdep.h" /* environment dependent */
38 #include "envind.h" /* environment independent */
39 #include "gen.h" /* general layer */
40 #include "ssi.h" /* system service interface */
41 #include "cm_hash.h" /* common hash list */
42 #include "cm_llist.h" /* common linked list library */
43 #include "cm_err.h" /* common error */
44 #include "cm_lte.h" /* common LTE */
52 #include "rg_sch_inf.h"
55 /* header/extern include files (.x) */
56 #include "gen.x" /* general layer typedefs */
57 #include "ssi.x" /* system services typedefs */
58 #include "cm5.x" /* common timers */
59 #include "cm_hash.x" /* common hash list */
60 #include "cm_lib.x" /* common library */
61 #include "cm_llist.x" /* common linked list */
62 #include "cm_mblk.x" /* memory management */
63 #include "cm_tkns.x" /* common tokens */
64 #include "cm_lte.x" /* common tokens */
65 #include "rgu.x" /* RGU types */
66 #include "tfu.x" /* TFU types */
67 #include "lrg.x" /* layer management typedefs for MAC */
68 #include "rgr.x" /* layer management typedefs for MAC */
69 #include "crg.x" /* layer management typedefs for MAC */
70 #include "rg_sch_inf.x" /* typedefs for Scheduler */
71 #include "rg_prg.x" /* typedefs for PRG interface */
72 #include "du_app_mac_inf.h"
73 #include "rg.x" /* MAC types */
76 static const char* RLOG_MODULE_NAME="MAC";
77 static int RLOG_FILE_ID=183;
78 static int RLOG_MODULE_ID=4096;
83 PRIVATE S16 rgL2mInsertMeasCb ARGS((
86 RgInfL2MeasReq *measInfo ));
88 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb ARGS((
90 RgInfL2MeasReq *measInfo,
93 /* Function definitions */
95 /** @brief This function creates the measCb
99 * Function: rgL2mCreateMeasCb
101 * - Check the measType
102 * - Create measCb for every qci
104 * @param [in] RgCellCb *cell
105 * @param [in] RgInfL2MeasReq *measInfo
106 * @param [in] U8 measType
107 * @param [out] RgErrInfo *err
114 PUBLIC S16 rgL2mCreateMeasCb
117 RgInfL2MeasReq *measInfo,
122 PUBLIC S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
124 RgInfL2MeasReq *measInfo;
129 // Inst inst = cell->macInst - RG_INST_START;
131 RgL2MeasCb *measCb = NULLP;
137 TRC3(rgL2mCreateMeasCb)
139 if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
141 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
144 //Memcpy is already done in rgL2mAllocMeasCb
145 /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\
146 sizeof(RgInfL2MeasReq));*/
147 rgL2mInsertMeasCb(cell, measCb, measInfo);
148 measCb->measReq.timePrd = measInfo->timePrd;
150 if(measInfo->timePrd == 0)
152 cell->sndL2Meas = FALSE;
155 for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
157 if(measInfo->timePrd == 0)
159 qciVal = measInfo->t.prbReq.qci[idx];
160 cell->qciArray[qciVal].qci = qciVal;
162 cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
165 } /* rgL2mCreateMeasCb */
169 * @brief Layer Manager Measurement request handler.
173 * Function : rgL2mMeasReq
175 * This function handles measurement request received at MAC
176 * from the Scheduler.
177 * -# Measurement request will be stored in the list in descending order of
180 * @param[in] Pst *pst, the post structure
181 * @param[in] RgInfL2MeasReq *measInfo, the measurement request structure
182 * @param[out] RgErrInfo *err, error information
187 PUBLIC S16 rgL2mMeasReq
190 RgInfL2MeasReq *measInfo,
194 PUBLIC S16 rgL2mMeasReq(cell, measInfo, err)
196 RgInfL2MeasReq *measInfo;
203 /* Creaet MeasCb Insert in cell->l2mList and return*/
204 if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
205 LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
207 /* Clear Downlink MeasCb created Above If exists*/
212 /** @brief This function sends the measurement confirm
213 * from mac to scheduler
217 * Function: rgSndL2MeasCfm
219 * @param [in] RgCellCb *cell
220 * @param [in] RgInfL2MeasCfm *measCfm
223 PRIVATE Void rgSndL2MeasCfm
226 RgInfL2MeasCfm *measCfm
229 PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
231 RgInfL2MeasCfm *measCfm;
235 Inst macInst = cell->macInst - RG_INST_START;
238 cmMemset((U8 *)&pst, 0, sizeof(Pst));
239 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
240 RgMacSchL2Meas(&pst, measCfm);
243 }/* rgSndL2MeasCfm */
245 /** @brief This function sends the measurement stop confirm
246 * from mac to scheduler
250 * Function: rgSndL2MeasStopCfm
252 * @param [in] RgCellCb *cell
253 * @param [in] RgInfL2MeasCfm *measCfm
256 PRIVATE Void rgSndL2MeasStopCfm
259 RgInfL2MeasCfm *measCfm
262 PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
264 RgInfL2MeasCfm *measCfm;
268 Inst macInst = cell->macInst - RG_INST_START;
270 TRC3(rgSndL2MeasStopCfm)
271 cmMemset((U8 *)&pst, 0, sizeof(Pst));
272 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
273 RgMacSchL2MeasStop(&pst, measCfm);
276 }/* rgSndL2MeasStopCfm */
279 * @brief L2 Measurement request handler.This function shall be called by
280 * scheduler to calculate average PRB usage Per Qci in Uplink
284 * Function : RgSchMacL2MeasReq
286 * @param[in] Pst *pst, the post structure
287 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
293 PUBLIC S16 RgSchMacL2MeasReq
295 Pst *pst, /* post structure */
296 RgInfL2MeasReq *measInfo /* Meas Req Info */
299 PUBLIC S16 RgSchMacL2MeasReq(pst, measInfo)
300 Pst *pst; /* post structure */
301 RgInfL2MeasReq *measInfo; /* Meas Req Info */
305 RgCellCb *cellCb = NULLP;
308 RgInfL2MeasCfm measCfm;
310 TRC3(RgSchMacL2MeasReq)
313 RG_IS_INST_VALID(pst->dstInst);
314 inst = pst->dstInst - RG_INST_START;
315 cellCb = rgCb[inst].cell;
316 /* Get the cell using cellId */
317 if ((cellCb == NULLP) ||
318 (cellCb->cellId != measInfo->cellId))
320 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
323 /* Call L2M Function to store Meas req */
324 ret = rgL2mMeasReq(cellCb, measInfo, &err);
327 cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
328 measCfm.transId = measInfo->transId;
329 measCfm.cellId = measInfo->cellId;
330 measCfm.measType = measInfo->measType;
331 measCfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL;
332 measCfm.cfm.status = LCM_PRIM_NOK;
333 rgSndL2MeasCfm(cellCb, &measCfm);
334 RLOG_ARG2(L_ERROR,DBG_CELLID,measInfo->cellId,
335 "Meas req Failed errType(%d) errCause(%d)",
336 err.errType, err.errCause);
340 } /* -- RgSchMacL2MeasReq-- */
343 * @brief L2 Measurement request handler.This function shall be called by
344 * sch to to stop l2 measurement in MAC,
348 * Function : RgSchMacL2MeasStopReq
350 * @param[in] Pst *pst, the post structure
351 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
357 PUBLIC S16 RgSchMacL2MeasStopReq
359 Pst *pst, /* post structure */
360 RgInfL2MeasStopReq *measInfo /* Meas Req Info */
363 PUBLIC S16 RgSchMacL2MeasStopReq(pst, measInfo)
364 Pst *pst; /* post structure */
365 RgInfL2MeasStopReq *measInfo; /* Meas Req Info */
369 CmLList *node = NULLP;
370 RgL2MeasCb *measCb = NULLP;
374 RgCellCb *cellCb = NULLP;
376 RgInfL2MeasCfm measCfm;
378 TRC3(RgSchMacL2MeasStopReq)
381 RG_IS_INST_VALID(pst->dstInst);
382 inst = pst->dstInst - RG_INST_START;
383 cellCb = rgCb[inst].cell;
384 /* Get the cell using cellId */
385 if ((cellCb == NULLP) ||
386 (cellCb->cellId != measInfo->cellId))
389 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
390 "Unable to get the cellCb");
393 node = cellCb->l2mList.first;
396 measCb = (RgL2MeasCb *)(node)->node;
398 /*L2 Meas off for qci in cell */
399 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
401 qciVal = measCb->measReq.t.prbReq.qci[idx];
402 cellCb->qciArray[qciVal].mask = FALSE;
404 cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
405 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
407 cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
408 measCfm.transId = measInfo->transId;
409 measCfm.cellId = measInfo->cellId;
410 measCfm.measType = measInfo->measType;
411 measCfm.cfm.status = LCM_PRIM_OK;
412 rgSndL2MeasStopCfm(cellCb, &measCfm);
414 } /* -- RgSchMacL2MeasStopReq-- */
417 * @brief L2 Measurement request handler.This function shall be called by
418 * scheduler for sending L2 meas
422 * Function : RgSchMacL2MeasSendReq
424 * @param[in] Pst *pst, the post structure
425 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
431 PUBLIC S16 RgSchMacL2MeasSendReq
433 Pst *pst, /* post structure */
434 RgInfL2MeasSndReq *measInfo /* Meas Req Info */
437 PUBLIC S16 RgSchMacL2MeasSendReq(pst, measInfo)
438 Pst *pst; /* post structure */
439 RgInfL2MeasSndReq *measInfo; /* Meas Req Info */
443 RgCellCb *cellCb = NULLP;
446 TRC3(RgSchMacL2MeasSendReq)
449 RG_IS_INST_VALID(pst->dstInst);
450 inst = pst->dstInst - RG_INST_START;
451 cellCb = rgCb[inst].cell;
452 /* Get the cell using cellId */
453 if ((cellCb == NULLP) ||
454 (cellCb->cellId != measInfo->cellId))
457 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
458 "Unable to get the cellCb");
461 /*set sndL2Meas as applicatoin sent l2 meas info request*/
462 cellCb->sndL2Meas = TRUE;
465 }/*RgSchMacL2MeasSendReq*/
467 /** @brief This function inserts the MeasCb in to data base
471 * Function: rgL2mInsertMeasCb
473 * @param [in] RgCellCb *cell
474 * @param [in] RgL2MeasCb *measCb
475 * @param [in] RgInfMeasReq *measInfo
481 PRIVATE S16 rgL2mInsertMeasCb
485 RgInfL2MeasReq *measInfo
488 PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
491 RgInfL2MeasReq *measInfo;
495 RgL2MeasCb *oldMeasCb;
498 TRC3(rgL2mInsertMeasCb)
501 * 1. Check if l2mList has any entries.
503 * 1. Take the first entrie's time period and find the diff with
505 * 2. If the diff is > measInfo->timePeriod then insert before this
507 * 3. Else take the next entry in list
508 * 4. If reached without adding to list . Append at the end of list.
509 * 3. If no entries in l2mList add at the first.
511 lnk = cell->l2mList.first;
513 node = &measCb->measLnk;
514 node->node = (PTR)measCb;
517 oldMeasCb = (RgL2MeasCb *)lnk->node;
518 diffTime = (oldMeasCb->measReq.timePrd -
519 (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
520 if (diffTime > measInfo->timePrd)
522 cell->l2mList.crnt = lnk;
523 cmLListInsCrnt(&(cell->l2mList), node);
532 cmLListAdd2Tail(&(cell->l2mList), node);
534 } /* rgL2mInsertMeasCb */
536 /** @brief This function allocates memory from the heap
540 * Function: rgL2mAllocMeasCb
542 * @param [in] RgCellCb *cell
543 * @param [in] RgInfL2MeasReq *measInfo
544 * @param [out] RgErrInfo *err
545 * @return RgSchL2MeasCb *
548 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
551 RgInfL2MeasReq *measInfo,
555 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
557 RgInfL2MeasReq *measInfo;
561 RgL2MeasCb *measCb = NULLP;
562 Inst inst = cell->macInst - RG_INST_START;
564 TRC3(rgL2mAllocMeasCb)
566 if((rgAllocSBuf(inst,(Data **)&(measCb),
567 sizeof(RgL2MeasCb))) == RFAILED)
569 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
570 "Allocation of RgL2MeasCb failed");
571 err->errType = RGERR_L2M_MEASREQ;
572 err->errCause = RGERR_RAM_MEM_EXHAUST;
575 cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(RgInfL2MeasReq));
576 RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
579 } /* rgL2mAllocMeasCb */
583 * @brief This function calculates the measurement for measType
584 * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the
589 * Function : rgL2Meas
591 * @param[in] RgCellCb *cell
602 PUBLIC S16 rgL2Meas(cell)
606 CmLList *node = NULLP;
607 RgL2MeasCb *measCb = NULLP;
608 RgInfL2MeasCfm measCfm;
611 U32 measPrd; /*LTE_L2_MEAS_PHASE2*/
612 CmLteTimingInfo crntTime;
613 Inst inst = cell->macInst - RG_INST_START;
617 node = cell->l2mList.first;
621 measCb = (RgL2MeasCb *)node->node;
623 crntTime = cell->crntTime;
625 if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
630 measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime,
631 measCb->sfnCycle, measCb->startTime);
633 /*LTE_L2_MEAS_PHASE2*/
634 if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
636 cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
637 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
639 qciVal = measCb->measReq.t.prbReq.qci[idx];
640 measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
642 measCfm.transId = measCb->measReq.transId;
643 measCfm.measType = measCb->measReq.measType;
644 measCfm.cellId = measCb->measReq.cellId;
646 measCfm.u.prbCfm.prbUsage[idx].prbUsage =
647 cell->qciArray[qciVal].prbCount;
649 cell->qciArray[qciVal].prbCount = 0;
650 measCfm.u.prbCfm.numQci++;
651 if(measCb->measReq.timePrd > 0)
653 cell->qciArray[qciVal].mask = FALSE;
656 rgSndL2MeasCfm(cell, &measCfm);
658 if(measCb->measReq.timePrd > 0)
660 cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
661 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
663 else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
665 measCb->startTime = crntTime;
666 measCb->measReq.timePrd = 0;
667 cell->sndL2Meas = FALSE;
675 #endif /* LTE_L2_MEAS */
676 /**********************************************************************
679 **********************************************************************/