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
100 RgInfL2MeasReq *measInfo,
105 S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
107 RgInfL2MeasReq *measInfo;
112 // Inst inst = cell->macInst - RG_INST_START;
114 RgL2MeasCb *measCb = NULLP;
120 if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
122 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
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;
131 if(measInfo->timePrd == 0)
133 cell->sndL2Meas = FALSE;
136 for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
138 if(measInfo->timePrd == 0)
140 qciVal = measInfo->t.prbReq.qci[idx];
141 cell->qciArray[qciVal].qci = qciVal;
143 cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
146 } /* rgL2mCreateMeasCb */
150 * @brief Layer Manager Measurement request handler.
154 * Function : rgL2mMeasReq
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
161 * @param[in] Pst *pst, the post structure
162 * @param[in] RgInfL2MeasReq *measInfo, the measurement request structure
163 * @param[out] RgErrInfo *err, error information
171 RgInfL2MeasReq *measInfo,
175 S16 rgL2mMeasReq(cell, measInfo, err)
177 RgInfL2MeasReq *measInfo;
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)
187 /* Clear Downlink MeasCb created Above If exists*/
192 /** @brief This function sends the measurement confirm
193 * from mac to scheduler
197 * Function: rgSndL2MeasCfm
199 * @param [in] RgCellCb *cell
200 * @param [in] RgInfL2MeasCfm *measCfm
203 PRIVATE Void rgSndL2MeasCfm
206 RgInfL2MeasCfm *measCfm
209 PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
211 RgInfL2MeasCfm *measCfm;
215 Inst macInst = cell->macInst - RG_INST_START;
217 memset(&pst, 0, sizeof(Pst));
218 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
219 RgMacSchL2Meas(&pst, measCfm);
222 }/* rgSndL2MeasCfm */
224 /** @brief This function sends the measurement stop confirm
225 * from mac to scheduler
229 * Function: rgSndL2MeasStopCfm
231 * @param [in] RgCellCb *cell
232 * @param [in] RgInfL2MeasCfm *measCfm
235 PRIVATE Void rgSndL2MeasStopCfm
238 RgInfL2MeasCfm *measCfm
241 PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
243 RgInfL2MeasCfm *measCfm;
247 Inst macInst = cell->macInst - RG_INST_START;
249 memset(&pst, 0, sizeof(Pst));
250 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
251 RgMacSchL2MeasStop(&pst, measCfm);
254 }/* rgSndL2MeasStopCfm */
257 * @brief L2 Measurement request handler.This function shall be called by
258 * scheduler to calculate average PRB usage Per Qci in Uplink
262 * Function : RgSchMacL2MeasReq
264 * @param[in] Pst *pst, the post structure
265 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
271 S16 RgSchMacL2MeasReq
273 Pst *pst, /* post structure */
274 RgInfL2MeasReq *measInfo /* Meas Req Info */
277 S16 RgSchMacL2MeasReq(pst, measInfo)
278 Pst *pst; /* post structure */
279 RgInfL2MeasReq *measInfo; /* Meas Req Info */
283 RgCellCb *cellCb = NULLP;
286 RgInfL2MeasCfm measCfm;
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))
295 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
298 /* Call L2M Function to store Meas req */
299 ret = rgL2mMeasReq(cellCb, measInfo, &err);
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);
315 } /* -- RgSchMacL2MeasReq-- */
318 * @brief L2 Measurement request handler.This function shall be called by
319 * sch to to stop l2 measurement in MAC,
323 * Function : RgSchMacL2MeasStopReq
325 * @param[in] Pst *pst, the post structure
326 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
332 S16 RgSchMacL2MeasStopReq
334 Pst *pst, /* post structure */
335 RgInfL2MeasStopReq *measInfo /* Meas Req Info */
338 S16 RgSchMacL2MeasStopReq(pst, measInfo)
339 Pst *pst; /* post structure */
340 RgInfL2MeasStopReq *measInfo; /* Meas Req Info */
344 CmLList *node = NULLP;
345 RgL2MeasCb *measCb = NULLP;
349 RgCellCb *cellCb = NULLP;
351 RgInfL2MeasCfm measCfm;
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))
361 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
362 "Unable to get the cellCb");
365 node = cellCb->l2mList.first;
368 measCb = (RgL2MeasCb *)(node)->node;
370 /*L2 Meas off for qci in cell */
371 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
373 qciVal = measCb->measReq.t.prbReq.qci[idx];
374 cellCb->qciArray[qciVal].mask = FALSE;
376 cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
377 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
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);
386 } /* -- RgSchMacL2MeasStopReq-- */
389 * @brief L2 Measurement request handler.This function shall be called by
390 * scheduler for sending L2 meas
394 * Function : RgSchMacL2MeasSendReq
396 * @param[in] Pst *pst, the post structure
397 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
403 S16 RgSchMacL2MeasSendReq
405 Pst *pst, /* post structure */
406 RgInfL2MeasSndReq *measInfo /* Meas Req Info */
409 S16 RgSchMacL2MeasSendReq(pst, measInfo)
410 Pst *pst; /* post structure */
411 RgInfL2MeasSndReq *measInfo; /* Meas Req Info */
415 RgCellCb *cellCb = NULLP;
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))
426 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
427 "Unable to get the cellCb");
430 /*set sndL2Meas as applicatoin sent l2 meas info request*/
431 cellCb->sndL2Meas = TRUE;
434 }/*RgSchMacL2MeasSendReq*/
436 /** @brief This function inserts the MeasCb in to data base
440 * Function: rgL2mInsertMeasCb
442 * @param [in] RgCellCb *cell
443 * @param [in] RgL2MeasCb *measCb
444 * @param [in] RgInfMeasReq *measInfo
450 PRIVATE S16 rgL2mInsertMeasCb
454 RgInfL2MeasReq *measInfo
457 PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
460 RgInfL2MeasReq *measInfo;
464 RgL2MeasCb *oldMeasCb;
468 * 1. Check if l2mList has any entries.
470 * 1. Take the first entrie's time period and find the diff with
472 * 2. If the diff is > measInfo->timePeriod then insert before this
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.
478 lnk = cell->l2mList.first;
480 node = &measCb->measLnk;
481 node->node = (PTR)measCb;
484 oldMeasCb = (RgL2MeasCb *)lnk->node;
485 diffTime = (oldMeasCb->measReq.timePrd -
486 (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
487 if (diffTime > measInfo->timePrd)
489 cell->l2mList.crnt = lnk;
490 cmLListInsCrnt(&(cell->l2mList), node);
499 cmLListAdd2Tail(&(cell->l2mList), node);
501 } /* rgL2mInsertMeasCb */
503 /** @brief This function allocates memory from the heap
507 * Function: rgL2mAllocMeasCb
509 * @param [in] RgCellCb *cell
510 * @param [in] RgInfL2MeasReq *measInfo
511 * @param [out] RgErrInfo *err
512 * @return RgSchL2MeasCb *
515 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
518 RgInfL2MeasReq *measInfo,
522 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
524 RgInfL2MeasReq *measInfo;
528 RgL2MeasCb *measCb = NULLP;
529 Inst inst = cell->macInst - RG_INST_START;
532 if((rgAllocSBuf(inst,(Data **)&(measCb),
533 sizeof(RgL2MeasCb))) == RFAILED)
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;
541 memcpy(&measCb->measReq, measInfo, sizeof(RgInfL2MeasReq));
542 RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
545 } /* rgL2mAllocMeasCb */
549 * @brief This function calculates the measurement for measType
550 * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the
555 * Function : rgL2Meas
557 * @param[in] RgCellCb *cell
572 CmLList *node = NULLP;
573 RgL2MeasCb *measCb = NULLP;
574 RgInfL2MeasCfm measCfm;
577 U32 measPrd; /*LTE_L2_MEAS_PHASE2*/
578 CmLteTimingInfo crntTime;
579 Inst inst = cell->macInst - RG_INST_START;
581 node = cell->l2mList.first;
585 measCb = (RgL2MeasCb *)node->node;
587 crntTime = cell->crntTime;
589 if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
594 measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime,
595 measCb->sfnCycle, measCb->startTime);
597 /*LTE_L2_MEAS_PHASE2*/
598 if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
600 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
601 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
603 qciVal = measCb->measReq.t.prbReq.qci[idx];
604 measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
606 measCfm.transId = measCb->measReq.transId;
607 measCfm.measType = measCb->measReq.measType;
608 measCfm.cellId = measCb->measReq.cellId;
610 measCfm.u.prbCfm.prbUsage[idx].prbUsage =
611 cell->qciArray[qciVal].prbCount;
613 cell->qciArray[qciVal].prbCount = 0;
614 measCfm.u.prbCfm.numQci++;
615 if(measCb->measReq.timePrd > 0)
617 cell->qciArray[qciVal].mask = FALSE;
620 rgSndL2MeasCfm(cell, &measCfm);
622 if(measCb->measReq.timePrd > 0)
624 cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
625 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
627 else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
629 measCb->startTime = crntTime;
630 measCb->measReq.timePrd = 0;
631 cell->sndL2Meas = FALSE;
639 #endif /* LTE_L2_MEAS */
640 /**********************************************************************
643 **********************************************************************/