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 **********************************************************************/
31 static const char* RLOG_MODULE_NAME="MAC";
32 static int RLOG_FILE_ID=237;
33 static int RLOG_MODULE_ID=4096;
35 @brief This module does processing related to handling of lower interface APIs
36 invoked by PHY towards MAC
38 /* header include files -- defines (.h) */
39 #include "common_def.h"
40 #include "rgu.h" /* RGU defines */
41 #include "tfu.h" /* RGU defines */
42 #include "lrg.h" /* layer management defines for LTE-MAC */
43 #include "crg.h" /* layer management defines for LTE-MAC */
44 #include "rg_sch_inf.h" /* layer management defines for LTE-MAC */
45 #include "rg.h" /* defines and macros for MAC */
46 #include "rg_env.h" /* defines and macros for MAC */
47 #include "rg_err.h" /* defines and macros for MAC */
48 #include "rgm.h" /* layer management typedefs for MAC */
50 /* header/extern include files (.x) */
51 #include "crg.x" /* CRG interface typedefs */
52 #include "rgu.x" /* RGU types */
53 #include "tfu.x" /* RGU types */
54 #include "lrg.x" /* layer management typedefs for MAC */
55 #include "rg_sch_inf.x" /* SCH interface typedefs */
56 #include "rg_prg.x" /* PRG interface typedefs */
57 #include "rgm.x" /* layer management typedefs for MAC */
58 #include "rg.x" /* typedefs for MAC */
59 #ifdef MAC_RLC_UL_RBUF
64 /* ADD Changes for Downlink UE Timing Optimization */
65 #ifndef LTEMAC_DLUE_TMGOPTMZ
66 static S16 rgTOMUtlProcDlSf ARGS(( RgDlSf *dlSf, RgCellCb *cellCb,
69 S16 rgTOMUtlProcDlSf ARGS((RgDlSf *dlSf, RgCellCb *cellCb,
72 static S16 rgTOMProcCrntiCEInDatInd ARGS((
81 static S16 rgTOMProcCCCHSduInDatInd ARGS((
96 S16 RgUiRguFlowCntrlInd(Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd);
98 S16 rgEmtcHndl(RgCellCb *cell,RgInfSfAlloc *sfInfo);
99 S16 rgTOMEmtcUtlFillDatReqPdus(TfuDatReqInfo *datInfo, RgDlSf *dlSf, RgCellCb *cell, RgErrInfo *err);
100 Void rgTOMEmtcRlsSf(RgDlSf *dlSf);
103 static Void rgTOML2MCompileActiveLCs ARGS
110 static S16 rgTOMUtlL2MStoreBufSz ARGS
116 static S16 rgTomUtlPrepareL2MUlThrpInfo ARGS
120 RgRguDedDatInd *dDatInd
124 /* The below table takes lower values of BSR Range for a BSR value
125 This is to ensure that outstanding can be decrease to zero upon reception of
126 TB, which is not guaranteed if higher Range values are used */
127 /* Note: taking value 10 for BSR index 1 */
128 #ifndef MAC_5GTF_UPDATE
129 static uint32_t rgLwrBsrTbl[64] = {
130 0, 10, 10, 12, 14, 17, 19, 22, 26,
131 31, 36, 42, 49, 57, 67, 78, 91,
132 107, 125, 146, 171, 200, 234, 274, 321,
133 376, 440, 515, 603, 706, 826, 967, 1132,
134 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995,
135 4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099,
136 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759,
137 58255, 68201, 79846, 93479, 109439, 128125, 150000
141 static uint32_t rgLwrBsrTbl[64] = {
142 0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181,223,274,337,414,
143 509,625,769,945,1162,1429,1757,2161,2657,3267,4017,4940,6074,7469,
144 9185,11294,13888,17077,20999,25822,31752,39045,48012,59039,72598,
145 89272,109774,134986,165989,204111,250990,308634,379519,466683,
146 573866,705666,867737,1067031,1312097,1613447,1984009,2439678,
154 #define RG_TOM_INF_ALLOC(_pdu, _size, _dataPtr, _ret) {\
155 _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
158 /* global variables */
159 uint32_t rgUlrate_tfu;
161 uint32_t grgUlrate_tfu;
164 /** @brief This function fills the PDSCH data of a downlink subframe
168 * Function: rgTOMUtlFillDatReqPdus
171 * - Fill BCCH on DLSCH data using datInfo
172 * - Fill PCCH on DLSCH data using datInfo
173 * - Fill Dedicated data on DLSCH data using datInfo
174 * - Fill RA RSP data using datInfo
176 * @param [out] TfuDatReqInfo *datInfo
177 * @param [in] RgDlSf *dlSf
178 * @param [in] RgCellCb *cellCb
179 * @param [out] RgErrInfo *err
184 static S16 rgTOMUtlFillDatReqPdus (TfuDatReqInfo *datInfo,RgDlSf *dlSf,RgCellCb *cellCb, RgErrInfo *err)
187 TfuDatReqPduInfo *datReq=NULLP;
188 /* Moving node declaration to limited scope for optimization */
191 Inst inst = cellCb->macInst - RG_INST_START;
194 /* first lets send the BCCH data down to PHY */
195 if (dlSf->bcch.tb != NULLP)
197 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
198 &(datInfo->memCp))) != ROK)
200 err->errCause = RGERR_TOM_MEM_EXHAUST;
201 RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion ");
204 #ifdef TFU_ALLOC_EVENT_NO_INIT
208 datReq->tbInfo[0].lchInfo[0].mBuf[0]=NULLP;
211 datReq->rnti = RG_SI_RNTI;
212 datReq->dciInfo = dlSf->bcch.pdcch.dci;
213 /* Note: SCpyMsgMsg is not done since free of unsent buffer
214 * has been taken care through cell delete by invoking rgTomRlsSf
216 datReq->nmbOfTBs = 1;
218 datReq->mBuf[0] = dlSf->bcch.tb;
220 SFndLenMsg((Buffer *)dlSf->bcch.tb, &(datReq->tbInfo[0].tbSize));
221 datReq->tbInfo[0].tbPres = TRUE;
222 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->bcch.tb;
223 datReq->tbInfo[0].numLch = 1;
224 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
226 #ifdef TFU_ALLOC_EVENT_NO_INIT
227 datReq->tbInfo[1].tbPres = FALSE;
228 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
231 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
232 datReq->lnk.node = (PTR)datReq;
234 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
235 datReq->txPwrOffset = dlSf->bcch.txPwrOffset;
237 /* Setting the pointer to NULL post transmission */
238 dlSf->bcch.tb = NULLP;
241 if (dlSf->pcch.tb != NULLP)
243 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
244 &(datInfo->memCp))) != ROK)
246 err->errCause = RGERR_TOM_MEM_EXHAUST;
247 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion CRNTI:%d",datReq->rnti);
250 #ifdef TFU_ALLOC_EVENT_NO_INIT
255 datReq->rnti = RG_P_RNTI;
256 datReq->dciInfo = dlSf->pcch.pdcch.dci;
257 datReq->nmbOfTBs = 1;
259 datReq->mBuf[0] = dlSf->pcch.tb;
261 SFndLenMsg((Buffer *)dlSf->pcch.tb, &datReq->tbInfo[0].tbSize);
262 datReq->tbInfo[0].tbPres = TRUE;
263 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->pcch.tb;
264 #ifdef TFU_ALLOC_EVENT_NO_INIT
265 datReq->tbInfo[1].tbPres = FALSE;
266 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
268 datReq->tbInfo[0].numLch = 1;
269 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
271 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
272 datReq->lnk.node = (PTR)datReq;
274 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
275 datReq->txPwrOffset = dlSf->pcch.txPwrOffset;
277 dlSf->pcch.tb = NULLP;
280 for(idx=0; idx < dlSf->numRaRsp; idx++)
282 if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
283 &(datInfo->memCp))) != ROK)
285 err->errCause = RGERR_TOM_MEM_EXHAUST;
286 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion CRNTI:%d",
290 #ifdef TFU_ALLOC_EVENT_NO_INIT
295 datReq->rnti = dlSf->raRsp[idx].pdcch.rnti;
296 datReq->dciInfo = dlSf->raRsp[idx].pdcch.dci;
297 datReq->nmbOfTBs = 1;
299 datReq->mBuf[0] = dlSf->raRsp[idx].rar;
301 SFndLenMsg((Buffer *)dlSf->raRsp[idx].rar, &datReq->tbInfo[0].tbSize);
302 datReq->tbInfo[0].tbPres = TRUE;
303 datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->raRsp[idx].rar;
304 #ifdef TFU_ALLOC_EVENT_NO_INIT
305 datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP;
306 datReq->tbInfo[1].tbPres = FALSE;
308 datReq->tbInfo[0].numLch = 1;
309 datReq->tbInfo[0].lchInfo[0].numPdu = 1;
310 // prc_trace_format_string(0x40,3,"UE Id=(%d) tbSz=(%d)",datReq->rnti, datReq->tbInfo[0].tbSize);
312 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
313 datReq->lnk.node = (PTR)datReq;
315 /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */
316 datReq->txPwrOffset = dlSf->raRsp[idx].txPwrOffset;
318 dlSf->raRsp[idx].rar = NULLP;
321 /* Fill Dedicated UE data */
322 if (dlSf->tbs.count != 0)
325 while (dlSf->tbs.first)
327 node = dlSf->tbs.first;
328 hqCb = (RgDlHqProcCb*)node->node;
329 if ((ret = rgDHMSndDatReq (cellCb, dlSf, datInfo, hqCb, err)) != ROK)
331 RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,
332 "DHM unable to fill DATA request");
333 err->errType = RGERR_TOM_TTIIND;
340 } /* end of rgTOMUtlFillDatReqPdus*/
342 /** @brief This function does all the processing related to a single downlink
347 * Function: rgTOMUtlProcDlSf
350 * - collate control data for all UEs and send to PHY
351 * - collate data buffers for all UEs and send to PHY
353 * @param [in] RgDlSf *dlSf
354 * @param [in] RgCellCb *cellCb
355 * @param [out] RgErrInfo *err
358 /* ADD Changes for Downlink UE Timing Optimization */
359 #ifndef LTEMAC_DLUE_TMGOPTMZ
360 static S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
362 S16 rgTOMUtlProcDlSf(RgDlSf *dlSf,RgCellCb *cellCb,RgErrInfo *err)
366 TfuDatReqInfo *datInfo;
367 Inst inst = cellCb->macInst - RG_INST_START;
370 /* Fill Data Request Info from scheduler to PHY */
371 if ((ret = rgAllocEventMem(inst,(Ptr *)&datInfo,
372 sizeof(TfuDatReqInfo))) != ROK)
374 RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to Allocate TfuDatReqInfo");
379 cmLListInit(&datInfo->pdus);
381 RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DELTA);
383 RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DLDATA_DLDELTA);
385 datInfo->cellId = cellCb->cellId;
386 if((0 == (datInfo->timingInfo.sfn % 30)) && (0 == datInfo->timingInfo.slot))
388 //printf("5GTF_CHECK rgTOMUtlProcDlSf dat (%d : %d)\n", datInfo->timingInfo.sfn, datInfo->timingInfo.slot);
390 #ifdef TFU_ALLOC_EVENT_NO_INIT
391 datInfo->bchDat.pres = 0;
395 if (dlSf->bch.tb != NULLP)
397 datInfo->bchDat.pres = PRSNT_NODEF;
398 datInfo->bchDat.val = dlSf->bch.tb;
399 dlSf->bch.tb = NULLP;
402 /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
403 if ((ret = rgTOMEmtcUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
405 RG_FREE_MEM(datInfo);
409 /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */
410 if ((ret = rgTOMUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK)
412 RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to send data for cell");
413 RG_FREE_MEM(datInfo);
416 if((datInfo->pdus.count) || (datInfo->bchDat.pres == TRUE))
418 /* sending the data to Phy */
419 //if (rgLIMTfuDatReq(inst,datInfo) != ROK)
421 RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to send data info for cell");
426 /* Nothing to send: free the allocated datInfo */
427 RG_FREE_MEM(datInfo);
435 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
436 * with the SubHeaders list and the values of the Control elements.
440 * Function: rgTOMUtlAllocPduEvnt
443 * @param[in] Inst inst
444 * @param [out] RgMacPdu **pdu
450 static S16 rgTOMUtlAllocPduEvnt (Inst inst,RgMacPdu **pdu)
454 RgUstaDgn dgn; /* Alarm diagnostics structure */
455 volatile uint32_t startTime=0;
458 evntMem.region = rgCb[inst].rgInit.region;
459 evntMem.pool = rgCb[inst].rgInit.pool;
462 SStartTask(&startTime, PID_TOMUTL_CMALLCEVT);
464 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
465 MS_BUF_ADD_ALLOC_CALLER();
468 if (cmAllocEvnt (sizeof (RgMacPdu), RG_BLKSZ, &evntMem, (Ptr*)pdu) != ROK)
470 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
471 rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
472 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
473 RLOG0(L_ERROR,"Allocation of DUX event failed");
478 SStopTask(startTime, PID_TOMUTL_CMALLCEVT);
483 /** @brief This function frees up the RgMacPdu structure that has been
484 * populated by demux.
488 * Function: rgTOMUtlFreePduEvnt
489 * - Function frees up the RgMacPdu structure, in case of error it shall
490 * free up the buffer's present in the different sdu.
493 * @param [in] Inst inst
494 * @param [in] RgMacPdu *pdu
495 * @param [in] Bool *error
498 static Void rgTOMUtlFreePduEvnt( RgMacPdu *pdu,Bool error)
504 /* Steps of freeing up the PDU.
505 * 1. loop through the subHdrLst and free up all the buffers.
506 * 2. free up the whole event
508 if ((error == TRUE) && (pdu->sduLst.count > 0))
510 node = pdu->sduLst.first;
513 sdu = (RgMacSdu*)node->node;
514 RG_FREE_MSG(sdu->mBuf);
520 } /* end of rgTOMUtlFreePduEvnt */
522 /** @brief This function allocates the RgMacPdu that will be populated by DEMUX
523 * with the SubHeaders list and the values of the Control elements.
527 * Function: rgTOMInfAllocPduEvnt
530 * @param [in] Inst inst
531 * @param [out] RgMacPdu **pdu
537 static S16 rgTOMInfAllocPduEvnt (Inst inst,RgInfSfDatInd **sfInfo)
541 RgUstaDgn dgn; /* Alarm diagnostics structure */
542 volatile uint32_t startTime=0;
545 evntMem.region = rgCb[inst].rgInit.region;
546 evntMem.pool = rgCb[inst].rgInit.pool;
549 SStartTask(&startTime, PID_TOMINF_CMALLCEVT);
551 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
552 MS_BUF_ADD_ALLOC_CALLER();
554 if (cmAllocEvnt (sizeof (RgInfSfDatInd), RG_BLKSZ, &evntMem, (Ptr*)sfInfo) != ROK)
556 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
557 rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL,
558 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
559 RLOG0(L_ERROR,"Allocation failed");
564 SStopTask(startTime, PID_TOMINF_CMALLCEVT);
569 /** @brief This function frees up the RgMacPdu structure that has been
570 * populated by demux.
574 * Function: rgTOMInfFreePduEvnt
575 * - Function frees up the RgMacPdu structure, in case of error it shall
576 * free up the buffer's present in the different sdu.
579 * @param [in] RgMacPdu *pdu
580 * @param [in] Bool *error
583 static Void rgTOMInfFreePduEvnt(RgInfSfDatInd *sfInfo)
588 } /* end of rgTOMUtlFreePduEvnt */
592 /** @brief This function performs the preparation of information needed to set
593 * L2M Scheduled UL Throughput Information for a particular UE.
597 * Function: rgTomUtlPrepareL2MUlThrpInfo
598 * This function performs the preparation of information needed to set
599 * L2M Scheduled UL Throughput Information for a particular UE.
603 * @param [in] RgCellCb *cellCb
604 * @param [in] RgUeCb *ueCb
605 * @param [out] RgRguDedDatInd *dDatInd
608 static S16 rgTomUtlPrepareL2MUlThrpInfo(RgCellCb *cellCb,RgUeCb *ueCb,RgRguDedDatInd *dDatInd)
614 dDatInd->burstInd = RGU_L2M_UL_BURST_END;
615 for(loop=0;loop<dDatInd->numLch;loop++)
617 lcId=dDatInd->lchData[loop].lcId;
620 lcgId = ueCb->ul.lcCb[lcId - 1].lcgId;
621 if(ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs > 0)
623 dDatInd->burstInd = RGU_L2M_UL_BURST_START;
634 /** @brief This function is called by rgTOMDatInd. This function invokes the
635 * scheduler with the information of the received Data and any Control Elements
636 * if present. Also it generates Data indications towards the higher layers.
643 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
645 * - If UE exists then update the Schduler with any MAC CEs if present.
646 * - Invoke RAM module to do Msg3 related processing rgRAMProcMsg3
647 * - Loop through the SDU subheaders and invoke either a common data
648 * indication (rgUIMSndCmnDatInd) or dedicated data indication
649 * (rgUIMSndDedDatInd) towards the higher layers.
651 * @param [in] RgCellCb *cellCb
652 * @param [in] RgUeCb *ueCb
653 * @param [in] CmLteRnti rnti
654 * @param [in] RgMacPdu *pdu
655 * @param [out] uint32_t *lcgBytes
665 static S16 rgTOMUtlProcMsg
676 #else /* LTEMAC_SPS */
677 static S16 rgTOMUtlProcMsg
687 Inst inst = cellCb->macInst - RG_INST_START;
689 RgRguCmnDatInd *cDatInd;
690 RgRguDedDatInd *dDatInd;
697 // RgInfSpsRelInfo relInfo;
704 uint16_t totalBytesRcvd = 0;
705 uint16_t sduLen[RGU_MAX_LC] = {0};
706 uint8_t qciVal[RGU_MAX_LC] = {0};
713 /* Moved outside of LTE_L2_MEAS
714 * scope as this pointer will now be used to
715 * check for valid Logical Channel ID
737 if(pdu->sduLst.first)
739 sdu = (RgMacSdu*)(pdu->sduLst.first->node);
741 if ((sdu->lcId == RG_CCCH_LCID))
743 /* code for common channel dat indications */
744 if ((ret = rgAllocShrablSBuf (inst,(Data**)&cDatInd, sizeof(RgRguCmnDatInd))) != ROK)
748 cDatInd->cellId = cellCb->cellId;
749 cDatInd->rnti = ueCb->ueId;
750 /* rg001.101: Corrected lcId value for common data indication */
751 cDatInd->lcId = cellCb->ulCcchId;
752 cDatInd->pdu = sdu->mBuf;
753 SFndLenMsg (sdu->mBuf, &ccchSz);
754 /* Fix : syed Contention resolution ID copy should consider only
755 * 6 bytes of information from sdu->mBuf. Incase of CCCH sdu for reest
756 * message/psuedo reest message, ccchSz can go beyond 6 and can corrupt
757 * other fields of ueCb. */
758 if (ccchSz >= RG_CRES_LEN)
760 SCpyMsgFix (sdu->mBuf, (MsgLen)0, RG_CRES_LEN, ueCb->contResId.resId,
763 #ifdef XEON_SPECIFIC_CHANGES
764 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);
767 rgUIMSndCmnDatInd(inst,cellCb->rguUlSap,cDatInd);
769 } /* end of common channel processing */
771 if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
777 elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
782 dDatInd = (RgRguDedDatInd *)elem;
783 memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
785 dDatInd->cellId = cellCb->cellId;
786 dDatInd->rnti = ueCb->ueId;
790 ulSf = &cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)];
791 if(ulSf->ueUlAllocInfo != NULLP)
793 for(idx1 = 0; idx1 < ulSf->numUe; idx1++)
795 if(ulSf->ueUlAllocInfo[idx1].rnti == ueCb->ueId)
797 numPrb = ulSf->ueUlAllocInfo[idx1].numPrb;
803 node = pdu->sduLst.first;
806 sdu = (RgMacSdu*)node->node;
808 ulLcCb = rgDBMGetUlDedLcCb (ueCb, sdu->lcId);
812 RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId,"Unconfigured LCID:%d CRNTI:%d"
813 ,sdu->lcId,ueCb->ueId);
814 /* ccpu00128443: Fix for memory leak */
815 /* Fix : syed Neccessary to set sdu->mBuf = NULLP */
816 RG_FREE_MSG(sdu->mBuf);
820 #ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */
822 S16 rlcProcDlStatusPdu(Pst *udxPst,SuId suId,
823 CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu);
825 if(ROK == rlcProcDlStatusPdu(&(cellCb->rguDlSap->sapCfg.sapPst),
826 cellCb->rguDlSap->sapCfg.suId,
827 cellCb->cellId,ueCb->ueId,sdu->lcId,sdu->mBuf))
829 RG_FREE_MSG(sdu->mBuf);
836 /* ccpu00116477- Fixed the rgUIMSndDedDatInd condition when we receive 11 sdus in the
837 * list we are losing 11th sdu and sending the first 10 sdus again which
838 * is causing the duplicate packets and eNB crashing due to access
839 * of the freed memory */
840 if (dDatInd->numLch >= RGU_MAX_LC)
842 if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
844 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
845 "Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
849 if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK)
854 elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC);
859 dDatInd = (RgRguDedDatInd *)elem;
860 memset(dDatInd, 0x00, sizeof(RgRguDedDatInd));
862 dDatInd->cellId = cellCb->cellId;
863 dDatInd->rnti = ueCb->ueId;
866 dDatInd->lchData[dDatInd->numLch].lcId = sdu->lcId;
867 dDatInd->lchData[dDatInd->numLch].pdu.mBuf[dDatInd->lchData[dDatInd->numLch].pdu.numPdu] = sdu->mBuf;
868 dDatInd->lchData[dDatInd->numLch].pdu.numPdu++;
869 lcgId = ulLcCb->lcgId;
870 SFndLenMsg(sdu->mBuf, &bufSz);
874 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs -= bufSz;
877 //if ((lcgBytes != NULLP) && (ueCb->ul.lcgArr[lcgId].isGbr == TRUE))
878 if (lcgBytes != NULLP)
880 lcgBytes[lcgId] += bufSz;
885 /* Check if data has come on SPS LC */
886 /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */
887 if (ueCb->ul.spsLcId[sdu->lcId-1] == TRUE)
889 ueCb->ul.spsDatRcvd++;
894 /* Data rcvd on CRNTI*/
895 /* Retrieve the LCG ID of the LCID*/
896 /* SPS LCG has data whose size > SID Size */
897 /* Activate SPS if data recvd on SPS LCID and size > SID Packet Size */
898 if((ueCb->ul.spsLcId[sdu->lcId-1] == TRUE) &&
899 (sdu->len > RG_SPS_SID_PACKET_SIZE))
901 *spsToBeActvtd = TRUE;
909 if(cellCb->qciArray[ulLcCb->qci].mask == TRUE)
911 sduLen[ulLcCb->qci] = sdu->len;
912 totalBytesRcvd += sdu->len;
913 qciVal[ulLcCb->qci] = ulLcCb->qci;
917 } /* end of while for SubHeaders */
919 for(idx2 = 0; idx2 < RGU_MAX_LC; idx2++)
921 if((cellCb->qciArray[qciVal[idx2]].mask == TRUE) &&
924 cellCb->qciArray[qciVal[idx2]].prbCount +=
925 ((numPrb * sduLen[idx2]) / totalBytesRcvd);
929 if(totalBytesRcvd > 0 && qciVal[idx2] > 0)
931 RG_UPD_GBR_PRB(cellCb, qciVal[idx2], ((numPrb * sduLen[idx2])/totalBytesRcvd));
936 /*Added for explicit release - start*/
939 if(isSpsRnti && dDatInd && dDatInd->numLch)
941 if(ueCb->ul.spsDatRcvd != 0)
943 ueCb->ul.explRelCntr = 0;
944 ueCb->ul.spsDatRcvd = 0;
948 ueCb->ul.explRelCntr++;
949 if (ueCb->ul.explRelCntr == ueCb->ul.explRelCnt)
951 ueCb->ul.explRelCntr = 0;
952 /* Indicate scheduler for explicit release */
953 memset(&schPst1, 0, sizeof(Pst));
954 rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
955 //TODO: commented for compilation without SCH
957 relInfo.cellSapId = cellCb->schInstMap.cellSapId;
958 relInfo.cRnti = ueCb->ueId;
959 relInfo.isExplRel = TRUE;
960 /* Release indicator is called now through the matrix in the function below */
961 //TODO: commented for compilation without SCH RgMacSchSpsRel( &schPst1, &relInfo );
963 ueCb->ul.implRelCntr = 0;
970 if(ueCb->ul.spsDatRcvd != 0)
972 //ueCb->ul.implRelCntr = 0;
973 ueCb->ul.explRelCntr = 0;
974 ueCb->ul.spsDatRcvd = 0;
978 /*Added for explicit release - end */
980 if((dDatInd) && (dDatInd->numLch))
983 rgTomUtlPrepareL2MUlThrpInfo(cellCb, ueCb,dDatInd);
985 RG_CALC_TTI_CNT(cellCb, dDatInd->ttiCnt);
987 if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK)
989 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
990 "Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId);
995 else if((dDatInd) && (0 == dDatInd->numLch))
997 /* Free the memory allocated for dDatInd if we
998 * have no valid LCH PDU to send to RLC.*/
999 rgFreeSharableSBuf(inst,(Data **)&dDatInd,sizeof(RgRguDedDatInd));
1005 /** @brief This function frees up the RgMacPdu structure that has been
1006 * populated by demux.
1010 * Function: rgTOMUtlInsSchInfo
1011 * - Function frees up the RgMacPdu structure, in case of error it shall
1012 * free up the buffer's present in the different sdu.
1015 * @param [in] RgMacPdu *pdu
1016 * @param [in] Bool *error
1020 static S16 rgTOMUtlInsSchInfo
1023 RgInfSfDatInd *sfInfo,
1024 RgInfCeInfo *ceInfo,
1031 static S16 rgTOMUtlInsSchInfo
1034 RgInfSfDatInd *sfInfo,
1035 RgInfCeInfo *ceInfo,
1042 RgInfUeDatInd *ueInfo;
1047 RG_TOM_INF_ALLOC(sfInfo, sizeof(RgInfUeDatInd), ueInfo, ret);
1054 ueInfo->rnti = rnti;
1056 ueInfo->ceInfo = *ceInfo;
1057 ueInfo->ueLstEnt.node = (PTR)ueInfo;
1058 for (lcgId = 1, idx = 0; lcgId < RGINF_MAX_LCG_PER_UE; lcgId++)
1060 if (lcgBytes[lcgId] != 0)
1062 /* Only GBR bytes */
1063 ueInfo->lcgInfo[idx].lcgId = lcgId;
1064 ueInfo->lcgInfo[idx++].bytesRcvd = lcgBytes[lcgId];
1065 lcgBytes[lcgId] = 0;
1068 cmLListAdd2Tail(&sfInfo->ueLst, &ueInfo->ueLstEnt);
1070 } /* end of rgTOMUtlInsSchInfo */
1074 * @brief Handler for processing data indication recieved from PHY for UEs.
1078 * Function: rgTOMDatInd
1080 * Handler for processing data indication recieved from PHY for UEs.
1082 * Invoked by: RgLiTfuDatInd of LIM
1085 * For each DataInfo recieved
1086 * - Validate the information received and retrieve cellCb
1087 * Validate cellId, rnti
1088 * - Call De-Mux module to decode the data rgDUXDemuxData
1089 * - If received a CRNTI control element
1090 * - Check if a CCCH SDU is present, if it is return failure
1091 * - Check for the existence of UE, if its isnt present return failure.
1092 * - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1093 * primarily informs the scheduler about the data received and
1094 * generates Data indications towards the higher layer.
1095 * - If only CCCH SDU is present
1096 * - Invoke rgTOMUtlProcMsg3 for further processing.
1097 * - If its a non-Msg3 PDU i.e. received outside of a RA procedure
1098 * - Retrieve the UeCB
1099 * - Validate that the received PDU contains only configured Logical
1101 * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
1102 * scheduler with the information of the received Data and generates
1103 * DatIndications towards the higher layers.
1105 * @param [in] Inst inst
1106 * @param[in] TfuDatIndInfo *datInd
1111 S16 rgTOMDatInd(Inst inst, TfuDatIndInfo *datInd)
1116 RgUeCb *prevUeCb = NULLP;
1119 RgInfSfDatInd *sfInfo;
1123 TfuDatInfo *datInfo;
1127 Bool isSpsRnti=FALSE;
1129 // RgInfSpsRelInfo relInfo;
1130 Bool spsToBeActvtd = FALSE;
1131 uint16_t sduSize = 0;
1133 uint32_t lcgBytes[RGINF_MAX_LCG_PER_UE];
1136 #ifdef STUB_TTI_HANDLING_5GTF
1137 node = datInd->datIndLst.first;
1138 for (;node; node=node->next)
1140 datInfo = (TfuDatInfo*)node->node;
1143 SFndLenMsg(datInfo->mBuf, &len);
1144 rgUlrate_tfu += len;
1145 if (rgUlrate_tfu > 100000)
1147 printf("Sowmya:rgTOMDatInd datInfo->mBuf len =%d rgUlrate_tfu=%d",len,rgUlrate_tfu);
1155 memset(&lcgBytes, 0, sizeof(lcgBytes));
1157 tfuSap = &(rgCb[inst].tfuSap);
1159 cellCb = rgCb[inst].cell;
1160 if((cellCb == NULLP) ||
1161 (cellCb->cellId != datInd->cellId))
1164 RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to get the cellCb for cell");
1167 /* Avoiding memset as all the fields are getting initialized further */
1169 if (rgTOMInfAllocPduEvnt (inst,&sfInfo) != ROK)
1171 err.errType = RGERR_TOM_DATIND;
1172 RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to Allocate PDU for DUX cell");
1173 node = datInd->datIndLst.first;
1176 cmLListInit(&sfInfo->ueLst);
1177 sfInfo->cellId = datInd->cellId;
1178 sfInfo->timingInfo = datInd->timingInfo;
1179 slot = datInd->timingInfo.slot;
1181 node = datInd->datIndLst.first;
1182 for (;node; node=node->next)
1184 datInfo = (TfuDatInfo*)node->node;
1186 //uint32_t ulrate_tfu;
1188 SFndLenMsg(datInfo->mBuf, &len);
1189 #ifdef STUB_TTI_HANDLING_5GTF
1190 // printf("Sowmya:rgTOMDatInd datInfo->mBuf len =%d",len);
1192 rgUlrate_tfu += len;
1194 grgUlrate_tfu += len;
1197 #ifdef STUB_TTI_HANDLING_5GTF
1198 rgLIMUtlFreeDatIndEvnt(datInd,TRUE);
1200 /* We shall call De-Mux to process the received buffer. We shall try and find
1201 * out the RaCb based on the following -
1202 * 1. If the incoming PDU contained a CCCH SDU i.e. this is message 3.
1203 * 2. If the incoming PDU contained a CRNTI control element, i.e. we should
1204 * have a ueCb also for this
1206 /* Lets allocate the event that needs to be passed to DUX */
1207 if (rgTOMUtlAllocPduEvnt (inst,&pdu) != ROK)
1209 err.errType = RGERR_TOM_DATIND;
1210 RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to Allocate PDU for DUX cell");
1211 rgTOMInfFreePduEvnt (sfInfo);
1215 if ((ret = rgDUXDemuxData (inst,pdu, &ceInfo,
1216 &datInfo->mBuf, &err)) != ROK)
1219 /* Fix: sriky memory corruption precautions */
1220 rgTOMUtlFreePduEvnt (pdu, TRUE);
1221 err.errType = RGERR_TOM_DATIND;
1222 RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"DUX processing failed");
1223 tfuSap->sapSts.numPduDrop++;
1226 /* It could be that a non-msg3 pdu contains a CRNTI Control element. We
1227 * should check for CRNTI CE and if it exists the UECb must exist, also an
1228 * if the CRNTI in the CE and the one with which the message came in are
1229 * different we shall look for an raCb as well.
1232 if (ceInfo.bitMask & RG_CCCH_SDU_PRSNT)
1234 ret = rgTOMProcCCCHSduInDatInd(pdu, prevUeCb, \
1235 cellCb, datInfo, &ceInfo, slot);
1238 rgTOMUtlFreePduEvnt (pdu, TRUE);
1239 err.errType = RGERR_TOM_DATIND;
1240 tfuSap->sapSts.numPduDrop++;
1243 } /* end of Msg3 processing */
1245 else if (ceInfo.bitMask & RG_CRNTI_CE_PRSNT)
1247 ret = rgTOMProcCrntiCEInDatInd(pdu, prevUeCb, \
1248 cellCb, datInfo, &ceInfo, slot);
1251 rgTOMUtlFreePduEvnt (pdu, TRUE);
1252 err.errType = RGERR_TOM_DATIND;
1253 tfuSap->sapSts.numPduDrop++;
1257 } /* end of CRNTI based message */
1260 ueCb = rgDBMGetUeCb (cellCb, datInfo->rnti);
1264 /* Try getting the UE using SPS-RNTI. */
1265 ueCb = rgDBMGetSpsUeCb (cellCb, datInfo->rnti);
1269 /* Increment implrelCntr for an empty transmission */
1270 if (pdu->sduLst.count == 0)
1272 ueCb->ul.implRelCntr++;
1273 if (ueCb->ul.implRelCntr == ueCb->ul.implRelCnt)
1275 /* Indicate scheduler for implicit release */
1276 memset(&schPst1, 0, sizeof(Pst));
1277 rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst);
1279 ueCb->ul.implRelCntr = 0;
1280 ueCb->ul.explRelCntr = 0;
1282 relInfo.cellSapId = cellCb->schInstMap.cellSapId;
1283 relInfo.cRnti = ueCb->ueId;
1284 relInfo.isExplRel= FALSE;
1285 //TODO: commented for compilation without SCH RgMacSchSpsRel(&schPst1, &relInfo);
1291 /* Reset the implrelCntr */
1292 ueCb->ul.implRelCntr = 0;
1298 /* Perform failure if ueCb is still NULLP */
1299 rgTOMUtlFreePduEvnt (pdu, TRUE);
1300 err.errType = RGERR_TOM_DATIND;
1301 RLOG_ARG1(L_ERROR,DBG_CELLID,datInd->cellId,"RNTI:%d Unable to get the UE CB",
1303 tfuSap->sapSts.numPduDrop++;
1308 rgTOMUtlL2MStoreBufSz(ueCb, &ceInfo);
1309 rgTOML2MCompileActiveLCs (cellCb, ueCb, pdu, &ceInfo);
1312 if ((ret = rgTOMUtlProcMsg(cellCb, ueCb, pdu, isSpsRnti,&spsToBeActvtd,&sduSize, slot, (uint32_t *)&lcgBytes)) != ROK)
1314 if ((ret = rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, (uint32_t *)&lcgBytes)) != ROK)
1315 #endif /* LTEMAC_SPS */
1317 rgTOMUtlFreePduEvnt (pdu, TRUE);
1318 err.errType = RGERR_TOM_DATIND;
1319 RLOG_ARG1(L_ERROR,DBG_CELLID,datInd->cellId,
1320 "Unable to handle Data Indication CRNTI:%d",ueCb->ueId);
1321 tfuSap->sapSts.numPduDrop++;
1328 if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti,spsToBeActvtd,sduSize, (uint32_t *)&lcgBytes) != ROK)
1330 if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti, (uint32_t *)&lcgBytes) != ROK)
1334 rgTOMInfFreePduEvnt (sfInfo);
1335 rgTOMUtlFreePduEvnt (pdu, FALSE);
1338 /* free up the PDU memory */
1339 rgTOMUtlFreePduEvnt (pdu, FALSE);
1341 /* Free the allocated memory for ueUlAllocInfo here */
1343 if(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo != NULLP)
1345 /*ccpu00117052 - MOD - Passing double for proper NULLP
1347 rgFreeSBuf(inst,(Data **)&(cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].ueUlAllocInfo),
1348 ((cellCb->ulSf[(slot % RG_NUM_SUB_FRAMES)].numUe) * sizeof(RgUeUlAlloc)));
1352 /* Update PRB used for all GBR QCIs to scheduler */
1353 memcpy( &sfInfo->qcisUlPrbCnt[0],
1354 &cellCb->qcisUlPrbCnt[0],
1355 (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1356 /* clear the cellCb ul prb value */
1357 memset(&cellCb->qcisUlPrbCnt[0], 0,
1358 (RGM_MAX_QCI_REPORTS * sizeof(uint32_t)));
1362 rgGetPstToInst(&schPst, inst,cellCb->schInstMap.schInst);
1363 sfInfo->cellSapId = cellCb->schInstMap.cellSapId;
1364 //TODO: commented for compilation without SCH RgMacSchSfRecp(&schPst, sfInfo);
1369 * @brief Function handles allocation for common channels i.e. BCCH-BCH,
1370 * BCCH-DLSCH, PCCH-DLSCH.
1374 * Function : rgHndlCmnChnl
1376 * This function is invoked from RgSchMacSfAllocReq. This function handles
1377 * allocations made for common channels like BCCH and PCCH.
1380 * 1. If BCCH on BCH has been scheduled, send StatusIndication on RGU.
1381 * 2. If PCCH is scheduled, send StatusIndication on RGU.
1382 * 3. If BCCH on DLSCH has been scheduled and sndStatInd is TRUE, send
1383 * StatusIndication on RGU, else copy the bcch buffer onto the downlink
1387 * @param[in] RgCellCb *cell,
1388 * @param[in] CmLteTimingInfo timingInfo,
1389 * @param[in] RgInfCmnLcInfo *cmnLcInfo,
1390 * @param[in/out] RgErrInfo *err,
1395 static S16 rgHndlCmnChnl
1398 CmLteTimingInfo timingInfo,
1399 RgInfCmnLcInfo *cmnLcInfo,
1403 #if (ERRCLASS & ERRCLS_DEBUG)
1407 RgBcchDlschLcCb *bcch;
1408 #if (ERRCLASS & ERRCLS_DEBUG)
1411 #endif/*RGR_SI_SCH*/
1412 RguCStaIndInfo *staInd;
1414 Inst inst = cell->macInst - RG_INST_START;
1417 dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
1419 if(cmnLcInfo->bitMask & RGINF_BCH_INFO)
1422 #if (ERRCLASS & ERRCLS_DEBUG)
1423 if(NULLP == (bch = rgDBMGetBcchOnBch(cell)))
1427 if(cmnLcInfo->bchInfo.lcId != bch->lcId)
1433 if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1435 err->errCause = RGERR_TOM_MEM_EXHAUST;
1438 staInd->cellId = cell->cellId;
1439 staInd->rnti = RG_INVALID_RNTI;
1440 staInd->lcId = cmnLcInfo->bchInfo.lcId;
1441 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1442 /* ADD Changes for Downlink UE Timing Optimization */
1443 #ifdef LTEMAC_DLUE_TMGOPTMZ
1444 dlSf->remDatReqCnt++;
1446 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1451 /*Store the received BCH Data in the scheduled subframe*/
1452 dlSf->bch.tb = cmnLcInfo->bchInfo.pdu;
1453 #endif/*RGR_SI_SCH*/
1456 if(cmnLcInfo->bitMask & RGINF_PCCH_INFO)
1458 #if (ERRCLASS & ERRCLS_DEBUG)
1459 if(NULLP == (pcch = rgDBMGetPcch(cell)))
1463 if(cmnLcInfo->pcchInfo.lcId != pcch->lcId)
1469 dlSf->pcch.pdcch.rnti =
1470 cmnLcInfo->pcchInfo.rnti;
1471 dlSf->pcch.pdcch.dci =
1472 cmnLcInfo->pcchInfo.dciInfo;
1474 /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */
1475 dlSf->pcch.txPwrOffset = cmnLcInfo->pcchInfo.txPwrOffset;
1477 if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK)
1479 err->errCause = RGERR_TOM_MEM_EXHAUST;
1482 staInd->cellId = cell->cellId;
1483 staInd->rnti = RG_INVALID_RNTI;
1484 staInd->lcId = cmnLcInfo->pcchInfo.lcId;
1485 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1486 /* ADD Changes for Downlink UE Timing Optimization */
1487 #ifdef LTEMAC_DLUE_TMGOPTMZ
1488 dlSf->remDatReqCnt++;
1490 /* for consolidated CmnStaInd calling below function from function
1491 * rgHndlSchedUe once CmnStaInd prepared for all UEs
1493 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1499 if(cmnLcInfo->bitMask & RGINF_BCCH_INFO)
1501 dlSf->bcch.pdcch.rnti =
1502 cmnLcInfo->bcchInfo.rnti;
1503 dlSf->bcch.pdcch.dci =
1504 cmnLcInfo->bcchInfo.dciInfo;
1506 /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */
1507 dlSf->bcch.txPwrOffset = cmnLcInfo->bcchInfo.txPwrOffset;
1511 (bcch=rgDBMGetBcchOnDlsch(cell,cmnLcInfo->bcchInfo.lcId)))
1515 if(TRUE == cmnLcInfo->bcchInfo.sndStatInd)
1517 RG_FREE_MSG(bcch->tb);
1518 if (rgAllocShrablSBuf (inst,(Data**)&staInd,
1519 sizeof(RguCStaIndInfo)) != ROK)
1521 err->errCause = RGERR_TOM_MEM_EXHAUST;
1524 staInd->cellId = cell->cellId;
1525 staInd->rnti = RG_INVALID_RNTI;
1526 staInd->lcId = cmnLcInfo->bcchInfo.lcId;
1527 staInd->transId = (timingInfo.sfn << 8) | (timingInfo.slot);
1528 /* ADD Changes for Downlink UE Timing Optimization */
1529 #ifdef LTEMAC_DLUE_TMGOPTMZ
1530 dlSf->remDatReqCnt++;
1532 if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK)
1539 SCpyMsgMsg(bcch->tb, RG_GET_MEM_REGION(rgCb[inst]),
1540 RG_GET_MEM_POOL(rgCb[inst]), &dlSf->bcch.tb);
1543 /*Store the received BCCH Data in the scheduled subframe*/
1544 dlSf->bcch.tb = cmnLcInfo->bcchInfo.pdu;
1545 #endif/*RGR_SI_SCH*/
1549 } /* end of rgHndlCmnChnl */
1552 * @brief Function for handling allocations for dedicated channels for a
1557 * Function : rgHndlSchdUe
1559 * This function shall be invoked whenever scheduler is done with the
1560 * allocations of dedicated channels for a subframe. Invoked by the function
1561 * RgSchMacSfAllocReq.
1563 * Processing steps :
1564 * 1. Loops through the list of UE's scheduled looking for the corresponding
1566 * 2. Finds the corresponding HARQ process.
1567 * 3. Invokes the DHM function to issue StatusIndications on RGU.
1570 * @param[in] RgCellCb *cell,
1571 * @param[in] CmLteTimingInfo timingInfo,
1572 * @param[in] RgInfUeInfo *ueInfo
1573 * @param[in/out] RgErrInfo *err
1578 static S16 rgHndlSchdUe
1581 CmLteTimingInfo timingInfo,
1582 RgInfUeInfo *ueInfo,
1588 if(NULLP == ueInfo->allocInfo)
1593 rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err);
1596 } /* end of rgHndlSchdUe */
1600 * @brief Function for handling Uplink allocations for Ue for a
1605 * Function : rgHndlUlUeInfo
1607 * @param[in] RgCellCb *cell,
1608 * @param[in] CmLteTimingInfo timingInfo,
1609 * @param[in] RgInfUlUeInfo *ueInfo
1614 static S16 rgHndlUlUeInfo
1617 CmLteTimingInfo timingInfo,
1618 RgInfUlUeInfo *ueInfo
1621 Inst inst = cell->macInst - RG_INST_START;
1627 ulSf = &cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)];
1629 /* rg003.301-MOD- Corrected the purifier memory leak */
1630 if (ulSf->numUe != ueInfo->numUes)
1632 if (ulSf->ueUlAllocInfo)
1634 rgFreeSBuf(inst,(Data **)&(ulSf->ueUlAllocInfo),
1635 ulSf->numUe * sizeof(RgUeUlAlloc));
1638 #ifdef XEON_SPECIFIC_CHANGES
1639 CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_FREE);
1640 CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_FREE, ulSf->numUe);
1642 ulSf->numUe = ueInfo->numUes;
1643 if((ulSf->ueUlAllocInfo == NULLP) && (ueInfo->numUes > 0))
1645 /* Allocate memory for ulAllocInfo */
1646 if((ret = rgAllocSBuf(inst,(Data**)&(cell->ulSf[(timingInfo.slot % RGSCH_NUM_SUB_FRAMES)].
1647 ueUlAllocInfo), ueInfo->numUes * sizeof(RgUeUlAlloc))) != ROK)
1652 #ifdef XEON_SPECIFIC_CHANGES
1653 CM_MEAS_TIME((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_ALLOC);
1654 CM_ADD_INFO((cell->crntTime.slot % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_ALLOC, ueInfo->numUes);
1656 if (ulSf->ueUlAllocInfo != NULLP)
1658 for(idx = 0; idx < ueInfo->numUes; idx++)
1660 ulSf->ueUlAllocInfo[idx].rnti = ueInfo->ulAllocInfo[idx].rnti;
1661 ulSf->ueUlAllocInfo[idx].numPrb = ueInfo->ulAllocInfo[idx].numPrb;
1664 RGCPYTIMEINFO(timingInfo, ulSf->schdTime);
1666 } /* end of rgHndlUlUeInfo */
1669 * @brief Function for handling RaResp request received from scheduler to MAC
1673 * Function : rgTOMRlsSf
1675 * This function shall be invoked whenever scheduler is done with the
1676 * allocations of random access responses for a subframe.
1677 * This shall invoke RAM to create ueCbs for all the rapIds allocated and
1678 * shall invoke MUX to create RAR PDUs for raRntis allocated.
1681 * @param[in] Inst inst
1682 * @param[in] CmLteCellId cellId,
1683 * @param[in] CmLteTimingInfo timingInfo,
1684 * @param[in] RaRespInfo *rarInfo
1688 Void rgTOMRlsSf(Inst inst,RgDlSf *dlSf)
1693 if(dlSf->txDone == FALSE)
1695 RLOG0(L_ERROR, "SUBFRAME Not pushed to the PHY");
1697 if (dlSf->bch.tb != NULLP)
1699 RG_FREE_MSG(dlSf->bch.tb);
1701 if (dlSf->bcch.tb != NULLP)
1703 RG_FREE_MSG(dlSf->bcch.tb);
1705 if (dlSf->pcch.tb != NULLP)
1707 RG_FREE_MSG(dlSf->pcch.tb);
1710 rgTOMEmtcRlsSf(dlSf);
1712 for(idx=0; idx < dlSf->numRaRsp; idx++)
1714 RG_FREE_MSG(dlSf->raRsp[idx].rar);
1717 /* ADD Changes for Downlink UE Timing Optimization */
1718 #ifdef LTEMAC_DLUE_TMGOPTMZ
1719 dlSf->remDatReqCnt = 0;
1720 /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1722 dlSf->statIndDone = FALSE;
1724 if (dlSf->tbs.count)
1729 RGDBGERRNEW(inst, (rgPBuf(inst),
1730 "Error Stale TBs in Subframes TBS list\n"));
1731 node = dlSf->tbs.first;
1734 hqP = (RgDlHqProcCb*)node->node;
1738 for(i=0;i< RG_MAX_TB_PER_UE;i++)
1740 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
1742 cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
1743 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
1744 printf("\n rgTOMRlsSf:: hqP %p \n", (Void *)hqP);
1746 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
1751 /*arjun: check if dlSf laaTb list has to be freed???*/
1752 cmLListInit(&dlSf->tbs);
1753 dlSf->txDone = FALSE;
1759 * @brief Function is called by the scheduler once it has completed the
1760 * allocation for the subframe.
1764 * Function : rgHndlFlowCntrl
1765 * This function should fill and send Flow control
1769 * @param[in] Pst *cell
1770 * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation
1775 S16 rgHndlFlowCntrl(RgCellCb *cell,RgInfSfAlloc *sfInfo)
1777 RguFlowCntrlInd *flowCntrlInd;
1782 pst = &cell->rguDlSap->sapCfg.sapPst;
1783 /* flowCntrlInd is alloced in cell init time and will be re-used throughout */
1784 flowCntrlInd = cell->flowCntrlInd;
1785 flowCntrlInd->cellId = sfInfo->cellId;
1786 flowCntrlInd->numUes = sfInfo->flowCntrlInfo.numUes;
1788 for (ueIdx = 0; ueIdx < sfInfo->flowCntrlInfo.numUes; ueIdx++)
1790 flowCntrlInd->ueFlowCntrlInfo[ueIdx].ueId = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].ueId;
1791 flowCntrlInd->ueFlowCntrlInfo[ueIdx].numLcs = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].numLcs;
1793 for (lcIdx = 0; lcIdx < RGINF_MAX_NUM_DED_LC; lcIdx++)
1795 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId =
1796 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId;
1797 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt =
1798 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt;
1800 flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl =
1801 sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl;
1804 RgUiRguFlowCntrlInd(pst, cell->rguDlSap->sapCfg.spId,flowCntrlInd); /* TODO: Rishi confirm if the suId and pst pointer is correct */
1808 * @brief Function is called by the scheduler once it has completed the
1809 * allocation for the subframe.
1813 * Function : RgSchMacSfAllocReq
1815 * This function shall be invoked whenever scheduler is done with the
1816 * allocations of for a subframe. The sfInfo carries all the allocation
1817 * details for the common channels, RA responses and dedicated channel
1820 * Processing steps :
1821 * 1. Reset the information present in the downlink subframe that is
1823 * 2. Handle common channel allocations
1824 * 3. Handle RA Response allocations
1825 * 4. Handle dedicated channel allocations.
1827 * @param[in] Pst *pst
1828 * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation
1833 S16 RgSchMacSfAllocReq(Pst *pst,RgInfSfAlloc *sfInfo)
1838 volatile uint32_t startTime=0;
1842 RG_IS_INST_VALID(pst->dstInst);
1843 inst = pst->dstInst - RG_INST_START;
1845 SStartTask(&startTime, PID_MAC_SF_ALLOC_REQ);
1852 if((cell = rgCb[inst].cell) == NULLP)
1854 RLOG_ARG0(L_ERROR,DBG_CELLID,sfInfo->cellId, "No cellCb found with cell");
1858 dlSf = &cell->subFrms[(sfInfo->timingInfo.slot % RG_NUM_SUB_FRAMES)];
1860 rgTOMRlsSf(inst,dlSf);
1861 dlSf->schdTime = sfInfo->timingInfo;
1864 rgLaaInitTbInfoLst(cell);
1867 /* Fix : syed Ignore Failure Returns and continue processing.
1868 * Incomplete processing results in state sync loss between MAC-SCH. */
1870 if(TRUE == cell->emtcEnable)
1872 rgEmtcHndl(cell, sfInfo);
1875 rgHndlCmnChnl(cell, sfInfo->timingInfo, &sfInfo->cmnLcInfo, &err);
1877 rgHndlRaResp(cell, sfInfo->timingInfo, &sfInfo->rarInfo, &err);
1880 #ifdef XEON_SPECIFIC_CHANGES
1881 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_B4_UE_SCHD);
1883 rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1884 #ifdef XEON_SPECIFIC_CHANGES
1885 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_UE_SCHD);
1887 rgLaaChkAndReqTbs(dlSf,cell, inst);
1890 rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err);
1894 if(rgHndlUlUeInfo(cell, sfInfo->ulUeInfo.timingInfo,
1895 &sfInfo->ulUeInfo) != ROK)
1900 #ifdef XEON_SPECIFIC_CHANGES
1901 CM_MEAS_TIME((cell->crntTime.slot % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_MEAS);
1903 /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1907 /* Added the handling for pushing down
1908 * TFU Data request in the retransmission only scenario.*/
1909 #ifdef LTEMAC_DLUE_TMGOPTMZ
1910 dlSf->statIndDone = TRUE;
1911 /* Fix [ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled
1913 if(!(dlSf->txDone) &&
1915 (TRUE == rgLaaChkAllRxTbs(dlSf)) &&
1917 (0 == dlSf->remDatReqCnt) && (dlSf->statIndDone) &&
1918 (RG_TIMEINFO_SAME(cell->crntTime, dlSf->schdTime)))
1920 /*This is the case of rettransmission, so no need
1921 * to wait for TTI Ind to push TFU Data Request. Send
1923 if (ROK != rgTOMUtlProcDlSf (dlSf, cell, &err))
1925 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to process downlink subframe for cell");
1926 err.errType = RGERR_ROM_DEDDATREQ;
1928 /* Mark this frame as sent */
1929 dlSf->txDone = TRUE;
1932 if (sfInfo->flowCntrlInfo.numUes > 0)
1934 rgHndlFlowCntrl(cell,sfInfo);
1937 SStopTask(startTime, PID_MAC_SF_ALLOC_REQ);
1939 } /* end of RgSchMacSfAllocReq */
1941 * @brief Handler for processing data indication recieved from PHY for UEs.
1945 * Function: rgTOMProcCrntiCEInDatInd
1947 * Handler for processing data indication recieved from PHY for UEs.
1949 * Invoked by: RgLiTfuDatInd of LIM
1952 * For each DataInfo recieved
1953 * - If received a CRNTI control element
1954 * - Check if a CCCH SDU is present, if it is return failure
1955 * - Check for the existence of UE, if its isnt present return failure.
1956 * - Delegate the remaining processing to rgTOMUtlProcMsg3 which
1957 * primarily informs the scheduler about the data received and
1958 * generates Data indications towards the higher layer.
1960 * @param RgMacPdu *pdu,
1961 * @param RgUeCb *prevUeCb,
1962 * @param RgCellCb *cellCb,
1963 * @param TfuDatInfo *datInfo,
1964 * @param RgInfCeInfo *ceInfo
1969 static S16 rgTOMProcCrntiCEInDatInd
1974 TfuDatInfo *datInfo,
1975 RgInfCeInfo *ceInfo,
1979 RgUeCb *ueCb = NULLP;
1980 Inst inst = cellCb->macInst - RG_INST_START;
1993 ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
1997 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
1998 "RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
2002 prevUeCb = rgDBMGetUeCb (cellCb, ceInfo->ces.cRnti);
2003 if (prevUeCb == NULLP)
2005 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
2006 "RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti);
2009 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
2010 "CRNTI CE(%d) received through tmpCrnti(%d)",
2011 ceInfo->ces.cRnti, datInfo->rnti);
2012 rgDBMDelUeCbFromRachLst(cellCb, ueCb);
2013 rgRAMFreeUeCb(inst,ueCb);
2016 if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2018 if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2019 #endif /* LTEMAC_SPS */
2021 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
2022 "RNTI:%d Processing for MSG3 failed",datInfo->rnti);
2028 * @brief Handler for processing data indication recieved from PHY for UEs.
2032 * Function: rgTOMProcCCCHSduInDatInd
2034 * Handler for processing data indication recieved from PHY for UEs.
2036 * Invoked by: RgLiTfuDatInd of LIM
2039 * For each DataInfo recieved
2040 * - If only CCCH SDU is present
2041 * - Invoke rgTOMUtlProcMsg3 for further processing.
2042 * - If its a non-Msg3 PDU i.e. received outside of a RA procedure
2043 * - Retrieve the UeCB
2044 * - Validate that the received PDU contains only configured Logical
2046 * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the
2047 * scheduler with the information of the received Data and generates
2048 * DatIndications towards the higher layers.
2050 * @param TfuDatIndInfo *datInd
2051 * @param RgMacPdu *pdu,
2052 * @param RgUeCb *prevUeCb,
2053 * @param RgCellCb *cellCb,
2054 * @param TfuDatInfo *datInfo,
2055 * @param RgInfCeInfo *ceInfo
2060 static S16 rgTOMProcCCCHSduInDatInd
2065 TfuDatInfo *datInfo,
2066 RgInfCeInfo *ceInfo,
2070 RgUeCb *ueCb = NULLP;
2071 Inst inst = cellCb->macInst - RG_INST_START;
2084 if (ceInfo->bitMask & RG_CRNTI_CE_PRSNT)
2086 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
2087 "CRNTI:%d Received MSG3 with CCCH",ceInfo->ces.cRnti);
2091 ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti);
2095 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
2096 "RNTI:%d Processing for MSG3 failed", datInfo->rnti);
2099 /* Fix: syed Drop any duplicate Msg3(CCCH Sdu) */
2100 if (ueCb->dl.hqEnt.numHqProcs)
2102 /* HqE is already initialized by a previuos Msg3 */
2103 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Processing for MSG3 failed. Duplicate "
2104 "MSG3 received. Dropping", datInfo->rnti);
2108 if(rgDHMHqEntInit(inst,&ueCb->dl.hqEnt,
2109 cellCb->maxDlHqProcPerUe) != ROK)
2111 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Harq Initialization failed ",
2115 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
2116 "CCCH SDU received through tmpCrnti(%d)",datInfo->rnti);
2118 if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, slot, NULLP)) != ROK)
2120 if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, slot, NULLP)) != ROK)
2121 #endif /* LTEMAC_SPS */
2123 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Processing for MSG3 failed",
2132 /** @brief This function captures the BSR value from Control Element
2133 * Info structure and updates the effective Buffer size into the
2134 * corresponding LCG ID.
2138 * Function: rgTOMUtlL2MStoreBufSz
2141 * - update/append the Data structure based on BSR type
2143 * @param [in] RgUeCb *ueCb
2144 * @param [in] RgInfCeInfo *ceInfo
2148 static S16 rgTOMUtlL2MStoreBufSz( RgUeCb *ueCb, RgInfCeInfo *ceInfo )
2153 if(ceInfo->bitMask & RG_TRUNC_BSR_CE_PRSNT)
2155 lcgId = ((ceInfo->ces.bsr.truncBsr >> 6) & 0x03);
2156 bsr = ceInfo->ces.bsr.truncBsr & 0x3F;
2157 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2159 else if(ceInfo->bitMask & RG_SHORT_BSR_CE_PRSNT)
2161 lcgId = ((ceInfo->ces.bsr.shortBsr >> 6) & 0x03);
2162 bsr = ceInfo->ces.bsr.shortBsr & 0x3F;
2163 ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr];
2166 else if(ceInfo->bitMask & RG_LONG_BSR_CE_PRSNT)
2168 ueCb->ul.lcgArr[0].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs1];
2169 ueCb->ul.lcgArr[1].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs2];
2170 ueCb->ul.lcgArr[2].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs3];
2171 ueCb->ul.lcgArr[3].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs4];
2174 } /* end of rgTOMUtlL2MStoreBufSz*/
2176 /** @brief : Compiles list of LCs received in UL data for DTCH RBs
2180 * @param [in] RgCellCb *cellCb
2181 * @param [in] RgUeCb *ueCb
2182 * @param [in] CmLteRnti rnti
2183 * @param [in] RgMacPdu *pdu
2189 static Void rgTOML2MCompileActiveLCs(RgCellCb *cellCb,RgUeCb *ueCb,RgMacPdu *pdu,RgInfCeInfo *ceInfo)
2196 node = pdu->sduLst.first;
2199 sdu = (RgMacSdu*)node->node;
2201 if ((ulLcCb = rgDBMGetUlDedLcCb(ueCb, sdu->lcId)), ulLcCb != NULLP)
2203 if (ulLcCb->lcgId != 0)
2205 ceInfo->bitMask |= RG_ACTIVE_LC_PRSNT;
2206 ceInfo->ulActLCs[ulLcCb->lcId - 1] = TRUE;
2217 /**********************************************************************
2220 **********************************************************************/