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 static S16 rgL2mInsertMeasCb ARGS((
69 RgInfL2MeasReq *measInfo ));
71 static 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] uint8_t measType
90 * @param [out] RgErrInfo *err
99 RgInfL2MeasReq *measInfo,
104 // Inst inst = cell->macInst - RG_INST_START;
106 RgL2MeasCb *measCb = NULLP;
112 if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
114 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
117 //Memcpy is already done in rgL2mAllocMeasCb
118 /*memcpy(&measCb->measReq, (const uint8_t *)measInfo,\
119 sizeof(RgInfL2MeasReq));*/
120 rgL2mInsertMeasCb(cell, measCb, measInfo);
121 measCb->measReq.timePrd = measInfo->timePrd;
123 if(measInfo->timePrd == 0)
125 cell->sndL2Meas = FALSE;
128 for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
130 if(measInfo->timePrd == 0)
132 qciVal = measInfo->t.prbReq.qci[idx];
133 cell->qciArray[qciVal].qci = qciVal;
135 cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
138 } /* rgL2mCreateMeasCb */
142 * @brief Layer Manager Measurement request handler.
146 * Function : rgL2mMeasReq
148 * This function handles measurement request received at MAC
149 * from the Scheduler.
150 * -# Measurement request will be stored in the list in descending order of
153 * @param[in] Pst *pst, the post structure
154 * @param[in] RgInfL2MeasReq *measInfo, the measurement request structure
155 * @param[out] RgErrInfo *err, error information
162 RgInfL2MeasReq *measInfo,
168 /* Creaet MeasCb Insert in cell->l2mList and return*/
169 if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
170 LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
172 /* Clear Downlink MeasCb created Above If exists*/
177 /** @brief This function sends the measurement confirm
178 * from mac to scheduler
182 * Function: rgSndL2MeasCfm
184 * @param [in] RgCellCb *cell
185 * @param [in] RgInfL2MeasCfm *measCfm
187 static Void rgSndL2MeasCfm(RgCellCb *cell, RgInfL2MeasCfm *measCfm)
190 Inst macInst = cell->macInst - RG_INST_START;
192 memset(&pst, 0, sizeof(Pst));
193 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
194 RgMacSchL2Meas(&pst, measCfm);
197 }/* rgSndL2MeasCfm */
199 /** @brief This function sends the measurement stop confirm
200 * from mac to scheduler
204 * Function: rgSndL2MeasStopCfm
206 * @param [in] RgCellCb *cell
207 * @param [in] RgInfL2MeasCfm *measCfm
209 static Void rgSndL2MeasStopCfm(RgCellCb *cell,RgInfL2MeasCfm *measCfm)
212 Inst macInst = cell->macInst - RG_INST_START;
214 memset(&pst, 0, sizeof(Pst));
215 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
216 RgMacSchL2MeasStop(&pst, measCfm);
219 }/* rgSndL2MeasStopCfm */
222 * @brief L2 Measurement request handler.This function shall be called by
223 * scheduler to calculate average PRB usage Per Qci in Uplink
227 * Function : RgSchMacL2MeasReq
229 * @param[in] Pst *pst, the post structure
230 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
235 S16 RgSchMacL2MeasReq
237 Pst *pst, /* post structure */
238 RgInfL2MeasReq *measInfo /* Meas Req Info */
242 RgCellCb *cellCb = NULLP;
245 RgInfL2MeasCfm measCfm;
247 RG_IS_INST_VALID(pst->dstInst);
248 inst = pst->dstInst - RG_INST_START;
249 cellCb = rgCb[inst].cell;
250 /* Get the cell using cellId */
251 if ((cellCb == NULLP) ||
252 (cellCb->cellId != measInfo->cellId))
254 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
257 /* Call L2M Function to store Meas req */
258 ret = rgL2mMeasReq(cellCb, measInfo, &err);
261 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
262 measCfm.transId = measInfo->transId;
263 measCfm.cellId = measInfo->cellId;
264 measCfm.measType = measInfo->measType;
265 measCfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL;
266 measCfm.cfm.status = LCM_PRIM_NOK;
267 rgSndL2MeasCfm(cellCb, &measCfm);
268 RLOG_ARG2(L_ERROR,DBG_CELLID,measInfo->cellId,
269 "Meas req Failed errType(%d) errCause(%d)",
270 err.errType, err.errCause);
274 } /* -- RgSchMacL2MeasReq-- */
277 * @brief L2 Measurement request handler.This function shall be called by
278 * sch to to stop l2 measurement in MAC,
282 * Function : RgSchMacL2MeasStopReq
284 * @param[in] Pst *pst, the post structure
285 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
290 S16 RgSchMacL2MeasStopReq
292 Pst *pst, /* post structure */
293 RgInfL2MeasStopReq *measInfo /* Meas Req Info */
297 CmLList *node = NULLP;
298 RgL2MeasCb *measCb = NULLP;
302 RgCellCb *cellCb = NULLP;
303 RgInfL2MeasCfm measCfm;
305 RG_IS_INST_VALID(pst->dstInst);
306 inst = pst->dstInst - RG_INST_START;
307 cellCb = rgCb[inst].cell;
308 /* Get the cell using cellId */
309 if ((cellCb == NULLP) ||
310 (cellCb->cellId != measInfo->cellId))
313 RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
314 "Unable to get the cellCb");
317 node = cellCb->l2mList.first;
320 measCb = (RgL2MeasCb *)(node)->node;
322 /*L2 Meas off for qci in cell */
323 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
325 qciVal = measCb->measReq.t.prbReq.qci[idx];
326 cellCb->qciArray[qciVal].mask = FALSE;
328 cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
329 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
331 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
332 measCfm.transId = measInfo->transId;
333 measCfm.cellId = measInfo->cellId;
334 measCfm.measType = measInfo->measType;
335 measCfm.cfm.status = LCM_PRIM_OK;
336 rgSndL2MeasStopCfm(cellCb, &measCfm);
338 } /* -- RgSchMacL2MeasStopReq-- */
341 * @brief L2 Measurement request handler.This function shall be called by
342 * scheduler for sending L2 meas
346 * Function : RgSchMacL2MeasSendReq
348 * @param[in] Pst *pst, the post structure
349 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
354 S16 RgSchMacL2MeasSendReq
356 Pst *pst, /* post structure */
357 RgInfL2MeasSndReq *measInfo /* Meas Req Info */
361 RgCellCb *cellCb = NULLP;
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 /*set sndL2Meas as applicatoin sent l2 meas info request*/
377 cellCb->sndL2Meas = TRUE;
380 }/*RgSchMacL2MeasSendReq*/
382 /** @brief This function inserts the MeasCb in to data base
386 * Function: rgL2mInsertMeasCb
388 * @param [in] RgCellCb *cell
389 * @param [in] RgL2MeasCb *measCb
390 * @param [in] RgInfMeasReq *measInfo
395 static S16 rgL2mInsertMeasCb
399 RgInfL2MeasReq *measInfo
403 RgL2MeasCb *oldMeasCb;
407 * 1. Check if l2mList has any entries.
409 * 1. Take the first entrie's time period and find the diff with
411 * 2. If the diff is > measInfo->timePeriod then insert before this
413 * 3. Else take the next entry in list
414 * 4. If reached without adding to list . Append at the end of list.
415 * 3. If no entries in l2mList add at the first.
417 lnk = cell->l2mList.first;
419 node = &measCb->measLnk;
420 node->node = (PTR)measCb;
423 oldMeasCb = (RgL2MeasCb *)lnk->node;
424 diffTime = (oldMeasCb->measReq.timePrd -
425 (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
426 if (diffTime > measInfo->timePrd)
428 cell->l2mList.crnt = lnk;
429 cmLListInsCrnt(&(cell->l2mList), node);
438 cmLListAdd2Tail(&(cell->l2mList), node);
440 } /* rgL2mInsertMeasCb */
442 /** @brief This function allocates memory from the heap
446 * Function: rgL2mAllocMeasCb
448 * @param [in] RgCellCb *cell
449 * @param [in] RgInfL2MeasReq *measInfo
450 * @param [out] RgErrInfo *err
451 * @return RgSchL2MeasCb *
453 static RgL2MeasCb * rgL2mAllocMeasCb
456 RgInfL2MeasReq *measInfo,
460 RgL2MeasCb *measCb = NULLP;
461 Inst inst = cell->macInst - RG_INST_START;
464 if((rgAllocSBuf(inst,(Data **)&(measCb),
465 sizeof(RgL2MeasCb))) == RFAILED)
467 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
468 "Allocation of RgL2MeasCb failed");
469 err->errType = RGERR_L2M_MEASREQ;
470 err->errCause = RGERR_RAM_MEM_EXHAUST;
473 memcpy(&measCb->measReq, measInfo, sizeof(RgInfL2MeasReq));
474 RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
477 } /* rgL2mAllocMeasCb */
481 * @brief This function calculates the measurement for measType
482 * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the
487 * Function : rgL2Meas
489 * @param[in] RgCellCb *cell
494 S16 rgL2Meas(RgCellCb *cell)
496 CmLList *node = NULLP;
497 RgL2MeasCb *measCb = NULLP;
498 RgInfL2MeasCfm measCfm;
501 uint32_t measPrd; /*LTE_L2_MEAS_PHASE2*/
502 CmLteTimingInfo crntTime;
503 Inst inst = cell->macInst - RG_INST_START;
505 node = cell->l2mList.first;
509 measCb = (RgL2MeasCb *)node->node;
511 crntTime = cell->crntTime;
513 if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
518 measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime,
519 measCb->sfnCycle, measCb->startTime);
521 /*LTE_L2_MEAS_PHASE2*/
522 if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
524 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
525 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
527 qciVal = measCb->measReq.t.prbReq.qci[idx];
528 measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
530 measCfm.transId = measCb->measReq.transId;
531 measCfm.measType = measCb->measReq.measType;
532 measCfm.cellId = measCb->measReq.cellId;
534 measCfm.u.prbCfm.prbUsage[idx].prbUsage =
535 cell->qciArray[qciVal].prbCount;
537 cell->qciArray[qciVal].prbCount = 0;
538 measCfm.u.prbCfm.numQci++;
539 if(measCb->measReq.timePrd > 0)
541 cell->qciArray[qciVal].mask = FALSE;
544 rgSndL2MeasCfm(cell, &measCfm);
546 if(measCb->measReq.timePrd > 0)
548 cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
549 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
551 else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
553 measCb->startTime = crntTime;
554 measCb->measReq.timePrd = 0;
555 cell->sndL2Meas = FALSE;
563 #endif /* LTE_L2_MEAS */
564 /**********************************************************************
567 **********************************************************************/