From: lal.harshita Date: Mon, 21 Aug 2023 15:00:02 +0000 (+0530) Subject: [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-523] Statistics Request API and Timer Based... X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=f73456bd55152c329601f8286ae67fe9875025bc;p=o-du%2Fl2.git [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-523] Statistics Request API and Timer Based KPI calculation at SCH Change-Id: If23ab70473a2a028c425fa8c9c1e3031eb0406dc Signed-off-by: lal.harshita --- diff --git a/src/5gnrmac/mac_cfg_hdl.c b/src/5gnrmac/mac_cfg_hdl.c index fee5f4f77..fa17ba067 100644 --- a/src/5gnrmac/mac_cfg_hdl.c +++ b/src/5gnrmac/mac_cfg_hdl.c @@ -1014,6 +1014,105 @@ uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq) } return ret; } + +/** + * @brief Mac process the statistics Req received from DUAPP + * + * @details + * + * Function : MacProcStatsReq + * + * This function process the statistics request from duapp + * + * @param[in] Pst *pst + * @param[in] StatsReq *statsReq + * @return int + * -# ROK + **/ +uint8_t MacProcStatsReq(Pst *pst, MacStatsReq *macStatsReq) +{ + uint8_t macStatsIdx = 0, schStatsIdx = 0; + uint8_t ret = RFAILED; + bool measTypeInvalid = false; + Pst schPst; + SchStatsReq *schStatsReq = NULLP; + CauseOfResult cause; + + if(macStatsReq) + { + DU_LOG("\nINFO --> MAC : Received Statistics Request from DU_APP"); + + MAC_ALLOC(schStatsReq, sizeof(SchStatsReq)); + if(schStatsReq == NULLP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq: Failed to allocate memory"); + cause = RESOURCE_UNAVAILABLE; + } + else + { + schStatsReq->numStats = 0; + for(macStatsIdx=0; macStatsIdx < macStatsReq->numStats; macStatsIdx++) + { + /* Checking each measurement type to send only SCH related + * measurement config to SCH + * This will be useful in future when some measurement type will + * be configured for SCH and rest for only MAC */ + switch(macStatsReq->statsList[macStatsIdx].type) + { + case MAC_DL_TOTAL_PRB_USAGE: + { + schStatsReq->statsList[schStatsIdx].type = SCH_DL_TOTAL_PRB_USAGE; + break; + } + case MAC_UL_TOTAL_PRB_USAGE: + { + schStatsReq->statsList[schStatsIdx].type = SCH_UL_TOTAL_PRB_USAGE; + break; + } + default: + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq: Invalid measurement type [%d]", \ + macStatsReq->statsList[macStatsIdx].type); + measTypeInvalid = true; + } + } + + if(!measTypeInvalid) + { + schStatsReq->statsList[schStatsIdx].periodicity = macStatsReq->statsList[macStatsIdx].periodicity; + schStatsIdx++; + measTypeInvalid = false; + } + } + schStatsReq->numStats = schStatsIdx; + + /* If no measurement types are valid, it is failure scenario. + * Even if one measurement type is valid, send to SCH */ + if(schStatsReq->numStats) + { + FILL_PST_MAC_TO_SCH(schPst, EVENT_STATISTICS_REQ_TO_SCH); + ret = SchMessageRouter(&schPst, (void *)schStatsReq); + } + else + { + cause = PARAM_INVALID; + } + } + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq)); + } + else + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq(): Received Null pointer"); + cause = PARAM_INVALID; + } + + if(ret == RFAILED) + { + /* Send negative acknowledgment to DU APP. TBD in next gerrit */ + } + return ret; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrmac/mac_msg_router.c b/src/5gnrmac/mac_msg_router.c index 1ed8fb3b0..62b25d321 100755 --- a/src/5gnrmac/mac_msg_router.c +++ b/src/5gnrmac/mac_msg_router.c @@ -187,6 +187,12 @@ void MacHdlDuappEvents(Pst *pst, Buffer *mBuf) break; } + case EVENT_MAC_STATISTICS_REQ: + { + /* Process Statistics Request */ + unpackMacStatsReq(MacProcStatsReq, pst, mBuf); + } + default: RG_FREE_MSG(mBuf); break; @@ -337,6 +343,9 @@ void callFlowMacActvTsk(Pst *pst) case EVENT_MAC_SLICE_RECFG_REQ: strcpy(message,"EVENT_MAC_SLICE_RECFG_REQ"); break; + case EVENT_MAC_STATISTICS_REQ: + strcpy(message,"EVENT_MAC_STATISTICS_REQ"); + break; default: strcpy(message,"Invalid Event"); break; diff --git a/src/5gnrmac/rg_env.h b/src/5gnrmac/rg_env.h index 192d80674..199b80884 100755 --- a/src/5gnrmac/rg_env.h +++ b/src/5gnrmac/rg_env.h @@ -155,7 +155,6 @@ //uint32_t wrSmDfltNumCells; #define RGSCH_MAX_UE_PER_DL_SF 32 #define RGSCH_MAX_RARNTI_PER_DL_SF 4 -#define SCH_INST_START 1 #define RGSCH_MAX_INST 2 /*MCELL changes*/ #define RG_MAX_INST 4 diff --git a/src/5gnrmac/rg_lmm.c b/src/5gnrmac/rg_lmm.c index a31bd2380..69fad5b4c 100755 --- a/src/5gnrmac/rg_lmm.c +++ b/src/5gnrmac/rg_lmm.c @@ -169,9 +169,6 @@ Reason reason /* reason */ SAttachSRngBuf(SS_RNG_BUF_ULMAC_TO_ULRLC, SS_RBUF_ENT_ULRLC,SS_RNG_RX); #endif - /* Initialize Scheduler as well */ - schActvInit(ENTMAC, SCH_INST_START, DFLT_REGION, PWR_UP); - /* Initialize lower mac */ lwrMacLayerInit(region, 0); diff --git a/src/5gnrrlc/rlc_tmr.c b/src/5gnrrlc/rlc_tmr.c index 0c7234e64..2f3a18732 100755 --- a/src/5gnrrlc/rlc_tmr.c +++ b/src/5gnrrlc/rlc_tmr.c @@ -60,28 +60,6 @@ * @brief RLC Timer Module */ -/** - * @def RLC_TMR_CALCUATE_WAIT - * - * This macro calculates and assigns wait time based on the value of the - * timer and the timer resolution. Timer value of 0 signifies that the - * timer is not configured - * - * @param[out] _wait Time for which to arm the timer changed to proper - * value according to the resolution - * @param[in] _tmrVal Value of the timer - * @param[in] _timerRes Resolution of the timer - * -*/ -#define RLC_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \ -{ \ - (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \ - if((0 != (_tmrVal)) && (0 == (_wait))) \ - { \ - (_wait) = 1; \ - } \ -} - /* private function declarations */ static Void rlcBndTmrExpiry(PTR cb); @@ -113,7 +91,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcUmUl* umUl = &(((RlcUlRbCb *)cb)->m.umUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes); arg.timers = &umUl->reAsmblTmr; arg.max = RLC_MAX_UM_TMR; @@ -123,7 +101,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes); arg.timers = &amUl->reAsmblTmr; arg.max = RLC_MAX_AM_TMR; @@ -133,7 +111,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, amUl->staProhTmrInt, gCb->genCfg.timeRes); @@ -145,7 +123,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmDl* amDl = &(((RlcDlRbCb *)cb)->m.amDl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, amDl->pollRetxTmrInt, gCb->genCfg.timeRes); @@ -157,7 +135,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcRguSapCb* rguSap = (RlcRguSapCb *)cb; /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes); arg.timers = &rguSap->bndTmr; arg.max = RLC_MAX_RGUSAP_TMR; @@ -169,7 +147,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { measEvtCb = (RlcL2MeasEvtCb *)cb; /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, measEvtCb->l2TmrCfg.val, gCb->genCfg.timeRes); @@ -181,7 +159,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) case EVENT_RLC_UE_THROUGHPUT_TMR: { RlcThpt *thptCb = (RlcThpt *)cb; - RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); arg.timers = &thptCb->ueTputInfo.ueThptTmr; arg.max = RLC_MAX_THPT_TMR; break; @@ -189,7 +167,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) case EVENT_RLC_UE_DELETE_TMR: { RlcUlUeCb *ulUeCb = (RlcUlUeCb*)cb; - RLC_TMR_CALCUATE_WAIT(arg.wait, RLC_UE_DELETE_WAIT_TIME, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, RLC_UE_DELETE_WAIT_TIME, gCb->genCfg.timeRes); arg.timers = &ulUeCb->ueDeleteInfo.ueDelTmr; arg.max = RLC_MAX_UE_TMR; break; @@ -197,7 +175,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) case EVENT_RLC_SNSSAI_THROUGHPUT_TMR: { RlcThpt *thptCb = (RlcThpt *)cb; - RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); arg.timers = &thptCb->snssaiTputInfo.snssaiThptTmr; arg.max = RLC_MAX_THPT_TMR; break; diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index 293add2bb..563cb5a47 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -46,51 +46,11 @@ #include "rg_sch_inf.x" /* typedefs for Scheduler */ #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #include "sch_fcfs.h" #include "sch_slice_based.h" -/** - * @brief Task Initiation function. - * - * @details - * - * Function : schActvInit - * - * This function is supplied as one of parameters during MAC's - * task registration. MAC will invoke this function once, after - * it creates and attaches this TAPA Task to a system task. - * - * @param[in] Ent Entity, the entity ID of this task. - * @param[in] Inst Inst, the instance ID of this task. - * @param[in] Region Region, the region ID registered for memory - * usage of this task. - * @param[in] Reason Reason. - * @return int - * -# ROK - **/ -uint8_t schActvInit(Ent entity, Inst instId, Region region, Reason reason) -{ - Inst inst = (instId - SCH_INST_START); - - /* Initialize the MAC TskInit structure to zero */ - memset ((uint8_t *)&schCb[inst], 0, sizeof(schCb)); - - /* Initialize the MAC TskInit with received values */ - schCb[inst].schInit.ent = entity; - schCb[inst].schInit.inst = inst; - schCb[inst].schInit.region = region; - schCb[inst].schInit.pool = 0; - schCb[inst].schInit.reason = reason; - schCb[inst].schInit.cfgDone = FALSE; - schCb[inst].schInit.acnt = FALSE; - schCb[inst].schInit.usta = FALSE; - schCb[inst].schInit.trc = FALSE; - schCb[inst].schInit.procId = ODU_GET_PROCID(); - - return ROK; -} /* schActvInit */ - /** * @brief Scheduler All Apis initialized. * @@ -150,28 +110,27 @@ uint8_t SchInstCfg(RgCfg *cfg, Inst dInst) schCb[inst].schInit.region = cfg->s.schInstCfg.genCfg.mem.region; schCb[inst].schInit.pool = cfg->s.schInstCfg.genCfg.mem.pool; - schCb[inst].genCfg.tmrRes = cfg->s.schInstCfg.genCfg.tmrRes; #ifdef LTE_ADV schCb[inst].genCfg.forceCntrlSrbBoOnPCel = cfg->s.schInstCfg.genCfg.forceCntrlSrbBoOnPCel; schCb[inst].genCfg.isSCellActDeactAlgoEnable = cfg->s.schInstCfg.genCfg.isSCellActDeactAlgoEnable; #endif schCb[inst].genCfg.startCellId = cfg->s.schInstCfg.genCfg.startCellId; + schCb[inst].schTimersInfo.tmrRes = cfg->s.schInstCfg.genCfg.tmrRes; /* Initialzie the timer queue */ - memset(&schCb[inst].tmrTq, 0, sizeof(CmTqType) * SCH_TQ_SIZE); + memset(&schCb[inst].schTimersInfo.tmrTq, 0, sizeof(CmTqType) * SCH_TQ_SIZE); /* Initialize the timer control point */ - memset(&schCb[inst].tmrTqCp, 0, sizeof(CmTqCp)); - schCb[inst].tmrTqCp.tmrLen = RGSCH_TQ_SIZE; + memset(&schCb[inst].schTimersInfo.tmrTqCp, 0, sizeof(CmTqCp)); + schCb[inst].schTimersInfo.tmrTqCp.tmrLen = SCH_TQ_SIZE; /* SS_MT_TMR needs to be enabled as schActvTmr needs instance information */ /* Timer Registration request to system services */ - if (ODU_REG_TMR_MT(schCb[inst].schInit.ent, dInst, (int)schCb[inst].genCfg.tmrRes, schActvTmr) != ROK) + if (ODU_REG_TMR_MT(schCb[inst].schInit.ent, dInst, (int)schCb[inst].schTimersInfo.tmrRes, schActvTmr) != ROK) { - DU_LOG("\nERROR --> SCH : SchInstCfg(): Failed to " - "register timer."); + DU_LOG("\nERROR --> SCH : SchInstCfg(): Failed to register timer."); return (LCM_REASON_MEM_NOAVAIL); } - + /* Set Config done in TskInit */ schCb[inst].schInit.cfgDone = TRUE; DU_LOG("\nINFO --> SCH : Scheduler gen config done"); @@ -1422,6 +1381,10 @@ uint8_t allocatePrbDl(SchCellCb *cell, SlotTimingInfo slotTime, \ return RFAILED; } } + + /* Update statistics of PRB usage if stats calculation is enabled */ + if(schCb[cell->instIdx].statistics.dlTotalPrbUsage) + prbAlloc->numPrbAlloc += numPrb; /* Update the remaining number for free PRBs */ removeAllocatedPrbFromFreePrbList(&prbAlloc->freePrbBlockList, freePrbNode, *startPrb, numPrb); @@ -1556,6 +1519,10 @@ uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, \ } } + /* Update statistics of PRB usage if stats calculation is enabled */ + if(schCb[cell->instIdx].statistics.ulTotalPrbUsage) + prbAlloc->numPrbAlloc += numPrb; + /* Update the remaining number for free PRBs */ removeAllocatedPrbFromFreePrbList(&prbAlloc->freePrbBlockList, freePrbNode, *startPrb, numPrb); @@ -2534,6 +2501,150 @@ uint8_t SchProcPhrInd(Pst *pst, SchPwrHeadroomInd *schPhrInd) return ret; } +/******************************************************************* + * + * @brief Processes Statistics Request from MAC + * + * @details + * + * Function : SchProcStatsReq + * + * Functionality: + * Processes Statistics Request from MAC + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t SchProcStatsReq(Pst *pst, SchStatsReq *statsReq) +{ + uint8_t idx; + Inst inst = pst->dstInst - SCH_INST_START; + SchMacRsp rsp = RSP_OK; + CauseOfResult cause = SUCCESSFUL; + bool isDlTotlPrbUseCfgd = false, isUlTotlPrbUseCfgd = false; + + DU_LOG("\nINFO --> SCH : Received Statistics Request from MAC"); + + for(idx=0; idx < statsReq->numStats; idx++) + { + switch(statsReq->statsList[idx].type) + { + case SCH_DL_TOTAL_PRB_USAGE: + { + /* Check if duplicate configuration */ + if(schCb[inst].statistics.dlTotalPrbUsage) + { + DU_LOG("\nERROR --> SCH : SCH_DL_TOTAL_PRB_USAGE stats already configured"); + rsp = RSP_NOK; + cause = DUPLICATE_ENTRY; + } + + /* Allocate memory */ + SCH_ALLOC(schCb[inst].statistics.dlTotalPrbUsage, sizeof(TotalPrbUsage)); + if(!schCb[inst].statistics.dlTotalPrbUsage) + { + DU_LOG("\nERROR --> SCH : Memory allocation failed for dlTotalPrbUsage in \ + SchProcStatsReq()"); + rsp = RSP_NOK; + cause = RESOURCE_UNAVAILABLE; + break; + } + + /* Initialize */ + memset(schCb[inst].statistics.dlTotalPrbUsage, 0, sizeof(TotalPrbUsage)); + + /* Configure */ + schCb[inst].statistics.dlTotalPrbUsage->schInst = inst; + schCb[inst].statistics.dlTotalPrbUsage->periodicity = statsReq->statsList[idx].periodicity; + cmInitTimers(&(schCb[inst].statistics.dlTotalPrbUsage->periodTimer), 1); + + /* Start timer */ + schStartTmr(&schCb[inst], (PTR)(schCb[inst].statistics.dlTotalPrbUsage), \ + EVENT_DL_TOTAL_PRB_USAGE_TMR, schCb[inst].statistics.dlTotalPrbUsage->periodicity); + + isDlTotlPrbUseCfgd = true; + break; + } + + case SCH_UL_TOTAL_PRB_USAGE: + { + /* Check if duplicate configuration */ + if(schCb[inst].statistics.ulTotalPrbUsage) + { + DU_LOG("\nERROR --> SCH : SCH_UL_TOTAL_PRB_USAGE stats already configured"); + rsp = RSP_NOK; + cause = DUPLICATE_ENTRY; + } + + /* Allocate memory */ + SCH_ALLOC(schCb[inst].statistics.ulTotalPrbUsage, sizeof(TotalPrbUsage)); + if(!schCb[inst].statistics.ulTotalPrbUsage) + { + DU_LOG("\nERROR --> SCH : Memory allocation failed for ulTotalPrbUsage in \ + SchProcStatsReq()"); + rsp = RSP_NOK; + cause = RESOURCE_UNAVAILABLE; + break; + } + + /* Initialize */ + memset(schCb[inst].statistics.ulTotalPrbUsage, 0, sizeof(TotalPrbUsage)); + + /* Configure */ + schCb[inst].statistics.ulTotalPrbUsage->schInst = inst; + schCb[inst].statistics.ulTotalPrbUsage->periodicity = statsReq->statsList[idx].periodicity; + cmInitTimers(&(schCb[inst].statistics.ulTotalPrbUsage->periodTimer), 1); + + /* Start timer */ + schStartTmr(&schCb[inst], (PTR)(schCb[inst].statistics.ulTotalPrbUsage), \ + EVENT_UL_TOTAL_PRB_USAGE_TMR, schCb[inst].statistics.ulTotalPrbUsage->periodicity); + + isUlTotlPrbUseCfgd = true; + break; + } + default: + { + DU_LOG("\nERROR --> SCH : Invalid statistics type [%d]", statsReq->statsList[idx].type); + rsp = RSP_NOK; + cause = PARAM_INVALID; + } + } /* End of switch */ + + if(rsp == RSP_NOK) + { + /* If failed to configure any KPI, then clear configuration of other + * KPIs that were configured successfully as part of this statsReq */ + if(isDlTotlPrbUseCfgd) + { + if((schChkTmr((PTR)(schCb[inst].statistics.dlTotalPrbUsage), EVENT_DL_TOTAL_PRB_USAGE_TMR)) == FALSE) + { + schStopTmr(&schCb[inst], (PTR)(schCb[inst].statistics.dlTotalPrbUsage), EVENT_DL_TOTAL_PRB_USAGE_TMR); + } + SCH_FREE(schCb[inst].statistics.dlTotalPrbUsage, sizeof(TotalPrbUsage)); + } + + if(isUlTotlPrbUseCfgd) + { + if((schChkTmr((PTR)(schCb[inst].statistics.ulTotalPrbUsage), EVENT_UL_TOTAL_PRB_USAGE_TMR)) == FALSE) + { + schStopTmr(&schCb[inst], (PTR)(schCb[inst].statistics.ulTotalPrbUsage), EVENT_UL_TOTAL_PRB_USAGE_TMR); + } + SCH_FREE(schCb[inst].statistics.ulTotalPrbUsage, sizeof(TotalPrbUsage)); + } + break; + } + } /* End of FOR */ + + SCH_FREE(statsReq, sizeof(SchStatsReq)); + + /* TODO : in next gerrit */ + //SchSendStatsRspToMac(inst, rsp, cause); + + return ROK; +} /* End of SchProcStatsReq */ + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 4feaa1828..537ed318b 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -17,8 +17,6 @@ *******************************************************************************/ /* macros */ -#define SCH_INST_START 1 -#define SCH_MAX_INST 1 #define SCH_MU0_NUM_SLOTS 10 #define SCH_MU1_NUM_SLOTS 20 #define SCH_MU2_NUM_SLOTS 30 @@ -47,7 +45,6 @@ #define NUM_DMRS_SYMBOLS 1 #define DMRS_ADDITIONAL_POS 0 #define SCH_DEFAULT_K1 1 -#define SCH_TQ_SIZE 10 #define SSB_IDX_SUPPORTED 1 #define CRC_FAILED 0 @@ -80,6 +77,8 @@ #define NUM_SCH_TYPE 2 /*Supported number of Scheduler Algorithm types*/ +#define SCH_TQ_SIZE 10 + typedef struct schDlHqProcCb SchDlHqProcCb; typedef struct schUlHqEnt SchUlHqEnt; typedef struct schRaReq SchRaReq; @@ -279,7 +278,6 @@ struct schDlHqEnt */ typedef struct schGenCb { - uint8_t tmrRes; /*!< Timer resolution */ uint8_t startCellId; /*!< Starting Cell Id */ #ifdef LTE_ADV bool forceCntrlSrbBoOnPCel; /*!< value 1 means force scheduling @@ -304,6 +302,7 @@ typedef struct schPrbAlloc { CmLListCp freePrbBlockList; /*!< List of continuous blocks for available PRB */ uint64_t prbBitMap[ MAX_SYMB_PER_SLOT][PRB_BITMAP_MAX_IDX]; /*!< BitMap to store the allocated PRBs */ + uint16_t numPrbAlloc; }SchPrbAlloc; /** @@ -601,6 +600,21 @@ typedef struct PdschCfg sib1PdschCfg; }SchSib1Cfg; +typedef struct dlTotalPrbUsage +{ + Inst schInst; + uint16_t numPrbUsedForTx; + uint16_t totalPrbAvailForTx; + uint16_t periodicity; + CmTimer periodTimer; +}TotalPrbUsage; + +typedef struct schStatistics +{ + TotalPrbUsage *dlTotalPrbUsage; + TotalPrbUsage *ulTotalPrbUsage; +}SchStatistics; + /** * @brief * Cell Control block per cell. @@ -646,6 +660,12 @@ typedef struct schCellCb uint8_t maxMsg3Tx; /* MAximum num of msg3 tx*/ }SchCellCb; +typedef struct schTimer +{ + CmTqCp tmrTqCp; /*!< Timer Task Queue Cntrl Point */ + CmTqType tmrTq[SCH_TQ_SIZE]; /*!< Timer Task Queue */ + uint8_t tmrRes; /*!< Timer resolution */ +}SchTimer; /** * @brief @@ -655,11 +675,11 @@ typedef struct schCb { TskInit schInit; /*!< Task Init info */ SchGenCb genCfg; /*!< General Config info */ - CmTqCp tmrTqCp; /*!< Timer Task Queue Cntrl Point */ - CmTqType tmrTq[SCH_TQ_SIZE]; /*!< Timer Task Queue */ + SchTimer schTimersInfo; /*!< Sch timer queues and resolution */ SchAllApis allApis[NUM_SCH_TYPE]; /*!schPucchInfo, 0, sizeof(SchPucchInfo)); } - //send msg to MAC + /* Send msg to MAC */ ret = sendUlSchInfoToMac(&ulSchedInfo, schInst); if(ret != ROK) { DU_LOG("\nERROR --> SCH : Sending UL Sch info from SCH to MAC failed"); } + /* Update UL statistics */ + if(schCb[schInst].statistics.ulTotalPrbUsage) + { + schCb[schInst].statistics.ulTotalPrbUsage->numPrbUsedForTx += schUlSlotInfo->prbAlloc.numPrbAlloc; + schCb[schInst].statistics.ulTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB; + } + + /* Re-initialize UL Slot */ schInitUlSlot(schUlSlotInfo); return ret; } diff --git a/src/5gnrsch/sch_crc.c b/src/5gnrsch/sch_crc.c index 3730988a6..abd9f4def 100644 --- a/src/5gnrsch/sch_crc.c +++ b/src/5gnrsch/sch_crc.c @@ -24,6 +24,7 @@ #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" /** diff --git a/src/5gnrsch/sch_fcfs.c b/src/5gnrsch/sch_fcfs.c index edfad6659..09e2c64b1 100644 --- a/src/5gnrsch/sch_fcfs.c +++ b/src/5gnrsch/sch_fcfs.c @@ -41,6 +41,7 @@ File: sch_fcfs.c #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #include "sch_fcfs.h" #ifdef NR_DRX diff --git a/src/5gnrsch/sch_harq_dl.c b/src/5gnrsch/sch_harq_dl.c index 1ec31bc5e..f058cdc0d 100644 --- a/src/5gnrsch/sch_harq_dl.c +++ b/src/5gnrsch/sch_harq_dl.c @@ -24,6 +24,7 @@ #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #include "cm_llist.h" #ifdef NR_DRX diff --git a/src/5gnrsch/sch_harq_ul.c b/src/5gnrsch/sch_harq_ul.c index 343859a8a..c5433f9fe 100644 --- a/src/5gnrsch/sch_harq_ul.c +++ b/src/5gnrsch/sch_harq_ul.c @@ -24,6 +24,7 @@ #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #ifdef NR_DRX #include "sch_drx.h" diff --git a/src/5gnrsch/sch_msg_router.c b/src/5gnrsch/sch_msg_router.c index edb21b881..ca15f65b8 100755 --- a/src/5gnrsch/sch_msg_router.c +++ b/src/5gnrsch/sch_msg_router.c @@ -42,6 +42,74 @@ #include "rgr.x" /* layer management typedefs for MAC */ #include "rg_sch_inf.x" /* typedefs for Scheduler */ #include "sch.h" +#include "sch_tmr.h" + +/** + * @brief Task Initiation function. + * + * @details + * + * Function : schActvInit + * + * This function is supplied as one of parameters during MAC's + * task registration. MAC will invoke this function once, after + * it creates and attaches this TAPA Task to a system task. + * + * @param[in] Ent Entity, the entity ID of this task. + * @param[in] Inst Inst, the instance ID of this task. + * @param[in] Region Region, the region ID registered for memory + * usage of this task. + * @param[in] Reason Reason. + * @return int + * -# ROK + **/ +uint8_t schActvInit(Ent entity, Inst instId, Region region, Reason reason) +{ + Inst inst = (instId - SCH_INST_START); + + /* Initialize the MAC TskInit structure to zero */ + memset ((uint8_t *)&schCb[inst], 0, sizeof(schCb)); + + /* Initialize the MAC TskInit with received values */ + schCb[inst].schInit.ent = entity; + schCb[inst].schInit.inst = inst; + schCb[inst].schInit.region = region; + schCb[inst].schInit.pool = 0; + schCb[inst].schInit.reason = reason; + schCb[inst].schInit.cfgDone = FALSE; + schCb[inst].schInit.acnt = FALSE; + schCb[inst].schInit.usta = FALSE; + schCb[inst].schInit.trc = FALSE; + schCb[inst].schInit.procId = ODU_GET_PROCID(); + + return ROK; +} /* schActvInit */ + +/** + * @brief Task Activation callback function. + * + * @details + * + * Function : schActvTsk + * + * Primitives invoked by SCH's users/providers through + * a loosely coupled interface arrive here by means of + * SSI's message handling. This API is registered with + * SSI during the Task Registration of SCH. + * + * @param[in] Pst *pst, Post structure of the primitive. + * @param[in] Buffer *mBuf, Packed primitive parameters in the buffer. + * @param[in] Reason reason. + * @return uint8_t + * -# ROK + **/ +uint8_t schActvTsk(Pst *pst, Buffer *mBuf) +{ + SchMessageRouter(pst, (void *)mBuf); + + ODU_EXIT_TASK(); + return ROK; +} #ifdef CALL_FLOW_DEBUG_LOG /** @@ -176,6 +244,11 @@ void callFlowSchMsgRouter(Pst *pst) strcpy(message,"EVENT_DL_HARQ_IND_TO_SCH"); break; } + case EVENT_STATISTICS_REQ_TO_SCH: + { + strcpy(message,"EVENT_STATISTICS_REQ_TO_SCH"); + break; + } default: strcpy(message,"Invalid Event"); break; @@ -298,6 +371,11 @@ uint8_t SchMessageRouter(Pst *pst, void *msg) SchProcDlHarqInd(pst, (DlHarqInd *)msg); break; } + case EVENT_STATISTICS_REQ_TO_SCH: + { + SchProcStatsReq(pst, (SchStatsReq *)msg); + break; + } default: { DU_LOG("\nERROR --> SCH : SchMessageRouter(): Invalid event [%d] received", pst->event); diff --git a/src/5gnrsch/sch_rach.c b/src/5gnrsch/sch_rach.c index 8d5b79ca7..e4f6fb468 100644 --- a/src/5gnrsch/sch_rach.c +++ b/src/5gnrsch/sch_rach.c @@ -40,6 +40,7 @@ #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" /** diff --git a/src/5gnrsch/sch_slice_based.c b/src/5gnrsch/sch_slice_based.c index 149e7d975..ece81a09b 100644 --- a/src/5gnrsch/sch_slice_based.c +++ b/src/5gnrsch/sch_slice_based.c @@ -40,6 +40,7 @@ File: sch_slice_based.c #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #include "sch_slice_based.h" #ifdef NR_DRX diff --git a/src/5gnrsch/sch_slot_ind.c b/src/5gnrsch/sch_slot_ind.c index 00ea9b933..5051095ef 100644 --- a/src/5gnrsch/sch_slot_ind.c +++ b/src/5gnrsch/sch_slot_ind.c @@ -40,6 +40,7 @@ File: sch_slot_ind.c #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #ifdef NR_DRX #include "sch_drx.h" @@ -749,11 +750,23 @@ uint8_t SchProcSlotInd(Pst *pst, SlotTimingInfo *slotInd) return (ret); } + /* Update DL statistics */ + if(schCb[schInst].statistics.dlTotalPrbUsage) + { + schCb[schInst].statistics.dlTotalPrbUsage->numPrbUsedForTx += cell->schUlSlotInfo[slot]->prbAlloc.numPrbAlloc; + schCb[schInst].statistics.dlTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB; + } + + /* Re-initialize DL slot */ schInitDlSlot(cell->schDlSlotInfo[slot]); + + /* Send UL Resource allocation to MAC */ schUlResAlloc(cell, schInst); + #ifdef NR_DRX schHandleExpiryDrxTimer(cell); #endif + return ret; } diff --git a/src/5gnrsch/sch_tmr.c b/src/5gnrsch/sch_tmr.c index e880db0ac..e31c5182a 100644 --- a/src/5gnrsch/sch_tmr.c +++ b/src/5gnrsch/sch_tmr.c @@ -21,6 +21,216 @@ #include "lrg.x" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" + +/** + * @brief Handler to check if the timer is running + * + * @param[in] cb Control block depending on the type of the timer event. + * @param[in] tmrEvnt Timer event to be started + * + * @return Bool indicating whether the timer is running or not + * -# ROK + * -# RFAILED +*/ +bool schChkTmr(PTR cb, int16_t tmrEvnt) +{ + switch (tmrEvnt) + { + case EVENT_DL_TOTAL_PRB_USAGE_TMR: + { + if(((TotalPrbUsage *)cb)->periodTimer.tmrEvnt == EVENT_DL_TOTAL_PRB_USAGE_TMR) + { + DU_LOG("\nDEBUG --> SCH : schChkTmr: Timer Evnt [%d] already running", tmrEvnt); + return TRUE; + } + break; + } + + case EVENT_UL_TOTAL_PRB_USAGE_TMR: + { + if(((TotalPrbUsage *)cb)->periodTimer.tmrEvnt == EVENT_UL_TOTAL_PRB_USAGE_TMR) + { + DU_LOG("\nDEBUG --> SCH : schChkTmr: Timer Evnt [%d] already running", tmrEvnt); + return TRUE; + } + break; + } + + default: + { + DU_LOG("\nERROR --> SCH : schChkTmr: Invalid tmr Evnt [%d]", tmrEvnt); + } + } + + return FALSE; +} + +/** + * @brief Handler to start timer + * + * @param[in] cb Control block depending on the type of the timer event. + * @param[in] tmrEvnt Timer event to be started + * + * @return Void +*/ +void schStartTmr(SchCb *gCb, PTR cb, int16_t tmrEvnt, uint8_t timerValue) +{ + TotalPrbUsage *dlTotalPrbUsage; + TotalPrbUsage *ulTotalPrbUsage; + CmTmrArg arg; + + arg.wait = 0; + + DU_LOG("\nINFO --> SCH : Starting Timer Event [%d] with Wait Time [%d] ms", \ + tmrEvnt, timerValue); + + switch (tmrEvnt) + { + case EVENT_DL_TOTAL_PRB_USAGE_TMR: + { + dlTotalPrbUsage = ((TotalPrbUsage *)cb); + TMR_CALCUATE_WAIT(arg.wait, timerValue, gCb->schTimersInfo.tmrRes); + + arg.timers = &dlTotalPrbUsage->periodTimer; + arg.max = MAX_TOTAL_PRB_USAGE_TMR; + break; + } + + case EVENT_UL_TOTAL_PRB_USAGE_TMR: + { + ulTotalPrbUsage = ((TotalPrbUsage *)cb); + TMR_CALCUATE_WAIT(arg.wait, timerValue, gCb->schTimersInfo.tmrRes); + + arg.timers = &ulTotalPrbUsage->periodTimer; + arg.max = MAX_TOTAL_PRB_USAGE_TMR; + break; + } + default: + { + DU_LOG("\nERROR --> SCH : schStartTmr: Invalid tmr Evnt [%d]", tmrEvnt); + } + } + + if(arg.wait != 0) + { + arg.tqCp = &(gCb->schTimersInfo.tmrTqCp); + arg.tq = gCb->schTimersInfo.tmrTq; + arg.cb = cb; + arg.evnt = tmrEvnt; + arg.tNum = 0; + + cmPlcCbTq(&arg); + } + + return; +} + +/** + * @brief Handler to stop a timer + * + * @param[in] cb Control block depending on the type of the timer event. + * @param[in] tmrType Timer event to be started + * + * @return Void +*/ +void schStopTmr(SchCb *gCb, PTR cb, uint8_t tmrType) +{ + CmTmrArg arg; + + arg.timers = NULLP; + + DU_LOG("\nINFO --> SCH : Stopping Timer Event [%d]", tmrType); + + switch (tmrType) + { + case EVENT_DL_TOTAL_PRB_USAGE_TMR: + { + arg.timers = &((TotalPrbUsage *)cb)->periodTimer; + arg.max = MAX_TOTAL_PRB_USAGE_TMR; + break; + } + case EVENT_UL_TOTAL_PRB_USAGE_TMR: + { + arg.timers = &((TotalPrbUsage *)cb)->periodTimer; + arg.max = MAX_TOTAL_PRB_USAGE_TMR; + break; + } + + default: + { + DU_LOG("\nERROR --> SCH : schStopTmr: Invalid tmr Evnt[%d]", tmrType); + break; + } + } + + if (tmrType != TMR0) + { + arg.tqCp = &gCb->schTimersInfo.tmrTqCp; + arg.tq = gCb->schTimersInfo.tmrTq; + arg.cb = cb; + arg.evnt = tmrType; + arg.wait = 0; + arg.tNum = 0; + cmRmvCbTq(&arg); + } + + return; +} + +/** + * @brief Handler to process Timer expiry of DL Total PRB Usage calculation + * + * @param[in] cb Control block depending on the type of the timer event. + * @param[in] tmrEvnt Timer event to be started + * + * @return Bool indicating whether the timer is running or not + * -# ROK + * -# RFAILED +*/ +uint8_t SchProcDlTotalPrbUsageTmrExp(TotalPrbUsage *dlTotalPrbUsage) +{ + uint8_t percentageOfTotalPrbUsed = 0; + + if(dlTotalPrbUsage->totalPrbAvailForTx) + percentageOfTotalPrbUsed = ((dlTotalPrbUsage->numPrbUsedForTx * 100) / dlTotalPrbUsage->totalPrbAvailForTx); + //SchSendStatsIndToMac(dlTotalPrbUsage->schInst, SCH_DL_TOTAL_PRB_USAGE, percentageOfTotalPrbUsed); + + /* Restart Timer */ + dlTotalPrbUsage->numPrbUsedForTx = 0; + dlTotalPrbUsage->totalPrbAvailForTx = 0; + schStartTmr(&schCb[dlTotalPrbUsage->schInst], (PTR)(dlTotalPrbUsage), EVENT_DL_TOTAL_PRB_USAGE_TMR, \ + dlTotalPrbUsage->periodicity); + + return ROK; +} + +/** + * @brief Handler to check if the timer is running + * + * @param[in] cb Control block depending on the type of the timer event. + * @param[in] tmrEvnt Timer event to be started + * + * @return Bool indicating whether the timer is running or not + * -# ROK + * -# RFAILED +*/ +uint8_t SchProcUlTotalPrbUsageTmrExp(TotalPrbUsage *ulTotalPrbUsage) +{ + uint8_t percentageOfTotalPrbUsed = 0; + + if(ulTotalPrbUsage->totalPrbAvailForTx) + percentageOfTotalPrbUsed = ((ulTotalPrbUsage->numPrbUsedForTx * 100) / ulTotalPrbUsage->totalPrbAvailForTx); + //SchSendStatsIndToMac(ulTotalPrbUsage->schInst, SCH_UL_TOTAL_PRB_USAGE, percentageOfTotalPrbUsed); + + /* Restart Timer */ + ulTotalPrbUsage->numPrbUsedForTx = 0; + ulTotalPrbUsage->totalPrbAvailForTx = 0; + schStartTmr(&schCb[ulTotalPrbUsage->schInst], (PTR)(ulTotalPrbUsage), EVENT_UL_TOTAL_PRB_USAGE_TMR, \ + ulTotalPrbUsage->periodicity); + + return ROK; +} /** * @brief Timer Expiry handler. @@ -34,13 +244,37 @@ * about tmrEvnt=Bind timer. * * @param[in] PTR cb, Entry for which Timer expired - * @param[in] S16 tmrEvnt, the Timer Event + * @param[in] uint8_t tmrEvnt, the Timer Event * @return uint8_t * -# ROK **/ uint8_t schTmrExpiry(PTR cb, uint8_t tmrEvnt) { - /* TODO : Handling of any timer event expiry */ + DU_LOG("\nINFO --> SCH : Timer Event [%d] expired", tmrEvnt); + + struct timeval tp; + gettimeofday(&tp, 0); + time_t curtime = tp.tv_sec; + struct tm *t = localtime(&curtime); + + switch (tmrEvnt) + { + case EVENT_DL_TOTAL_PRB_USAGE_TMR: + { + SchProcDlTotalPrbUsageTmrExp((TotalPrbUsage*)cb); + break; + } + case EVENT_UL_TOTAL_PRB_USAGE_TMR: + { + SchProcUlTotalPrbUsageTmrExp((TotalPrbUsage*)cb); + break; + } + default: + { + DU_LOG("\nERROR --> DU : duStartTmr: Invalid tmr Evnt [%d]", tmrEvnt); + break; + } + } return ROK; } @@ -65,8 +299,7 @@ short int schActvTmr(Ent ent,Inst inst) Inst schInst = (inst - SCH_INST_START); /* Check if any timer in the scheduler instance has expired */ - cmPrcTmr(&schCb[schInst].tmrTqCp, - schCb[schInst].tmrTq, (PFV) schTmrExpiry); + cmPrcTmr(&schCb[schInst].schTimersInfo.tmrTqCp, schCb[schInst].schTimersInfo.tmrTq, (PFV) schTmrExpiry); return ROK; diff --git a/src/5gnrsch/sch_tmr.h b/src/5gnrsch/sch_tmr.h new file mode 100644 index 000000000..105346d1e --- /dev/null +++ b/src/5gnrsch/sch_tmr.h @@ -0,0 +1,31 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ +*******************************************************************************/ + +#define MAX_TOTAL_PRB_USAGE_TMR 1 + +#define EVENT_DL_TOTAL_PRB_USAGE_TMR 1 +#define EVENT_UL_TOTAL_PRB_USAGE_TMR 2 + +bool schChkTmr(PTR cb, int16_t tmrEvnt); +void schStartTmr(SchCb *gCb, PTR cb, int16_t tmrEvnt, uint8_t timerValue); +void schStopTmr(SchCb *gCb, PTR cb, uint8_t tmrType); + +/********************************************************************** + End of file + **********************************************************************/ + diff --git a/src/5gnrsch/sch_ue_mgr.c b/src/5gnrsch/sch_ue_mgr.c index 1711ecbe4..d416a0749 100644 --- a/src/5gnrsch/sch_ue_mgr.c +++ b/src/5gnrsch/sch_ue_mgr.c @@ -27,6 +27,7 @@ #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #ifdef NR_DRX #include "sch_drx.h" diff --git a/src/5gnrsch/sch_utils.c b/src/5gnrsch/sch_utils.c index 9d65480b6..7e849abb7 100644 --- a/src/5gnrsch/sch_utils.c +++ b/src/5gnrsch/sch_utils.c @@ -41,6 +41,7 @@ #include "lrg.x" /* layer management typedefs for MAC */ #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" #include "math.h" diff --git a/src/cm/common_def.h b/src/cm/common_def.h index ffc921ea2..371a1d5a5 100644 --- a/src/cm/common_def.h +++ b/src/cm/common_def.h @@ -53,6 +53,9 @@ #include "cm_lib.x" #include "du_log.h" +#define SCH_INST_START 1 +#define SCH_MAX_INST 1 + #define RADIO_FRAME_DURATION 10 /* Time duration of a radio frame in ms */ /* MAX values */ #define MAX_NUM_CELL 2 /* Changed to 2 to support cell Id 2 even if there is only one cell in DU */ @@ -129,6 +132,8 @@ /*First SCS in kHz as per 3gpp spec 38.211 Table 4.2-1 */ #define BASE_SCS 15 +#define MAX_NUM_STATS 10 + /* Defining macros for common utility functions */ #define ODU_GET_MSG_BUF SGetMsg #define ODU_PUT_MSG_BUF SPutMsg @@ -226,6 +231,28 @@ _isLcidValid = ((_lcId >= SRB0_LCID && _lcId <= MAX_DRB_LCID) ? 1 : 0);\ } +/** + * @def TMR_CALCUATE_WAIT + * + * This macro calculates and assigns wait time based on the value of the + * timer and the timer resolution. Timer value of 0 signifies that the + * timer is not configured + * + * @param[out] _wait Time for which to arm the timer changed to proper + * value according to the resolution + * @param[in] _tmrVal Value of the timer + * @param[in] _timerRes Resolution of the timer + * +*/ +#define TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \ +{ \ + (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \ + if((0 != (_tmrVal)) && (0 == (_wait))) \ + { \ + (_wait) = 1; \ + } \ +} + typedef enum { SUCCESSFUL, @@ -233,6 +260,8 @@ typedef enum UEID_INVALID, RESOURCE_UNAVAILABLE, SLICE_NOT_FOUND, + DUPLICATE_ENTRY, + PARAM_INVALID }CauseOfResult ; typedef enum diff --git a/src/cm/du_app_mac_inf.c b/src/cm/du_app_mac_inf.c index 3ea1b0cce..e5e18c9b5 100644 --- a/src/cm/du_app_mac_inf.c +++ b/src/cm/du_app_mac_inf.c @@ -2318,6 +2318,85 @@ void unsetBitInUeBitMap(uint16_t cellId, uint8_t bitPos) UNSET_ONE_BIT(bitPos, ueBitMapPerCell[cellIdx]); } +/******************************************************************* +* +* @brief Packs and Sends Statistics Request from DUAPP to MAC +* +* @details +* +* Function : packDuMacStatsReq +* +* Functionality: +* Packs and Sends statistics request from DUAPP to MAC +* +* +* @params[in] Post structure pointer +* StatsReq pointer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t packDuMacStatsReq(Pst *pst, MacStatsReq *statsReq) +{ + Buffer *mBuf = NULLP; + + if(pst->selector == ODU_SELECTOR_LWLC) + { + if (ODU_GET_MSG_BUF(pst->region, pst->pool, &mBuf) != ROK) + { + DU_LOG("\nERROR --> MAC : Memory allocation failed at packDuMacStatsReq"); + return RFAILED; + } + /* pack the address of the structure */ + CMCHKPK(oduPackPointer,(PTR)statsReq, mBuf); + } + else + { + DU_LOG("\nERROR --> MAC: Only LWLC supported for packDuMacStatsReq"); + return RFAILED; + } + return ODU_POST_TASK(pst,mBuf); +} + +/******************************************************************* +* +* @brief Unpacks Statistics Request received from DU APP +* +* @details +* +* Function : unpackMacStatsReq +* +* Functionality: +* Unpacks Statistics Request received from DU APP +* +* @params[in] Pointer to Handler +* Post structure pointer +* Message Buffer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t unpackMacStatsReq(DuMacStatsReqFunc func, Pst *pst, Buffer *mBuf) +{ + if(pst->selector == ODU_SELECTOR_LWLC) + { + MacStatsReq *statsReq; + + /* unpack the address of the structure */ + CMCHKUNPK(oduUnpackPointer, (PTR *)&statsReq, mBuf); + ODU_PUT_MSG_BUF(mBuf); + return (*func)(pst, statsReq); + } + else + { + /* Nothing to do for other selectors */ + DU_LOG("\nERROR --> DU APP : Only LWLC supported for Statistics Request "); + ODU_PUT_MSG_BUF(mBuf); + } + + return RFAILED; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/du_app_mac_inf.h b/src/cm/du_app_mac_inf.h index 7cb789700..c7f88d68a 100644 --- a/src/cm/du_app_mac_inf.h +++ b/src/cm/du_app_mac_inf.h @@ -89,6 +89,7 @@ #define EVENT_MAC_UE_RESET_RSP 226 #define EVENT_MAC_UE_SYNC_STATUS_IND 227 #define EVENT_MAC_DL_BROADCAST_REQ 228 +#define EVENT_MAC_STATISTICS_REQ 229 #define BSR_PERIODIC_TIMER_SF_10 10 #define BSR_RETX_TIMER_SF_320 320 @@ -97,6 +98,10 @@ #define PAGING_SCHED_DELTA 4 #define MAX_PLMN 2 +/********************* Global Variable ********************/ +uint64_t ueBitMapPerCell[MAX_NUM_CELL]; /* Bit Map to store used/free UE-IDX per Cell */ + +/********************* Interface structure definition ********************/ typedef enum { SIB_TYPE2, @@ -578,6 +583,13 @@ typedef enum RESTART_TRANSMISSION }DataTransmissionAction; +/* Performance measurements from 3GPP TS 28.552 Release 15 */ +typedef enum +{ + MAC_DL_TOTAL_PRB_USAGE, + MAC_UL_TOTAL_PRB_USAGE +}MacMeasurementType; + typedef struct failureCause { CauseGrp type; @@ -1841,6 +1853,20 @@ typedef struct macDlBroadcastReq SiSchedulingInfo **siSchedulingInfo; }MacDlBroadcastReq; +typedef struct macStatsInfo +{ + MacMeasurementType type; + uint16_t periodicity; /* In milliseconds */ +}MacStatsInfo; + +typedef struct macStatsReq +{ + uint8_t numStats; + MacStatsInfo statsList[MAX_NUM_STATS]; +}MacStatsReq; + +/****************** FUNCTION POINTERS ********************************/ + /* DL broadcast req from DU APP to MAC*/ typedef uint8_t (*DuMacDlBroadcastReq) ARGS(( Pst *pst, @@ -1993,98 +2019,136 @@ typedef uint8_t (*MacDuUeSyncStatusIndFunc) ARGS(( Pst *pst, MacUeSyncStatusInd *syncStatusInd)); -uint64_t ueBitMapPerCell[MAX_NUM_CELL]; /* Bit Map to store used/free UE-IDX per Cell */ +/* Statitics Request from DU APP to MAC */ +typedef uint8_t (*DuMacStatsReqFunc) ARGS(( + Pst *pst, + MacStatsReq *statsReq)); +/******************** FUNCTION DECLARATIONS ********************************/ uint8_t packMacCellUpInd(Pst *pst, OduCellId *cellId); uint8_t unpackMacCellUpInd(DuMacCellUpInd func, Pst *pst, Buffer *mBuf); uint8_t duHandleCellUpInd(Pst *pst, OduCellId *cellId); + uint8_t packMacCellStart(Pst *pst, CellStartInfo *cellStartInfo); uint8_t unpackMacCellStart(DuMacCellStart func, Pst *pst, Buffer *mBuf); uint8_t MacProcCellStart(Pst *pst, CellStartInfo *cellStartInfo); + uint8_t packMacCellStop(Pst *pst, CellStopInfo *cellStopInfo); uint8_t unpackMacCellStop(DuMacCellStop func, Pst *pst, Buffer *mBuf); uint8_t MacProcCellStop(Pst *pst, CellStopInfo *cellStopInfo); + uint8_t packMacCellCfg(Pst *pst, MacCellCfg *macCellCfg); uint8_t unpackDuMacCellCfg(DuMacCellCfgReq func, Pst *pst, Buffer *mBuf); uint8_t MacProcCellCfgReq(Pst *pst, MacCellCfg *macCellCfg); + uint8_t packMacCellCfgCfm(Pst *pst, MacCellCfgCfm *macCellCfgCfm); uint8_t unpackMacCellCfgCfm(DuMacCellCfgCfm func, Pst *pst, Buffer *mBuf); uint8_t duHandleMacCellCfgCfm(Pst *pst, MacCellCfgCfm *macCellCfgCfm); + uint8_t packMacStopInd(Pst *pst, OduCellId *cellId); uint8_t unpackMacStopInd(DuMacStopInd func, Pst *pst, Buffer *mBuf); uint8_t duHandleStopInd(Pst *pst, OduCellId *cellId); +uint8_t sendStopIndMacToDuApp(uint16_t cellId); + uint8_t packMacUlCcchInd(Pst *pst, UlCcchIndInfo *ulCcchIndInfo); uint8_t unpackMacUlCcchInd(DuMacUlCcchInd func, Pst *pst, Buffer *mBuf); uint8_t duHandleUlCcchInd(Pst *pst, UlCcchIndInfo *ulCcchIndInfo); + uint8_t packMacDlCcchInd(Pst *pst, DlCcchIndInfo *dlCcchIndInfo); uint8_t unpackMacDlCcchInd(DuMacDlCcchInd func, Pst *pst, Buffer *mBuf); uint8_t MacProcDlCcchInd(Pst *pst, DlCcchIndInfo *dlCcchIndInfo); + uint8_t packDuMacUeCreateReq(Pst *pst, MacUeCreateReq *ueCfg); uint8_t unpackMacUeCreateReq(DuMacUeCreateReq func, Pst *pst, Buffer *mBuf); uint8_t MacProcUeCreateReq(Pst *pst, MacUeCreateReq *ueCfg); -uint8_t sendStopIndMacToDuApp(uint16_t cellId); + uint8_t packDuMacUeCreateRsp(Pst *pst, MacUeCreateRsp *cfgRsp); uint8_t unpackDuMacUeCreateRsp(MacDuUeCreateRspFunc func, Pst *pst, Buffer *mBuf); uint8_t DuProcMacUeCreateRsp(Pst *pst, MacUeCreateRsp *cfgRsp); + uint8_t packDuMacUeReconfigReq(Pst *pst, MacUeRecfg *ueRecfg); uint8_t unpackMacUeReconfigReq(DuMacUeReconfigReq func, Pst *pst, Buffer *mBuf); uint8_t MacProcUeReconfigReq(Pst *pst, MacUeRecfg *ueRecfg); + uint8_t packDuMacUeRecfgRsp(Pst *pst, MacUeRecfgRsp *recfgRsp); uint8_t unpackDuMacUeRecfgRsp(MacDuUeRecfgRspFunc func, Pst *pst, Buffer *mBuf); uint8_t DuProcMacUeRecfgRsp(Pst *pst, MacUeRecfgRsp *recfgRsp); + uint8_t packDuMacRachRsrcReq(Pst *pst, MacRachRsrcReq *rachRsrcReq); uint8_t unpackMacRachRsrcReq(DuMacRachRsrcReq func, Pst *pst, Buffer *mBuf); uint8_t MacProcRachRsrcReq(Pst *pst, MacRachRsrcReq *rachRsrcReq); + uint8_t packDuMacRachRsrcRsp(Pst *pst, MacRachRsrcRsp *rachRsrcRsp); uint8_t unpackDuMacRachRsrcRsp(MacDuRachRsrcRspFunc func, Pst *pst, Buffer *mBuf); uint8_t DuProcMacRachRsrcRsp(Pst *pst, MacRachRsrcRsp *rachRsrcRsp); + uint8_t packDuMacRachRsrcRel(Pst *pst, MacRachRsrcRel *rachRsrcRel); uint8_t unpackMacRachRsrcRel(DuMacRachRsrcRel func, Pst *pst, Buffer *mBuf); uint8_t MacProcRachRsrcRel(Pst *pst, MacRachRsrcRel *rachRsrcRel); + uint8_t packDuMacUeDeleteReq(Pst *pst, MacUeDelete *ueDelete); uint8_t MacProcUeDeleteReq(Pst *pst, MacUeDelete *ueDelete); uint8_t unpackMacUeDeleteReq(DuMacUeDeleteReq func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacUeDeleteRsp(Pst *pst, MacUeDeleteRsp *deleteRsp); uint8_t DuProcMacUeDeleteRsp(Pst *pst, MacUeDeleteRsp *deleteRsp); uint8_t unpackDuMacUeDeleteRsp(MacDuUeDeleteRspFunc func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacCellDeleteReq(Pst *pst, MacCellDeleteReq *cellDelete); uint8_t MacProcCellDeleteReq(Pst *pst, MacCellDeleteReq *cellDelete); uint8_t unpackMacCellDeleteReq(DuMacCellDeleteReq func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacCellDeleteRsp(Pst *pst, MacCellDeleteRsp *cellDeleteRsp); uint8_t DuProcMacCellDeleteRsp(Pst *pst, MacCellDeleteRsp *cellDeleteRsp); uint8_t unpackDuMacCellDeleteRsp(MacDuCellDeleteRspFunc func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacSliceCfgReq(Pst *pst, MacSliceCfgReq *sliceCfgReq); uint8_t MacProcSliceCfgReq(Pst *pst, MacSliceCfgReq *sliceCfgReq); uint8_t unpackMacSliceCfgReq(DuMacSliceCfgReq func, Pst *pst, Buffer *mBuf); + uint8_t DuProcMacSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp); uint8_t packDuMacSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp); uint8_t unpackDuMacSliceCfgRsp(MacDuSliceCfgRspFunc func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacSliceRecfgReq(Pst *pst, MacSliceRecfgReq *sliceRecfgReq); uint8_t MacProcSliceRecfgReq(Pst *pst, MacSliceRecfgReq *sliceRecfgReq); uint8_t unpackMacSliceRecfgReq(DuMacSliceRecfgReq func, Pst *pst, Buffer *mBuf); + uint8_t DuProcMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *sliceRecfgRsp); uint8_t packDuMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *sliceRecfgRsp); uint8_t unpackDuMacSliceRecfgRsp(MacDuSliceRecfgRspFunc func, Pst *pst, Buffer *mBuf); + uint8_t duHandleSlotInd(Pst *pst, SlotTimingInfo *slotIndInfo); uint8_t packMacSlotInd(Pst *pst, SlotTimingInfo *slotIndInfo); uint8_t unpackDuMacSlotInd(DuMacSlotInd func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacDlPcchInd(Pst *pst, DlPcchInd *pcchInd); uint8_t MacProcDlPcchInd(Pst *pst, DlPcchInd *pcchInd); uint8_t unpackMacDlPcchInd(DuMacDlPcchInd func, Pst *pst, Buffer *mBuf); + int8_t getFreeBitFromUeBitMap(uint16_t cellId); void unsetBitInUeBitMap(uint16_t cellId, uint8_t bitPos); + uint8_t packDuMacUeResetReq(Pst *pst, MacUeResetReq *ueReset); uint8_t MacProcUeResetReq(Pst *pst, MacUeResetReq *ueReset); uint8_t unpackMacUeResetReq(DuMacUeResetReq func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacUeResetRsp(Pst *pst, MacUeResetRsp *resetRsp); uint8_t DuProcMacUeResetRsp(Pst *pst, MacUeResetRsp *resetRsp); uint8_t unpackDuMacUeResetRsp(MacDuUeResetRspFunc func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacUeSyncStatusInd(Pst *pst, MacUeSyncStatusInd *ueSyncStatusInd); uint8_t DuProcMacUeSyncStatusInd(Pst *pst, MacUeSyncStatusInd *ueSyncStatusInd); uint8_t unpackDuMacUeSyncStatusInd(MacDuUeSyncStatusIndFunc func, Pst *pst, Buffer *mBuf); + uint8_t packDuMacDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq); uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq); uint8_t unpackMacDlBroadcastReq(DuMacDlBroadcastReq func, Pst *pst, Buffer *mBuf); + +uint8_t packDuMacStatsReq(Pst *pst, MacStatsReq *statsReq); +uint8_t MacProcStatsReq(Pst *pst, MacStatsReq *statsReq); +uint8_t unpackMacStatsReq(DuMacStatsReqFunc func, Pst *pst, Buffer *mBuf); + #endif diff --git a/src/cm/mac_sch_interface.h b/src/cm/mac_sch_interface.h index f3d4799d5..ca3497003 100644 --- a/src/cm/mac_sch_interface.h +++ b/src/cm/mac_sch_interface.h @@ -51,6 +51,8 @@ #define EVENT_DL_CQI_TO_SCH 32 #define EVENT_UL_CQI_TO_SCH 33 #define EVENT_PHR_IND_TO_SCH 34 +#define EVENT_STATISTICS_REQ_TO_SCH 35 + /*macros*/ #define MAX_SSB_IDX 1 /* forcing it as 1 for now. Right value is 64 */ #define SCH_SSB_MASK_SIZE 1 @@ -448,6 +450,13 @@ typedef enum CQI_PUSCH }CqiUlReportType; +/* Performance measurements from 3GPP TS 28.552 Release 15 */ +typedef enum +{ + SCH_DL_TOTAL_PRB_USAGE, + SCH_UL_TOTAL_PRB_USAGE +}SchMeasurementType; + /*structures*/ typedef struct timeDomainAlloc { @@ -2237,8 +2246,19 @@ typedef struct schRlsHqInfo SchUeHqInfo *ueHqInfo; }SchRlsHqInfo; +typedef struct schStatsInfo +{ + SchMeasurementType type; + uint16_t periodicity; /* In milliseconds */ +}SchStatsInfo; + +typedef struct schStatsReq +{ + uint8_t numStats; + SchStatsInfo statsList[MAX_NUM_STATS]; +}SchStatsReq; + /* function declarations */ -uint8_t schActvInit(Ent entity, Inst instId, Region region, Reason reason); uint8_t MacMessageRouter(Pst *pst, void *msg); uint8_t SchMessageRouter(Pst *pst, void *msg); diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h index 5004628ea..9259ae844 100644 --- a/src/du_app/du_e2ap_mgr.h +++ b/src/du_app/du_e2ap_mgr.h @@ -246,7 +246,8 @@ typedef struct /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.3.11 */ typedef struct { - /* TODO : To be added when list of KPIs are finalised */ + /* TODO : To be added in future when subcounters for any + * measurment type is required */ }LabelInfo; /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.2.1 */ @@ -257,16 +258,19 @@ typedef struct char measurementTypeName[STRING_SIZE_150_BYTES]; uint16_t measurementTypeId; }choice; - uint32_t numOfLabels; - LabelInfo LabelInfoList[MAX_LABEL_INFO]; + + /* As of now Labels are not used, hence it is not implemented completely */ + //uint32_t numOfLabels; + //LabelInfo LabelInfoList[MAX_LABEL_INFO]; + + CmLListCp measuredValue; /* To be filled when numOfLabels is 0, else values are calculated per Label */ }MeasurementInfo; /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.2.1 */ typedef struct { - uint16_t numOfMeasuermentInfo; - MeasurementInfo **measurementInfoList; - uint32_t granularityPeriod; /* In millisecond */ + CmLListCp measurementInfoList; /* Each node corresponds to MeasurementInfo */ + uint32_t granularityPeriod; /* In millisecond */ }ActionDefFormat1; /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.2.2 */ @@ -313,6 +317,7 @@ typedef struct uint8_t id; ActionType type; ActionDefinition definition; + ConfigType action; }ActionInfo; /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.1.1 : maxofRICActionID */ diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index e340e4363..d528b5121 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -1652,6 +1652,13 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) } free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ list.array); + + /* This is a dummy trigger for statistics request. It will + * be removed in next gerrit and actual statistics request + * will be sent when RIC subscription request is received + * from RIC */ + ricSubscriptionInfo->actionSequence[0].definition.styleType = 1; + BuildAndSendStatsReq(ricSubscriptionInfo->actionSequence[0].definition); } break; } diff --git a/src/du_app/du_e2ap_msg_hdl.h b/src/du_app/du_e2ap_msg_hdl.h index ed81ae077..18edc2770 100644 --- a/src/du_app/du_e2ap_msg_hdl.h +++ b/src/du_app/du_e2ap_msg_hdl.h @@ -25,6 +25,7 @@ uint8_t BuildAndSendE2NodeConfigUpdate(); uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause); void E2APMsgHdlr(Buffer *mBuf); uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo); +uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction); /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_mgr.h b/src/du_app/du_mgr.h index ba079dbdc..fd73b05ab 100644 --- a/src/du_app/du_mgr.h +++ b/src/du_app/du_mgr.h @@ -353,7 +353,6 @@ typedef struct duCb DuTimers duTimersInfo; /* Du timers queue */ }DuCb; - typedef struct duLSapCfg { SuId suId; @@ -372,6 +371,17 @@ typedef struct duLSapCfg TmrCfg connTmr; }DuLSapCfg; +/* Statistics Reported */ +typedef struct statistics +{ + /* As of now, KPI reporting is not implemented at RLC and DU APP. + * Below members are just for future reference*/ + //DuAppStats duAppStats; + //RlcStatsReq rlcStatsReq; + + MacStatsReq macStatsReq; +}Statistics; + /* global variables */ DuCb duCb; //DuCfgParams duCfgParam; diff --git a/src/du_app/du_mgr_main.c b/src/du_app/du_mgr_main.c index dfcc19816..f78728468 100644 --- a/src/du_app/du_mgr_main.c +++ b/src/du_app/du_mgr_main.c @@ -46,6 +46,8 @@ uint8_t rlcDlActvTsk (Pst *, Buffer *); uint8_t rlcDlActvInit (Ent, Inst, Region, Reason); uint8_t macActvTsk (Pst *, Buffer *); uint8_t macActvInit (Ent, Inst, Region, Reason); +uint8_t schActvTsk (Pst *, Buffer *); +uint8_t schActvInit(Ent, Inst, Region, Reason); uint8_t lwrMacActvTsk(Pst *, Buffer *); uint8_t lwrMacActvInit(Ent, Inst, Region, Reason); #ifndef INTEL_WLS_MEM @@ -364,6 +366,7 @@ uint8_t sctpInit(SSTskId sysTskId) sysTskId); return ROK; } + /******************************************************************* * * @brief Initializes RLC DL, MAC TAPA task @@ -405,9 +408,41 @@ uint8_t rlcDlInit(SSTskId sysTskId) { return RFAILED; } + } - DU_LOG("\nINFO --> DU_APP : RLC DL and MAC TAPA task created and registered to \ - %d sys task", sysTskId); +/******************************************************************* + * + * @brief Initializes SCH TAPA task + * + * @details + * + * Function : schInit + * + * Functionality: + * - Registers and attaches TAPA tasks for SCH + * + * @params[in] system task ID + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + uint8_t schInit(SSTskId sysTskId) + { + /* Register SCH TAPA Task */ + if(ODU_REG_TTSK((Ent)ENTMAC, (Inst)SCH_INST_START, (Ttype)TTNORM, (Prior)PRIOR0, + schActvInit, (ActvTsk)schActvTsk) != ROK) + { + return RFAILED; + } + /* Attach SCH Task */ + if (ODU_ATTACH_TTSK((Ent)ENTMAC, (Inst)SCH_INST_START, sysTskId)!= ROK) + { + return RFAILED; + } + + + DU_LOG("\nINFO --> DU_APP : SCH TAPA task created and registered to \ + %d sys task", sysTskId); return ROK; } @@ -537,7 +572,7 @@ uint8_t phyStubInit(SSTskId sysTskId) uint8_t commonInit() { /* Declare system task Ids */ - SSTskId du_app_stsk, egtp_stsk, sctp_stsk, rlc_ul_stsk, rlc_mac_cl_stsk, lwr_mac_stsk, phy_stub_slot_ind_stsk; + SSTskId du_app_stsk, egtp_stsk, sctp_stsk, rlc_ul_stsk, rlc_mac_cl_stsk, sch_stsk, lwr_mac_stsk, phy_stub_slot_ind_stsk; pthread_attr_t attr; @@ -577,6 +612,14 @@ uint8_t commonInit() return RFAILED; } ODU_SET_THREAD_AFFINITY(&rlc_ul_stsk, SS_AFFINITY_MODE_EXCL, 22, 0); + + /* system task for SCH */ + if(ODU_CREATE_TASK(PRIOR1, &sch_stsk) != ROK) + { + DU_LOG("\nERROR --> DU_APP : System Task creation for SCH failed"); + return RFAILED; + } + ODU_SET_THREAD_AFFINITY(&sch_stsk, SS_AFFINITY_MODE_EXCL, 22, 0); /* system task for SCTP receiver thread */ if(ODU_CREATE_TASK(PRIOR0, &sctp_stsk) != ROK) @@ -635,6 +678,12 @@ uint8_t commonInit() return RFAILED; } + if(schInit(sch_stsk) != ROK) + { + DU_LOG("\nERROR --> DU_APP : SCH Tapa Task initialization failed"); + return RFAILED; + } + if(lwrMacInit(lwr_mac_stsk) != ROK) { DU_LOG("\nERROR --> DU_APP : Lower MAC Tapa Task initialization failed"); diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index 5ab931b81..e29aa3b0d 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -97,10 +97,18 @@ DuMacSliceCfgReq packMacSliceCfgReqOpts[] = DuMacSliceRecfgReq packMacSliceRecfgReqOpts[] = { - packDuMacSliceRecfgReq, /* Loose coupling */ - MacProcSliceRecfgReq, /* TIght coupling */ - packDuMacSliceRecfgReq /* Light weight-loose coupling */ + packDuMacSliceRecfgReq, /* Loose coupling */ + MacProcSliceRecfgReq, /* TIght coupling */ + packDuMacSliceRecfgReq /* Light weight-loose coupling */ }; + +DuMacStatsReqFunc packMacStatsReqOpts[]= +{ + packDuMacStatsReq, /* Loose Coupling */ + MacProcStatsReq, /* Tight Coupling */ + packDuMacStatsReq /* Light weight-loose coupling */ +}; + /************************************************************************** * @brief Function to fill configs required by RLC * @@ -726,7 +734,7 @@ uint8_t duBuildMacGenCfg() /*----------- Fill General Configuration Parameters ---------*/ genCfg->mem.region = MAC_MEM_REGION; genCfg->mem.pool = MAC_POOL; - genCfg->tmrRes = 10; + genCfg->tmrRes = 1; genCfg->numRguSaps = 2; genCfg->lmPst.dstProcId = DU_PROC; @@ -1299,7 +1307,7 @@ uint8_t duSendSchCfg() /* Filling of Gen config */ cfg->genCfg.mem.region = MAC_MEM_REGION; cfg->genCfg.mem.pool = MAC_POOL; - cfg->genCfg.tmrRes = 10; + cfg->genCfg.tmrRes = 1; #ifdef LTE_ADV cfg->genCfg.forceCntrlSrbBoOnPCel = FALSE; @@ -2068,6 +2076,147 @@ uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats) return ROK; } + +/******************************************************************* + * + * @brief Send Statistics request to MAC + * + * @details + * + * Function : BuildAndSendStatsReqToMac() + * + * Functionality: Send Statistics Request To Mac + * + * @params[in] + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendStatsReqToMac(MacStatsReq duMacStatsReq) +{ + Pst pst; + MacStatsReq *macStatsReq = NULLP; + + DU_LOG("\nINFO --> DU_APP : Builds Statistics Request to send to MAC"); + + DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq)); + if(macStatsReq == NULLP) + { + DU_LOG("\nERROR --> DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac"); + return RFAILED; + } + else + { + memcpy(macStatsReq, &duMacStatsReq, sizeof(MacStatsReq)); + + FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ); + + DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Request to MAC "); + if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == RFAILED) + { + DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC"); + DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq)); + return RFAILED; + } + } + return ROK; +} + +/******************************************************************* + * + * @brief Fetch statistics details from Action Definition Format 1 + * + * @details + * + * Function : FetchStatsFromActionDefFormat1() + * + * Functionality: Fetch statistics details from Action + * Definition Format 1 received in an E2 message from + * RIC. + * + * @params[in] ActionDefFormat1 + * + * @return Statistics + * + * ****************************************************************/ +Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1) +{ + Statistics stats; + + /* TODO : When E2AP subscription procedure is implemented: + * Measurement info list is traveresed + * Based on KPI type, stats.macStatsReq or stats.rlcstatsReq is filled */ + + /* Hardcoding values for now for testing purpose + * Will be removed in next gerrit */ + stats.macStatsReq.numStats = 2; + stats.macStatsReq.statsList[0].type = MAC_DL_TOTAL_PRB_USAGE; + stats.macStatsReq.statsList[0].periodicity = 100; + stats.macStatsReq.statsList[1].type = MAC_UL_TOTAL_PRB_USAGE; + stats.macStatsReq.statsList[1].periodicity = 100; + + return stats; +} + +/******************************************************************* + * + * @brief Send Statistics request to DU layers + * + * @details + * + * Function : BuildAndSendStatsReq() + * + * Functionality: Check if there is an update in statistics + * reporting configuration. If so, send the update to + * respective layer. + * + * @params[in] + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction) +{ + Statistics stats; + + switch(subscribedAction.styleType) + { + case 1: + stats = FetchStatsFromActionDefFormat1(subscribedAction.choice.format1); + case 2: + case 3: + case 4: + case 5: + default: + break; + } + + if(BuildAndSendStatsReqToMac(stats.macStatsReq) != ROK) + { + DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToMac()"); + return RFAILED; + } + +/* TODO : When KPI collection from RLC will be supported, this function will be + * called to configure KPIs to be colled */ +#if 0 + if(BuildAndSendStatsReqToRlc(macStatsReq->rlcStatsReq) != ROK) + { + DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()"); + return RFAILED; + } +#endif + + /* TODO : In the caller of this function, change ActionDefinition->action + * from CONFIG_ADD to CONFIG_UNKNOWN once configuration is sent + * To be done in next gerrit*/ + + + return ROK; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_tmr.c b/src/du_app/du_tmr.c index 432a3d368..3d89d9857 100644 --- a/src/du_app/du_tmr.c +++ b/src/du_app/du_tmr.c @@ -84,7 +84,7 @@ void duStartTmr(PTR cb, int16_t tmrEvnt, uint8_t timerValue) case EVENT_E2_SETUP_TMR: { e2apDb = ((E2apDb *)cb); - DU_TMR_CALCUATE_WAIT(arg.wait, timerValue, duCb.duTimersInfo.tmrRes); + TMR_CALCUATE_WAIT(arg.wait, timerValue, duCb.duTimersInfo.tmrRes); arg.timers = &e2apDb->e2TimersInfo.e2Timers.e2SetupTimer; arg.max = MAX_E2_SETUP_TMR; diff --git a/src/du_app/du_tmr.h b/src/du_app/du_tmr.h index d7529b77c..809b087c0 100644 --- a/src/du_app/du_tmr.h +++ b/src/du_app/du_tmr.h @@ -19,28 +19,6 @@ #define DU_TIMER_RESOLUTION 1 #define DU_TQ_SIZE 2 -/** - * @def DU_TMR_CALCUATE_WAIT - * - * This macro calculates and assigns wait time based on the value of the - * timer and the timer resolution. Timer value of 0 signifies that the - * timer is not configured - * - * @param[out] _wait Time for which to arm the timer changed to proper - * value according to the resolution - * @param[in] _tmrVal Value of the timer - * @param[in] _timerRes Resolution of the timer - * -*/ -#define DU_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \ -{ \ - (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \ - if((0 != (_tmrVal)) && (0 == (_wait))) \ - { \ - (_wait) = 1; \ - } \ -} - short int duActvTmr(Ent ent,Inst inst); bool duChkTmr(PTR cb, int16_t tmrEvnt); void duStartTmr(PTR cb, int16_t tmrEvnt, uint8_t timerValue); diff --git a/src/mt/mt_ss.c b/src/mt/mt_ss.c index b91b442da..cb1ad0b87 100644 --- a/src/mt/mt_ss.c +++ b/src/mt/mt_ss.c @@ -501,11 +501,23 @@ SsRegCfg cfgRegInfo[SS_MAX_REGS] = { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE }, { SS_POOL_STATIC, 0 } } + }, + { + SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1, + { + { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE }, + { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE }, + { SS_POOL_DYNAMIC, MT_POOL_2_DSIZE }, + { SS_POOL_DYNAMIC, MT_POOL_3_DSIZE }, + { SS_POOL_DYNAMIC, MT_POOL_4_DSIZE }, + { SS_POOL_STATIC, 0 } + } } + #ifndef INTEL_WLS_MEM , { - SS_DFLT_REGION + 7, SS_MAX_POOLS_PER_REG - 1, + SS_DFLT_REGION + 8, SS_MAX_POOLS_PER_REG - 1, { { SS_POOL_DYNAMIC, MT_POOL_0_DSIZE }, { SS_POOL_DYNAMIC, MT_POOL_1_DSIZE }, @@ -611,11 +623,23 @@ MtDynMemCfg mtDynMemoCfg = {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} } + }, + { + SS_DFLT_REGION + 7, /* region id */ + MT_MAX_BKTS, /* number of buckets */ + { + /* block size, no. of blocks, Upper threshold, lower threshold */ + {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, + {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, + {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, + {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD}, + {SS_BLK_RELEASE_THRESHOLD, SS_BLK_ACQUIRE_THRESHOLD} + } } #ifndef INTEL_WLS_MEM , { - SS_DFLT_REGION + 7, /* region id */ + SS_DFLT_REGION + 8, /* region id */ MT_MAX_BKTS, /* number of buckets */ { /* block size, no. of blocks, Upper threshold, lower threshold */ @@ -792,11 +816,24 @@ MtMemCfg mtMemoCfg = {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */ {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */ } + }, + { + SS_DFLT_REGION + 7, /* region id */ + MT_MAX_BKTS, /* number of buckets */ + MT_HEAP_SIZE, /* heap size */ + { + {MT_BKT_0_DSIZE, MT_BKT_0_STATIC_NUMBLKS}, /* block size, no. of blocks */ + {MT_BKT_1_DSIZE, MT_BKT_1_STATIC_NUMBLKS}, /* block size, no. of blocks */ + {MT_BKT_2_DSIZE, MT_BKT_2_STATIC_NUMBLKS}, /* block size, no. of blocks */ + {MT_BKT_3_DSIZE, MT_BKT_3_STATIC_NUMBLKS}, /* block size, no. of blocks */ + {MT_BKT_4_DSIZE, MT_BKT_4_STATIC_NUMBLKS} /* block size, no. of blocks */ + } } + #ifndef INTEL_WLS_MEM , { - SS_DFLT_REGION + 7, /* region id */ + SS_DFLT_REGION + 8, /* region id */ MT_MAX_BKTS, /* number of buckets */ MT_HEAP_SIZE, /* heap size */ { diff --git a/src/mt/mt_ss.h b/src/mt/mt_ss.h index 4c002560c..68c021354 100755 --- a/src/mt/mt_ss.h +++ b/src/mt/mt_ss.h @@ -64,7 +64,7 @@ #endif #else #ifndef INTEL_WLS_MEM -#define SS_MAX_STSKS 8 +#define SS_MAX_STSKS 9 #else #define SS_MAX_STSKS 7 #endif @@ -94,7 +94,7 @@ #ifdef SS_MULTICORE_SUPPORT #define SS_MAX_REGS SS_MAX_STSKS #else -#define SS_MAX_REGS 7 +#define SS_MAX_REGS 8 #endif #ifdef CMM_MAX_BKT_ENT