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 */
61 static S16 rgL2mInsertMeasCb ARGS((
64 RgInfL2MeasReq *measInfo ));
66 static RgL2MeasCb * rgL2mAllocMeasCb ARGS((
68 RgInfL2MeasReq *measInfo,
71 /* Function definitions */
73 /** @brief This function creates the measCb
77 * Function: rgL2mCreateMeasCb
79 * - Check the measType
80 * - Create measCb for every qci
82 * @param [in] RgCellCb *cell
83 * @param [in] RgInfL2MeasReq *measInfo
84 * @param [in] uint8_t measType
85 * @param [out] RgErrInfo *err
94 RgInfL2MeasReq *measInfo,
99 // Inst inst = cell->macInst - RG_INST_START;
101 RgL2MeasCb *measCb = NULLP;
107 if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
109 DU_LOG("\nERROR --> MAC : Allocation of RgL2MeasCb failed");
112 //Memcpy is already done in rgL2mAllocMeasCb
113 /*memcpy(&measCb->measReq, (const uint8_t *)measInfo,\
114 sizeof(RgInfL2MeasReq));*/
115 rgL2mInsertMeasCb(cell, measCb, measInfo);
116 measCb->measReq.timePrd = measInfo->timePrd;
118 if(measInfo->timePrd == 0)
120 cell->sndL2Meas = FALSE;
123 for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
125 if(measInfo->timePrd == 0)
127 qciVal = measInfo->t.prbReq.qci[idx];
128 cell->qciArray[qciVal].qci = qciVal;
130 cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
133 } /* rgL2mCreateMeasCb */
137 * @brief Layer Manager Measurement request handler.
141 * Function : rgL2mMeasReq
143 * This function handles measurement request received at MAC
144 * from the Scheduler.
145 * -# Measurement request will be stored in the list in descending order of
148 * @param[in] Pst *pst, the post structure
149 * @param[in] RgInfL2MeasReq *measInfo, the measurement request structure
150 * @param[out] RgErrInfo *err, error information
157 RgInfL2MeasReq *measInfo,
163 /* Creaet MeasCb Insert in cell->l2mList and return*/
164 if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
165 LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
167 /* Clear Downlink MeasCb created Above If exists*/
172 /** @brief This function sends the measurement confirm
173 * from mac to scheduler
177 * Function: rgSndL2MeasCfm
179 * @param [in] RgCellCb *cell
180 * @param [in] RgInfL2MeasCfm *measCfm
182 static Void rgSndL2MeasCfm(RgCellCb *cell, RgInfL2MeasCfm *measCfm)
185 Inst macInst = cell->macInst - RG_INST_START;
187 memset(&pst, 0, sizeof(Pst));
188 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
189 RgMacSchL2Meas(&pst, measCfm);
192 }/* rgSndL2MeasCfm */
194 /** @brief This function sends the measurement stop confirm
195 * from mac to scheduler
199 * Function: rgSndL2MeasStopCfm
201 * @param [in] RgCellCb *cell
202 * @param [in] RgInfL2MeasCfm *measCfm
204 static Void rgSndL2MeasStopCfm(RgCellCb *cell,RgInfL2MeasCfm *measCfm)
207 Inst macInst = cell->macInst - RG_INST_START;
209 memset(&pst, 0, sizeof(Pst));
210 rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
211 RgMacSchL2MeasStop(&pst, measCfm);
214 }/* rgSndL2MeasStopCfm */
217 * @brief L2 Measurement request handler.This function shall be called by
218 * scheduler to calculate average PRB usage Per Qci in Uplink
222 * Function : RgSchMacL2MeasReq
224 * @param[in] Pst *pst, the post structure
225 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
230 S16 RgSchMacL2MeasReq
232 Pst *pst, /* post structure */
233 RgInfL2MeasReq *measInfo /* Meas Req Info */
237 RgCellCb *cellCb = NULLP;
240 RgInfL2MeasCfm measCfm;
242 RG_IS_INST_VALID(pst->dstInst);
243 inst = pst->dstInst - RG_INST_START;
244 cellCb = rgCb[inst].cell;
245 /* Get the cell using cellId */
246 if ((cellCb == NULLP) ||
247 (cellCb->cellId != measInfo->cellId))
249 DU_LOG("\nERROR --> MAC : unable to get the cellCb");
252 /* Call L2M Function to store Meas req */
253 ret = rgL2mMeasReq(cellCb, measInfo, &err);
256 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
257 measCfm.transId = measInfo->transId;
258 measCfm.cellId = measInfo->cellId;
259 measCfm.measType = measInfo->measType;
260 measCfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL;
261 measCfm.cfm.status = LCM_PRIM_NOK;
262 rgSndL2MeasCfm(cellCb, &measCfm);
263 DU_LOG("\nERROR --> MAC : Meas req Failed errType(%d) errCause(%d)",
264 err.errType, err.errCause);
268 } /* -- RgSchMacL2MeasReq-- */
271 * @brief L2 Measurement request handler.This function shall be called by
272 * sch to to stop l2 measurement in MAC,
276 * Function : RgSchMacL2MeasStopReq
278 * @param[in] Pst *pst, the post structure
279 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
284 S16 RgSchMacL2MeasStopReq
286 Pst *pst, /* post structure */
287 RgInfL2MeasStopReq *measInfo /* Meas Req Info */
291 CmLList *node = NULLP;
292 RgL2MeasCb *measCb = NULLP;
296 RgCellCb *cellCb = NULLP;
297 RgInfL2MeasCfm measCfm;
299 RG_IS_INST_VALID(pst->dstInst);
300 inst = pst->dstInst - RG_INST_START;
301 cellCb = rgCb[inst].cell;
302 /* Get the cell using cellId */
303 if ((cellCb == NULLP) ||
304 (cellCb->cellId != measInfo->cellId))
307 DU_LOG("\nERROR --> MAC : Unable to get the cellCb");
310 node = cellCb->l2mList.first;
313 measCb = (RgL2MeasCb *)(node)->node;
315 /*L2 Meas off for qci in cell */
316 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
318 qciVal = measCb->measReq.t.prbReq.qci[idx];
319 cellCb->qciArray[qciVal].mask = FALSE;
321 cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
322 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
324 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
325 measCfm.transId = measInfo->transId;
326 measCfm.cellId = measInfo->cellId;
327 measCfm.measType = measInfo->measType;
328 measCfm.cfm.status = LCM_PRIM_OK;
329 rgSndL2MeasStopCfm(cellCb, &measCfm);
331 } /* -- RgSchMacL2MeasStopReq-- */
334 * @brief L2 Measurement request handler.This function shall be called by
335 * scheduler for sending L2 meas
339 * Function : RgSchMacL2MeasSendReq
341 * @param[in] Pst *pst, the post structure
342 * @param[in] RgInfL2MeasReq *measInfo, L2 Measurement req structure
347 S16 RgSchMacL2MeasSendReq
349 Pst *pst, /* post structure */
350 RgInfL2MeasSndReq *measInfo /* Meas Req Info */
354 RgCellCb *cellCb = NULLP;
357 RG_IS_INST_VALID(pst->dstInst);
358 inst = pst->dstInst - RG_INST_START;
359 cellCb = rgCb[inst].cell;
360 /* Get the cell using cellId */
361 if ((cellCb == NULLP) ||
362 (cellCb->cellId != measInfo->cellId))
365 DU_LOG("\nERROR --> MAC : Unable to get the cellCb");
368 /*set sndL2Meas as applicatoin sent l2 meas info request*/
369 cellCb->sndL2Meas = TRUE;
372 }/*RgSchMacL2MeasSendReq*/
374 /** @brief This function inserts the MeasCb in to data base
378 * Function: rgL2mInsertMeasCb
380 * @param [in] RgCellCb *cell
381 * @param [in] RgL2MeasCb *measCb
382 * @param [in] RgInfMeasReq *measInfo
387 static S16 rgL2mInsertMeasCb
391 RgInfL2MeasReq *measInfo
395 RgL2MeasCb *oldMeasCb;
399 * 1. Check if l2mList has any entries.
401 * 1. Take the first entrie's time period and find the diff with
403 * 2. If the diff is > measInfo->timePeriod then insert before this
405 * 3. Else take the next entry in list
406 * 4. If reached without adding to list . Append at the end of list.
407 * 3. If no entries in l2mList add at the first.
409 lnk = cell->l2mList.first;
411 node = &measCb->measLnk;
412 node->node = (PTR)measCb;
415 oldMeasCb = (RgL2MeasCb *)lnk->node;
416 diffTime = (oldMeasCb->measReq.timePrd -
417 (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
418 if (diffTime > measInfo->timePrd)
420 cell->l2mList.crnt = lnk;
421 cmLListInsCrnt(&(cell->l2mList), node);
430 cmLListAdd2Tail(&(cell->l2mList), node);
432 } /* rgL2mInsertMeasCb */
434 /** @brief This function allocates memory from the heap
438 * Function: rgL2mAllocMeasCb
440 * @param [in] RgCellCb *cell
441 * @param [in] RgInfL2MeasReq *measInfo
442 * @param [out] RgErrInfo *err
443 * @return RgSchL2MeasCb *
445 static RgL2MeasCb * rgL2mAllocMeasCb
448 RgInfL2MeasReq *measInfo,
452 RgL2MeasCb *measCb = NULLP;
453 Inst inst = cell->macInst - RG_INST_START;
456 if((rgAllocSBuf(inst,(Data **)&(measCb),
457 sizeof(RgL2MeasCb))) == RFAILED)
459 DU_LOG("\nERROR --> MAC : Allocation of RgL2MeasCb failed");
460 err->errType = RGERR_L2M_MEASREQ;
461 err->errCause = RGERR_RAM_MEM_EXHAUST;
464 memcpy(&measCb->measReq, measInfo, sizeof(RgInfL2MeasReq));
465 RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
468 } /* rgL2mAllocMeasCb */
472 * @brief This function calculates the measurement for measType
473 * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the
478 * Function : rgL2Meas
480 * @param[in] RgCellCb *cell
485 S16 rgL2Meas(RgCellCb *cell)
487 CmLList *node = NULLP;
488 RgL2MeasCb *measCb = NULLP;
489 RgInfL2MeasCfm measCfm;
492 uint32_t measPrd; /*LTE_L2_MEAS_PHASE2*/
493 CmLteTimingInfo crntTime;
494 Inst inst = cell->macInst - RG_INST_START;
496 node = cell->l2mList.first;
500 measCb = (RgL2MeasCb *)node->node;
502 crntTime = cell->crntTime;
504 if(cell->crntTime.sfn == 0 && (cell->crntTime.slot % RG_NUM_SUB_FRAMES) == 0)
509 measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime,
510 measCb->sfnCycle, measCb->startTime);
512 /*LTE_L2_MEAS_PHASE2*/
513 if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
515 memset(&measCfm, 0, sizeof(RgInfL2MeasCfm));
516 for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
518 qciVal = measCb->measReq.t.prbReq.qci[idx];
519 measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
521 measCfm.transId = measCb->measReq.transId;
522 measCfm.measType = measCb->measReq.measType;
523 measCfm.cellId = measCb->measReq.cellId;
525 measCfm.u.prbCfm.prbUsage[idx].prbUsage =
526 cell->qciArray[qciVal].prbCount;
528 cell->qciArray[qciVal].prbCount = 0;
529 measCfm.u.prbCfm.numQci++;
530 if(measCb->measReq.timePrd > 0)
532 cell->qciArray[qciVal].mask = FALSE;
535 rgSndL2MeasCfm(cell, &measCfm);
537 if(measCb->measReq.timePrd > 0)
539 cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
540 rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
542 else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
544 measCb->startTime = crntTime;
545 measCb->measReq.timePrd = 0;
546 cell->sndL2Meas = FALSE;
554 #endif /* LTE_L2_MEAS */
555 /**********************************************************************
558 **********************************************************************/