1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
32 @brief This module does processing related to handling of lower interface APIs
33 invoked by PHY towards MAC
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "rgu.h" /* RGU defines */
38 #include "tfu.h" /* RGU defines */
39 #include "lrg.h" /* layer management defines for LTE-MAC */
40 #include "crg.h" /* layer management defines for LTE-MAC */
41 #include "rg_sch_inf.h" /* layer management defines for LTE-MAC */
42 #include "rg.h" /* defines and macros for MAC */
43 #include "rg_env.h" /* defines and macros for MAC */
44 #include "rg_err.h" /* defines and macros for MAC */
45 #include "rgm.h" /* layer management typedefs for MAC */
47 /* header/extern include files (.x) */
48 #include "crg.x" /* CRG interface typedefs */
49 #include "rgu.x" /* RGU types */
50 #include "tfu.x" /* RGU types */
51 #include "lrg.x" /* layer management typedefs for MAC */
52 #include "rg_sch_inf.x" /* SCH interface typedefs */
53 #include "rg_prg.x" /* PRG interface typedefs */
54 #include "rgm.x" /* layer management typedefs for MAC */
55 #include "rg.x" /* typedefs for MAC */
56 #ifdef MAC_RLC_UL_RBUF
61 /* ADD Changes for Downlink UE Timing Optimization */
62 #ifndef LTEMAC_DLUE_TMGOPTMZ
63 static S16 rgTOMUtlProcDlSf ARGS(( RgDlSf *dlSf, RgCellCb *cellCb,
66 S16 rgTOMUtlProcDlSf ARGS((RgDlSf *dlSf, RgCellCb *cellCb,
69 static S16 rgTOMProcCrntiCEInDatInd ARGS((
78 static S16 rgTOMProcCCCHSduInDatInd ARGS((
93 S16 RgUiRguFlowCntrlInd(Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd);
95 S16 rgEmtcHndl(RgCellCb *cell,RgInfSfAlloc *sfInfo);
96 S16 rgTOMEmtcUtlFillDatReqPdus(TfuDatReqInfo *datInfo, RgDlSf *dlSf, RgCellCb *cell, RgErrInfo *err);
97 Void rgTOMEmtcRlsSf(RgDlSf *dlSf);
100 static Void rgTOML2MCompileActiveLCs ARGS
107 static S16 rgTOMUtlL2MStoreBufSz ARGS
113 static S16 rgTomUtlPrepareL2MUlThrpInfo ARGS
117 RgRguDedDatInd *dDatInd
121 /* The below table takes lower values of BSR Range for a BSR value
122 This is to ensure that outstanding can be decrease to zero upon reception of
123 TB, which is not guaranteed if higher Range values are used */
124 /* Note: taking value 10 for BSR index 1 */
125 #ifndef MAC_5GTF_UPDATE
126 static uint32_t rgLwrBsrTbl[64] = {
127 0, 10, 10, 12, 14, 17, 19, 22, 26,
128 31, 36, 42, 49, 57, 67, 78, 91,
129 107, 125, 146, 171, 200, 234, 274, 321,
130 376, 440, 515, 603, 706, 826, 967, 1132,
131 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
132 4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
133 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
134 58255, 68201, 79846, 93479, 109439, 128125, 150000
138 static uint32_t rgLwrBsrTbl[64] = {
139 0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181,223,274,337,414,
140 509,625,769,945,1162,1429,1757,2161,2657,3267,4017,4940,6074,7469,
141 9185,11294,13888,17077,20999,25822,31752,39045,48012,59039,72598,
142 89272,109774,134986,165989,204111,250990,308634,379519,466683,
143 573866,705666,867737,1067031,1312097,1613447,1984009,2439678,
151 #define RG_TOM_INF_ALLOC(_pdu, _size, _dataPtr, _ret) {\
152 _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
155 /* global variables */
156 uint32_t rgUlrate_tfu;
158 uint32_t grgUlrate_tfu;
161 /** @brief This function fills the PDSCH data of a downlink subframe
165 * Function: rgTOMUtlFillDatReqPdus
168 * - Fill BCCH on DLSCH data using datInfo
169 * - Fill PCCH on DLSCH data using datInfo
170 * - Fill Dedicated data on DLSCH data using datInfo
171 * - Fill RA RSP data using datInfo
173 * @param [out] TfuDatReqInfo *datInfo
174 * @param [in] RgDlSf *dlSf
175 * @param [in] RgCellCb *cellCb
176 * @param [out] RgErrInfo *err
181 static S16 rgTOMUtlFillDatReqPdus (TfuDatReqInfo *datInfo,RgDlSf *dlSf,RgCellCb *cellCb, RgErrInfo *err)
184 TfuDatReqPduInfo *datReq=NULLP;
185 /* Moving node declaration to limited scope for optimization */
188 Inst inst = cellCb->macInst - RG_INST_START;
191 /* first lets send the BCCH data down to PHY */
192 if (dlSf->bcch.tb != NULLP)
194 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
195 &(datInfo->memCp))) != ROK)
197 err->errCause = RGERR_TOM_MEM_EXHAUST;
198 DU_LOG("\nERROR --> MAC : Memory Exhaustion ");
201 #ifdef TFU_ALLOC_EVENT_NO_INIT
205 datReq->tbInfo[0].lchInfo[0].mBuf[0]=NULLP;
208 datReq->rnti = RG_SI_RNTI;
209 datReq->dciInfo = dlSf->bcch.pdcch.dci;
210 /* Note: SCpyMsgMsg is not done since free of unsent buffer
211 * has been taken care through cell delete by invoking rgTomRlsSf
213 datReq->nmbOfTBs = 1;
215 datReq->mBuf[0] = dlSf->bcch.tb;
217 SFndLenMsg((Buffer *)dlSf->bcch.tb, &(datReq->tbInfo[0].tbSize));
218 datReq->tbInfo[0].tbPres = TRUE;
219 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->bcch.tb;
220 datReq->tbInfo[0].numLch = 1;
221 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
223 #ifdef TFU_ALLOC_EVENT_NO_INIT
224 datReq->tbInfo[1].tbPres = FALSE;
225 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
228 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
229 datReq->lnk.node = (PTR)datReq;
231 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
232 datReq->txPwrOffset = dlSf->bcch.txPwrOffset;
234 /* Setting the pointer to NULL post transmission */
235 dlSf->bcch.tb = NULLP;
238 if (dlSf->pcch.tb != NULLP)
240 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
241 &(datInfo->memCp))) != ROK)
243 err->errCause = RGERR_TOM_MEM_EXHAUST;
244 DU_LOG("\nERROR --> MAC : Memory Exhaustion CRNTI:%d",datReq->rnti);
247 #ifdef TFU_ALLOC_EVENT_NO_INIT
252 datReq->rnti = RG_P_RNTI;
253 datReq->dciInfo = dlSf->pcch.pdcch.dci;
254 datReq->nmbOfTBs = 1;
256 datReq->mBuf[0] = dlSf->pcch.tb;
258 SFndLenMsg((Buffer *)dlSf->pcch.tb, &datReq->tbInfo[0].tbSize);
259 datReq->tbInfo[0].tbPres = TRUE;
260 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->pcch.tb;
261 #ifdef TFU_ALLOC_EVENT_NO_INIT
262 datReq->tbInfo[1].tbPres = FALSE;
263 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
265 datReq->tbInfo[0].numLch = 1;
266 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
268 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
269 datReq->lnk.node = (PTR)datReq;
271 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
272 datReq->txPwrOffset = dlSf->pcch.txPwrOffset;
274 dlSf->pcch.tb = NULLP;
277 for(idx=0; idx < dlSf->numRaRsp; idx++)
279 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
280 &(datInfo->memCp))) != ROK)
282 err->errCause = RGERR_TOM_MEM_EXHAUST;
283 DU_LOG("\nERROR --> MAC : Memory Exhaustion CRNTI:%d",
287 #ifdef TFU_ALLOC_EVENT_NO_INIT
292 datReq->rnti = dlSf->raRsp[idx].pdcch.rnti;
293 datReq->dciInfo = dlSf->raRsp[idx].pdcch.dci;
294 datReq->nmbOfTBs = 1;
296 datReq->mBuf[0] = dlSf->raRsp[idx].rar;
298 SFndLenMsg((Buffer *)dlSf->raRsp[idx].rar, &datReq->tbInfo[0].tbSize);
299 datReq->tbInfo[0].tbPres = TRUE;
300 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->raRsp[idx].rar;
301 #ifdef TFU_ALLOC_EVENT_NO_INIT
302 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
303 datReq->tbInfo[1].tbPres = FALSE;
305 datReq->tbInfo[0].numLch = 1;
306 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
307 // prc_trace_format_string(0x40,3,"UE Id=(%d) tbSz=(%d)",datReq->rnti, datReq->tbInfo[0].tbSize);
309 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
310 datReq->lnk.node = (PTR)datReq;
312 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
313 datReq->txPwrOffset = dlSf->raRsp[idx].txPwrOffset;
315 dlSf->raRsp[idx].rar = NULLP;
318 /* Fill Dedicated UE data */
319 if (dlSf->tbs.count != 0)
322 while (dlSf->tbs.first)
324 node = dlSf->tbs.first;
325 hqCb = (RgDlHqProcCb*)node->node;
326 if ((ret = rgDHMSndDatReq (cellCb, dlSf, datInfo, hqCb, err)) != ROK)
328 DU_LOG("\nERROR --> MAC : DHM unable to fill DATA request");
329 err->errType = RGERR_TOM_TTIIND;
336 } /* end of rgTOMUtlFillDatReqPdus*/
338 /** @brief This function does all the processing related to a single downlink
343 * Function: rgTOMUtlProcDlSf
346 * - collate control data for all UEs and send to PHY
347 * - collate data buffers for all UEs and send to PHY
349 * @param [in] RgDlSf *dlSf
350 * @param [in] RgCellCb *cellCb
351 * @param [out] RgErrInfo *err
354 /* ADD Changes for Downlink UE Timing Optimization */
355 #ifndef LTEMAC_DLUE_TMGOPTMZ
356 static S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
358 S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
362 TfuDatReqInfo *datInfo;
363 Inst inst = cellCb->macInst - RG_INST_START;
366 /* Fill Data Request Info from scheduler to PHY */
367 if ((ret = rgAllocEventMem(inst,(Ptr *)&datInfo,
368 sizeof(TfuDatReqInfo))) != ROK)
370 DU_LOG("\nERROR --> MAC : Unable to Allocate TfuDatReqInfo");
375 cmLListInit(&datInfo->pdus);
377 RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DELTA);
379 RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DLDATA_DLDELTA);
381 datInfo->cellId = cellCb->cellId;
382 if((0 == (datInfo->timingInfo.sfn % 30)) && (0 == datInfo->timingInfo.slot))
384 //DU_LOG("5GTF_CHECK rgTOMUtlProcDlSf dat (%d : %d)\n", datInfo->timingInfo.sfn, datInfo->timingInfo.slot);
386 #ifdef TFU_ALLOC_EVENT_NO_INIT
387 datInfo->bchDat.pres = 0;
391 if (dlSf->bch.tb != NULLP)
393 datInfo->bchDat.pres = PRSNT_NODEF;
394 datInfo->bchDat.val = dlSf->bch.tb;
395 dlSf->bch.tb = NULLP;
398 /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
399 if ((ret = rgTOMEmtcUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
401 RG_FREE_MEM(datInfo);
405 /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
406 if ((ret = rgTOMUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
408 DU_LOG("\nERROR --> MAC : Unable to send data for cell");
409 RG_FREE_MEM(datInfo);
412 if((datInfo->pdus.count) || (datInfo->bchDat.pres == TRUE))
414 /* sending the data to Phy */
415 //if (rgLIMTfuDatReq(inst,datInfo) != ROK)
417 DU_LOG("\nERROR --> MAC : Unable to send data info for cell");
422 /* Nothing to send: free the allocated datInfo */
423 RG_FREE_MEM(datInfo);
431 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
432 * with the SubHeaders list and the values of the Control elements.
436 * Function: rgTOMUtlAllocPduEvnt
439 * @param[in] Inst inst
440 * @param [out] RgMacPdu **pdu
446 static S16 rgTOMUtlAllocPduEvnt (Inst inst,RgMacPdu **pdu)
450 RgUstaDgn dgn; /* Alarm diagnostics structure */
451 volatile uint32_t startTime=0;
454 evntMem.region = rgCb[inst].rgInit.region;
455 evntMem.pool = rgCb[inst].rgInit.pool;
458 SStartTask(&startTime, PID_TOMUTL_CMALLCEVT);
460 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
461 MS_BUF_ADD_ALLOC_CALLER();
464 if (cmAllocEvnt (sizeof (RgMacPdu), RG_BLKSZ, &evntMem, (Ptr*)pdu) != ROK)
466 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
467 rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
468 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
469 DU_LOG("\nERROR --> MAC : Allocation of DUX event failed");
474 SStopTask(startTime, PID_TOMUTL_CMALLCEVT);
479 /** @brief This function frees up the RgMacPdu structure that has been
480 * populated by demux.
484 * Function: rgTOMUtlFreePduEvnt
485 * - Function frees up the RgMacPdu structure, in case of error it shall
486 * free up the buffer's present in the different sdu.
489 * @param [in] Inst inst
490 * @param [in] RgMacPdu *pdu
491 * @param [in] Bool *error
494 static Void rgTOMUtlFreePduEvnt( RgMacPdu *pdu,Bool error)
500 /* Steps of freeing up the PDU.
501 * 1. loop through the subHdrLst and free up all the buffers.
502 * 2. free up the whole event
504 if ((error == TRUE) && (pdu->sduLst.count > 0))
506 node = pdu->sduLst.first;
509 sdu = (RgMacSdu*)node->node;
510 RG_FREE_MSG(sdu->mBuf);
516 } /* end of rgTOMUtlFreePduEvnt */
518 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
519 * with the SubHeaders list and the values of the Control elements.
523 * Function: rgTOMInfAllocPduEvnt
526 * @param [in] Inst inst
527 * @param [out] RgMacPdu **pdu
533 static S16 rgTOMInfAllocPduEvnt (Inst inst,RgInfSfDatInd **sfInfo)
537 RgUstaDgn dgn; /* Alarm diagnostics structure */
538 volatile uint32_t startTime=0;
541 evntMem.region = rgCb[inst].rgInit.region;
542 evntMem.pool = rgCb[inst].rgInit.pool;
545 SStartTask(&startTime, PID_TOMINF_CMALLCEVT);
547 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
548 MS_BUF_ADD_ALLOC_CALLER();
550 if (cmAllocEvnt (sizeof (RgInfSfDatInd), RG_BLKSZ, &evntMem, (Ptr*)sfInfo) != ROK)
552 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
553 rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
554 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
555 DU_LOG("\nERROR --> MAC : Allocation failed");
560 SStopTask(startTime, PID_TOMINF_CMALLCEVT);
565 /** @brief This function frees up the RgMacPdu structure that has been
566 * populated by demux.
570 * Function: rgTOMInfFreePduEvnt
571 * - Function frees up the RgMacPdu structure, in case of error it shall
572 * free up the buffer's present in the different sdu.
575 * @param [in] RgMacPdu *pdu
576 * @param [in] Bool *error
579 static Void rgTOMInfFreePduEvnt(RgInfSfDatInd *sfInfo)
584 } /* end of rgTOMUtlFreePduEvnt */
588 /** @brief This function performs the preparation of information needed to set
589 * L2M Scheduled UL Throughput Information for a particular UE.
593 * Function: rgTomUtlPrepareL2MUlThrpInfo
594 * This function performs the preparation of information needed to set
595 * L2M Scheduled UL Throughput Information for a particular UE.
599 * @param [in] RgCellCb *cellCb
600 * @param [in] RgUeCb *ueCb
601 * @param [out] RgRguDedDatInd *dDatInd
604 static S16 rgTomUtlPrepareL2MUlThrpInfo(RgCellCb *cellCb,RgUeCb *ueCb,RgRguDedDatInd *dDatInd)
610 dDatInd->burstInd = RGU_L2M_UL_BURST_END;
611 for(loop=0;loop<dDatInd->numLch;loop++)
613 lcId=dDatInd->lchData[loop].lcId;
616 lcgId = ueCb->ul.lcCb[lcId - 1].lcgId;
617 if(ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs > 0)
619 dDatInd->burstInd = RGU_L2M_UL_BURST_START;
630 /** @brief This function is called by rgTOMDatInd. This function invokes the
631 * scheduler with the information of the received Data and any Control Elements
632 * if present. Also it generates Data indications towards the higher layers.
639 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
641 * - If UE exists then update the Schduler with any MAC CEs if present.
642 * - Invoke RAM module to do Msg3 related processing rgRAMProcMsg3
643 * - Loop through the SDU subheaders and invoke either a common data
644 * indication (rgUIMSndCmnDatInd) or dedicated data indication
645 * (rgUIMSndDedDatInd) towards the higher layers.
647 * @param [in] RgCellCb *cellCb
648 * @param [in] RgUeCb *ueCb
649 * @param [in] CmLteRnti rnti
650 * @param [in] RgMacPdu *pdu
651 * @param [out] uint32_t *lcgBytes
661 static S16 rgTOMUtlProcMsg
672 #else /* LTEMAC_SPS */
673 static S16 rgTOMUtlProcMsg
683 Inst inst = cellCb->macInst - RG_INST_START;
685 RgRguCmnDatInd *cDatInd;
686 RgRguDedDatInd *dDatInd;
693 // RgInfSpsRelInfo relInfo;
700 uint16_t totalBytesRcvd = 0;
701 uint16_t sduLen[RGU_MAX_LC] = {0};
702 uint8_t qciVal[RGU_MAX_LC] = {0};
709 /* Moved outside of LTE_L2_MEAS
710 * scope as this pointer will now be used to
711 * check for valid Logical Channel ID
733 if(pdu->sduLst.first)
735 sdu = (RgMacSdu*)(pdu->sduLst.first->node);
737 if ((sdu->lcId == RG_CCCH_LCID))
739 /* code for common channel dat indications */
740 if ((ret = rgAllocShrablSBuf (inst,(Data**)&cDatInd, sizeof(RgRguCmnDatInd))) != ROK)
744 cDatInd->cellId = cellCb->cellId;
745 cDatInd->rnti = ueCb->ueId;
746 /* rg001.101: Corrected lcId value for common data indication */
747 cDatInd->lcId = cellCb->ulCcchId;
748 cDatInd->pdu = sdu->mBuf;
749 SFndLenMsg (sdu->mBuf, &ccchSz);
750 /* Fix : syed Contention resolution ID copy should consider only
751 * 6 bytes of information from sdu->mBuf. Incase of CCCH sdu for reest
752 * message/psuedo reest message, ccchSz can go beyond 6 and can corrupt
753 * other fields of ueCb. */
754 if (ccchSz >= RG_CRES_LEN)
756 SCpyMsgFix (sdu->mBuf, (MsgLen)0, RG_CRES_LEN, ueCb->contResId.resId,
759 #ifdef XEON_SPECIFIC_CHANGES
760 CM_LOG_DEBUG(CM_LOG_ID_MAC, "CCCH SDU of size(%d) received for UE(%d) CRES[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x] Time[%d %d]\n", ((S16)ccchSz), ueCb->ueId,ueCb->contResId.resId[0], ueCb->contResId.resId[1], ueCb->contResId.resId[2], ueCb->contResId.resId[3], ueCb->contResId.resId[4], ueCb->contResId.resId[5], cellCb->crntTime.sfn, cellCb->crntTime.slot);
763 rgUIMSndCmnDatInd(inst,cellCb->rguUlSap,cDatInd);
765 } /* end of common channel processing */
767 if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
773 elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
778 dDatInd = (RgRguDedDatInd *)elem;
779 memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
781 dDatInd->cellId = cellCb->cellId;
782 dDatInd->rnti = ueCb->ueId;
786 ulSf = &cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)];
787 if(ulSf->ueUlAllocInfo != NULLP)
789 for(idx1 = 0; idx1 < ulSf->numUe; idx1++)
791 if(ulSf->ueUlAllocInfo[idx1].rnti == ueCb->ueId)
793 numPrb = ulSf->ueUlAllocInfo[idx1].numPrb;
799 node = pdu->sduLst.first;
802 sdu = (RgMacSdu*)node->node;
804 ulLcCb = rgDBMGetUlDedLcCb (ueCb, sdu->lcId);
808 DU_LOG("\nERROR --> MAC : Unconfigured LCID:%d CRNTI:%d"
809 ,sdu->lcId,ueCb->ueId);
810 /* ccpu00128443: Fix for memory leak */
811 /* Fix : syed Neccessary to set sdu->mBuf = NULLP */
812 RG_FREE_MSG(sdu->mBuf);
816 #ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */
818 S16 rlcProcDlStatusPdu(Pst *udxPst,SuId suId,
819 CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu);
821 if(ROK == rlcProcDlStatusPdu(&(cellCb->rguDlSap->sapCfg.sapPst),
822 cellCb->rguDlSap->sapCfg.suId,
823 cellCb->cellId,ueCb->ueId,sdu->lcId,sdu->mBuf))
825 RG_FREE_MSG(sdu->mBuf);
832 /* ccpu00116477- Fixed the rgUIMSndDedDatInd condition when we receive 11 sdus in the
833 * list we are losing 11th sdu and sending the first 10 sdus again which
834 * is causing the duplicate packets and eNB crashing due to access
835 * of the freed memory */
836 if (dDatInd->numLch >= RGU_MAX_LC)
838 if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
840 DU_LOG("\nERROR --> MAC : Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
844 if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
849 elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
854 dDatInd = (RgRguDedDatInd *)elem;
855 memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
857 dDatInd->cellId = cellCb->cellId;
858 dDatInd->rnti = ueCb->ueId;
861 dDatInd->lchData[dDatInd->numLch].lcId = sdu->lcId;
862 dDatInd->lchData[dDatInd->numLch].pdu.mBuf[dDatInd->lchData[dDatInd->numLch].pdu.numPdu] = sdu->mBuf;
863 dDatInd->lchData[dDatInd->numLch].pdu.numPdu++;
864 lcgId = ulLcCb->lcgId;
865 SFndLenMsg(sdu->mBuf, &bufSz);
869 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs -= bufSz;
872 //if ((lcgBytes != NULLP) && (ueCb->ul.lcgArr[lcgId].isGbr == TRUE))
873 if (lcgBytes != NULLP)
875 lcgBytes[lcgId] += bufSz;
880 /* Check if data has come on SPS LC */
881 /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */
882 if (ueCb->ul.spsLcId[sdu->lcId-1] == TRUE)
884 ueCb->ul.spsDatRcvd++;
889 /* Data rcvd on CRNTI*/
890 /* Retrieve the LCG ID of the LCID*/
891 /* SPS LCG has data whose size > SID Size */
892 /* Activate SPS if data recvd on SPS LCID and size > SID Packet Size */
893 if((ueCb->ul.spsLcId[sdu->lcId-1] == TRUE) &&
894 (sdu->len > RG_SPS_SID_PACKET_SIZE))
896 *spsToBeActvtd = TRUE;
904 if(cellCb->qciArray[ulLcCb->qci].mask == TRUE)
906 sduLen[ulLcCb->qci] = sdu->len;
907 totalBytesRcvd += sdu->len;
908 qciVal[ulLcCb->qci] = ulLcCb->qci;
912 } /* end of while for SubHeaders */
914 for(idx2 = 0; idx2 < RGU_MAX_LC; idx2++)
916 if((cellCb->qciArray[qciVal[idx2]].mask == TRUE) &&
919 cellCb->qciArray[qciVal[idx2]].prbCount +=
920 ((numPrb * sduLen[idx2]) / totalBytesRcvd);
924 if(totalBytesRcvd > 0 && qciVal[idx2] > 0)
926 RG_UPD_GBR_PRB(cellCb, qciVal[idx2], ((numPrb * sduLen[idx2])/totalBytesRcvd));
931 /*Added for explicit release - start*/
934 if(isSpsRnti && dDatInd && dDatInd->numLch)
936 if(ueCb->ul.spsDatRcvd != 0)
938 ueCb->ul.explRelCntr = 0;
939 ueCb->ul.spsDatRcvd = 0;
943 ueCb->ul.explRelCntr++;
944 if (ueCb->ul.explRelCntr == ueCb->ul.explRelCnt)
946 ueCb->ul.explRelCntr = 0;
947 /* Indicate scheduler for explicit release */
948 memset(&schPst1, 0, sizeof(Pst));
949 rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
950 //TODO: commented for compilation without SCH
952 relInfo.cellSapId = cellCb->schInstMap.cellSapId;
953 relInfo.cRnti = ueCb->ueId;
954 relInfo.isExplRel = TRUE;
955 /* Release indicator is called now through the matrix in the function below */
956 //TODO: commented for compilation without SCH RgMacSchSpsRel( &schPst1, &relInfo );
958 ueCb->ul.implRelCntr = 0;
965 if(ueCb->ul.spsDatRcvd != 0)
967 //ueCb->ul.implRelCntr = 0;
968 ueCb->ul.explRelCntr = 0;
969 ueCb->ul.spsDatRcvd = 0;
973 /*Added for explicit release - end */
975 if((dDatInd) && (dDatInd->numLch))
978 rgTomUtlPrepareL2MUlThrpInfo(cellCb, ueCb,dDatInd);
980 RG_CALC_TTI_CNT(cellCb, dDatInd->ttiCnt);
982 if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
984 DU_LOG("\nERROR --> MAC : Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
989 else if((dDatInd) && (0 == dDatInd->numLch))
991 /* Free the memory allocated for dDatInd if we
992 * have no valid LCH PDU to send to RLC.*/
993 rgFreeSharableSBuf(inst,(Data **)&dDatInd,sizeof(RgRguDedDatInd));
999 /** @brief This function frees up the RgMacPdu structure that has been
1000 * populated by demux.
1004 * Function: rgTOMUtlInsSchInfo
1005 * - Function frees up the RgMacPdu structure, in case of error it shall
1006 * free up the buffer's present in the different sdu.
1009 * @param [in] RgMacPdu *pdu
1010 * @param [in] Bool *error
1014 static S16 rgTOMUtlInsSchInfo
1017 RgInfSfDatInd *sfInfo,
1018 RgInfCeInfo *ceInfo,
1025 static S16 rgTOMUtlInsSchInfo
1028 RgInfSfDatInd *sfInfo,
1029 RgInfCeInfo *ceInfo,
1036 RgInfUeDatInd *ueInfo;
1041 RG_TOM_INF_ALLOC(sfInfo, sizeof(RgInfUeDatInd), ueInfo, ret);
1048 ueInfo->rnti = rnti;
1050 ueInfo->ceInfo = *ceInfo;
1051 ueInfo->ueLstEnt.node = (PTR)ueInfo;
1052 for (lcgId = 1, idx = 0; lcgId < RGINF_MAX_LCG_PER_UE; lcgId++)
1054 if (lcgBytes[lcgId] != 0)
1056 /* Only GBR bytes */
1057 ueInfo->lcgInfo[idx].lcgId = lcgId;
1058 ueInfo->lcgInfo[idx++].bytesRcvd = lcgBytes[lcgId];
1059 lcgBytes[lcgId] = 0;
1062 cmLListAdd2Tail(&sfInfo->ueLst, &ueInfo->ueLstEnt);
1064 } /* end of rgTOMUtlInsSchInfo */
1068 * @brief Handler for processing data indication recieved from PHY for UEs.
1072 * Function: rgTOMDatInd
1074 * Handler for processing data indication recieved from PHY for UEs.
1076 * Invoked by: RgLiTfuDatInd of LIM
1079 * For each DataInfo recieved
1080 * - Validate the information received and retrieve cellCb
1081 * Validate cellId, rnti
1082 * - Call De-Mux module to decode the data rgDUXDemuxData
1083 * - If received a CRNTI control element
1084 * - Check if a CCCH SDU is present, if it is return failure
1085 * - Check for the existence of UE, if its isnt present return failure.
1086 * - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1087 * primarily informs the scheduler about the data received and
1088 * generates Data indications towards the higher layer.
1089 * - If only CCCH SDU is present
1090 * - Invoke rgTOMUtlProcMsg3 for further processing.
1091 * - If its a non-Msg3 PDU i.e. received outside of a RA procedure
1092 * - Retrieve the UeCB
1093 * - Validate that the received PDU contains only configured Logical
1095 * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
1096 * scheduler with the information of the received Data and generates
1097 * DatIndications towards the higher layers.
1099 * @param [in] Inst inst
1100 * @param[in] TfuDatIndInfo *datInd
1105 S16 rgTOMDatInd(Inst inst, TfuDatIndInfo *datInd)
1110 RgUeCb *prevUeCb = NULLP;
1113 RgInfSfDatInd *sfInfo;
1117 TfuDatInfo *datInfo;
1121 Bool isSpsRnti=FALSE;
1123 // RgInfSpsRelInfo relInfo;
1124 Bool spsToBeActvtd = FALSE;
1125 uint16_t sduSize = 0;
1127 uint32_t lcgBytes[RGINF_MAX_LCG_PER_UE];
1130 #ifdef STUB_TTI_HANDLING_5GTF
1131 node = datInd->datIndLst.first;
1132 for (;node; node=node->next)
1134 datInfo = (TfuDatInfo*)node->node;
1137 SFndLenMsg(datInfo->mBuf, &len);
1138 rgUlrate_tfu += len;
1139 if (rgUlrate_tfu > 100000)
1141 DU_LOG("\nINFO --> MAC : rgTOMDatInd datInfo->mBuf len =%d rgUlrate_tfu=%d",len,rgUlrate_tfu);
1149 memset(&lcgBytes, 0, sizeof(lcgBytes));
1151 tfuSap = &(rgCb[inst].tfuSap);
1153 cellCb = rgCb[inst].cell;
1154 if((cellCb == NULLP) ||
1155 (cellCb->cellId != datInd->cellId))
1158 DU_LOG("\nERROR --> MAC : Unable to get the cellCb for cell");
1161 /* Avoiding memset as all the fields are getting initialized further */
1163 if (rgTOMInfAllocPduEvnt (inst,&sfInfo) != ROK)
1165 err.errType = RGERR_TOM_DATIND;
1166 DU_LOG("\nERROR --> MAC : Unable to Allocate PDU for DUX cell");
1167 node = datInd->datIndLst.first;
1170 cmLListInit(&sfInfo->ueLst);
1171 sfInfo->cellId = datInd->cellId;
1172 sfInfo->timingInfo = datInd->timingInfo;
1173 slot = datInd->timingInfo.slot;
1175 node = datInd->datIndLst.first;
1176 for (;node; node=node->next)
1178 datInfo = (TfuDatInfo*)node->node;
1180 //uint32_t ulrate_tfu;
1182 SFndLenMsg(datInfo->mBuf, &len);
1183 #ifdef STUB_TTI_HANDLING_5GTF
1184 // DU_LOG(":rgTOMDatInd datInfo->mBuf len =%d",len);
1186 rgUlrate_tfu += len;
1188 grgUlrate_tfu += len;
1191 #ifdef STUB_TTI_HANDLING_5GTF
1192 rgLIMUtlFreeDatIndEvnt(datInd,TRUE);
1194 /* We shall call De-Mux to process the received buffer. We shall try and find
1195 * out the RaCb based on the following -
1196 * 1. If the incoming PDU contained a CCCH SDU i.e. this is message 3.
1197 * 2. If the incoming PDU contained a CRNTI control element, i.e. we should
1198 * have a ueCb also for this
1200 /* Lets allocate the event that needs to be passed to DUX */
1201 if (rgTOMUtlAllocPduEvnt (inst,&pdu) != ROK)
1203 err.errType = RGERR_TOM_DATIND;
1204 DU_LOG("\nERROR --> MAC : Unable to Allocate PDU for DUX cell");
1205 rgTOMInfFreePduEvnt (sfInfo);
1209 if ((ret = rgDUXDemuxData (inst,pdu, &ceInfo,
1210 &datInfo->mBuf, &err)) != ROK)
1213 /* Fix: sriky memory corruption precautions */
1214 rgTOMUtlFreePduEvnt (pdu, TRUE);
1215 err.errType = RGERR_TOM_DATIND;
1216 DU_LOG("\nERROR --> MAC : DUX processing failed");
1217 tfuSap->sapSts.numPduDrop++;
1220 /* It could be that a non-msg3 pdu contains a CRNTI Control element. We
1221 * should check for CRNTI CE and if it exists the UECb must exist, also an
1222 * if the CRNTI in the CE and the one with which the message came in are
1223 * different we shall look for an raCb as well.
1226 if (ceInfo.bitMask & RG_CCCH_SDU_PRSNT)
1228 ret = rgTOMProcCCCHSduInDatInd(pdu, prevUeCb, \
1229 cellCb, datInfo, &ceInfo, slot);
1232 rgTOMUtlFreePduEvnt (pdu, TRUE);
1233 err.errType = RGERR_TOM_DATIND;
1234 tfuSap->sapSts.numPduDrop++;
1237 } /* end of Msg3 processing */
1239 else if (ceInfo.bitMask & RG_CRNTI_CE_PRSNT)
1241 ret = rgTOMProcCrntiCEInDatInd(pdu, prevUeCb, \
1242 cellCb, datInfo, &ceInfo, slot);
1245 rgTOMUtlFreePduEvnt (pdu, TRUE);
1246 err.errType = RGERR_TOM_DATIND;
1247 tfuSap->sapSts.numPduDrop++;
1251 } /* end of CRNTI based message */
1254 ueCb = rgDBMGetUeCb (cellCb, datInfo->rnti);
1258 /* Try getting the UE using SPS-RNTI. */
1259 ueCb = rgDBMGetSpsUeCb (cellCb, datInfo->rnti);
1263 /* Increment implrelCntr for an empty transmission */
1264 if (pdu->sduLst.count == 0)
1266 ueCb->ul.implRelCntr++;
1267 if (ueCb->ul.implRelCntr == ueCb->ul.implRelCnt)
1269 /* Indicate scheduler for implicit release */
1270 memset(&schPst1, 0, sizeof(Pst));
1271 rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
1273 ueCb->ul.implRelCntr = 0;
1274 ueCb->ul.explRelCntr = 0;
1276 relInfo.cellSapId = cellCb->schInstMap.cellSapId;
1277 relInfo.cRnti = ueCb->ueId;
1278 relInfo.isExplRel= FALSE;
1279 //TODO: commented for compilation without SCH RgMacSchSpsRel(&schPst1, &relInfo);
1285 /* Reset the implrelCntr */
1286 ueCb->ul.implRelCntr = 0;
1292 /* Perform failure if ueCb is still NULLP */
1293 rgTOMUtlFreePduEvnt (pdu, TRUE);
1294 err.errType = RGERR_TOM_DATIND;
1295 DU_LOG("\nERROR --> MAC : RNTI:%d Unable to get the UE CB",
1297 tfuSap->sapSts.numPduDrop++;
1302 rgTOMUtlL2MStoreBufSz(ueCb, &ceInfo);
1303 rgTOML2MCompileActiveLCs (cellCb, ueCb, pdu, &ceInfo);
1306 if ((ret = rgTOMUtlProcMsg(cellCb, ueCb, pdu, isSpsRnti,&spsToBeActvtd,&sduSize, slot, (uint32_t *)&lcgBytes)) != ROK)
1308 if ((ret = rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, (uint32_t *)&lcgBytes)) != ROK)
1309 #endif /* LTEMAC_SPS */
1311 rgTOMUtlFreePduEvnt (pdu, TRUE);
1312 err.errType = RGERR_TOM_DATIND;
1313 DU_LOG("\nERROR --> MAC : Unable to handle Data Indication CRNTI:%d",ueCb->ueId);
1314 tfuSap->sapSts.numPduDrop++;
1321 if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti,spsToBeActvtd,sduSize, (uint32_t *)&lcgBytes) != ROK)
1323 if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti, (uint32_t *)&lcgBytes) != ROK)
1327 rgTOMInfFreePduEvnt (sfInfo);
1328 rgTOMUtlFreePduEvnt (pdu, FALSE);
1331 /* free up the PDU memory */
1332 rgTOMUtlFreePduEvnt (pdu, FALSE);
1334 /* Free the allocated memory for ueUlAllocInfo here */
1336 if(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo != NULLP)
1338 /*ccpu00117052 - MOD - Passing double for proper NULLP
1340 rgFreeSBuf(inst,(Data **)&(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo),
1341 ((cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].numUe) * sizeof(RgUeUlAlloc)));
1345 /* Update PRB used for all GBR QCIs to scheduler */
1346 memcpy( &sfInfo->qcisUlPrbCnt[0],
1347 &cellCb->qcisUlPrbCnt[0],
1348 (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1349 /* clear the cellCb ul prb value */
1350 memset(&cellCb->qcisUlPrbCnt[0], 0,
1351 (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1355 rgGetPstToInst(&schPst, inst,cellCb->schInstMap.schInst);
1356 sfInfo->cellSapId = cellCb->schInstMap.cellSapId;
1357 //TODO: commented for compilation without SCH RgMacSchSfRecp(&schPst, sfInfo);
1362 * @brief Function handles allocation for common channels i.e. BCCH-BCH,
1363 * BCCH-DLSCH, PCCH-DLSCH.
1367 * Function : rgHndlCmnChnl
1369 * This function is invoked from RgSchMacSfAllocReq. This function handles
1370 * allocations made for common channels like BCCH and PCCH.
1373 * 1. If BCCH on BCH has been scheduled, send StatusIndication on RGU.
1374 * 2. If PCCH is scheduled, send StatusIndication on RGU.
1375 * 3. If BCCH on DLSCH has been scheduled and sndStatInd is TRUE, send
1376 * StatusIndication on RGU, else copy the bcch buffer onto the downlink
1380 * @param[in] RgCellCb *cell,
1381 * @param[in] CmLteTimingInfo timingInfo,
1382 * @param[in] RgInfCmnLcInfo *cmnLcInfo,
1383 * @param[in/out] RgErrInfo *err,
1388 static S16 rgHndlCmnChnl
1391 CmLteTimingInfo timingInfo,
1392 RgInfCmnLcInfo *cmnLcInfo,
1396 #if (ERRCLASS & ERRCLS_DEBUG)
1400 RgBcchDlschLcCb *bcch;
1401 #if (ERRCLASS & ERRCLS_DEBUG)
1404 #endif/*RGR_SI_SCH*/
1405 RguCStaIndInfo *staInd;
1407 Inst inst = cell->macInst - RG_INST_START;
1410 dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
1412 if(cmnLcInfo->bitMask & RGINF_BCH_INFO)
1415 #if (ERRCLASS & ERRCLS_DEBUG)
1416 if(NULLP == (bch = rgDBMGetBcchOnBch(cell)))
1420 if(cmnLcInfo->bchInfo.lcId != bch->lcId)
1426 if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1428 err->errCause = RGERR_TOM_MEM_EXHAUST;
1431 staInd->cellId = cell->cellId;
1432 staInd->rnti = RG_INVALID_RNTI;
1433 staInd->lcId = cmnLcInfo->bchInfo.lcId;
1434 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1435 /* ADD Changes for Downlink UE Timing Optimization */
1436 #ifdef LTEMAC_DLUE_TMGOPTMZ
1437 dlSf->remDatReqCnt++;
1439 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1444 /*Store the received BCH Data in the scheduled subframe*/
1445 dlSf->bch.tb = cmnLcInfo->bchInfo.pdu;
1446 #endif/*RGR_SI_SCH*/
1449 if(cmnLcInfo->bitMask & RGINF_PCCH_INFO)
1451 #if (ERRCLASS & ERRCLS_DEBUG)
1452 if(NULLP == (pcch = rgDBMGetPcch(cell)))
1456 if(cmnLcInfo->pcchInfo.lcId != pcch->lcId)
1462 dlSf->pcch.pdcch.rnti =
1463 cmnLcInfo->pcchInfo.rnti;
1464 dlSf->pcch.pdcch.dci =
1465 cmnLcInfo->pcchInfo.dciInfo;
1467 /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */
1468 dlSf->pcch.txPwrOffset = cmnLcInfo->pcchInfo.txPwrOffset;
1470 if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1472 err->errCause = RGERR_TOM_MEM_EXHAUST;
1475 staInd->cellId = cell->cellId;
1476 staInd->rnti = RG_INVALID_RNTI;
1477 staInd->lcId = cmnLcInfo->pcchInfo.lcId;
1478 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1479 /* ADD Changes for Downlink UE Timing Optimization */
1480 #ifdef LTEMAC_DLUE_TMGOPTMZ
1481 dlSf->remDatReqCnt++;
1483 /* for consolidated CmnStaInd calling below function from function
1484 * rgHndlSchedUe once CmnStaInd prepared for all UEs
1486 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1492 if(cmnLcInfo->bitMask & RGINF_BCCH_INFO)
1494 dlSf->bcch.pdcch.rnti =
1495 cmnLcInfo->bcchInfo.rnti;
1496 dlSf->bcch.pdcch.dci =
1497 cmnLcInfo->bcchInfo.dciInfo;
1499 /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */
1500 dlSf->bcch.txPwrOffset = cmnLcInfo->bcchInfo.txPwrOffset;
1504 (bcch=rgDBMGetBcchOnDlsch(cell,cmnLcInfo->bcchInfo.lcId)))
1508 if(TRUE == cmnLcInfo->bcchInfo.sndStatInd)
1510 RG_FREE_MSG(bcch->tb);
1511 if (rgAllocShrablSBuf (inst,(Data**)&staInd,
1512 sizeof(RguCStaIndInfo)) != ROK)
1514 err->errCause = RGERR_TOM_MEM_EXHAUST;
1517 staInd->cellId = cell->cellId;
1518 staInd->rnti = RG_INVALID_RNTI;
1519 staInd->lcId = cmnLcInfo->bcchInfo.lcId;
1520 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1521 /* ADD Changes for Downlink UE Timing Optimization */
1522 #ifdef LTEMAC_DLUE_TMGOPTMZ
1523 dlSf->remDatReqCnt++;
1525 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1532 SCpyMsgMsg(bcch->tb, RG_GET_MEM_REGION(rgCb[inst]),
1533 RG_GET_MEM_POOL(rgCb[inst]), &dlSf->bcch.tb);
1536 /*Store the received BCCH Data in the scheduled subframe*/
1537 dlSf->bcch.tb = cmnLcInfo->bcchInfo.pdu;
1538 #endif/*RGR_SI_SCH*/
1542 } /* end of rgHndlCmnChnl */
1545 * @brief Function for handling allocations for dedicated channels for a
1550 * Function : rgHndlSchdUe
1552 * This function shall be invoked whenever scheduler is done with the
1553 * allocations of dedicated channels for a subframe. Invoked by the function
1554 * RgSchMacSfAllocReq.
1556 * Processing steps :
1557 * 1. Loops through the list of UE's scheduled looking for the corresponding
1559 * 2. Finds the corresponding HARQ process.
1560 * 3. Invokes the DHM function to issue StatusIndications on RGU.
1563 * @param[in] RgCellCb *cell,
1564 * @param[in] CmLteTimingInfo timingInfo,
1565 * @param[in] RgInfUeInfo *ueInfo
1566 * @param[in/out] RgErrInfo *err
1571 static S16 rgHndlSchdUe
1574 CmLteTimingInfo timingInfo,
1575 RgInfUeInfo *ueInfo,
1581 if(NULLP == ueInfo->allocInfo)
1586 rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err);
1589 } /* end of rgHndlSchdUe */
1593 * @brief Function for handling Uplink allocations for Ue for a
1598 * Function : rgHndlUlUeInfo
1600 * @param[in] RgCellCb *cell,
1601 * @param[in] CmLteTimingInfo timingInfo,
1602 * @param[in] RgInfUlUeInfo *ueInfo
1607 static S16 rgHndlUlUeInfo
1610 CmLteTimingInfo timingInfo,
1611 RgInfUlUeInfo *ueInfo
1614 Inst inst = cell->macInst - RG_INST_START;
1620 ulSf = &cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)];
1622 /* rg003.301-MOD- Corrected the purifier memory leak */
1623 if (ulSf->numUe != ueInfo->numUes)
1625 if (ulSf->ueUlAllocInfo)
1627 rgFreeSBuf(inst,(Data **)&(ulSf->ueUlAllocInfo),
1628 ulSf->numUe * sizeof(RgUeUlAlloc));
1631 #ifdef XEON_SPECIFIC_CHANGES
1632 CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_FREE);
1633 CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_FREE, ulSf->numUe);
1635 ulSf->numUe = ueInfo->numUes;
1636 if((ulSf->ueUlAllocInfo == NULLP) && (ueInfo->numUes > 0))
1638 /* Allocate memory for ulAllocInfo */
1639 if((ret = rgAllocSBuf(inst,(Data**)&(cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)].
1640 ueUlAllocInfo), ueInfo->numUes * sizeof(RgUeUlAlloc))) != ROK)
1645 #ifdef XEON_SPECIFIC_CHANGES
1646 CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_ALLOC);
1647 CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_ALLOC, ueInfo->numUes);
1649 if (ulSf->ueUlAllocInfo != NULLP)
1651 for(idx = 0; idx < ueInfo->numUes; idx++)
1653 ulSf->ueUlAllocInfo[idx].rnti = ueInfo->ulAllocInfo[idx].rnti;
1654 ulSf->ueUlAllocInfo[idx].numPrb = ueInfo->ulAllocInfo[idx].numPrb;
1657 RGCPYTIMEINFO(timingInfo, ulSf->schdTime);
1659 } /* end of rgHndlUlUeInfo */
1662 * @brief Function for handling RaResp request received from scheduler to MAC
1666 * Function : rgTOMRlsSf
1668 * This function shall be invoked whenever scheduler is done with the
1669 * allocations of random access responses for a subframe.
1670 * This shall invoke RAM to create ueCbs for all the rapIds allocated and
1671 * shall invoke MUX to create RAR PDUs for raRntis allocated.
1674 * @param[in] Inst inst
1675 * @param[in] CmLteCellId cellId,
1676 * @param[in] CmLteTimingInfo timingInfo,
1677 * @param[in] RaRespInfo *rarInfo
1681 Void rgTOMRlsSf(Inst inst,RgDlSf *dlSf)
1686 if(dlSf->txDone == FALSE)
1688 DU_LOG("\nERROR --> MAC : SUBFRAME Not pushed to the PHY");
1690 if (dlSf->bch.tb != NULLP)
1692 RG_FREE_MSG(dlSf->bch.tb);
1694 if (dlSf->bcch.tb != NULLP)
1696 RG_FREE_MSG(dlSf->bcch.tb);
1698 if (dlSf->pcch.tb != NULLP)
1700 RG_FREE_MSG(dlSf->pcch.tb);
1703 rgTOMEmtcRlsSf(dlSf);
1705 for(idx=0; idx < dlSf->numRaRsp; idx++)
1707 RG_FREE_MSG(dlSf->raRsp[idx].rar);
1710 /* ADD Changes for Downlink UE Timing Optimization */
1711 #ifdef LTEMAC_DLUE_TMGOPTMZ
1712 dlSf->remDatReqCnt = 0;
1713 /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1715 dlSf->statIndDone = FALSE;
1717 if (dlSf->tbs.count)
1722 DU_LOG("\nERROR --> MAC : Error Stale TBs in Subframes TBS list\n");
1723 node = dlSf->tbs.first;
1726 hqP = (RgDlHqProcCb*)node->node;
1730 for(i=0;i< RG_MAX_TB_PER_UE;i++)
1732 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
1734 cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
1735 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
1736 DU_LOG("\nERROR --> MAC : rgTOMRlsSf:: hqP %p \n", (Void *)hqP);
1738 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
1743 /*arjun: check if dlSf laaTb list has to be freed???*/
1744 cmLListInit(&dlSf->tbs);
1745 dlSf->txDone = FALSE;
1751 * @brief Function is called by the scheduler once it has completed the
1752 * allocation for the subframe.
1756 * Function : rgHndlFlowCntrl
1757 * This function should fill and send Flow control
1761 * @param[in] Pst *cell
1762 * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation
1767 S16 rgHndlFlowCntrl(RgCellCb *cell,RgInfSfAlloc *sfInfo)
1769 RguFlowCntrlInd *flowCntrlInd;
1774 pst = &cell->rguDlSap->sapCfg.sapPst;
1775 /* flowCntrlInd is alloced in cell init time and will be re-used throughout */
1776 flowCntrlInd = cell->flowCntrlInd;
1777 flowCntrlInd->cellId = sfInfo->cellId;
1778 flowCntrlInd->numUes = sfInfo->flowCntrlInfo.numUes;
1780 for (ueIdx = 0; ueIdx < sfInfo->flowCntrlInfo.numUes; ueIdx++)
1782 flowCntrlInd->ueFlowCntrlInfo[ueIdx].ueId = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].ueId;
1783 flowCntrlInd->ueFlowCntrlInfo[ueIdx].numLcs = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].numLcs;
1785 for (lcIdx = 0; lcIdx < RGINF_MAX_NUM_DED_LC; lcIdx++)
1787 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId =
1788 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId;
1789 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt =
1790 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt;
1792 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl =
1793 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl;
1796 RgUiRguFlowCntrlInd(pst, cell->rguDlSap->sapCfg.spId,flowCntrlInd); /* TODO: Rishi confirm if the suId and pst pointer is correct */
1800 * @brief Function is called by the scheduler once it has completed the
1801 * allocation for the subframe.
1805 * Function : RgSchMacSfAllocReq
1807 * This function shall be invoked whenever scheduler is done with the
1808 * allocations of for a subframe. The sfInfo carries all the allocation
1809 * details for the common channels, RA responses and dedicated channel
1812 * Processing steps :
1813 * 1. Reset the information present in the downlink subframe that is
1815 * 2. Handle common channel allocations
1816 * 3. Handle RA Response allocations
1817 * 4. Handle dedicated channel allocations.
1819 * @param[in] Pst *pst
1820 * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation
1825 S16 RgSchMacSfAllocReq(Pst *pst,RgInfSfAlloc *sfInfo)
1830 volatile uint32_t startTime=0;
1834 RG_IS_INST_VALID(pst->dstInst);
1835 inst = pst->dstInst - RG_INST_START;
1837 SStartTask(&startTime, PID_MAC_SF_ALLOC_REQ);
1844 if((cell = rgCb[inst].cell) == NULLP)
1846 DU_LOG("\nERROR --> MAC : No cellCb found with cell");
1850 dlSf = &cell->subFrms[(sfInfo->timingInfo.slot % RG_NUM_SUB_FRAMES)];
1852 rgTOMRlsSf(inst,dlSf);
1853 dlSf->schdTime = sfInfo->timingInfo;
1856 rgLaaInitTbInfoLst(cell);
1859 /* Fix : syed Ignore Failure Returns and continue processing.
1860 * Incomplete processing results in state sync loss between MAC-SCH. */
1862 if(TRUE == cell->emtcEnable)
1864 rgEmtcHndl(cell, sfInfo);
1867 rgHndlCmnChnl(cell, sfInfo->timingInfo, &sfInfo->cmnLcInfo, &err);
1869 rgHndlRaResp(cell, sfInfo->timingInfo, &sfInfo->rarInfo, &err);
1872 #ifdef XEON_SPECIFIC_CHANGES
1873 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_B4_UE_SCHD);
1875 rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1876 #ifdef XEON_SPECIFIC_CHANGES
1877 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_UE_SCHD);
1879 rgLaaChkAndReqTbs(dlSf,cell, inst);
1882 rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1886 if(rgHndlUlUeInfo(cell, sfInfo->ulUeInfo.timingInfo,
1887 &sfInfo->ulUeInfo) != ROK)
1892 #ifdef XEON_SPECIFIC_CHANGES
1893 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_MEAS);
1895 /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1899 /* Added the handling for pushing down
1900 * TFU Data request in the retransmission only scenario.*/
1901 #ifdef LTEMAC_DLUE_TMGOPTMZ
1902 dlSf->statIndDone = TRUE;
1903 /* Fix [ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1905 if(!(dlSf->txDone) &&
1907 (TRUE == rgLaaChkAllRxTbs(dlSf)) &&
1909 (0 == dlSf->remDatReqCnt) && (dlSf->statIndDone) &&
1910 (RG_TIMEINFO_SAME(cell->crntTime, dlSf->schdTime)))
1912 /*This is the case of rettransmission, so no need
1913 * to wait for TTI Ind to push TFU Data Request. Send
1915 if (ROK != rgTOMUtlProcDlSf (dlSf, cell, &err))
1917 DU_LOG("\nERROR --> MAC : Unable to process downlink subframe for cell");
1918 err.errType = RGERR_ROM_DEDDATREQ;
1920 /* Mark this frame as sent */
1921 dlSf->txDone = TRUE;
1924 if (sfInfo->flowCntrlInfo.numUes > 0)
1926 rgHndlFlowCntrl(cell,sfInfo);
1929 SStopTask(startTime, PID_MAC_SF_ALLOC_REQ);
1931 } /* end of RgSchMacSfAllocReq */
1933 * @brief Handler for processing data indication recieved from PHY for UEs.
1937 * Function: rgTOMProcCrntiCEInDatInd
1939 * Handler for processing data indication recieved from PHY for UEs.
1941 * Invoked by: RgLiTfuDatInd of LIM
1944 * For each DataInfo recieved
1945 * - If received a CRNTI control element
1946 * - Check if a CCCH SDU is present, if it is return failure
1947 * - Check for the existence of UE, if its isnt present return failure.
1948 * - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1949 * primarily informs the scheduler about the data received and
1950 * generates Data indications towards the higher layer.
1952 * @param RgMacPdu *pdu,
1953 * @param RgUeCb *prevUeCb,
1954 * @param RgCellCb *cellCb,
1955 * @param TfuDatInfo *datInfo,
1956 * @param RgInfCeInfo *ceInfo
1961 static S16 rgTOMProcCrntiCEInDatInd
1966 TfuDatInfo *datInfo,
1967 RgInfCeInfo *ceInfo,
1971 RgUeCb *ueCb = NULLP;
1972 Inst inst = cellCb->macInst - RG_INST_START;
1985 ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
1989 DU_LOG("\nERROR --> MAC : RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
1993 prevUeCb = rgDBMGetUeCb (cellCb, ceInfo->ces.cRnti);
1994 if (prevUeCb == NULLP)
1996 DU_LOG("\nERROR --> MAC : RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
1999 DU_LOG("\nERROR --> MAC : CRNTI CE(%d) received through tmpCrnti(%d)",
2000 ceInfo->ces.cRnti, datInfo->rnti);
2001 rgDBMDelUeCbFromRachLst(cellCb, ueCb);
2002 rgRAMFreeUeCb(inst,ueCb);
2005 if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2007 if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2008 #endif /* LTEMAC_SPS */
2010 DU_LOG("\nERROR --> MAC : RNTI:%d Processing for MSG3 failed",datInfo->rnti);
2016 * @brief Handler for processing data indication recieved from PHY for UEs.
2020 * Function: rgTOMProcCCCHSduInDatInd
2022 * Handler for processing data indication recieved from PHY for UEs.
2024 * Invoked by: RgLiTfuDatInd of LIM
2027 * For each DataInfo recieved
2028 * - If only CCCH SDU is present
2029 * - Invoke rgTOMUtlProcMsg3 for further processing.
2030 * - If its a non-Msg3 PDU i.e. received outside of a RA procedure
2031 * - Retrieve the UeCB
2032 * - Validate that the received PDU contains only configured Logical
2034 * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
2035 * scheduler with the information of the received Data and generates
2036 * DatIndications towards the higher layers.
2038 * @param TfuDatIndInfo *datInd
2039 * @param RgMacPdu *pdu,
2040 * @param RgUeCb *prevUeCb,
2041 * @param RgCellCb *cellCb,
2042 * @param TfuDatInfo *datInfo,
2043 * @param RgInfCeInfo *ceInfo
2048 static S16 rgTOMProcCCCHSduInDatInd
2053 TfuDatInfo *datInfo,
2054 RgInfCeInfo *ceInfo,
2058 RgUeCb *ueCb = NULLP;
2059 Inst inst = cellCb->macInst - RG_INST_START;
2072 if (ceInfo->bitMask & RG_CRNTI_CE_PRSNT)
2074 DU_LOG("\nERROR --> MAC : CRNTI:%d Received MSG3 with CCCH",ceInfo->ces.cRnti);
2078 ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
2082 DU_LOG("\nERROR --> MAC : RNTI:%d Processing for MSG3 failed", datInfo->rnti);
2085 /* Fix: syed Drop any duplicate Msg3(CCCH Sdu) */
2086 if (ueCb->dl.hqEnt.numHqProcs)
2088 /* HqE is already initialized by a previuos Msg3 */
2089 DU_LOG("\nERROR --> MAC : RNTI:%d Processing for MSG3 failed. Duplicate "
2090 "MSG3 received. Dropping", datInfo->rnti);
2094 if(rgDHMHqEntInit(inst,&ueCb->dl.hqEnt,
2095 cellCb->maxDlHqProcPerUe) != ROK)
2097 DU_LOG("\nERROR --> MAC : RNTI:%d Harq Initialization failed ",
2101 DU_LOG("\nDEBUG --> MAC : CCCH SDU received through tmpCrnti(%d)",datInfo->rnti);
2103 if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2105 if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2106 #endif /* LTEMAC_SPS */
2108 DU_LOG("\nERROR --> MAC : RNTI:%d Processing for MSG3 failed",
2117 /** @brief This function captures the BSR value from Control Element
2118 * Info structure and updates the effective Buffer size into the
2119 * corresponding LCG ID.
2123 * Function: rgTOMUtlL2MStoreBufSz
2126 * - update/append the Data structure based on BSR type
2128 * @param [in] RgUeCb *ueCb
2129 * @param [in] RgInfCeInfo *ceInfo
2133 static S16 rgTOMUtlL2MStoreBufSz( RgUeCb *ueCb, RgInfCeInfo *ceInfo )
2138 if(ceInfo->bitMask & RG_TRUNC_BSR_CE_PRSNT)
2140 lcgId = ((ceInfo->ces.bsr.truncBsr >> 6) & 0x03);
2141 bsr = ceInfo->ces.bsr.truncBsr & 0x3F;
2142 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2144 else if(ceInfo->bitMask & RG_SHORT_BSR_CE_PRSNT)
2146 lcgId = ((ceInfo->ces.bsr.shortBsr >> 6) & 0x03);
2147 bsr = ceInfo->ces.bsr.shortBsr & 0x3F;
2148 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2151 else if(ceInfo->bitMask & RG_LONG_BSR_CE_PRSNT)
2153 ueCb->ul.lcgArr[0].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs1];
2154 ueCb->ul.lcgArr[1].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs2];
2155 ueCb->ul.lcgArr[2].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs3];
2156 ueCb->ul.lcgArr[3].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs4];
2159 } /* end of rgTOMUtlL2MStoreBufSz*/
2161 /** @brief : Compiles list of LCs received in UL data for DTCH RBs
2165 * @param [in] RgCellCb *cellCb
2166 * @param [in] RgUeCb *ueCb
2167 * @param [in] CmLteRnti rnti
2168 * @param [in] RgMacPdu *pdu
2174 static Void rgTOML2MCompileActiveLCs(RgCellCb *cellCb,RgUeCb *ueCb,RgMacPdu *pdu,RgInfCeInfo *ceInfo)
2181 node = pdu->sduLst.first;
2184 sdu = (RgMacSdu*)node->node;
2186 if ((ulLcCb = rgDBMGetUlDedLcCb(ueCb, sdu->lcId)), ulLcCb != NULLP)
2188 if (ulLcCb->lcgId != 0)
2190 ceInfo->bitMask |= RG_ACTIVE_LC_PRSNT;
2191 ceInfo->ulActLCs[ulLcCb->lcId - 1] = TRUE;
2202 /**********************************************************************
2205 **********************************************************************/