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 "common_def.h"
44 #include "rg_sch_inf.h"
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 */
59 static const char* RLOG_MODULE_NAME="MAC";
60 static int RLOG_FILE_ID=183;
61 static int RLOG_MODULE_ID=4096;
66 PRIVATE S16 rgL2mInsertMeasCb ARGS((
69 RgInfL2MeasReq *measInfo ));
71 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb ARGS((
73 RgInfL2MeasReq *measInfo,
76 /* Function definitions */
78 /** @brief This function creates the measCb
82 * Function: rgL2mCreateMeasCb
84 * - Check the measType
85 * - Create measCb for every qci
87 * @param [in] RgCellCb *cell
88 * @param [in] RgInfL2MeasReq *measInfo
89 * @param [in] U8 measType
90 * @param [out] RgErrInfo *err
97 PUBLIC S16 rgL2mCreateMeasCb
100 RgInfL2MeasReq *measInfo,
105 PUBLIC S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
107 RgInfL2MeasReq *measInfo;
112 // Inst inst = cell->macInst - RG_INST_START;
114 RgL2MeasCb *measCb = NULLP;
120 TRC3(rgL2mCreateMeasCb)
122 if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
124 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
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;
133 if(measInfo->timePrd == 0)
135 cell->sndL2Meas = FALSE;
138 for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
140 if(measInfo->timePrd == 0)
142 qciVal = measInfo->t.prbReq.qci[idx];
143 cell->qciArray[qciVal].qci = qciVal;
145 cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
148 } /* rgL2mCreateMeasCb */
152 * @brief Layer Manager Measurement request handler.
156 * Function : rgL2mMeasReq
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
163 * @param[in] Pst *pst, the post structure
164 * @param[in] RgInfL2MeasReq *measInfo, the measurement request structure
165 * @param[out] RgErrInfo *err, error information
170 PUBLIC S16 rgL2mMeasReq
173 RgInfL2MeasReq *measInfo,
177 PUBLIC S16 rgL2mMeasReq(cell, measInfo, err)
179 RgInfL2MeasReq *measInfo;
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)
190 /* Clear Downlink MeasCb created Above If exists*/
195 /** @brief This function sends the measurement confirm
196 * from mac to scheduler
200 * Function: rgSndL2MeasCfm
202 * @param [in] RgCellCb *cell
203 * @param [in] RgInfL2MeasCfm *measCfm
206 PRIVATE Void rgSndL2MeasCfm
209 RgInfL2MeasCfm *measCfm
212 PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
214 RgInfL2MeasCfm *measCfm;
218 Inst macInst = cell->macInst - RG_INST_START;
221 cmMemset((U8 *)&pst, 0, sizeof(Pst));
222 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
223 RgMacSchL2Meas(&pst, measCfm);
226 }/* rgSndL2MeasCfm */
228 /** @brief This function sends the measurement stop confirm
229 * from mac to scheduler
233 * Function: rgSndL2MeasStopCfm
235 * @param [in] RgCellCb *cell
236 * @param [in] RgInfL2MeasCfm *measCfm
239 PRIVATE Void rgSndL2MeasStopCfm
242 RgInfL2MeasCfm *measCfm
245 PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
247 RgInfL2MeasCfm *measCfm;
251 Inst macInst = cell->macInst - RG_INST_START;
253 TRC3(rgSndL2MeasStopCfm)
254 cmMemset((U8 *)&pst, 0, sizeof(Pst));
255 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
256 RgMacSchL2MeasStop(&pst, measCfm);
259 }/* rgSndL2MeasStopCfm */
262 * @brief L2 Measurement request handler.This function shall be called by
263 * scheduler to calculate average PRB usage Per Qci in Uplink
267 * Function : RgSchMacL2MeasReq
269 * @param[in] Pst *pst, the post structure
270 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
276 PUBLIC S16 RgSchMacL2MeasReq
278 Pst *pst, /* post structure */
279 RgInfL2MeasReq *measInfo /* Meas Req Info */
282 PUBLIC S16 RgSchMacL2MeasReq(pst, measInfo)
283 Pst *pst; /* post structure */
284 RgInfL2MeasReq *measInfo; /* Meas Req Info */
288 RgCellCb *cellCb = NULLP;
291 RgInfL2MeasCfm measCfm;
293 TRC3(RgSchMacL2MeasReq)
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))
303 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
306 /* Call L2M Function to store Meas req */
307 ret = rgL2mMeasReq(cellCb, measInfo, &err);
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);
323 } /* -- RgSchMacL2MeasReq-- */
326 * @brief L2 Measurement request handler.This function shall be called by
327 * sch to to stop l2 measurement in MAC,
331 * Function : RgSchMacL2MeasStopReq
333 * @param[in] Pst *pst, the post structure
334 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
340 PUBLIC S16 RgSchMacL2MeasStopReq
342 Pst *pst, /* post structure */
343 RgInfL2MeasStopReq *measInfo /* Meas Req Info */
346 PUBLIC S16 RgSchMacL2MeasStopReq(pst, measInfo)
347 Pst *pst; /* post structure */
348 RgInfL2MeasStopReq *measInfo; /* Meas Req Info */
352 CmLList *node = NULLP;
353 RgL2MeasCb *measCb = NULLP;
357 RgCellCb *cellCb = NULLP;
359 RgInfL2MeasCfm measCfm;
361 TRC3(RgSchMacL2MeasStopReq)
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))
372 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
373 "Unable to get the cellCb");
376 node = cellCb->l2mList.first;
379 measCb = (RgL2MeasCb *)(node)->node;
381 /*L2 Meas off for qci in cell */
382 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
384 qciVal = measCb->measReq.t.prbReq.qci[idx];
385 cellCb->qciArray[qciVal].mask = FALSE;
387 cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
388 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
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);
397 } /* -- RgSchMacL2MeasStopReq-- */
400 * @brief L2 Measurement request handler.This function shall be called by
401 * scheduler for sending L2 meas
405 * Function : RgSchMacL2MeasSendReq
407 * @param[in] Pst *pst, the post structure
408 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
414 PUBLIC S16 RgSchMacL2MeasSendReq
416 Pst *pst, /* post structure */
417 RgInfL2MeasSndReq *measInfo /* Meas Req Info */
420 PUBLIC S16 RgSchMacL2MeasSendReq(pst, measInfo)
421 Pst *pst; /* post structure */
422 RgInfL2MeasSndReq *measInfo; /* Meas Req Info */
426 RgCellCb *cellCb = NULLP;
429 TRC3(RgSchMacL2MeasSendReq)
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))
440 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
441 "Unable to get the cellCb");
444 /*set sndL2Meas as applicatoin sent l2 meas info request*/
445 cellCb->sndL2Meas = TRUE;
448 }/*RgSchMacL2MeasSendReq*/
450 /** @brief This function inserts the MeasCb in to data base
454 * Function: rgL2mInsertMeasCb
456 * @param [in] RgCellCb *cell
457 * @param [in] RgL2MeasCb *measCb
458 * @param [in] RgInfMeasReq *measInfo
464 PRIVATE S16 rgL2mInsertMeasCb
468 RgInfL2MeasReq *measInfo
471 PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
474 RgInfL2MeasReq *measInfo;
478 RgL2MeasCb *oldMeasCb;
481 TRC3(rgL2mInsertMeasCb)
484 * 1. Check if l2mList has any entries.
486 * 1. Take the first entrie's time period and find the diff with
488 * 2. If the diff is > measInfo->timePeriod then insert before this
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.
494 lnk = cell->l2mList.first;
496 node = &measCb->measLnk;
497 node->node = (PTR)measCb;
500 oldMeasCb = (RgL2MeasCb *)lnk->node;
501 diffTime = (oldMeasCb->measReq.timePrd -
502 (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
503 if (diffTime > measInfo->timePrd)
505 cell->l2mList.crnt = lnk;
506 cmLListInsCrnt(&(cell->l2mList), node);
515 cmLListAdd2Tail(&(cell->l2mList), node);
517 } /* rgL2mInsertMeasCb */
519 /** @brief This function allocates memory from the heap
523 * Function: rgL2mAllocMeasCb
525 * @param [in] RgCellCb *cell
526 * @param [in] RgInfL2MeasReq *measInfo
527 * @param [out] RgErrInfo *err
528 * @return RgSchL2MeasCb *
531 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
534 RgInfL2MeasReq *measInfo,
538 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
540 RgInfL2MeasReq *measInfo;
544 RgL2MeasCb *measCb = NULLP;
545 Inst inst = cell->macInst - RG_INST_START;
547 TRC3(rgL2mAllocMeasCb)
549 if((rgAllocSBuf(inst,(Data **)&(measCb),
550 sizeof(RgL2MeasCb))) == RFAILED)
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;
558 cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(RgInfL2MeasReq));
559 RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
562 } /* rgL2mAllocMeasCb */
566 * @brief This function calculates the measurement for measType
567 * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the
572 * Function : rgL2Meas
574 * @param[in] RgCellCb *cell
585 PUBLIC S16 rgL2Meas(cell)
589 CmLList *node = NULLP;
590 RgL2MeasCb *measCb = NULLP;
591 RgInfL2MeasCfm measCfm;
594 U32 measPrd; /*LTE_L2_MEAS_PHASE2*/
595 CmLteTimingInfo crntTime;
596 Inst inst = cell->macInst - RG_INST_START;
600 node = cell->l2mList.first;
604 measCb = (RgL2MeasCb *)node->node;
606 crntTime = cell->crntTime;
608 if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
613 measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime,
614 measCb->sfnCycle, measCb->startTime);
616 /*LTE_L2_MEAS_PHASE2*/
617 if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
619 cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
620 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
622 qciVal = measCb->measReq.t.prbReq.qci[idx];
623 measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
625 measCfm.transId = measCb->measReq.transId;
626 measCfm.measType = measCb->measReq.measType;
627 measCfm.cellId = measCb->measReq.cellId;
629 measCfm.u.prbCfm.prbUsage[idx].prbUsage =
630 cell->qciArray[qciVal].prbCount;
632 cell->qciArray[qciVal].prbCount = 0;
633 measCfm.u.prbCfm.numQci++;
634 if(measCb->measReq.timePrd > 0)
636 cell->qciArray[qciVal].mask = FALSE;
639 rgSndL2MeasCfm(cell, &measCfm);
641 if(measCb->measReq.timePrd > 0)
643 cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
644 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
646 else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
648 measCb->startTime = crntTime;
649 measCb->measReq.timePrd = 0;
650 cell->sndL2Meas = FALSE;
658 #endif /* LTE_L2_MEAS */
659 /**********************************************************************
662 **********************************************************************/