Merge "replaced cmMemSet, cmMemcpy with memset and memcpy resp AND Removed TRC()...
[o-du/l2.git] / src / 5gnrsch / rg_sch_l2m.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /************************************************************************
20  
21      Name:     LTE-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for L2 Measurement fucntions
26   
27      File:     rg_sch_l2m.c
28   
29 **********************************************************************/
30
31 /** @file rg_sch_l2m.c
32 @brief This file implements the L2 Measurement feature code.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "lrg.h"
38 #include "rgr.h"
39 #include "rgm.h"
40 #include "tfu.h"
41 #include "rg_env.h"
42 #include "rg_sch.h"
43 #include "rg_sch_cmn.h"
44 #include "rg_sch_inf.h"         /* typedefs for Scheduler */
45 #include "rg_sch_err.h"
46 #include "rl_interface.h"
47 #include "rl_common.h"
48
49 /* header/extern include files (.x) */
50 #include "tfu.x"           /* TFU types */
51 #include "lrg.x"           /* layer management typedefs for MAC */
52 #include "rgr.x"           /* layer management typedefs for MAC */
53 #include "rgm.x"           /* layer management typedefs for MAC */
54 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
55 #include "rg_sch.x"        /* typedefs for Scheduler */
56 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
57 /* local defines */
58 U32 dlPrbCnt;
59 #ifdef LTE_L2_MEAS
60
61 static const char* RLOG_MODULE_NAME="MAC";
62 static int RLOG_MODULE_ID=4096;
63 static int RLOG_FILE_ID=166;
64
65 PRIVATE S16 rgSchL2mInsertMeasCb ARGS((
66          RgSchCellCb       *cell,
67          RgSchL2MeasCb     *measCb,
68          LrgSchMeasReqInfo *measInfo ));
69
70 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb ARGS((
71          RgSchCellCb       *cell,
72          LrgSchMeasReqInfo *measInfo,
73          RgSchErrInfo      err));
74
75 /* Function definitions */
76
77 /** @brief This function fills the L2 measurement confirm structure
78  *
79  * @details
80  *
81  *     Function: rgSchFillL2MeasCfm
82  *
83  * @param  [in] RgSchCellCb *cell 
84  * @param  [in] RgSchL2MeasCb *measCb
85  * @param  [out] LrgSchMeasCfmInfo *measCfm
86  * @param  [in] measTime
87  * @return  Void
88  */
89 #ifdef ANSI
90 S16 rgSchFillL2MeasCfm
91 (
92 RgSchCellCb       *cell,
93 RgSchL2MeasCb     *measCb,
94 LrgSchMeasCfmInfo *cfm,
95 U32               measTime   
96 )
97 #else
98 S16 rgSchFillL2MeasCfm(cell, measCb, cfm, measTime)
99 RgSchCellCb       *cell;
100 RgSchL2MeasCb     *measCb;
101 LrgSchMeasCfmInfo *cfm;
102 U32               measTime;
103 #endif
104 {
105    U8                 idx;
106    LrgSchMeasReqInfo  *measInfo;
107    U8                 qciVal = 0;
108    U32                 sampOc = 0;
109
110    measInfo = &measCb->measReq;   
111
112    cfm->hdr.transId  = measInfo->hdr.transId;
113    cfm->measType     = measInfo->measType;
114    cfm->cellId       = measInfo->cellId;
115    cfm->cfm.status   = LCM_PRIM_OK;
116    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL) &&
117                                     (measCb->dlTotalBw))
118    {
119        cfm->avgPrbDl.prbPerc = ((cell->avgPrbDl.prbCount * 100) /
120                                  measCb->dlTotalBw);
121        /* Resetting the prbCount to 0,  fix for ccpu00125002 */
122        cell->avgPrbDl.prbCount = 0;
123    }
124    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL) &&
125                                     (measCb->ulTotalBw))
126    {
127        cfm->avgPrbUl.prbPerc = ((cell->avgPrbUl.prbCount * 100) /
128                                  measCb->ulTotalBw);
129        /* Resetting the prbCount to 0,  fix for ccpu00125002 */
130        cell->avgPrbUl.prbCount = 0;
131    }
132    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
133                                     (measCb->dlTotalBw))
134    {
135        cfm->avgPrbQciDlCfm.numQci = measCb->measReq.avgPrbQciDl.numQci;
136        for(idx = 0; idx < measCb->measReq.avgPrbQciDl.numQci; idx++)
137        {
138           qciVal = measCb->measReq.avgPrbQciDl.qci[idx];
139           cfm->avgPrbQciDlCfm.prbPercQci[idx].prbPercQci = 
140           ((cell->qciArray[qciVal].dlPrbCount * 100) /
141             measCb->dlTotalBw);
142             cfm->avgPrbQciDlCfm.prbPercQci[idx].qciValue = qciVal;
143           cell->qciArray[qciVal].dlPrbCount = 0;
144        }
145    }
146    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) && 
147                                     (measCb->ulTotalBw))
148    {
149        cfm->avgPrbQciUlCfm.numQci = measCb->measReq.avgPrbQciUl.numQci;
150        for(idx = 0; idx < measCb->measReq.avgPrbQciUl.numQci; idx++)
151        {
152           cfm->avgPrbQciUlCfm.prbPercQci[idx].qciValue = 
153                                  measCb->avgPrbQciUl.prbUsage[idx].qciValue;
154
155           if(measCb->avgPrbQciUl.prbUsage[idx].prbUsage > measCb->ulTotalBw)
156           {
157              measCb->avgPrbQciUl.prbUsage[idx].prbUsage = measCb->ulTotalBw;
158           }   
159
160           cfm->avgPrbQciUlCfm.prbPercQci[idx].prbPercQci = 
161              ((measCb->avgPrbQciUl.prbUsage[idx].prbUsage * 100) /
162                measCb->ulTotalBw);
163        }
164    }
165    if(measCb->measReq.measType & LRG_L2MEAS_RA_PREAMBLE)
166    {
167        cfm->raPrmbsCfm.dedPreambles        = cell->raPrmbs.dedPream;
168        cfm->raPrmbsCfm.randSelPreLowRange  = cell->raPrmbs.preamGrpA;
169        cfm->raPrmbsCfm.randSelPreHighRange = cell->raPrmbs.preamGrpB;
170        cell->raPrmbs.dedPream              = 0;
171        cell->raPrmbs.preamGrpA             = 0;
172        cell->raPrmbs.preamGrpB             = 0;
173    }
174    if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
175    {
176        cfm->numUeQciDlCfm.numQci = measInfo->nmbActvUeQciDl.numQci;
177        sampOc = (measTime / measInfo->nmbActvUeQciDl.sampPrd);
178        
179        if(sampOc)
180        {   
181           if (measCb->measReq.nmbActvUeQciDl.numQci)
182           {
183              for(idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; idx++)
184              {
185                 qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx];
186                 /* L2_COUNTERS */
187                 cell->qciArray[qciVal].dlTotal_UeCount +=
188                    cell->qciArray[qciVal].dlUeCount;
189                 cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci =
190                    cell->qciArray[qciVal].dlTotal_UeCount / sampOc;
191                 cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal;
192                 
193                 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
194                       "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ",
195                       qciVal,cell->qciArray[qciVal].dlTotal_UeCount,
196                       cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci);
197                 
198                 cell->qciArray[qciVal].dlTotal_UeCount = 0;
199              }
200           }
201           else
202           {
203              idx = 0;
204              for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
205              {
206                 /* L2_COUNTERS */
207                 cell->qciArray[qciVal].dlTotal_UeCount +=
208                    cell->qciArray[qciVal].dlUeCount;
209                 if (cell->qciArray[qciVal].dlTotal_UeCount)
210                 {
211                    cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci =
212                       cell->qciArray[qciVal].dlTotal_UeCount / sampOc;
213                    cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal;
214
215                    RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
216                          "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ",
217                          qciVal,cell->qciArray[qciVal].dlTotal_UeCount,
218                          cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci);
219
220                    cell->qciArray[qciVal].dlTotal_UeCount = 0;
221                    idx++;
222                 }
223              }
224              cfm->numUeQciDlCfm.numQci = idx;
225           }
226        }
227    }
228    if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
229    {
230        cfm->numUeQciUlCfm.numQci = measInfo->nmbActvUeQciUl.numQci;
231        sampOc = (measTime / measInfo->nmbActvUeQciUl.sampPrd);
232        
233        
234        if(sampOc)
235        {   
236           if (measCb->measReq.nmbActvUeQciUl.numQci)
237           {
238              for(idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; idx++)
239              {
240                 cell->qciArray[qciVal].ulTotal_UeCount +=
241                    cell->qciArray[qciVal].ulUeCount;
242                 qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx]; 
243                 cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci =
244                    cell->qciArray[qciVal].ulTotal_UeCount/ sampOc;
245                 cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal;
246                 
247                 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
248                       "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ",
249                       qciVal,cell->qciArray[qciVal].ulTotal_UeCount,
250                       cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci);
251                 
252                 cell->qciArray[qciVal].ulTotal_UeCount = 0;
253              }
254           }
255           else
256           {
257              idx = 0;
258              for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
259              {
260                 cell->qciArray[qciVal].ulTotal_UeCount +=
261                    cell->qciArray[qciVal].ulUeCount;
262                 if (cell->qciArray[qciVal].ulTotal_UeCount)
263                 {
264                    cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci =
265                       cell->qciArray[qciVal].ulTotal_UeCount/ sampOc;
266                    cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal;
267
268                    RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
269                          "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ",
270                          qciVal,cell->qciArray[qciVal].ulTotal_UeCount,
271                          cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci);
272
273                    cell->qciArray[qciVal].ulTotal_UeCount = 0;
274                    idx++;
275                 }
276              }
277              cfm->numUeQciUlCfm.numQci = idx;
278           }
279        }
280    }
281    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_COUNT)
282    {
283       cfm->tbTransDlTotalCnt = cell->dlUlTbCnt.tbTransDlTotalCnt;
284       cell->dlUlTbCnt.tbTransDlTotalCnt = 0;
285    }   
286    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_FAULTY_COUNT)
287    {
288       cfm->tbTransDlFaulty = cell->dlUlTbCnt.tbTransDlFaulty;
289       cell->dlUlTbCnt.tbTransDlFaulty = 0;
290    }   
291    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_COUNT)
292    {
293       cfm->tbTransUlTotalCnt = cell->dlUlTbCnt.tbTransUlTotalCnt;
294       cell->dlUlTbCnt.tbTransUlTotalCnt = 0;
295    }   
296    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_FAULTY_COUNT)
297    {
298       cfm->tbTransUlFaulty = cell->dlUlTbCnt.tbTransUlFaulty;
299       cell->dlUlTbCnt.tbTransUlFaulty = 0;
300    }
301
302    measCb->dlTotalBw = 0;
303    measCb->ulTotalBw = 0;
304
305    return ROK;
306 } /* rgSchFillL2MeasCfm */
307
308 /** @brief This function sends the L2 measurement confirm to LM 
309  * from Shceduler
310  *
311  * @details
312  *
313  *     Function: rgSchL2mSndCfm
314  *
315  * @param  [in] Pst   *pst
316  * @param  [in] RgSchL2MeasCb *measCb
317  * @param  [in] Bool     isErr
318  * @return  Void
319  */
320 #ifdef ANSI
321 S16 rgSchL2mSndCfm
322 (
323 Pst               *pst,
324 RgSchL2MeasCb     *measCb,
325 LrgSchMeasReqInfo *measInfo,
326 Bool              isErr
327 )
328 #else
329 S16 rgSchL2mSndCfm(pst, measCb, measInfo, isErr)
330 Pst               *pst;
331 RgSchL2MeasCb     *measCb;
332 LrgSchMeasReqInfo *measInfo;
333 Bool              isErr;
334 #endif
335 {
336    LrgSchMeasCfmInfo   cfm;
337
338    memset(&cfm, 0, sizeof(LrgSchMeasCfmInfo));
339    cfm.hdr.transId  = measInfo->hdr.transId;
340    cfm.measType     = measInfo->measType;
341    cfm.cellId       = measInfo->cellId;
342    cfm.cfm.status   = LCM_PRIM_OK;
343    if(isErr == TRUE)
344    {
345       cfm.cfm.status   = LCM_PRIM_NOK;
346       cfm.cfm.reason   = LCM_REASON_INVALID_PAR_VAL;
347       RgMiLrgSchL2MeasCfm(pst, &cfm);
348       return ROK;
349    }
350    return ROK;
351 } /* rgSchL2mSndCfm */
352
353 /** @brief This function fills the LM confirmation pst structure 
354  *
355  * @details
356  *
357  *     Function: rgSchL2mFillCfmPst
358  *
359  * @param  [in] Pst    *pst
360  * @param  [out] Pst    *cfmPst
361  * @param  [in] LrgSchMeasReqInfo *measInfo
362  * @return  Void
363  */
364 #ifdef ANSI
365 Void rgSchL2mFillCfmPst
366 (
367 Pst    *pst,
368 Pst    *cfmPst,
369 LrgSchMeasReqInfo *measInfo 
370 )
371 #else
372 Void rgSchL2mFillCfmPst(pst, cfmPst, measInfo)
373 Pst    *pst;
374 Pst    *cfmPst;
375 LrgSchMeasReqInfo *measInfo;
376 #endif
377 {
378  
379    cfmPst->srcEnt    = pst->dstEnt;
380    cfmPst->srcInst   = pst->dstInst;
381    cfmPst->srcProcId = pst->dstProcId;
382    cfmPst->dstEnt    = pst->srcEnt;
383    cfmPst->dstInst   = pst->srcInst;
384    cfmPst->dstProcId = pst->srcProcId;
385
386    cfmPst->selector  = measInfo->hdr.response.selector;
387    cfmPst->prior     = measInfo->hdr.response.prior;
388    cfmPst->route     = measInfo->hdr.response.route;
389    cfmPst->region    = measInfo->hdr.response.mem.region;
390    cfmPst->pool      = measInfo->hdr.response.mem.pool;
391
392    RETVOID;
393 } /* rgSchL2mFillCfmPst */
394
395 /** @brief This function inserts the MeasCb in to data base
396  *
397  * @details
398  *
399  *     Function: rgSchL2mInsertMeasCb
400  *
401  * @param  [in] RgSchCellCb       *cell
402  * @param  [in] RgSchL2MeasCb     *measCb
403  * @param  [in] LrgSchMeasReqInfo *measInfo
404  * @return  S16
405  *      -# ROK 
406  *      -# RFAILED 
407  */
408 #ifdef ANSI
409 PRIVATE S16 rgSchL2mInsertMeasCb
410 (
411 RgSchCellCb       *cell,
412 RgSchL2MeasCb     *measCb,
413 LrgSchMeasReqInfo *measInfo
414 )
415 #else
416 PRIVATE S16 rgSchL2mInsertMeasCb(cell, measCb, measInfo)
417 RgSchCellCb       *cell;
418 RgSchL2MeasCb     *measCb;
419 LrgSchMeasReqInfo *measInfo;
420 #endif
421 {
422    CmLList   *lnk, *node;
423    RgSchL2MeasCb   *oldMeasCb;
424    U32              diffTime;
425    
426    /* 
427     * 1. Check if l2mList has any entries.
428     * 2. If yes 
429     *       1. Take the first entrie's time period and find the diff with
430     *       cell->crntTime.
431     *       2. If the diff is > measInfo->timePeriod then insert before this
432     *       entry.
433     *       3. Else take the next entry in list
434     *       4. If reached without adding to list . Append at the end of list.
435     * 3. If no entries in l2mList add at the first.
436     */
437    lnk = cell->l2mList.first;
438    node = &measCb->measLnk;
439    node->node = (PTR)measCb;
440    while(lnk != NULLP )
441    {
442       oldMeasCb = (RgSchL2MeasCb *)lnk->node;
443       diffTime = (oldMeasCb->measReq.timePrd - 
444                  (RGSCH_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
445       if (diffTime > measInfo->timePrd)
446       {
447          cell->l2mList.crnt = lnk;
448          cmLListInsCrnt(&(cell->l2mList), node);
449          return ROK;
450       }
451       else
452       {
453          lnk = lnk->next;
454       }
455    }  /* End of While */
456    cmLListAdd2Tail(&(cell->l2mList), node);
457    return ROK;
458 } /* rgSchL2mInsertMeasCb */
459
460 /** @brief This function calculates the Down link prb count 
461  * for a DlSf
462  *
463  * @details
464  *
465  *     Function: rgSchL2CalDlPrbCount
466  *
467  * @param  [in] RgSchCellCb       *cell
468  */
469 #ifdef ANSI
470 PRIVATE Void rgSchL2CalDlPrbCount
471 (
472 RgSchCellCb       *cell
473 )
474 #else
475 PRIVATE Void rgSchL2CalDlPrbCount(cell)
476 RgSchCellCb       *cell;
477 #endif
478 {
479    CmLteTimingInfo    frm;
480    RgSchDlSf          *sf = NULLP;
481 #ifdef LTE_TDD
482    U8                 idx;
483 #endif
484
485    frm   = cell->crntTime;
486    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
487    sf = rgSCHUtlSubFrmGet(cell, frm);
488 #ifdef LTE_TDD
489    idx = (cell->crntTime.slot + RG_SCH_CMN_DL_DELTA) % 
490                   RGSCH_NUM_SUB_FRAMES;
491    if(RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, idx)) 
492    {
493       cell->avgPrbDl.prbCount += sf->bwAssigned;
494       dlPrbCnt += sf->bwAssigned;
495    }
496 #else
497    cell->avgPrbDl.prbCount += sf->bwAssigned;
498 #endif
499    RETVOID;
500 }
501
502 /** @brief This function calculates the up link prb count 
503  * for a UlSf
504  *
505  * @details
506  *
507  *     Function: rgSchL2CalUlPrbCount
508  *
509  * @param  [in] RgSchCellCb       *cell
510  */
511 #ifdef ANSI
512 PRIVATE Void rgSchL2CalUlPrbCount
513 (
514 RgSchCellCb       *cell
515 )
516 #else
517 PRIVATE Void rgSchL2CalUlPrbCount(cell)
518 RgSchCellCb       *cell;
519 #endif
520 {
521    RgSchUlSf        *sf = NULLP;
522    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
523 #ifdef LTE_TDD
524    U8                 idx;
525 #endif
526
527 #ifdef LTE_TDD
528    idx = cellUl->schdIdx;
529    if(idx < cellUl->numUlSubfrms)
530    {
531       sf = &cellUl->ulSfArr[idx];
532       cell->avgPrbUl.prbCount += sf->totPrb;
533    }
534 #else
535    sf = &cellUl->ulSfArr[cellUl->schdIdx];
536    cell->avgPrbUl.prbCount += sf->totPrb;
537 #endif
538    RETVOID;
539 }
540 /** @brief This function allocates memory from the heap
541  *
542  * @details
543  *
544  *     Function: rgSchL2mAllocMeasCb
545  *
546  * @param  [in] RgSchCellCb       *cell
547  * @param  [in] RgSchL2MeasCb     *measInfo
548  * @param  [out] RgSchErrInfo      *err
549  * @return  RgSchL2MeasCb *
550  */
551 #ifdef ANSI
552 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb
553 (
554 RgSchCellCb       *cell,
555 LrgSchMeasReqInfo *measInfo,
556 RgSchErrInfo      err
557 )
558 #else
559 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb(cell, measInfo, err)
560 RgSchCellCb       *cell;
561 LrgSchMeasReqInfo *measInfo;
562 RgSchErrInfo      err;
563 #endif
564 {
565    RgSchL2MeasCb       *measCb = NULLP;
566    Inst                inst = cell->instIdx;
567    UNUSED(err);
568
569    if((rgSCHUtlAllocSBuf(inst, (Data **)&measCb,
570                    sizeof(RgSchL2MeasCb))) == RFAILED)
571    {
572       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSchL2mAllocMeasCb():"
573                   "Allocation of RgSchL2MeasCb failed");
574       return (NULLP);
575    }
576    memcpy(&measCb->measReq, measInfo, sizeof(LrgSchMeasReqInfo));
577    RGSCHCPYTIMEINFO(cell->crntTime, measCb->startTime);
578
579    measCb->dlTotalBw = 0;
580    measCb->ulTotalBw = 0;
581
582    return (measCb);
583 } /* rgSchL2mAllocMeasCb */
584
585 /**
586  * @brief Layer Manager Measurement request handler. 
587  *
588  * @details
589  *
590  *     Function : rgSchL2mMeasReq
591  *     
592  *     This function handles  measurement request received at scheduler instance
593  *     from the Layer Manager.
594  *     -# Measurement request will be stored in the list in ascending order of
595  *     their time period.
596  *     
597  *  @param[in]  Pst *pst, the post structure     
598  *  @param[in]  LrgSchMeasReqInfo *measInfo, the measurement request structure
599  *  @param[out] RgSchErrInfo   *err, error information
600  *  @return  S16
601  *      -# ROK
602  *      -# RFAILED
603  **/
604 #ifdef ANSI
605 S16 rgSchL2mMeasReq 
606 (
607 RgSchCellCb       *cell,
608 LrgSchMeasReqInfo *measInfo,
609 RgSchErrInfo      err
610 )
611 #else
612 S16 rgSchL2mMeasReq(cell, measInfo, err)
613 RgSchCellCb       *cell;
614 LrgSchMeasReqInfo *measInfo;
615 RgSchErrInfo      err;
616 #endif    
617 {
618    RgSchL2MeasCb *measCb;
619    U8            idx;
620    U8            qciVal;
621
622
623    qciVal = 0;
624    if ((measCb = rgSchL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
625    {
626        RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ,
627                     RGSCHERR_SCH_ALLOC_FAILED);
628        RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSchL2mMeasReq():"
629                 "Allocation of RgSchL2MeasCb failed");
630        return RFAILED;
631    }
632    /*memcpy(&measCb->measReq, measInfo,\
633              sizeof(LrgSchMeasReqInfo));*/
634    rgSchL2mInsertMeasCb(cell, measCb, measInfo);
635   
636    if (measInfo->timePrd == 0)
637    {
638       cell->sndL2Meas = FALSE;
639       if (measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL)
640       {
641          for (idx = 0; idx < measInfo->avgPrbQciDl.numQci; idx++)
642          {
643             qciVal = measInfo->avgPrbQciDl.qci[idx];
644             cell->qciArray[qciVal].qci = qciVal;
645          }
646       }
647       if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
648       {
649          for (idx = 0; idx < measInfo->nmbActvUeQciDl.numQci; idx++)
650          {
651             qciVal = measInfo->nmbActvUeQciDl.qci[idx];
652             cell->qciArray[qciVal].qci = qciVal;
653          }
654       }
655       if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
656       {
657          for (idx = 0; idx < measInfo->nmbActvUeQciUl.numQci; idx++)
658          {
659             qciVal = measInfo->nmbActvUeQciUl.qci[idx];
660             cell->qciArray[qciVal].qci = qciVal;
661          }
662       }
663    }
664    /* Here post the message to MAC */
665    if(measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)
666    {
667       RgInfL2MeasReq    measReq;
668       Pst               pst;
669       memset(&measReq, 0, sizeof(RgInfL2MeasReq));
670       measReq.transId  = measInfo->hdr.transId;
671       measReq.measType = measInfo->measType;
672       measReq.timePrd  = measInfo->timePrd;
673       measReq.cellId   = measInfo->cellId;
674       measReq.t.prbReq.numQci = measInfo->avgPrbQciUl.numQci;
675       for (idx = 0; idx < measInfo->avgPrbQciUl.numQci; idx++)
676       {
677         measReq.t.prbReq.qci[idx] = measInfo->avgPrbQciUl.qci[idx]; 
678       }
679       /* Send measReq to MAC */
680       rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
681       RgSchMacL2Meas(&pst, &measReq);
682    }
683    return ROK;
684 } /* rgSchL2mMeasReq */
685
686 /**
687  * @brief This function calculates the measurement for differnt measurement type
688  * and send the end result to the layer manager
689  *
690  * @details
691  *
692  *     Function : rgSCHL2Meas
693  *     
694  *  @param[in] RgSchCellCb  *cell
695  *  @return  S16
696  *      -# ROK
697  *      -# RFAILED
698  **/
699 #ifdef ANSI
700 S16 rgSCHL2Meas
701 (
702 RgSchCellCb  *cell,
703 U8 isCalrCrcInd
704 )
705 #else
706 S16 rgschL2Meas(cell,isCalrCrcInd)
707 RgSchCellCb  *cell;
708 U8 isCalrCrcInd
709 #endif
710 {
711    CmLList           *node = NULLP;
712    RgSchL2MeasCb     *measCb = NULLP;
713    U8                idx;
714    LrgSchMeasCfmInfo measCfm;
715    U8                qciVal = 0;
716    U32               sfDiff;
717    U32               meas;
718 #ifdef LTE_TDD
719    U8                sfIdx;
720    Bool              isDlDataAllowed;  
721    U8                rem;
722    U32               numDlSf;
723    U32               numUlSf;
724 #endif
725
726    node = cell->l2mList.first;
727    memset(&measCfm, 0, sizeof(LrgSchMeasCfmInfo));
728    while(node != NULLP)
729    {
730       measCb = (RgSchL2MeasCb *)node->node;
731       node = node->next;
732       if(cell->crntTime.sfn == 1023 && cell->crntTime.slot == 9)  
733       {
734          /*calculates diff between crnt time and start time*/
735          meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, 
736                measCb->sfnCycle, measCb->startTime);
737          measCb->sfnCycle++;
738       }
739       else
740       {
741          /*calculates diff between crnt time and start time*/
742          meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, 
743                measCb->sfnCycle, measCb->startTime);
744       }
745
746       if (cell->sndL2Meas || meas == measCb->measReq.timePrd)
747       {
748 #ifdef LTE_TDD
749          rem = meas % RGSCH_NUM_SUB_FRAMES;
750          /* Get the total number of DL and UL subframes within the reporting period*/
751          numDlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
752          numUlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
753
754          sfIdx = (measCb->startTime.slot + 1) % RGSCH_NUM_SUB_FRAMES;
755
756          while(rem)
757          {
758             isDlDataAllowed = RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, sfIdx); 
759             if(isDlDataAllowed)
760             {
761                numDlSf++;
762             }   
763             else if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][sfIdx] == 
764                   RG_SCH_TDD_UL_SUBFRAME)
765             {
766                numUlSf++;
767             }     
768             sfIdx = (sfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
769             rem--;
770          }   
771
772          measCb->dlTotalBw = numDlSf * cell->bwCfg.dlTotalBw;
773          measCb->ulTotalBw = numUlSf * cell->bwCfg.ulTotalBw;
774
775 #else            
776          measCb->dlTotalBw = meas * cell->bwCfg.dlTotalBw;
777          measCb->ulTotalBw = meas * cell->bwCfg.ulTotalBw;
778 #endif            
779          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL))
780          {
781             if(measCb->cfmRcvd)
782             {
783                rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas);
784             }
785             else
786             {
787                continue;
788             }
789          }
790          else
791          {
792             rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas);
793          }
794          RgMiLrgSchL2MeasCfm(&(rgSchCb[cell->instIdx].rgSchInit.lmPst),
795                &measCfm);
796          memset(&measCfm, 0, sizeof(LrgSchMeasCfmInfo));
797          
798          /* Delete this measCb from the list */
799          if(measCb->measReq.timePrd > 0)
800          {
801             cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
802             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,
803                   sizeof(RgSchL2MeasCb));
804          }
805          else/*do not delete measCb, will use for next measurement*/
806          {
807             measCb->startTime = cell->crntTime;
808             measCb->sfnCycle = 0;
809             measCb->cfmRcvd = FALSE;
810             memset(&measCb->avgPrbQciUl, 0, sizeof(LrgAvgPrbQCICfm));
811             cell->sndL2Meas = FALSE;
812          } 
813          /* ccpu00117052 - MOD - Passing double pointer
814             for proper NULLP assignment*/
815       }
816       else
817       {
818          /* Just update the AVERAGE UL PRB counter here and return
819           * if the caller is CRCIndication() and the UL scheduling happens
820           * as a part of it*/
821 #ifdef RG_ULSCHED_AT_CRC 
822          if(isCalrCrcInd)
823          {
824             if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL)
825             {
826                rgSchL2CalUlPrbCount(cell);
827             }
828             continue;
829          }
830 #else
831          /* UL PRB counter gets updated as a part of CRC indication 
832           * if the UL scheduling happens there */
833          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL))
834          {
835             rgSchL2CalUlPrbCount(cell);
836          }
837 #endif
838          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL))
839          {
840             rgSchL2CalDlPrbCount(cell);
841          }
842          if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
843          {
844             sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, measCb->startTime);
845
846             if((sfDiff % measCb->measReq.nmbActvUeQciDl.sampPrd) == 0)
847             {
848                if (measCb->measReq.nmbActvUeQciDl.numQci)
849                {
850                   for (idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; 
851                         idx++)
852                   {
853                      qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx];
854                      cell->qciArray[qciVal].dlTotal_UeCount +=
855                         cell->qciArray[qciVal].dlUeCount;
856                   }
857                }
858                else
859                {
860                   for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
861                   {
862                      cell->qciArray[qciVal].dlTotal_UeCount +=
863                         cell->qciArray[qciVal].dlUeCount;
864                   }
865                }
866             }
867          }
868          if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
869          {
870             sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime , measCb->startTime);
871             if((sfDiff % measCb->measReq.nmbActvUeQciUl.sampPrd) == 0)
872             {
873                if (measCb->measReq.nmbActvUeQciUl.numQci)
874                {
875                   for (idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; 
876                         idx++)
877                   {
878                      qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx];
879                      cell->qciArray[qciVal].ulTotal_UeCount += 
880                         cell->qciArray[qciVal].ulUeCount;
881                   }
882                }
883                else
884                {
885                   for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
886                   {
887                      cell->qciArray[qciVal].ulTotal_UeCount += 
888                         cell->qciArray[qciVal].ulUeCount;
889                   }
890                }
891             }
892          }
893       }
894    }/* end of while */
895    return ROK;
896 } /* rgSCHL2MEas */
897 #endif /* LTE_L2_MEAS */
898 /**********************************************************************
899  
900          End of file
901 **********************************************************************/