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: Source code for RLC Utility Module
26 This file contains following functions
31 --rlcUtlSendDedLcBoStatus
32 --rlcUtlSendUlDataToDu
37 **********************************************************************/
38 static const char* RLOG_MODULE_NAME="UTL";
39 static int RLOG_MODULE_ID=2048;
40 static int RLOG_FILE_ID=209;
43 @brief RLC Utility Module
46 /* header (.h) include files */
48 #include "common_def.h"
49 /* kw005.201 added support for L2 Measurement */
53 #include "ckw.h" /* CKW defines */
54 #include "kwu.h" /* CKW defines */
55 #include "lkw.h" /* LKW defines */
56 #include "rgu.h" /* RGU defiens */
58 #include "kw_env.h" /* RLC environment options */
59 #include "kw.h" /* RLC defines */
60 #include "kw_err.h" /* Error defines */
64 /* extern (.x) include files */
65 #include "ckw.x" /* CKW includes */
66 #include "kwu.x" /* KWU includes */
67 #include "lkw.x" /* LKW inlcudes */
68 #include "rgu.x" /* RGU includes */
70 #include "kw.x" /* RLC includes */
71 #include "kw_udx.x" /* UDX interface includes */
72 #include "kw_dl.x" /* RLC downlink includes */
74 #include "rlc_utils.h"
75 #include "rlc_mac_inf.h"
76 #include "rlc_lwr_inf_api.h"
81 EXTERN SsRngBufCnt rngCb;
83 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS))
84 extern U32 isDatReqProcessed;
86 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_DL) /* for debugging purpose */
87 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) || defined (SS_RBUF)
88 EXTERN void rlcUtlDlBatchProcHqStaInd ARGS ((Void));
90 Void ResetRLCStats(Void)
92 RlcCb* dlInst = rlcCb[1];
93 RlcCb* ulInst = rlcCb[0];
94 memset(&gRlcStats, 0, sizeof(RLCStats));
95 memset(&dlInst->genSts,0,sizeof(RlcGenSts));
96 memset(&ulInst->genSts,0,sizeof(RlcGenSts));
100 Void PrintRLCStats(Void)
102 RlcCb* dlInst = rlcCb[1];
103 RlcCb* ulInst = rlcCb[0];
105 RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
106 dlInst->genSts.pdusSent,
107 dlInst->genSts.pdusRetx,
108 dlInst->genSts.protTimeOut,
109 dlInst->genSts.numSduDisc);
110 RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
111 ulInst->genSts.pdusRecv,
112 ulInst->genSts.unexpPdusRecv,
113 ulInst->genSts.errorPdusRecv);
114 RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
115 "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
116 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
117 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
118 RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
119 "DRB:%lu MaxRetx:%lu RetransPdus:%lu",
120 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
121 gRlcStats.amRlcStats.numDLRetransPdus);
122 RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
123 " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ",
124 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
125 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
127 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)\n",
128 dlInst->genSts.pdusSent,
129 dlInst->genSts.pdusRetx,
130 dlInst->genSts.protTimeOut,
131 dlInst->genSts.numSduDisc);
132 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)\n",
133 ulInst->genSts.pdusRecv,
134 ulInst->genSts.unexpPdusRecv,
135 ulInst->genSts.errorPdusRecv);
136 RTLIN_DUMP_DEBUG("RLC Stats:"
137 "AMDL: StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu DRB:%lu MaxRetx:%lu RetransPdus:%lu \n"
138 "AMUL: PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu \n",
139 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
140 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
141 gRlcStats.amRlcStats.numDLRetransPdus, gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
142 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
145 Void PrintRLCStats(Void)
147 RlcCb* dlInst = rlcCb[1];
148 RlcCb* ulInst = rlcCb[0];
150 printf ("\n================================ RLC STATS ===========================\n");
151 RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
152 dlInst->genSts.pdusSent,
153 dlInst->genSts.pdusRetx,
154 dlInst->genSts.protTimeOut,
155 dlInst->genSts.numSduDisc);
156 RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
157 ulInst->genSts.pdusRecv,
158 ulInst->genSts.unexpPdusRecv,
159 ulInst->genSts.errorPdusRecv);
160 RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
161 "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
162 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
163 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
164 RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
165 "DRB:%lu MaxRetx:%lu RetransPdus:%lu",
166 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
167 gRlcStats.amRlcStats.numDLRetransPdus);
168 RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
169 " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ",
170 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
171 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
172 /* RTLIN_DUMP_DEBUG("AM RLC Stats:"
173 "AMDL: SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) MaxRetx:(%u) WindowStalls: (%u) \n"
174 "AMUL: DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx :(%u) \n",
175 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
176 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmMaxRetx, gRlcStats.amRlcStats.numRlcAmCellWinStall,
177 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
178 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
180 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)\n",
181 dlInst->genSts.pdusSent,
182 dlInst->genSts.pdusRetx,
183 dlInst->genSts.protTimeOut,
184 dlInst->genSts.numSduDisc);
185 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)\n",
186 ulInst->genSts.pdusRecv,
187 ulInst->genSts.unexpPdusRecv,
188 ulInst->genSts.errorPdusRecv);
189 RTLIN_DUMP_DEBUG("AMDL: StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u DRB:%u MaxRetx:%u RetransPdus:%u \n"
190 " SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) WindowStalls: (%u) \n"
192 "AMUL: PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u \n"
193 " DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx:(%u) \n",
194 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
195 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb,
196 gRlcStats.amRlcStats.numDLMaxRetx, gRlcStats.amRlcStats.numDLRetransPdus,
197 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
198 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmCellWinStall,
199 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
200 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd,
201 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
202 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
206 /*******************************************************************
209 * Handler for storing all DL PDU Info into RLC-MAC interface
210 * struct and sending to lower interface
213 * This function stores DL PDU info for all logical channels
214 * of per UE grant per TTI and sends to MAC
216 * Function : rlcSendDedLcDlData
219 * @return ROK - success
222 * ****************************************************************/
223 uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo)
225 uint8_t ueIdx; /* UE info list iterator */
226 uint8_t tbIdx; /* TB info list iterator */
227 uint8_t lchIdx; /* Lch info list iterator */
228 uint8_t pduIdx; /* RLC PDU list iterator */
229 RguDDatReqPerUe datPerUe; /* DL data info per UE */
230 RguDatReqTb datPerTb; /* DL data info per TB */
231 RguLchDatReq datPerLch; /* DL data info per Lch */
232 RlcData *dlData; /* DL data to be sent to MAC */
233 Pst pst; /* Post structure */
234 uint16_t pduLen; /* PDU length */
235 uint16_t copyLen; /* Number of bytes copied */
238 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
239 dlData, sizeof(RlcData));
240 #if (ERRCLASS & ERRCLS_ADD_RES)
241 if ( dlData == NULLP )
243 DU_LOG("\nRLC: rlcSendDedLcDlData: Memory allocation failed for dl data");
244 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
245 datReqInfo, sizeof(RguDDatReqInfo));
248 #endif /* ERRCLASS & ERRCLS_ADD_RES */
250 for(ueIdx = 0; ueIdx < datReqInfo->nmbOfUeGrantPerTti; ueIdx++)
252 datPerUe = datReqInfo->datReq[ueIdx];
254 memset(dlData, 0, sizeof(RlcData));
256 dlData->cellId = datReqInfo->cellId;
257 dlData->rnti = datPerUe.rnti;
259 /* Retrieving sfn/slot from transId. It was filled in RlcProcSchedResultRpt */
260 dlData->slotInfo.sfn = datPerUe.transId >> 16;
261 dlData->slotInfo.slot = datPerUe.transId & 0xffff;
264 for(tbIdx = 0; tbIdx < datPerUe.nmbOfTbs; tbIdx++)
266 datPerTb = datPerUe.datReqTb[tbIdx];
267 for(lchIdx = 0; lchIdx < datPerTb.nmbLch; lchIdx++)
269 datPerLch = datPerTb.lchData[lchIdx];
270 for(pduIdx = 0; pduIdx < datPerLch.pdu.numPdu; pduIdx++)
272 dlData->pduInfo[dlData->numPdu].commCh = FALSE;
273 dlData->pduInfo[dlData->numPdu].lcId = datPerLch.lcId;
275 /* Copy Message to fixed buffer to send */
276 ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen);
277 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
278 dlData->pduInfo[dlData->numPdu].pduBuf, pduLen);
280 if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP )
282 DU_LOG("\nRLC: rlcSendDedLcDlData: Memory allocation failed");
283 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
285 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
286 dlData->pduInfo[pduIdx].pduLen);
288 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
289 dlData, sizeof(RlcData));
290 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
291 datReqInfo, sizeof(RguDDatReqInfo));
295 ODU_COPY_MSG_TO_FIX_BUF(datPerLch.pdu.mBuf[pduIdx], 0, pduLen, \
296 dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)©Len);
297 dlData->pduInfo[dlData->numPdu].pduLen = pduLen;
300 ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]);
304 }/* For Data per Lch */
305 }/* For Data per Tb */
307 /* Sending DL Data per UE to MAC */
308 memset(&pst, 0, sizeof(Pst));
309 FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
310 if(RlcSendDlDataToMac(&pst, dlData) != ROK)
312 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
314 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
315 dlData->pduInfo[pduIdx].pduLen);
317 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
319 } /* For Data per UE */
321 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
322 datReqInfo, sizeof(RguDDatReqInfo));
325 }/* End of rlcSendDedLcDlData */
330 * Handler for sending the data to multiple logical channels of a UE
333 * This function sends the data for one or more logical channels
334 * after processing the SDUs and forming the PDUs.It calls
335 * UMM or AMM functions to form the PDUs for the requested sizes
338 * @param[in] gCb RLC instance Control block
339 * @param[in] staIndInfo Status Indication Information containing the
340 * size of PDU(s) for one or more logical channels
347 uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
351 RlcDlUeCb *ueCb; /* UE control block */
352 uint32_t count; /* Loop Counter */
353 uint32_t numTb; /* Number of Tbs */
354 RlcDlRbCb *rbCb; /* RB Control Block */
355 RlcDatReq datReq; /* PDUs Information */
356 RguDDatReqInfo *datReqInfo; /* Data Request Information */
357 RlcRguSapCb *rguSap; /* MAC SAP CB */
358 uint32_t totNumPdu; /* Total number of PDUS */
359 RguStaIndTb *staIndTb = NULLP;
360 RguDatReqTb *datReqTb = NULLP;
361 RguDStaIndPerUe *staInd = NULLP;
363 uint32_t grantPerLch[RGU_MAX_LC] = {0};
365 /* kw005.201 added support for L2 Measurement */
366 #ifdef LTE_L2_MEAS_LOSS_DELAY
369 #endif /* LTE_L2_MEAS */
373 uint32_t staIndSz=0,datIndSz = 0;
376 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
377 datReqInfo,sizeof(RguDDatReqInfo));
378 #if (ERRCLASS & ERRCLS_ADD_RES)
379 if ( datReqInfo == NULLP )
381 DU_LOG("\nRLC: rlcUtlSendToMac: Memory allocation failed");
384 #endif /* ERRCLASS & ERRCLS_ADD_RES */
385 for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++)
387 staInd = &staIndInfo->staInd[idx];
388 /* Fetch Ue control block */
389 GET_UE_IDX(staInd->rnti, ueIdx);
390 if(ROK != rlcDbmFetchDlUeCb(gCb, ueIdx, staIndInfo->cellId,&ueCb))
392 /* Fetch UeCb failed */
393 DU_LOG("\nRLC: rlcUtlSendToMac: UeId[%u]:ueCb not found",
395 /* If ueCb is not found for current rnti then continue to look for next rnti*/
398 /* kw002.201 Removed the allocation of RlcDatReq */
399 /* kw004.201 Used SSI function to initialize the variable */
400 memset(&datReq, 0, sizeof(RlcDatReq) );
402 for (numTb = 0; numTb < staInd->nmbOfTbs; numTb++)
404 staIndTb = &(staInd->staIndTb[numTb]);
405 datReqTb = &(datReqInfo->datReq[idx].datReqTb[numTb]);
407 ueCb->tbIdx = (ueCb->tbIdx+1) % RLC_MAX_TB_PER_UE;
409 for (count = 0;count < staIndTb->nmbLch; count++)
412 /*Calculate the total grant size from MAC */
413 if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC)
414 || (staIndTb->lchStaInd[count].lcId == 0))
416 /* TODO : Need to figure out why this is happening */
421 grantPerLch[staIndTb->lchStaInd[count].lcId] += staIndTb->lchStaInd[count].totBufSize;
424 rbCb = ueCb->lCh[staIndTb->lchStaInd[count].lcId - 1].dlRbCb;
426 if (rbCb && (!rlcDlUtlIsReestInProgress(rbCb)))
429 staIndSz += staIndTb->lchStaInd[count].totBufSize;
430 datReq.pduSz = staIndTb->lchStaInd[count].totBufSize;
432 datReq.totMacGrant = grantPerLch[staIndTb->lchStaInd[count].lcId];
434 rlcUtlGetCurrTime(&datReq.boRep.oldestSduArrTime);
435 if ( CM_LTE_MODE_UM == rbCb->mode )
437 rlcUmmProcessSdus(gCb,rbCb,&datReq);
439 else if ( CM_LTE_MODE_AM == rbCb->mode )
441 rlcAmmProcessSdus(gCb,rbCb,&datReq,staInd->fillCtrlPdu);
444 grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant;
446 if ( 0 == datReq.pduInfo.numPdu )
450 totNumPdu += datReq.pduInfo.numPdu;
451 memcpy(&(datReqTb->lchData[count].pdu),
452 &(datReq.pduInfo),sizeof(KwPduInfo));
454 for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++)
457 ODU_GET_MSG_LEN(datReqTb->lchData[count].pdu.mBuf[numPdu],&len);
460 datReqTb->lchData[count].setMaxUlPrio = FALSE;
461 if (RLC_AM_IS_POLL_BIT_SET(AMDL) &&
462 (AMDL.sduQ.count > 1))
464 /* Poll bit is set indicate to MAC*/
465 datReqTb->lchData[count].setMaxUlPrio = TRUE;
467 datReqTb->lchData[count].boReport.bo = datReq.boRep.bo;
470 datReqTb->lchData[count].boReport.estRlcHdrSz =
471 datReq.boRep.estHdrSz;
472 datReqTb->lchData[count].boReport.staPduPrsnt =
473 datReq.boRep.staPduPrsnt;
474 #endif /* CCPU_OPT */
475 datReqTb->lchData[count].boReport.staPduBo =
476 datReq.boRep.staPduBo;
477 datReqTb->lchData[count].lcId = staIndTb->lchStaInd[count].lcId;
480 /* Set if Bearer is UM */
481 if ( CM_LTE_MODE_UM == rbCb->mode )
483 datReqTb->lchData[count].freeBuff = TRUE;
487 datReqTb->lchData[count].freeBuff = FALSE;
491 /* kw005.201 added support for L2 Measurement */
492 #ifdef LTE_L2_MEAS_LOSS_DELAY
493 datReqTb->rguSnInfo->lchMap[count].lChId =
494 staIndTb->lchStaInd[count].lcId;
495 /* In some cases L2 Measurement for few of the lcId may be off,
496 * in this case we are assigning snList to 0xffff
498 for(snIdx1 = 0; snIdx1 < RGU_MAX_PDU; snIdx1++)
500 datReqTb->rguSnInfo->lchMap[count].snList[snIdx1] = 0xffff;
502 if(tbSnMap->numSn != 0)
505 for(snIdx1=tbSnMap->prevNumSn;snIdx1 < tbSnMap->numSn;snIdx1++)
507 datReqTb->rguSnInfo->lchMap[count].snList[snIdx2++] =
508 tbSnMap->snSduMap[snIdx1].sn;
510 tbSnMap->prevNumSn = tbSnMap->numSn;
513 datReqTb->lchData[count].boReport.oldestSduArrTime =
514 datReq.boRep.oldestSduArrTime;
515 /* kw004.201 Used SSI function to initialize the variable */
516 memset(&datReq, 0, sizeof(RlcDatReq) );
520 if(ueCb->l2MeasTbCb[ueCb->tbIdx]!= NULLP)
522 datReqTb->tbId = ueCb->tbIdx;
526 datReqTb->tbId = RLC_INVALID_TBID;
529 datReqTb->nmbLch = staIndTb->nmbLch;
530 /*adding the check to make sure that lcId is not sent as 0
531 * when no data is there in datReq */
532 if ( 0 == totNumPdu )
534 datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId;
536 /* kw005.201 added support for L2 Measurement */
537 #ifdef LTE_L2_MEAS_LOSS_DELAY
538 if(tbSnMap->numSn == 0)
540 RLC_FREE(tbSnMap,sizeof(RlcTbSnMap));
541 RLC_FREE(datReqTb->rguSnInfo,sizeof(RguSnMapInfo));
542 datReqTb->rguSnInfo = NULLP;
543 rlcCb.rlcL2Cb.curTbSnMap = NULLP;
544 datReqTb->snMapPres = FALSE;
548 cmHashListInsert(&(rlcCb.rlcL2Cb.tbHlCp),(PTR)tbSnMap,
549 (U8 *) &(tbSnMap->tbId), (U16)sizeof(tbSnMap->tbId));
550 rlcCb.rlcL2Cb.curTbSnMap = NULLP;
552 #endif /* LTE_L2_MEAS */
554 datReqInfo->datReq[idx].nmbOfTbs = staInd->nmbOfTbs;
555 datReqInfo->datReq[idx].transId = staInd->transId;
556 datReqInfo->datReq[idx].rnti = staInd->rnti;
558 datReqInfo->cellId = staIndInfo->cellId;
559 datReqInfo->nmbOfUeGrantPerTti = staIndInfo->nmbOfUeGrantPerTti;
561 rguSap = &(gCb->u.dlCb->rguDlSap[suId]);
562 rlcSendDedLcDlData(&rguSap->pst,rguSap->spId,datReqInfo);
569 * Handler for sending Status Response to MAC.
572 * This function is used by RLC entity for sending
573 * status response to MAC after receiving a SDU from
576 * @param[in] gCb RLC instance Control block
577 * @param[in] rbCb Radio Bearer Control Block
578 * @param[in] bo Buffer Occupancy
579 * @param[in] estHdrSz Estimated Header Size
580 * @param[in] staPduPrsnt Status PDU present or not
586 uint8_t rlcUtlSendDedLcBoStatus(RlcCb *gCb, RlcDlRbCb *rbCb, int32_t bo, \
587 int32_t estHdrSz, bool staPduPrsnt, uint32_t staPduBo)
589 Pst pst; /* Post info */
590 RlcBoStatus *boStatus; /* Buffer occupancy status information */
593 if ((rbCb->lastRprtdBoToMac > (uint32_t)8000) && (rbCb->boUnRprtdCnt < (uint32_t)5)
594 && (!staPduPrsnt) && ((CM_LTE_MODE_AM == rbCb->mode ) && (AMDL.nxtRetx == NULLP)))
596 rbCb->boUnRprtdCnt++;
600 rbCb->boUnRprtdCnt = (uint32_t)0;
601 rbCb->lastRprtdBoToMac = (uint32_t)bo;
603 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, \
604 boStatus, sizeof(RlcBoStatus));
606 boStatus->cellId = rbCb->rlcId.cellId;
607 boStatus->ueIdx = rbCb->rlcId.ueId;
608 boStatus->commCh = FALSE;
609 boStatus->lcId = rbCb->lch.lChId;
612 FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_BO_STATUS_TO_MAC);
613 /* Send Status Response to MAC layer */
614 if(RlcSendBoStatusToMac(&pst, boStatus) != ROK)
616 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus));
625 * Handler for emptying the SDU queue.
628 * This function is used to empty the SDU queue when
629 * a re-establishment request is received from the
632 * @param[in] gCb RLC instance control block
633 * @param[in] rbCb Radio bearer control block
634 * @param[in] sduQ SDU queue to be emptied
638 /* kw005.201 added support for L2 Measurement */
639 #ifdef LTE_L2_MEAS_RLC
648 Void rlcUtlEmptySduQ(gCb,rbCb, sduQ)
661 Void rlcUtlEmptySduQ(gCb,sduQ)
667 #ifdef LTE_L2_MEAS_RLC
668 CmLListCp *sduSnMapQ; /* SDU Sequence number map queue */
669 CmLList *firstSduSnMap; /* First Node in SDU SnMap Queue */
670 RlcSduSnMap *sduSnMap; /* SDU Sn Map */
673 firstSduSnMap = NULLP;
677 sduSnMapQ = &rbCb->sduSnMapQ;
678 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
682 sduSnMap = (RlcSduSnMap *)firstSduSnMap->node;
683 if(sduSnMap != NULLP)
685 cmLListDelFrm(&(rbCb->sduSnMapQ), &(sduSnMap->lstEnt));
686 RLC_FREE(sduSnMap, sizeof(RlcSduSnMap));
687 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
691 CM_LLIST_NEXT_NODE(sduSnMapQ, firstSduSnMap);
701 * Handler for calculating the Length Indicator (LI) length for a SDU
704 * This function is used to calculate the LI (Length Indicator) length
705 * which has to be substracted from the pduSize to correctly match the
706 * formed PDU(s) size with the size requested by MAC.
708 * @param[in] gCb RLC instance control block
709 * @param[in] numLi Number of LIs already present
710 * @param[in] msgLen Size of the SDU
711 * @param[in/out] pduSz Size of the pDU to be formed
715 void rlcUtlCalcLiForSdu(RlcCb *gCb, uint16_t numLi, MsgLen msgLen, int16_t *pduSz)
717 if ( (*pduSz > msgLen) && (msgLen < RLC_2K_BYTE))
719 if(0 == (numLi & RLC_BIT0)) /* check if number of LIs are odd or even */
721 /* if number of LI's are even 2 bytes needed */
726 /* if number of LI's are odd one byte needed */
736 * Function to set that re-establishment has started for an RB
739 * This function is used to set the reestInProgress flag to TRUE.
740 * This also sets the estimated header size to 0 and sends bo as
741 * 0 to MAC so that RLC does not need to transmit any data.
742 * If the poll re-transmit timer is running for the RB;
745 * @param[in] gCb RLC instance control block
746 * @param[in] rbCb RB for which re-establishment has started
751 Void rlcDlUtlSetReestInProgressForRB
757 Void rlcDlUtlSetReestInProgressForRB(gCb,rbCb)
763 rbCb->reestInProgress = TRUE;
765 if(rbCb->mode == CM_LTE_MODE_AM )
767 rbCb->m.amDl.estHdrSz = 0;
769 if(rlcChkTmr(gCb, (PTR)rbCb, RLC_EVT_AMDL_POLL_RETX_TMR))
771 rlcStopTmr(gCb, (PTR)rbCb, RLC_EVT_AMDL_POLL_RETX_TMR);
776 rbCb->m.umDl.estHdrSz= 0;
779 rlcUtlSendDedLcBoStatus(gCb, rbCb, 0, 0, FALSE,0);
787 * Function to check if re-establishment is ongoing for an RB
789 * @param[in] rbCb RB for which re-establishment is to be checked
792 * TRUE : Re-establishment is in progress
793 * FALSE : Re-establishment is not in progress
795 bool rlcDlUtlIsReestInProgress(RlcDlRbCb *rbCb)
797 return (rbCb->reestInProgress);
803 * Function to set re-establishment to FALSE
805 * @param[in] rbCb RB for which re-establishment is to be reset
810 Void rlcDlUtlResetReestInProgress
815 Void rlcDlUtlResetReestInProgress(rbCb)
820 rbCb->reestInProgress = FALSE;
826 * Function to set that re-establishment has started for all the RBs
827 * of an UE; except for SRB1
829 * @detail: For SRB1 only the poll-retransmit timer is stopped
831 * @param[in] gCb RLC instance control block
832 * @param[in] ueCb UE for which re-establishment has started
837 Void rlcDlUtlSetReestInProgressForAllRBs
843 Void rlcDlUtlSetReestInProgressForAllRBs(gCb,ueCb)
850 for(rbIdx = 0;rbIdx < RLC_MAX_SRB_PER_UE;rbIdx++)
852 if(ueCb->srbCb[rbIdx] != NULLP)
854 if(ueCb->srbCb[rbIdx]->rlcId.rbId != 1)
856 rlcDlUtlSetReestInProgressForRB(gCb,ueCb->srbCb[rbIdx]);
860 /* For SRB we just need to stop the poll re-transmit timer */
861 if(rlcChkTmr(gCb, (PTR)ueCb->srbCb[rbIdx], RLC_EVT_AMDL_POLL_RETX_TMR))
863 rlcStopTmr(gCb, (PTR)ueCb->srbCb[rbIdx], RLC_EVT_AMDL_POLL_RETX_TMR);
869 for(rbIdx = 0;rbIdx < RLC_MAX_DRB_PER_UE;rbIdx++)
871 if(ueCb->drbCb[rbIdx] != NULLP)
873 rlcDlUtlSetReestInProgressForRB(gCb,ueCb->drbCb[rbIdx]);
881 * @brief Function to increment number of SDUs transmitted
882 * in KWU SAP statistics
885 * @param[in] rlckwuSap KWU SAP in which to increment the counter
889 void rlcUtlIncrementKwuStsSduTx(RlcKwuSapCb *rlckwuSap)
891 rlckwuSap->sts.sduTx++;
896 * @brief Function to increment number of bytes and PDUs transmitted
897 * in General statistics
900 * @param[in] genSts KWU SAP in which to increment the counter
901 * @param[in] pdu The PDU which is sent
905 void rlcUtlIncrementGenStsBytesAndPdusSent(RlcGenSts *genSts, Buffer *pdu)
908 ODU_GET_MSG_LEN(pdu, &bytesSent);
909 genSts->bytesSent += bytesSent;
915 * @brief Function to initialize the data structures used to free memory
918 * @param[in] gCb RLC instance control block
919 * @param[out] toBeFreed Pointer to the freeing structure. This is
925 Void rlcUtlInitToBeFreed
928 RlcDlDataToBeFreed *toBeFreed
931 Void rlcUtlInitToBeFreed(gCb, toBeFreed)
933 RlcDlDataToBeFreed *toBeFreed;
936 cmLListInit(&(toBeFreed->sduLst));
937 cmLListInit(&(toBeFreed->rbLst));
938 cmLListInit(&(toBeFreed->reTxLst));
939 cmLListInit(&(toBeFreed->txLst));
945 * @brief Function to initialize the DL self Pst structure
948 * @param[in] gCb RLC instance control block
953 Void rlcUtlInitializeSelfPst
958 Void rlcUtlInitializeSelfPst(gCb)
962 Pst *selfPst = &gCb->u.dlCb->selfPst;
964 RLC_MEM_SET(selfPst, 0, sizeof(Pst));
965 selfPst->srcProcId = SFndProcId();
966 selfPst->dstProcId = SFndProcId();
967 selfPst->dstEnt = gCb->init.ent;
968 selfPst->dstInst = gCb->init.inst; /* this is for the DL instance */
969 selfPst->srcEnt = gCb->init.ent;
970 selfPst->srcInst = gCb->init.inst; /* DL instance will send to itself */
971 selfPst->prior = PRIOR3;
972 selfPst->event = UDX_EVT_DL_CLEANUP_MEM;
976 * @brief Function to send a DL cleanup event
979 * @param[in] gCb RLC instance control block
983 void rlcUtlRaiseDlCleanupEvent(RlcCb *gCb)
985 #ifdef KWSELFPSTDLCLEAN
986 if(!gCb->u.dlCb->eventInQueue)
988 ODU_POST_TASK(&gCb->u.dlCb->selfPst, gCb->u.dlCb->selfPstMBuf);
989 gCb->u.dlCb->eventInQueue = TRUE;
996 * @brief Function to add a SDU to the to be freed sdu list
999 * @param[in] gCb RLC instance control block
1000 * @param[in] sdu SDU to be added to the list
1004 void rlcUtlAddSduToBeFreedQueue(RlcCb *gCb, RlcSdu *sdu)
1006 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.sduLst), &(sdu->lstEnt));
1011 * @brief Function to add a re-transmitted pdu to the to be freed list
1014 * @param[in] gCb RLC instance control block
1015 * @param[in] retx Re-transmitted pdu to be added to the list
1020 Void rlcUtlAddReTxPduToBeFreedQueue
1026 Void rlcUtlAddReTxPduToBeFreedQueue(gCb, retx)
1031 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.reTxLst), &(retx->lstEnt));
1036 * @brief Function to add a transmitted pdu to the to be freed list
1039 * @param[in] gCb RLC instance control block
1040 * @param[in] pdu PDU to be added to the list
1045 Void rlcUtlAddTxPduToBeFreedQueue
1051 Void rlcUtlAddTxPduToBeFreedQueue(gCb, pdu)
1056 pdu->rlsLnk.node = (PTR)pdu;
1057 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.txLst), &(pdu->rlsLnk));
1063 * function to free/release the Acknowledged mode RBCB buffers
1066 * This primitive Frees the Acknowledged Mode RbCb transmission Buffer,
1067 * retransmission Buffer and reciption Buffers
1069 * @param [in] gCb - RLC instance control block
1070 * @param [in] rbCb - Downlink RB Control Block
1071 * @param [in,out] toBeFreed - Number of buffers to be freed
1074 * - TRUE if more data to be freed
1075 * - FALSE if all the data has been freed
1078 PRIVATE Bool rlcUtlFreeDlAmRbMemory
1085 PRIVATE Bool rlcUtlFreeDlAmRbMemory(gCb, rbCb, toBeFreed)
1091 RlcRetx *retx; /* retransmission buffer */
1092 RlcSn mTxNext; /* send state variable */
1095 MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1097 /* TODO : to be checked changed from <= to < */
1098 while ((0 < mTxNext) && *toBeFreed)
1100 txBuf = rlcUtlGetTxBuf(AMDL.txBufLst, AMDL.txNextAck);
1101 if (txBuf && txBuf->pduLst.first)
1103 while(txBuf->pduLst.first)
1105 RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(txBuf->pduLst.first->node);
1106 RLC_FREE_BUF(pduInfo->pdu);
1107 /* Delete node from the txBuf Pdu lst */
1108 cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first);
1109 RLC_FREE_WC(gCb, pduInfo, sizeof(RlcDlPduInfo));
1111 rlcUtlDelTxBuf(AMDL.txBufLst, txBuf, gCb);
1112 if(gCb->u.dlCb->shutdownReceived == 0)
1117 AMDL.txNextAck = (AMDL.txNextAck + 1) & AMDL.snModMask;
1118 MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1126 RLC_FREE(gCb,AMDL.txBufLst, (RLC_TX_BUF_BIN_SIZE * sizeof(CmLListCp)));
1129 RLC_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1130 while (retx && (*toBeFreed)) /* Till to be freed becomes 0 */
1133 RLC_FREE_BUF(retx->seg);
1135 cmLListDelFrm(&AMDL.retxLst, &retx->lstEnt);
1136 RLC_FREE_WC(gCb, retx, sizeof(RlcRetx));
1138 RLC_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1139 if(gCb->u.dlCb->shutdownReceived == 0)
1146 AMDL.nxtRetx = NULLP;
1148 /* clean up if there is info about STATUS PDU to be sent */
1152 udxPst = &gCb->u.dlCb->udxDlSap->pst;
1153 RLC_FREE_SHRABL_BUF_WC(udxPst->region,
1156 sizeof(RlcUdxDlStaPdu));
1157 AMDL.pStaPdu = NULLP;
1164 if(gCb->u.dlCb->shutdownReceived)
1173 * @brief Function to free memory from the DL instance
1176 * @param[in] gCb RLC instance control block
1181 Void rlcUtlFreeDlMemory
1186 Void rlcUtlFreeDlMemory(gCb)
1192 /* safety check, in case some event was still lying in the queue after
1193 the dlCb was deleted*/
1199 RlcDlDataToBeFreed* pToBeFreed = &gCb->u.dlCb->toBeFreed;
1201 if(gCb->u.dlCb->shutdownReceived)
1203 toBeFreed = pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count + pToBeFreed->rbLst.count;
1207 if ((pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count) > (3 * RLC_MAX_TO_BE_FREED))
1209 #if !defined(KWSELFPSTDLCLEAN) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
1210 if (isDatReqProcessed)
1212 toBeFreed = (2 *RLC_MAX_TO_BE_FREED);
1217 toBeFreed = (3 *RLC_MAX_TO_BE_FREED)/2;
1222 toBeFreed = RLC_MAX_TO_BE_FREED;
1227 gCb->u.dlCb->eventInQueue = FALSE; /* reset as we have received the event
1228 and are processing it */
1230 /* Free from the ReTx list */
1231 lst = &pToBeFreed->reTxLst;
1233 while((lst->first) && toBeFreed && (pToBeFreed->reTxLst.count > 100))
1235 while((lst->first) && toBeFreed)
1238 RlcRetx* seg = (RlcRetx *)(lst->first->node);
1239 cmLListDelFrm(lst, lst->first);
1240 RLC_FREE_BUF_WC(seg->seg);
1241 RLC_FREE_WC(gCb,seg, sizeof(RlcRetx));
1245 /* Free from the Tx list */
1246 lst = &pToBeFreed->txLst;
1248 while((lst->first) && toBeFreed && (pToBeFreed->txLst.count > 100))
1250 while((lst->first) && toBeFreed)
1253 RlcTx* pdu = (RlcTx *)(lst->first->node);
1254 cmLListDelFrm(lst, lst->first);
1255 while(pdu->pduLst.first)
1257 RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(pdu->pduLst.first->node);
1259 cmLListDelFrm(&pdu->pduLst, pdu->pduLst.first);
1260 RLC_FREE_BUF_WC(pduInfo->pdu);
1261 RLC_FREE_WC(gCb, pduInfo, sizeof(RlcDlPduInfo));
1263 RLC_FREE_WC(gCb,pdu, sizeof(RlcTx));
1267 /* Free from the SDU queue */
1268 lst = &pToBeFreed->sduLst;
1270 while((lst->first) && toBeFreed && (pToBeFreed->sduLst.count > 100))
1272 while((lst->first) && toBeFreed)
1275 RlcSdu* sdu = (RlcSdu *)(lst->first->node);
1276 RLC_RMV_SDU(gCb, lst, sdu);
1280 /* Free from the RBs */
1281 lst = &pToBeFreed->rbLst;
1283 while((lst->first) && toBeFreed && (pToBeFreed->rbLst.count > 100))
1285 while((lst->first) && toBeFreed)
1288 RlcDlRbCb* rbCb = (RlcDlRbCb *)(lst->first->node);
1289 Bool moreToBeFreed = rlcUtlFreeDlAmRbMemory(gCb, rbCb,&toBeFreed);
1292 cmLListDelFrm(lst, lst->first);
1293 RLC_FREE_WC(gCb, rbCb, sizeof(RlcDlRbCb));
1297 if ((toBeFreed == 0) && !(gCb->u.dlCb->shutdownReceived))
1299 rlcUtlRaiseDlCleanupEvent(gCb);
1309 * @brief Function to initialise measurement
1313 * @param[in] gCb RLC Instance Control Block
1318 S16 rlcUtlL2MeasDlInit(RlcCb *gCb)
1322 gCb->u.dlCb->rlcL2Cb.rlcNumMeas=0;
1323 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
1325 memset(&(gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
1327 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DISC].measCb.measType = LKW_L2MEAS_DL_DISC;
1328 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_IP].measCb.measType = LKW_L2MEAS_DL_IP;
1329 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DELAY].measCb.measType= LKW_L2MEAS_DL_DELAY;
1330 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UU_LOSS].measCb.measType= LKW_L2MEAS_UU_LOSS;
1331 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_ACT_UE].measCb.measType= LKW_L2MEAS_ACT_UE;
1337 * @brief Function to detect the data Burst start Condition in a DTCH
1341 * @param[in] rbCb RB control block
1342 * @param[in] contSduLst Array of Contained SDUs in the DTCH
1343 * @param[in] dataVol Available data in the DTCH
1344 * @param[in] schPduSz Total grant Size given by MAC
1350 Void rlcUtlUpdateBurstSdus
1354 RlcContSduLst *contSduLst,
1359 Void rlcUtlUpdateBurstSdus (gCb, rbCb, contSduLst, dataVol, schPduSz)
1362 RlcContSduLst *contSduLst;
1368 RlcL2MeasDlIpTh *l2MeasDlIpThruput = NULLP;
1369 RlcL2MeasTb *l2MeasTb = NULLP;
1372 VOLATILE U32 startTime = 0;
1373 RlcContSduLst *dstContSduLst;
1377 SStartTask(&startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1379 l2MeasDlIpThruput = &rbCb->l2MeasIpThruput.dlIpTh;
1381 if(RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb))
1383 if(dataVol > schPduSz)
1385 if(l2MeasDlIpThruput->isBurstAct == FALSE)
1387 l2MeasDlIpThruput->burstStartTime = glblTtiCnt;
1388 l2MeasDlIpThruput->isBurstAct = TRUE;
1389 l2MeasDlIpThruput->burstEndSduId = 0;
1392 { /* This is the case when another burst started before RLC gets the
1393 l2MeasDlIpThruput->burstEndSduId = 0; */
1397 { /* Store the burstEndSduId here */
1398 if((l2MeasDlIpThruput->isBurstAct == TRUE) &&
1399 (!l2MeasDlIpThruput->burstEndSduId))
1401 l2MeasDlIpThruput->burstEndSduId =
1402 l2MeasDlIpThruput->outStngSduArr[l2MeasDlIpThruput->lastSduIdx].sduId;
1405 if(l2MeasDlIpThruput->isBurstAct == TRUE)
1407 l2MeasTb = rlcUtlGetCurMeasTb(gCb,rbCb);
1408 /* Get the lChId from index 0, because index 0 is always for DL */
1409 if(l2MeasTb->numLcId >= RLC_MAX_ACTV_DRB)
1414 l2MeasTb->sduInfo[l2MeasTb->numLcId].lcId = rbCb->lch.lChId;
1415 /* Copy all the sduIdx from sduInfo to tb sduInfo */
1416 currTbIdx = l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus;
1417 dstContSduLst = &l2MeasTb->sduInfo[l2MeasTb->numLcId];
1419 for(idx = 0; ((idx < contSduLst->numSdus)
1420 && (currTbIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)) ; idx++)
1422 dstContSduLst->sduIdx[currTbIdx++] = contSduLst->sduIdx[idx];
1424 l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus += idx;
1425 l2MeasTb->numLcId++;
1426 }/* End of isBurstAct */
1427 }/* End of if measOn */
1430 SStopTask(startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1435 * This function is used to store locally the sduIdx of the sdu in the
1436 * outstanding SDU array
1439 * Stores the Sdu Idx in the contained SDU Array and increments
1440 * the num contained Sdus
1442 * @param[in] sduIdx the Index of the SDU in the outstanding SDU array
1443 * @param[out] contSduLst This stores the indices of the SDUs
1448 Void rlcUtlUpdateContainedSduLst
1451 RlcContSduLst *contSduLst
1454 Void rlcUtlUpdateContainedSduLst(sduIdx, contSduLst)
1456 RlcContSduLst *contSduLst;
1459 if (contSduLst->numSdus < RLC_L2MEAS_MAX_OUTSTNGSDU)
1461 contSduLst->sduIdx[contSduLst->numSdus] = sduIdx;
1462 contSduLst->numSdus++;
1469 * This function is used to store the sduId of the sdu in the
1470 * outstanding SDU array
1473 * Stores the Sdu Id in the outstanding SDU Array and increments
1474 * the num contained Sdus
1476 * @param[out] dlIpThPut The structure in which the outstanding sdus are
1478 * @param[in] sduIdx The Idx at which the sdu ID is stored
1479 * @param[in] sduLen The size if sdu in bytes
1480 * @param[in] newIdx Indicates if the sdu is already present in the
1486 Void rlcUtlUpdateOutStandingSduLst
1488 RlcL2MeasDlIpTh *dlIpThPut,
1495 Void rlcUtlUpdateOutStandingSduLst(dlIpThPut, sduIdx, sduLen, sduId, newIdx)
1496 RlcL2MeasDlIpTh *dlIpThPut;
1503 if (sduIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)
1507 dlIpThPut->outStngSduArr[sduIdx].numTb = 0;
1509 dlIpThPut->outStngSduArr[sduIdx].numTb++;
1510 dlIpThPut->outStngSduArr[sduIdx].sduId = sduId;
1511 dlIpThPut->outStngSduArr[sduIdx].sduLen = sduLen;
1516 RlcL2MeasTb * rlcUtlGetCurMeasTb
1522 RlcL2MeasTb * rlcUtlGetCurMeasTb(gCb, rbCb)
1527 RlcL2MeasTb *curL2MeasTb;
1530 if((curL2MeasTb = rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx]) == NULLP)
1532 /* Intentionally avoiding the RLC_ALLOC macro to avoid memset */
1533 if (SGetSBuf(gCb->init.region,
1535 (Data **)&curL2MeasTb,
1536 (Size)sizeof(RlcL2MeasTb)) != ROK)
1540 rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx] = curL2MeasTb;
1541 /* Initialize the Meas Tb details */
1542 curL2MeasTb->numLcId = 0;
1543 curL2MeasTb->numLchInfo = 0;
1544 curL2MeasTb->txSegSduCnt = 0;
1545 for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1547 curL2MeasTb->sduInfo[idx].numSdus = 0;
1549 for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1551 curL2MeasTb->lchInfo[idx].numSdus = 0;
1554 return (curL2MeasTb);
1560 * @brief Handler for Processing harq status indication
1564 * This function is called when the MAC sends a harq ind Mesage.
1565 * This is used only for UuLoss and Dl Delay and DL Ipthoughput
1568 * @param[in] staInd Harq status indication received from MAC.
1569 * @param[in] ueCb UeCb corresponding to the Tb Id.
1570 * @param[in] tbIdx TB index, 0 for SISO and 0,1 for MIMO.
1578 S16 rlcUtlProcHarqInd
1581 RguHarqStatusInd *hqStaInd,
1586 S16 rlcUtlProcHarqInd(gCb, hqStaInd, ueCb, tbIdx)
1588 RguHarqStatusInd *hqStaInd;
1594 RlcDlRbCb *rlcRbCb; /* KW Control Block */
1595 RlcL2MeasTb *l2MeasTb = NULLP; /* Measurement TbCb */
1596 U8 lcIdx; /* Logical channel id index */
1597 U8 sduIndx; /* sdu index to out standing sdu list in rbCb */
1598 U32 numSdus; /* number of sdus in the outstanding sdu list */
1599 RlcOutStngSduInfo *outStngSduArr; /* Outstanding sdu list */
1606 VOLATILE U32 startTime = 0;
1607 /*kw005.201 Code added for DL IP thruput measurement*/
1610 SStartTask(&startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1613 if(hqStaInd->tbId[tbIdx] >= RLC_INVALID_TBID)
1618 /* Find the L2 measurement tbCb to process DL Ip thruput*/
1619 l2MeasTb = ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]];
1620 if(l2MeasTb == NULLP)
1624 /* For each logical channel in the tbCb, process
1625 * and get the DL IP thruput */
1626 ackTime = SGetTtiCount();
1627 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLcId) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1629 timeAddedFlag = FALSE;
1630 if((rlcRbCb = ueCb->lCh[l2MeasTb->sduInfo[lcIdx].lcId - 1].dlRbCb)
1635 /* fix for DL IP stop*/
1636 if (!gCb->u.dlCb->rlcL2Cb.measOn[rlcRbCb->qci]
1637 || (rlcRbCb->rlcId.rbType == CM_LTE_SRB))
1642 /* Get the outstanding SDUs using sdu index stored in Container sduList
1643 * and check for HARQ ACK/NACK */
1644 numSdus = l2MeasTb->sduInfo[lcIdx].numSdus;
1646 if ((numSdus >= RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1650 totlSduCnt += numSdus;
1652 if (RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,rlcRbCb))
1654 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1656 outStngSduArr =&(rlcRbCb->l2MeasIpThruput.dlIpTh.outStngSduArr[\
1657 l2MeasTb->sduInfo[lcIdx].sduIdx[sduIndx]]);
1658 if(hqStaInd->status[tbIdx] == TRUE)
1660 /* If ACK is for burst End Sdu Id set burstActive
1661 * to FALSE and accumulate time */
1662 if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1663 outStngSduArr->sduId) && (outStngSduArr->numTb == 1))
1665 rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1666 /*Update the l2Sts structure for calculating throughput*/
1667 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1668 += outStngSduArr->sduLen;
1670 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1671 += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1672 outStngSduArr->sduId = 0;
1673 outStngSduArr->sduLen = 0;
1674 outStngSduArr->numTb = 0;
1675 rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1678 /* If burst is active and this sdu is only transmitted in single TB then
1679 * accumulate volume and clear the outstanding sduList */
1680 if((rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) &&
1681 (--(outStngSduArr->numTb) == 0))
1683 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1684 += outStngSduArr->sduLen;
1686 if(timeAddedFlag == FALSE)
1688 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1689 += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1690 rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime = glblTtiCnt;
1691 timeAddedFlag = TRUE;
1693 outStngSduArr->sduId = 0;
1694 outStngSduArr->sduLen = 0;
1696 }/* End of status == TRUE */
1699 if(rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE)
1701 if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1702 outStngSduArr->sduId))
1704 rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1705 rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1707 /* Clear the outstanding sdu list */
1708 outStngSduArr->sduId = 0;
1709 outStngSduArr->sduLen = 0;
1710 outStngSduArr->numTb = 0;
1717 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLchInfo) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1719 if((rlcRbCb = ueCb->lCh[l2MeasTb->lchInfo[lcIdx].lcId - 1].dlRbCb)
1724 numSdus = l2MeasTb->lchInfo[lcIdx].numSdus;
1730 if ((numSdus > RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1735 if(hqStaInd->status[tbIdx] == TRUE)
1737 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1739 delay = RLC_TIME_DIFF(ackTime,l2MeasTb->lchInfo[lcIdx].sduInfo[sduIndx].arvlTime);
1740 RLC_UPD_PDCP_L2_DLDELAY_STS(gCb,rlcRbCb, delay);
1742 /* Case of sduInfo not updated */
1743 if (totlSduCnt == 0)
1745 totlSduCnt = numSdus;
1747 RLC_UPD_L2_UU_LOSS_POS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1751 /* Case of sduInfo not updated */
1752 if (totlSduCnt == 0)
1754 totlSduCnt = numSdus;
1756 RLC_UPD_L2_UU_LOSS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1759 /* Free this tb, deallocate the memory */
1760 RLC_FREE(gCb, l2MeasTb, sizeof(RlcL2MeasTb));
1761 ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]] = NULLP;
1764 SStopTask(startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1767 }/* end of rlcUtlProcHarqInd */
1771 * @brief Handler for Sending L2 Measurement confirm.
1775 * This function sends a consolidates the mesaurements taken during
1776 * this time and sends the confirm .
1778 * @param[in] measEvtCb Measurement Event Control Block.
1786 S16 rlcUtlSndDlL2MeasCfm
1789 RlcL2MeasEvtCb *measEvtCb
1792 S16 rlcUtlSndDlL2MeasCfm(gCb, measEvtCb)
1794 RlcL2MeasEvtCb *measEvtCb;
1798 RlcL2MeasCb *measCb = NULLP;
1799 RlcL2MeasCfmEvt measCfmEvt;
1806 /* Discard new changes starts */
1809 /* Discard new changes ends */
1811 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
1813 RLOG1(L_DEBUG,"rlcUtlSndL2MeasCfm(transId(%ld))", measEvtCb->transId);
1815 RLOG1(L_DEBUG,"rlcUtlSndL2MeasCfm(transId(%d))", measEvtCb->transId);
1818 /* Clean up the RB data structures */
1819 measCb = &measEvtCb->measCb;
1821 memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
1822 measCfmEvt.transId = measEvtCb->transId;
1824 measCfmEvt.measType = measCb->measType;
1825 measCfmEvt.status.status = LCM_PRIM_OK;
1826 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
1828 if(measCb->measType & LKW_L2MEAS_DL_IP)
1830 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
1831 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
1833 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
1835 pUeInfoLstCfm[cfmIdx].numCfm = 0;
1836 if (pUeInfoLstCb[cntr].isValid == TRUE)
1838 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
1839 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
1840 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
1842 qci = pUeInfoLstCb[cntr].qci[qciIdx];
1843 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
1845 dlDataVol = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation;
1846 dlTime = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation;
1848 if((0 == dlTime) || !(gCb->u.dlCb->rlcL2Cb.measOn[qci] & LKW_L2MEAS_DL_IP) )
1850 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 0;
1854 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut =
1855 (dlDataVol / dlTime);
1857 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut *= 8;
1859 /* Reset the values after reporting to Application */
1860 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation = 0;
1861 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation = 0;
1863 measCfmEvt.val.ipThMeas.ueInfoLst[cfmIdx].numCfm++;
1868 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
1872 RlcL2Cntr *pMeasData = measCb->val.nonIpThMeas.measData;
1873 RlcL2MeasCfmNonIpThMeas *pMeasCfmNonIp = &measCfmEvt.val.nonIpThMeas;
1875 pMeasCfmNonIp->numCfm = 0;
1877 for(qciIdx = 0; qciIdx < LKW_MAX_QCI; qciIdx++)
1879 qci = measCb->val.nonIpThMeas.qci[qciIdx];
1882 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].qci = qci;
1884 if(measCb->measType & LKW_L2MEAS_UU_LOSS)
1886 dLoss = pMeasData[qci].uuLoss.dLoss;
1887 posPkts = pMeasData[qci].uuLoss.posPkts;
1888 if(((posPkts + dLoss) != 0))
1890 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.uuLoss =
1891 ((dLoss * 1000000) / (posPkts + dLoss));
1893 pMeasData[qci].uuLoss.dLoss = 0;
1894 pMeasData[qci].uuLoss.posPkts = 0;
1896 if(measCb->measType & LKW_L2MEAS_DL_DISC)
1899 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 0;
1900 if(pMeasData[qci].dlDisc.totSdus != 0)
1902 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate =
1903 (((pMeasData[qci].dlDisc.discSdus) * 1000000) / (pMeasData[qci].dlDisc.totSdus));
1906 pMeasData[qci].dlDisc.totSdus = 0;
1907 pMeasData[qci].dlDisc.discSdus = 0;
1909 if(measCb->measType & LKW_L2MEAS_DL_DELAY)
1911 if (pMeasData[qci].dlPjSduDelay.numSdus > 0)
1913 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlSduDelay =
1914 (pMeasData[qci].dlPjSduDelay.sduDelay / pMeasData[qci].dlPjSduDelay.numSdus);
1915 pMeasData[qci].dlPjSduDelay.sduDelay = 0;
1916 pMeasData[qci].dlPjSduDelay.numSdus = 0;
1919 pMeasCfmNonIp->numCfm++;
1923 /* Fix Klock warning */
1924 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
1926 } /* rlcUtlSndL2MeasCfm */
1929 * @brief Handler for Sending Negative confirm .
1933 * This function is called when the l2 measurement cannot be started
1934 * This function sends negative confirm for all the requests
1936 * @param[in] measReqEvt Measurement Req Structure
1944 S16 rlcUtlSndDlL2MeasNCfm
1947 RlcL2MeasReqEvt *measReqEvt,
1948 RlcL2MeasCfmEvt *measCfmEvt
1951 S16 rlcUtlSndDlL2MeasNCfm(gCb,measReqEvt, measCfmEvt)
1953 RlcL2MeasReqEvt *measReqEvt;
1954 RlcL2MeasCfmEvt *measCfmEvt;
1958 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
1960 } /* kwUtlSndL2MeasNCfm */
1963 * @brief Handler for resetting the RB data structures
1967 * This function resets the RB data structure after the expiry of
1968 * measurement timer.
1970 * @param[in] measCb Measurement Control Block.
1977 Void rlcUtlResetDlL2MeasInRlcRb
1980 RlcL2MeasCb *measCb,
1984 Void rlcUtlResetDlL2MeasInRlcRb(gCb, measCb, measType)
1986 RlcL2MeasCb *measCb;
1992 RlcDlUeCb *ueCb = NULL;
1996 if (measCb->measType & LKW_L2MEAS_DL_IP)
1998 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
2000 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
2002 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
2004 if (measType & LKW_L2MEAS_DL_IP)
2006 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.volSummation = 0;
2007 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.timeSummation = 0;
2008 gCb->u.dlCb->rlcL2Cb.measOn[qciIdx] &= ~measType;
2012 if(ROK != rlcDbmFetchDlUeCb(gCb,measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
2013 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
2023 /* for now the only meas should be DL discard in this case */
2024 if (measCb->measType & LKW_L2MEAS_DL_DISC)
2027 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2029 U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2031 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.discSdus = 0;
2032 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.totSdus = 0;
2036 if (measCb->measType & LKW_L2MEAS_DL_DELAY)
2039 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2041 U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2043 measCb->val.nonIpThMeas.measData[qciVal].dlPjSduDelay.sduDelay = 0;
2046 measCb->val.nonIpThMeas.numQci = 0;
2048 } /* rlcUtlResetDlL2MeasInRlcRb */
2051 PRIVATE Void dumpRLCDlRbInformation(RlcDlRbCb* dlRbCb)
2053 if(dlRbCb->mode == CM_LTE_MODE_UM)
2055 RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2056 "UM Downlink UEID:%d CELLID:%d Q size = %d",
2058 dlRbCb->rlcId.cellId,
2059 (int)dlRbCb->m.umDl.sduQ.count);
2061 else if(dlRbCb->mode == CM_LTE_MODE_AM)
2064 for(j = 0; j <= (RLC_AM_GET_WIN_SZ(dlRbCb->m.amDl.snLen)); j++)
2066 RlcTx *txBuf = rlcUtlGetTxBuf(dlRbCb->m.amDl.txBufLst, j);
2072 RLOG_ARG4(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2073 "AM Downlink UEID:%d CELLID:%d Sizes SDU Q = %d TX Q = %d ",
2075 dlRbCb->rlcId.cellId,
2076 (int)dlRbCb->m.amDl.sduQ.count,
2078 RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2079 "AM Downlink UEID:%d CELLID:%d RETX Q= %d",
2081 dlRbCb->rlcId.cellId,
2082 (int)dlRbCb->m.amDl.retxLst.count);
2086 Void DumpRLCDlDebugInformation(Void)
2088 RlcCb* dlInst = rlcCb[1]; /* TODO : Check whether DL is 0 or 1 */
2090 RlcDlCb *dlCb = dlInst->u.dlCb;
2092 RlcDlUeCb *ueCb = NULLP;
2093 RTLIN_DUMP_DEBUG("RLC Information\n");
2094 RTLIN_DUMP_DEBUG("===============\n");
2095 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
2096 while (ROK == cmHashListGetNext(&dlCb->ueLstCp,
2101 for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
2103 RlcDlRbCb* dlRbCb = ueCb->srbCb[i];
2104 if( dlRbCb != NULLP)
2106 dumpRLCDlRbInformation(dlRbCb);
2109 for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
2111 RlcDlRbCb* dlRbCb = ueCb->drbCb[i];
2112 if( dlRbCb != NULLP)
2114 dumpRLCDlRbInformation(dlRbCb);
2119 RlcDlDataToBeFreed* pToBeFreed = &dlCb->toBeFreed;
2121 RTLIN_DUMP_DEBUG("toBeFreed RETX list size = %d\n",(int)pToBeFreed->reTxLst.count);
2122 RTLIN_DUMP_DEBUG("toBeFreed TX list size = %d\n",(int)pToBeFreed->txLst.count);
2123 RTLIN_DUMP_DEBUG("toBeFreed SDU list size = %d\n",(int)pToBeFreed->sduLst.count);
2124 RTLIN_DUMP_DEBUG("toBeFreed RB list size = %d\n",(int)pToBeFreed->rbLst.count);
2130 * This function frees downlink memory
2139 void rlcUtlFreeDlMem
2144 void rlcUtlFreeDlMem()
2148 rlcUtlFreeDlMemory(RLC_GET_RLCCB(RLC_DL_INST));
2154 * This function returns current time
2162 void rlcUtlGetCurrTime(uint32_t *currTime)
2164 /* Need t define else part for PAL */
2165 *currTime = SGetTtiCount();
2168 #if defined(MAC_RLC_HARQ_STA_RBUF) || defined (SS_RBUF)
2171 void rlcUtlDlBatchProcHqStaInd
2176 void rlcUtlDlBatchProcHqStaInd()
2180 /* Read from Ring Buffer and process PDCP packets */
2183 Void *elmIndx = NULLP;
2184 RguHarqStaInd *staInd = NULLP;
2186 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2187 isDatReqProcessed = TRUE;
2189 elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ);
2190 while(NULLP != elmIndx)
2192 staInd = (RguHarqStaInd *)elmIndx;
2193 RlcLiRguHqStaInd(&(staInd->pst), 0, &(staInd->hqStatusInd));
2197 SRngIncrRIndx(SS_RNG_BUF_MAC_HARQ);
2199 if((elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ)) == NULLP)
2201 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2202 isDatReqProcessed = FALSE;
2212 * @brief evaluate and trigger PDB based flow control to PDCP
2216 * @param[in] rbCb RB control block
2223 Void rlcUtlTrigPdbFlowCntrl
2230 Void rlcUtlTrigPdbFlowCntrl(gCb,rbCb,pktAdmitCnt)
2236 KwuFlowCntrlIndInfo *flowCntrlInfo;
2237 RlcKwuSapCb* rlckwuSap;
2239 rlckwuSap = gCb->u.dlCb->rlcKwuDlSap + RLC_UI_PDCP;
2241 RLC_SHRABL_STATIC_BUF_ALLOC(rlckwuSap->pst.region,
2242 rlckwuSap->pst.pool,
2244 sizeof(KwuFlowCntrlIndInfo));
2245 flowCntrlInfo->rlcId = rbCb->rlcId;
2246 flowCntrlInfo->pktAdmitCnt = pktAdmitCnt;
2247 RlcUiKwuFlowCntrlInd(&rlckwuSap->pst, rlckwuSap->suId, flowCntrlInfo);
2252 * @brief Store the DL buffer in hashList
2257 * Use the SN % binSize as key and store the received UL buffer
2258 * @param[in] txBufLst List CP array
2259 * @param[in] txBuf transmitted buffer
2260 * @param[in] sn sn of the received buffer
2265 void rlcUtlStoreTxBuf(CmLListCp *txBufLst, RlcTx *txBuf, RlcSn sn)
2269 hashKey = (sn % RLC_TX_BUF_BIN_SIZE );
2271 txBuf->lnk.node = (PTR)txBuf;
2272 cmLListAdd2Tail(&(txBufLst[hashKey]), &txBuf->lnk);
2275 } /* rlcUtlStoreRecBuf */
2279 * @brief Retrieve the DL buffer from the list
2284 * Use the SN % binSize as key and retrieve the DL buffer
2285 * @param[in] txBufLst List CP array
2286 * @param[in] sn sn of the transmitted buffer
2291 RlcTx* rlcUtlGetTxBuf(CmLListCp *txBufLst, RlcSn sn)
2294 CmLListCp *txBufLstCp;
2296 CmLList *node = NULLP;
2298 hashKey = (sn % RLC_TX_BUF_BIN_SIZE );
2300 txBufLstCp = &txBufLst[hashKey];
2301 CM_LLIST_FIRST_NODE(txBufLstCp, node);
2304 txBuf = (RlcTx *) node->node;
2309 CM_LLIST_NEXT_NODE(txBufLstCp, node);
2312 } /* rlcUtlStoreTxBuf */
2315 * @brief Delete the DL buffer from the list
2320 * Use the SN % binSize as key and retrieve the DL buffer
2321 * @param[in] txBufLst List CP array
2322 * @param[in] sn sn of the transmitted bffer
2330 CmLListCp *txBufLst,
2335 Void rlcUtlDelTxBuf(txBufLst, txBuf, gCb)
2336 CmLListCp *txBufLst;
2342 CmLListCp *txBufLstCp;
2344 hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE );
2346 txBufLstCp = &txBufLst[hashKey];
2347 //printf("D-sn(%d)\n", txBuf->hdr.sn);
2348 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2349 RLC_FREE_WC(gCb, txBuf, sizeof(RlcTx));
2351 } /* rlcUtlDelTxBuf */
2355 * @brief Remove the DL buffer from the list
2360 * Use the SN % binSize as key and retrieve the DL buffer
2361 * @param[in] txBufLst List CP array
2362 * @param[in] sn sn of the transmitted bffer
2368 Void rlcUtlRemovTxBuf
2370 CmLListCp *txBufLst,
2375 Void rlcUtlRemovTxBuf(txBufLst, txBuf, gCb)
2376 CmLListCp *txBufLst;
2382 CmLListCp *txBufLstCp;
2384 hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE );
2386 txBufLstCp = &txBufLst[hashKey];
2387 //printf("D-sn(%d)\n", txBuf->hdr.sn);
2388 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2390 } /* rlcUtlRemovTxBuf */
2394 /********************************************************************30**
2396 **********************************************************************/