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
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 */
47 #include "envopt.h" /* environment options */
48 #include "envdep.h" /* environment dependent */
49 #include "envind.h" /* environment independent */
50 /* kw005.201 added support for L2 Measurement */
55 #include "gen.h" /* general */
56 #include "ssi.h" /* system services */
57 #include "cm5.h" /* common timer defines */
58 #include "cm_tkns.h" /* common tokens defines */
59 #include "cm_mblk.h" /* common memory allocation library defines */
60 #include "cm_llist.h" /* common link list defines */
61 #include "cm_hash.h" /* common hash list defines */
62 #include "cm_lte.h" /* common LTE defines */
63 #include "ckw.h" /* CKW defines */
64 #include "kwu.h" /* CKW defines */
65 #include "lkw.h" /* LKW defines */
66 #include "rgu.h" /* RGU defiens */
68 #include "kw_env.h" /* RLC environment options */
69 #include "kw.h" /* RLC defines */
70 #include "kw_err.h" /* Error defines */
74 /* extern (.x) include files */
75 #include "gen.x" /* general */
76 #include "ssi.x" /* system services */
78 #include "cm5.x" /* common timer library */
79 #include "cm_tkns.x" /* common tokens */
80 #include "cm_mblk.x" /* common memory allocation */
81 #include "cm_llist.x" /* common link list */
82 #include "cm_hash.x" /* common hash list */
83 #include "cm_lte.x" /* common LTE includes */
84 #include "cm_lib.x" /* common memory allocation library */
85 #include "ckw.x" /* CKW includes */
86 #include "kwu.x" /* KWU includes */
87 #include "lkw.x" /* LKW inlcudes */
88 #include "rgu.x" /* RGU includes */
90 #include "kw.x" /* RLC includes */
91 #include "kw_udx.x" /* UDX interface includes */
92 #include "kw_dl.x" /* RLC downlink includes */
97 EXTERN SsRngBufCnt rngCb;
99 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS))
100 extern U32 isDatReqProcessed;
102 #define KW_MODULE (KW_DBGMASK_DUT | KW_DBGMASK_DL) /* for debugging purpose */
103 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) || defined (SS_RBUF)
104 EXTERN void kwUtlDlBatchProcHqStaInd ARGS ((Void));
106 Void ResetRLCStats(Void)
108 KwCb* dlInst = kwCb[1];
109 KwCb* ulInst = kwCb[0];
110 cmMemset((U8*)&gRlcStats, 0, sizeof(RLCStats));
111 cmMemset((U8*)&dlInst->genSts,0,sizeof(KwGenSts));
112 cmMemset((U8*)&ulInst->genSts,0,sizeof(KwGenSts));
116 Void PrintRLCStats(Void)
118 KwCb* dlInst = kwCb[1];
119 KwCb* ulInst = kwCb[0];
121 RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
122 dlInst->genSts.pdusSent,
123 dlInst->genSts.pdusRetx,
124 dlInst->genSts.protTimeOut,
125 dlInst->genSts.numSduDisc);
126 RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
127 ulInst->genSts.pdusRecv,
128 ulInst->genSts.unexpPdusRecv,
129 ulInst->genSts.errorPdusRecv);
130 RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
131 "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
132 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
133 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
134 RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
135 "DRB:%lu MaxRetx:%lu RetransPdus:%lu",
136 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
137 gRlcStats.amRlcStats.numDLRetransPdus);
138 RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
139 " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ",
140 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
141 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
143 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)\n",
144 dlInst->genSts.pdusSent,
145 dlInst->genSts.pdusRetx,
146 dlInst->genSts.protTimeOut,
147 dlInst->genSts.numSduDisc);
148 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)\n",
149 ulInst->genSts.pdusRecv,
150 ulInst->genSts.unexpPdusRecv,
151 ulInst->genSts.errorPdusRecv);
152 RTLIN_DUMP_DEBUG("RLC Stats:"
153 "AMDL: StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu DRB:%lu MaxRetx:%lu RetransPdus:%lu \n"
154 "AMUL: PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu \n",
155 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
156 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
157 gRlcStats.amRlcStats.numDLRetransPdus, gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
158 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
161 Void PrintRLCStats(Void)
163 KwCb* dlInst = kwCb[1];
164 KwCb* ulInst = kwCb[0];
166 printf ("\n================================ RLC STATS ===========================\n");
167 RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
168 dlInst->genSts.pdusSent,
169 dlInst->genSts.pdusRetx,
170 dlInst->genSts.protTimeOut,
171 dlInst->genSts.numSduDisc);
172 RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
173 ulInst->genSts.pdusRecv,
174 ulInst->genSts.unexpPdusRecv,
175 ulInst->genSts.errorPdusRecv);
176 RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
177 "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
178 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
179 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
180 RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
181 "DRB:%lu MaxRetx:%lu RetransPdus:%lu",
182 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
183 gRlcStats.amRlcStats.numDLRetransPdus);
184 RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
185 " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ",
186 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
187 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
188 /* RTLIN_DUMP_DEBUG("AM RLC Stats:"
189 "AMDL: SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) MaxRetx:(%u) WindowStalls: (%u) \n"
190 "AMUL: DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx :(%u) \n",
191 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
192 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmMaxRetx, gRlcStats.amRlcStats.numRlcAmCellWinStall,
193 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
194 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
196 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)\n",
197 dlInst->genSts.pdusSent,
198 dlInst->genSts.pdusRetx,
199 dlInst->genSts.protTimeOut,
200 dlInst->genSts.numSduDisc);
201 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)\n",
202 ulInst->genSts.pdusRecv,
203 ulInst->genSts.unexpPdusRecv,
204 ulInst->genSts.errorPdusRecv);
205 RTLIN_DUMP_DEBUG("AMDL: StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u DRB:%u MaxRetx:%u RetransPdus:%u \n"
206 " SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) WindowStalls: (%u) \n"
208 "AMUL: PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u \n"
209 " DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx:(%u) \n",
210 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
211 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb,
212 gRlcStats.amRlcStats.numDLMaxRetx, gRlcStats.amRlcStats.numDLRetransPdus,
213 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
214 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmCellWinStall,
215 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
216 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd,
217 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
218 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
222 /*******************************************************************
225 * Handler for storing all DL PDU Info into RLC-MAC interface
226 * struct and sending to lower interface
229 * This function stores DL PDU info for all logical channels
230 * of per UE grant per TTI and sends to MAC
232 * Function : KwLiRguDDatReq
235 * @return ROK - success
238 * ****************************************************************/
240 PUBLIC S16 KwLiRguDDatReq
244 RguDDatReqInfo *datReqInfo
247 PUBLIC S16 KwLiRguDDatReq(post, spId, datReqInfo)
250 RguDDatReqInfo *datReqInfo;
253 U8 ueIdx; /* UE info list iterator */
254 U8 tbIdx; /* TB info list iterator */
255 U8 lchIdx; /* Lch info list iterator */
256 U8 pduIdx; /* RLC PDU list iterator */
257 RguDDatReqPerUe datPerUe; /* DL data info per UE */
258 RguDatReqTb datPerTb; /* DL data info per TB */
259 RguLchDatReq datPerLch; /* DL data info per Lch */
260 RguPduInfo pduInfo; /* DL RLC PDU infor */
261 RlcMacData *dlData; /* DL data to be sent to MAC */
266 KW_ALLOC_SHRABL_BUF(post->region, post->pool,
267 dlData, sizeof(RlcMacData));
268 #if (ERRCLASS & ERRCLS_ADD_RES)
269 if ( datReqInfo == NULLP )
271 RLOG0(L_FATAL,"Memory allocation failed");
274 #endif /* ERRCLASS & ERRCLS_ADD_RES */
276 for(ueIdx = 0; ueIdx < datReqInfo->nmbOfUeGrantPerTti; ueIdx++)
278 datPerUe = datReqInfo->datReq[ueIdx];
280 cmMemset((U8 *)dlData, 0, sizeof(RlcMacData));
282 dlData->cellId = datReqInfo->cellId;
283 dlData->rnti = datPerUe.rnti;
284 //dlData->timeToTx = datPerUe.transId; /* Derive timing info from transId */
287 for(tbIdx = 0; tbIdx < datPerUe.nmbOfTbs; tbIdx++)
289 datPerTb = datPerUe.datReqTb[tbIdx];
290 for(lchIdx = 0; lchIdx < datPerTb.nmbLch; lchIdx++)
292 datPerLch = datPerTb.lchData[lchIdx];
293 for(pduIdx = 0; pduIdx < datPerLch.pdu.numPdu; pduIdx++)
295 dlData->pduInfo[dlData->nmbPdu].commCh = FALSE;
296 dlData->pduInfo[dlData->nmbPdu].lcId = datPerLch.lcId;
297 dlData->pduInfo[dlData->nmbPdu].pduBuf = datPerLch.pdu.mBuf[pduIdx];
300 }/* For Data per Lch */
301 }/* For Data per Tb */
302 RlcMacSendDlData(post, spId, dlData);
303 } /* For Data per UE */
305 /* Check if to be freed here */
307 SPutSBuf(post->region,
309 (Data *)datReqInfo, sizeof(RguDDatReqInfo));
312 }/* End of KwLiRguDDatReq */
317 * Handler for sending the data to multiple logical channels of a UE
320 * This function sends the data for one or more logical channels
321 * after processing the SDUs and forming the PDUs.It calls
322 * UMM or AMM functions to form the PDUs for the requested sizes
325 * @param[in] gCb RLC instance Control block
326 * @param[in] staIndInfo Status Indication Information containing the
327 * size of PDU(s) for one or more logical channels
335 PUBLIC S16 kwUtlSndToLi
339 KwDStaIndInfo *staIndInfo
342 PUBLIC S16 kwUtlSndToLi(gCb, suId, staIndInfo)
345 KwDStaIndInfo *staIndInfo;
348 KwDlUeCb *ueCb; /* UE control block */
349 U32 count; /* Loop Counter */
350 U32 numTb; /* Number of Tbs */
351 KwDlRbCb *rbCb; /* RB Control Block */
352 KwDatReq datReq; /* PDUs Information */
353 RguDDatReqInfo *datReqInfo; /* Data Request Information */
354 KwRguSapCb *rguSap; /* MAC SAP CB */
355 U32 totNumPdu; /* Total number of PDUS */
356 RguStaIndTb *staIndTb = NULLP;
357 RguDatReqTb *datReqTb = NULLP;
358 RguDStaIndPerUe *staInd = NULLP;
360 U32 grantPerLch[RGU_MAX_LC] = {0};
362 /* kw005.201 added support for L2 Measurement */
363 #ifdef LTE_L2_MEAS_LOSS_DELAY
366 #endif /* LTE_L2_MEAS */
370 U32 staIndSz=0,datIndSz = 0;
375 KW_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap->pst.region,
376 gCb->u.dlCb->rguDlSap->pst.pool,
377 datReqInfo,sizeof(RguDDatReqInfo));
378 #if (ERRCLASS & ERRCLS_ADD_RES)
379 if ( datReqInfo == NULLP )
381 RLOG_ARG0(L_FATAL,DBG_CELLID,staIndInfo->cellId,
382 "Memory allocation failed");
385 #endif /* ERRCLASS & ERRCLS_ADD_RES */
386 for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++)
388 staInd = &staIndInfo->staInd[idx];
389 /* Fetch Ue control block */
390 if(ROK != kwDbmFetchDlUeCb(gCb,staInd->rnti,staIndInfo->cellId,&ueCb))
392 /* Fetch UeCb failed */
393 RLOG_ARG1(L_ERROR, DBG_CELLID,staIndInfo->cellId,
394 "UeId[%u]:ueCb not found",
396 /* If ueCb is not found for current rnti then continue to look for next rnti*/
399 /* kw002.201 Removed the allocation of KwDatReq */
400 /* kw004.201 Used SSI function to initialize the variable */
401 cmMemset( (U8 *)&datReq, 0, sizeof(KwDatReq) );
403 for (numTb = 0; numTb < staInd->nmbOfTbs; numTb++)
405 staIndTb = &(staInd->staIndTb[numTb]);
406 datReqTb = &(datReqInfo->datReq[idx].datReqTb[numTb]);
408 ueCb->tbIdx = (ueCb->tbIdx+1) % KW_MAX_TB_PER_UE;
410 for (count = 0;count < staIndTb->nmbLch; count++)
413 /*Calculate the total grant size from MAC */
414 if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC)
415 || (staIndTb->lchStaInd[count].lcId == 0))
417 /* TODO : Need to figure out why this is happening */
422 grantPerLch[staIndTb->lchStaInd[count].lcId] += staIndTb->lchStaInd[count].totBufSize;
425 rbCb = ueCb->lCh[staIndTb->lchStaInd[count].lcId - 1].dlRbCb;
427 if (rbCb && (!kwDlUtlIsReestInProgress(rbCb)))
430 staIndSz += staIndTb->lchStaInd[count].totBufSize;
431 datReq.pduSz = staIndTb->lchStaInd[count].totBufSize;
433 datReq.totMacGrant = grantPerLch[staIndTb->lchStaInd[count].lcId];
435 kwUtlGetCurrTime(&datReq.boRep.oldestSduArrTime);
436 if ( CM_LTE_MODE_UM == rbCb->mode )
438 kwUmmProcessSdus(gCb,rbCb,&datReq);
440 else if ( CM_LTE_MODE_AM == rbCb->mode )
442 kwAmmProcessSdus(gCb,rbCb,&datReq,staInd->fillCtrlPdu);
445 grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant;
447 if ( 0 == datReq.pduInfo.numPdu )
451 totNumPdu += datReq.pduInfo.numPdu;
452 cmMemcpy((U8 *)(&(datReqTb->lchData[count].pdu)),
453 (U8 *)(&(datReq.pduInfo)),sizeof(KwPduInfo));
457 for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++)
460 SFndLenMsg(datReqTb->lchData[count].pdu.mBuf[numPdu],&len);
463 datReqTb->lchData[count].setMaxUlPrio = FALSE;
464 if (KW_AM_IS_POLL_BIT_SET(AMDL) &&
465 (AMDL.sduQ.count > 1))
467 /* Poll bit is set indicate to MAC*/
468 datReqTb->lchData[count].setMaxUlPrio = TRUE;
470 datReqTb->lchData[count].boReport.bo = datReq.boRep.bo;
473 datReqTb->lchData[count].boReport.estRlcHdrSz =
474 datReq.boRep.estHdrSz;
475 datReqTb->lchData[count].boReport.staPduPrsnt =
476 datReq.boRep.staPduPrsnt;
477 #endif /* CCPU_OPT */
478 datReqTb->lchData[count].boReport.staPduBo =
479 datReq.boRep.staPduBo;
480 datReqTb->lchData[count].lcId = staIndTb->lchStaInd[count].lcId;
483 /* Set if Bearer is UM */
484 if ( CM_LTE_MODE_UM == rbCb->mode )
486 datReqTb->lchData[count].freeBuff = TRUE;
490 datReqTb->lchData[count].freeBuff = FALSE;
494 /* kw005.201 added support for L2 Measurement */
495 #ifdef LTE_L2_MEAS_LOSS_DELAY
496 datReqTb->rguSnInfo->lchMap[count].lChId =
497 staIndTb->lchStaInd[count].lcId;
498 /* In some cases L2 Measurement for few of the lcId may be off,
499 * in this case we are assigning snList to 0xffff
501 for(snIdx1 = 0; snIdx1 < RGU_MAX_PDU; snIdx1++)
503 datReqTb->rguSnInfo->lchMap[count].snList[snIdx1] = 0xffff;
505 if(tbSnMap->numSn != 0)
508 for(snIdx1=tbSnMap->prevNumSn;snIdx1 < tbSnMap->numSn;snIdx1++)
510 datReqTb->rguSnInfo->lchMap[count].snList[snIdx2++] =
511 tbSnMap->snSduMap[snIdx1].sn;
513 tbSnMap->prevNumSn = tbSnMap->numSn;
516 datReqTb->lchData[count].boReport.oldestSduArrTime =
517 datReq.boRep.oldestSduArrTime;
518 /* kw004.201 Used SSI function to initialize the variable */
519 cmMemset( (U8 *)&datReq, 0, sizeof(KwDatReq) );
523 if(ueCb->l2MeasTbCb[ueCb->tbIdx]!= NULLP)
525 datReqTb->tbId = ueCb->tbIdx;
529 datReqTb->tbId = KW_INVALID_TBID;
532 datReqTb->nmbLch = staIndTb->nmbLch;
533 /*adding the check to make sure that lcId is not sent as 0
534 * when no data is there in datReq */
535 if ( 0 == totNumPdu )
537 datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId;
539 /* kw005.201 added support for L2 Measurement */
540 #ifdef LTE_L2_MEAS_LOSS_DELAY
541 if(tbSnMap->numSn == 0)
543 KW_FREE(tbSnMap,sizeof(KwTbSnMap));
544 KW_FREE(datReqTb->rguSnInfo,sizeof(RguSnMapInfo));
545 datReqTb->rguSnInfo = NULLP;
546 kwCb.kwL2Cb.curTbSnMap = NULLP;
547 datReqTb->snMapPres = FALSE;
551 cmHashListInsert(&(kwCb.kwL2Cb.tbHlCp),(PTR)tbSnMap,
552 (U8 *) &(tbSnMap->tbId), (U16)sizeof(tbSnMap->tbId));
553 kwCb.kwL2Cb.curTbSnMap = NULLP;
555 #endif /* LTE_L2_MEAS */
557 datReqInfo->datReq[idx].nmbOfTbs = staInd->nmbOfTbs;
558 datReqInfo->datReq[idx].transId = staInd->transId;
559 datReqInfo->datReq[idx].rnti = staInd->rnti;
561 datReqInfo->cellId = staIndInfo->cellId;
562 datReqInfo->nmbOfUeGrantPerTti = staIndInfo->nmbOfUeGrantPerTti;
563 /* If trace flag is enabled send the trace indication */
564 if(TRUE == gCb->init.trc )
566 /* Populate the trace params */
567 kwLmmSendTrc(gCb,EVTRGUDDATREQ, NULLP);
570 rguSap = &(gCb->u.dlCb->rguDlSap[suId]);
572 KwLiRguDDatReq(&rguSap->pst,rguSap->spId,datReqInfo);
579 * Handler for sending Status Response to MAC.
582 * This function is used by RLC entity for sending
583 * status response to MAC after receiving a SDU from
586 * @param[in] gCb RLC instance Control block
587 * @param[in] rbCb Radio Bearer Control Block
588 * @param[in] bo Buffer Occupancy
589 * @param[in] estHdrSz Estimated Header Size
590 * @param[in] staPduPrsnt Status PDU present or not
597 PUBLIC S16 kwUtlSndDStaRsp
607 PUBLIC S16 kwUtlSndDStaRsp(gCb,rbCb,bo,estHdrSz,staPduPrsnt,staPduBo)
616 RlcMacBOStatus boStatus; /* Buffer occupancy status information */
617 KwRguSapCb *rguSap; /* MAC SAP Information */
618 TRC3(kwUtlSndDStaRsp)
620 if ((rbCb->lastRprtdBoToMac > (U32)8000) && (rbCb->boUnRprtdCnt < (U32)5)
621 && (!staPduPrsnt) && ((CM_LTE_MODE_AM == rbCb->mode ) && (AMDL.nxtRetx == NULLP)))
623 rbCb->boUnRprtdCnt++;
628 rguSap = &(gCb->u.dlCb->rguDlSap[rbCb->rguSapId]);
630 rbCb->boUnRprtdCnt = (U32)0;
631 rbCb->lastRprtdBoToMac = (U32)bo;
633 boStatus.cellId = rbCb->rlcId.cellId;
634 boStatus.rnti = rbCb->rlcId.ueId;
635 boStatus.commCh = FALSE;
636 boStatus.lcId = rbCb->lch.lChId;
639 /* If trace flag is enabled send the trace indication */
640 if(gCb->init.trc == TRUE)
642 /* Populate the trace params */
643 kwLmmSendTrc(gCb, EVTRLCBOSTA, NULLP);
645 /* Send Status Response to MAC layer */
646 RlcMacSendBOStatus(&rguSap->pst,rguSap->spId,&boStatus);
655 * Handler for emptying the SDU queue.
658 * This function is used to empty the SDU queue when
659 * a re-establishment request is received from the
662 * @param[in] gCb RLC instance control block
663 * @param[in] rbCb Radio bearer control block
664 * @param[in] sduQ SDU queue to be emptied
668 /* kw005.201 added support for L2 Measurement */
669 #ifdef LTE_L2_MEAS_RLC
671 PUBLIC Void kwUtlEmptySduQ
678 PUBLIC Void kwUtlEmptySduQ(gCb,rbCb, sduQ)
685 PUBLIC Void kwUtlEmptySduQ
691 PUBLIC Void kwUtlEmptySduQ(gCb,sduQ)
697 #ifdef LTE_L2_MEAS_RLC
698 CmLListCp *sduSnMapQ; /* SDU Sequence number map queue */
699 CmLList *firstSduSnMap; /* First Node in SDU SnMap Queue */
700 KwSduSnMap *sduSnMap; /* SDU Sn Map */
704 firstSduSnMap = NULLP;
708 sduSnMapQ = &rbCb->sduSnMapQ;
709 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
713 sduSnMap = (KwSduSnMap *)firstSduSnMap->node;
714 if(sduSnMap != NULLP)
716 cmLListDelFrm(&(rbCb->sduSnMapQ), &(sduSnMap->lstEnt));
717 KW_FREE(sduSnMap, sizeof(KwSduSnMap));
718 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
722 CM_LLIST_NEXT_NODE(sduSnMapQ, firstSduSnMap);
732 * Handler for calculating the Length Indicator (LI) length for a SDU
735 * This function is used to calculate the LI (Length Indicator) length
736 * which has to be substracted from the pduSize to correctly match the
737 * formed PDU(s) size with the size requested by MAC.
739 * @param[in] gCb RLC instance control block
740 * @param[in] numLi Number of LIs already present
741 * @param[in] msgLen Size of the SDU
742 * @param[in/out] pduSz Size of the pDU to be formed
747 PUBLIC Void kwUtlCalcLiForSdu
755 PUBLIC Void kwUtlCalcLiForSdu(gCb,numLi,msgLen,pduSz)
762 TRC2(kwUtlCalcLiForSdu)
764 if ( (*pduSz > msgLen) && (msgLen < KW_2K_BYTE))
766 if(0 == (numLi & KW_BIT0)) /* check if number of LIs are odd or even */
768 /* if number of LI's are even 2 bytes needed */
773 /* if number of LI's are odd one byte needed */
783 * Function to set that re-establishment has started for an RB
786 * This function is used to set the reestInProgress flag to TRUE.
787 * This also sets the estimated header size to 0 and sends bo as
788 * 0 to MAC so that RLC does not need to transmit any data.
789 * If the poll re-transmit timer is running for the RB;
792 * @param[in] gCb RLC instance control block
793 * @param[in] rbCb RB for which re-establishment has started
798 PUBLIC Void kwDlUtlSetReestInProgressForRB
804 PUBLIC Void kwDlUtlSetReestInProgressForRB(gCb,rbCb)
809 TRC2(kwDlUtlSetReestInProgressForRB)
811 rbCb->reestInProgress = TRUE;
813 if(rbCb->mode == CM_LTE_MODE_AM )
815 rbCb->m.amDl.estHdrSz = 0;
817 if(kwChkTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR))
819 kwStopTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR);
824 rbCb->m.umDl.estHdrSz= 0;
827 kwUtlSndDStaRsp(gCb, rbCb, 0, 0, FALSE,0);
835 * Function to check if re-establishment is ongoing for an RB
837 * @param[in] rbCb RB for which re-establishment is to be checked
840 * TRUE : Re-establishment is in progress
841 * FALSE : Re-establishment is not in progress
844 PUBLIC Bool kwDlUtlIsReestInProgress
849 PUBLIC Bool kwDlUtlIsReestInProgress(rbCb)
853 TRC2(kwDlUtlSetReestInProgressForRB)
855 RETVALUE(rbCb->reestInProgress);
861 * Function to set re-establishment to FALSE
863 * @param[in] rbCb RB for which re-establishment is to be reset
868 PUBLIC Void kwDlUtlResetReestInProgress
873 PUBLIC Void kwDlUtlResetReestInProgress(rbCb)
877 TRC2(kwDlUtlSetReestInProgressForRB)
879 rbCb->reestInProgress = FALSE;
885 * Function to set that re-establishment has started for all the RBs
886 * of an UE; except for SRB1
888 * @detail: For SRB1 only the poll-retransmit timer is stopped
890 * @param[in] gCb RLC instance control block
891 * @param[in] ueCb UE for which re-establishment has started
896 PUBLIC Void kwDlUtlSetReestInProgressForAllRBs
902 PUBLIC Void kwDlUtlSetReestInProgressForAllRBs(gCb,ueCb)
909 TRC2(kwDlUtlSetReestInProgressForAllRBs)
911 for(rbIdx = 0;rbIdx < KW_MAX_SRB_PER_UE;rbIdx++)
913 if(ueCb->srbCb[rbIdx] != NULLP)
915 if(ueCb->srbCb[rbIdx]->rlcId.rbId != 1)
917 kwDlUtlSetReestInProgressForRB(gCb,ueCb->srbCb[rbIdx]);
921 /* For SRB we just need to stop the poll re-transmit timer */
922 if(kwChkTmr(gCb, (PTR)ueCb->srbCb[rbIdx], KW_EVT_AMDL_POLL_RETX_TMR))
924 kwStopTmr(gCb, (PTR)ueCb->srbCb[rbIdx], KW_EVT_AMDL_POLL_RETX_TMR);
930 for(rbIdx = 0;rbIdx < KW_MAX_DRB_PER_UE;rbIdx++)
932 if(ueCb->drbCb[rbIdx] != NULLP)
934 kwDlUtlSetReestInProgressForRB(gCb,ueCb->drbCb[rbIdx]);
942 * @brief Function to increment number of SDUs transmitted
943 * in KWU SAP statistics
946 * @param[in] kwuSap KWU SAP in which to increment the counter
951 PUBLIC Void kwUtlIncrementKwuStsSduTx
956 PUBLIC Void kwUtlIncrementKwuStsSduTx(kwuSap)
965 * @brief Function to increment number of bytes and PDUs transmitted
966 * in General statistics
969 * @param[in] genSts KWU SAP in which to increment the counter
970 * @param[in] pdu The PDU which is sent
975 PUBLIC Void kwUtlIncrementGenStsBytesAndPdusSent
981 PUBLIC Void kwUtlIncrementGenStsBytesAndPdusSent(genSts, pdu)
987 SFndLenMsg(pdu, &bytesSent);
988 genSts->bytesSent += bytesSent;
994 * @brief Function to initialize the data structures used to free memory
997 * @param[in] gCb RLC instance control block
998 * @param[out] toBeFreed Pointer to the freeing structure. This is
1004 PUBLIC Void kwUtlInitToBeFreed
1007 KwDlDataToBeFreed *toBeFreed
1010 PUBLIC Void kwUtlInitToBeFreed(gCb, toBeFreed)
1012 KwDlDataToBeFreed *toBeFreed;
1015 cmLListInit(&(toBeFreed->sduLst));
1016 cmLListInit(&(toBeFreed->rbLst));
1017 cmLListInit(&(toBeFreed->reTxLst));
1018 cmLListInit(&(toBeFreed->txLst));
1024 * @brief Function to initialize the DL self Pst structure
1027 * @param[in] gCb RLC instance control block
1032 PUBLIC Void kwUtlInitializeSelfPst
1037 PUBLIC Void kwUtlInitializeSelfPst(gCb)
1041 Pst *selfPst = &gCb->u.dlCb->selfPst;
1043 KW_MEM_SET(selfPst, 0, sizeof(Pst));
1044 selfPst->srcProcId = SFndProcId();
1045 selfPst->dstProcId = SFndProcId();
1046 selfPst->dstEnt = gCb->init.ent;
1047 selfPst->dstInst = gCb->init.inst; /* this is for the DL instance */
1048 selfPst->srcEnt = gCb->init.ent;
1049 selfPst->srcInst = gCb->init.inst; /* DL instance will send to itself */
1050 selfPst->prior = PRIOR3;
1051 selfPst->event = UDX_EVT_DL_CLEANUP_MEM;
1055 * @brief Function to send a DL cleanup event
1058 * @param[in] gCb RLC instance control block
1063 PUBLIC Void kwUtlRaiseDlCleanupEvent
1068 PUBLIC Void kwUtlRaiseDlCleanupEvent(gCb)
1072 #ifdef KWSELFPSTDLCLEAN
1073 if(!gCb->u.dlCb->eventInQueue)
1075 SPstTsk(&gCb->u.dlCb->selfPst, gCb->u.dlCb->selfPstMBuf);
1076 gCb->u.dlCb->eventInQueue = TRUE;
1083 * @brief Function to add a SDU to the to be freed sdu list
1086 * @param[in] gCb RLC instance control block
1087 * @param[in] sdu SDU to be added to the list
1092 PUBLIC Void kwUtlAddSduToBeFreedQueue
1098 PUBLIC Void kwUtlAddSduToBeFreedQueue(gCb, sdu)
1103 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.sduLst), &(sdu->lstEnt));
1108 * @brief Function to add a re-transmitted pdu to the to be freed list
1111 * @param[in] gCb RLC instance control block
1112 * @param[in] retx Re-transmitted pdu to be added to the list
1117 PUBLIC Void kwUtlAddReTxPduToBeFreedQueue
1123 PUBLIC Void kwUtlAddReTxPduToBeFreedQueue(gCb, retx)
1128 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.reTxLst), &(retx->lstEnt));
1133 * @brief Function to add a transmitted pdu to the to be freed list
1136 * @param[in] gCb RLC instance control block
1137 * @param[in] pdu PDU to be added to the list
1142 PUBLIC Void kwUtlAddTxPduToBeFreedQueue
1148 PUBLIC Void kwUtlAddTxPduToBeFreedQueue(gCb, pdu)
1153 pdu->rlsLnk.node = (PTR)pdu;
1154 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.txLst), &(pdu->rlsLnk));
1160 * function to free/release the Acknowledged mode RBCB buffers
1163 * This primitive Frees the Acknowledged Mode RbCb transmission Buffer,
1164 * retransmission Buffer and reciption Buffers
1166 * @param [in] gCb - RLC instance control block
1167 * @param [in] rbCb - Downlink RB Control Block
1168 * @param [in,out] toBeFreed - Number of buffers to be freed
1171 * - TRUE if more data to be freed
1172 * - FALSE if all the data has been freed
1175 PRIVATE Bool kwUtlFreeDlAmRbMemory
1182 PRIVATE Bool kwUtlFreeDlAmRbMemory(gCb, rbCb, toBeFreed)
1188 KwRetx *retx; /* retransmission buffer */
1189 KwSn mTxNext; /* send state variable */
1192 TRC2(kwUtlFreeDlAmRbMemory)
1195 MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1197 /* TODO : to be checked changed from <= to < */
1198 while ((0 < mTxNext) && *toBeFreed)
1200 txBuf = kwUtlGetTxBuf(AMDL.txBufLst, AMDL.txNextAck);
1201 if (txBuf && txBuf->pduLst.first)
1203 while(txBuf->pduLst.first)
1205 KwDlPduInfo *pduInfo = (KwDlPduInfo *)(txBuf->pduLst.first->node);
1206 KW_FREE_BUF(pduInfo->pdu);
1207 /* Delete node from the txBuf Pdu lst */
1208 cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first);
1209 KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo));
1211 kwUtlDelTxBuf(AMDL.txBufLst, txBuf, gCb);
1212 if(gCb->u.dlCb->shutdownReceived == 0)
1217 AMDL.txNextAck = (AMDL.txNextAck + 1) & AMDL.snModMask;
1218 MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1226 KW_FREE(gCb,AMDL.txBufLst, (KW_TX_BUF_BIN_SIZE * sizeof(CmLListCp)));
1229 KW_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1230 while (retx && (*toBeFreed)) /* Till to be freed becomes 0 */
1233 KW_FREE_BUF(retx->seg);
1235 cmLListDelFrm(&AMDL.retxLst, &retx->lstEnt);
1236 KW_FREE_WC(gCb, retx, sizeof(KwRetx));
1238 KW_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1239 if(gCb->u.dlCb->shutdownReceived == 0)
1246 AMDL.nxtRetx = NULLP;
1248 /* clean up if there is info about STATUS PDU to be sent */
1252 udxPst = &gCb->u.dlCb->udxDlSap->pst;
1253 KW_FREE_SHRABL_BUF_WC(udxPst->region,
1256 sizeof(KwUdxDlStaPdu));
1257 AMDL.pStaPdu = NULLP;
1264 if(gCb->u.dlCb->shutdownReceived)
1273 * @brief Function to free memory from the DL instance
1276 * @param[in] gCb RLC instance control block
1281 PUBLIC Void kwUtlFreeDlMemory
1286 PUBLIC Void kwUtlFreeDlMemory(gCb)
1292 /* safety check, in case some event was still lying in the queue after
1293 the dlCb was deleted*/
1299 KwDlDataToBeFreed* pToBeFreed = &gCb->u.dlCb->toBeFreed;
1301 if(gCb->u.dlCb->shutdownReceived)
1303 toBeFreed = pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count + pToBeFreed->rbLst.count;
1307 if ((pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count) > (3 * KW_MAX_TO_BE_FREED))
1309 #if !defined(KWSELFPSTDLCLEAN) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
1310 if (isDatReqProcessed)
1312 toBeFreed = (2 *KW_MAX_TO_BE_FREED);
1317 toBeFreed = (3 *KW_MAX_TO_BE_FREED)/2;
1322 toBeFreed = KW_MAX_TO_BE_FREED;
1327 gCb->u.dlCb->eventInQueue = FALSE; /* reset as we have received the event
1328 and are processing it */
1330 /* Free from the ReTx list */
1331 lst = &pToBeFreed->reTxLst;
1333 while((lst->first) && toBeFreed && (pToBeFreed->reTxLst.count > 100))
1335 while((lst->first) && toBeFreed)
1338 KwRetx* seg = (KwRetx *)(lst->first->node);
1339 cmLListDelFrm(lst, lst->first);
1340 KW_FREE_BUF_WC(seg->seg);
1341 KW_FREE_WC(gCb,seg, sizeof(KwRetx));
1345 /* Free from the Tx list */
1346 lst = &pToBeFreed->txLst;
1348 while((lst->first) && toBeFreed && (pToBeFreed->txLst.count > 100))
1350 while((lst->first) && toBeFreed)
1353 KwTx* pdu = (KwTx *)(lst->first->node);
1354 cmLListDelFrm(lst, lst->first);
1355 while(pdu->pduLst.first)
1357 KwDlPduInfo *pduInfo = (KwDlPduInfo *)(pdu->pduLst.first->node);
1359 cmLListDelFrm(&pdu->pduLst, pdu->pduLst.first);
1360 KW_FREE_BUF_WC(pduInfo->pdu);
1361 KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo));
1363 KW_FREE_WC(gCb,pdu, sizeof(KwTx));
1367 /* Free from the SDU queue */
1368 lst = &pToBeFreed->sduLst;
1370 while((lst->first) && toBeFreed && (pToBeFreed->sduLst.count > 100))
1372 while((lst->first) && toBeFreed)
1375 KwSdu* sdu = (KwSdu *)(lst->first->node);
1376 KW_RMV_SDU(gCb, lst, sdu);
1380 /* Free from the RBs */
1381 lst = &pToBeFreed->rbLst;
1383 while((lst->first) && toBeFreed && (pToBeFreed->rbLst.count > 100))
1385 while((lst->first) && toBeFreed)
1388 KwDlRbCb* rbCb = (KwDlRbCb *)(lst->first->node);
1389 Bool moreToBeFreed = kwUtlFreeDlAmRbMemory(gCb, rbCb,&toBeFreed);
1392 cmLListDelFrm(lst, lst->first);
1393 KW_FREE_WC(gCb, rbCb, sizeof(KwDlRbCb));
1397 if ((toBeFreed == 0) && !(gCb->u.dlCb->shutdownReceived))
1399 kwUtlRaiseDlCleanupEvent(gCb);
1409 * @brief Function to initialise measurement
1413 * @param[in] gCb RLC Instance Control Block
1418 S16 kwUtlL2MeasDlInit(KwCb *gCb)
1422 gCb->u.dlCb->kwL2Cb.kwNumMeas=0;
1423 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
1425 cmMemset((U8 *)&(gCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]), 0, sizeof(KwL2MeasEvtCb));
1427 gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_DISC].measCb.measType = LKW_L2MEAS_DL_DISC;
1428 gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_IP].measCb.measType = LKW_L2MEAS_DL_IP;
1429 gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_DELAY].measCb.measType= LKW_L2MEAS_DL_DELAY;
1430 gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_UU_LOSS].measCb.measType= LKW_L2MEAS_UU_LOSS;
1431 gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_ACT_UE].measCb.measType= LKW_L2MEAS_ACT_UE;
1437 * @brief Function to detect the data Burst start Condition in a DTCH
1441 * @param[in] rbCb RB control block
1442 * @param[in] contSduLst Array of Contained SDUs in the DTCH
1443 * @param[in] dataVol Available data in the DTCH
1444 * @param[in] schPduSz Total grant Size given by MAC
1450 PUBLIC Void kwUtlUpdateBurstSdus
1454 KwContSduLst *contSduLst,
1459 PUBLIC Void kwUtlUpdateBurstSdus (gCb, rbCb, contSduLst, dataVol, schPduSz)
1462 KwContSduLst *contSduLst;
1468 KwL2MeasDlIpTh *l2MeasDlIpThruput = NULLP;
1469 KwL2MeasTb *l2MeasTb = NULLP;
1472 VOLATILE U32 startTime = 0;
1473 KwContSduLst *dstContSduLst;
1474 TRC2(kwUtlUpdateBurstSdus)
1478 SStartTask(&startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1480 l2MeasDlIpThruput = &rbCb->l2MeasIpThruput.dlIpTh;
1482 if(KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb))
1484 if(dataVol > schPduSz)
1486 if(l2MeasDlIpThruput->isBurstAct == FALSE)
1488 l2MeasDlIpThruput->burstStartTime = glblTtiCnt;
1489 l2MeasDlIpThruput->isBurstAct = TRUE;
1490 l2MeasDlIpThruput->burstEndSduId = 0;
1493 { /* This is the case when another burst started before RLC gets the
1494 l2MeasDlIpThruput->burstEndSduId = 0; */
1498 { /* Store the burstEndSduId here */
1499 if((l2MeasDlIpThruput->isBurstAct == TRUE) &&
1500 (!l2MeasDlIpThruput->burstEndSduId))
1502 l2MeasDlIpThruput->burstEndSduId =
1503 l2MeasDlIpThruput->outStngSduArr[l2MeasDlIpThruput->lastSduIdx].sduId;
1506 if(l2MeasDlIpThruput->isBurstAct == TRUE)
1508 l2MeasTb = kwUtlGetCurMeasTb(gCb,rbCb);
1509 /* Get the lChId from index 0, because index 0 is always for DL */
1510 if(l2MeasTb->numLcId >= KW_MAX_ACTV_DRB)
1515 l2MeasTb->sduInfo[l2MeasTb->numLcId].lcId = rbCb->lch.lChId;
1516 /* Copy all the sduIdx from sduInfo to tb sduInfo */
1517 currTbIdx = l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus;
1518 dstContSduLst = &l2MeasTb->sduInfo[l2MeasTb->numLcId];
1520 for(idx = 0; ((idx < contSduLst->numSdus)
1521 && (currTbIdx < KW_L2MEAS_MAX_OUTSTNGSDU)) ; idx++)
1523 dstContSduLst->sduIdx[currTbIdx++] = contSduLst->sduIdx[idx];
1525 l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus += idx;
1526 l2MeasTb->numLcId++;
1527 }/* End of isBurstAct */
1528 }/* End of if measOn */
1531 SStopTask(startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1536 * This function is used to store locally the sduIdx of the sdu in the
1537 * outstanding SDU array
1540 * Stores the Sdu Idx in the contained SDU Array and increments
1541 * the num contained Sdus
1543 * @param[in] sduIdx the Index of the SDU in the outstanding SDU array
1544 * @param[out] contSduLst This stores the indices of the SDUs
1549 PUBLIC Void kwUtlUpdateContainedSduLst
1552 KwContSduLst *contSduLst
1555 PUBLIC Void kwUtlUpdateContainedSduLst(sduIdx, contSduLst)
1557 KwContSduLst *contSduLst;
1560 if (contSduLst->numSdus < KW_L2MEAS_MAX_OUTSTNGSDU)
1562 contSduLst->sduIdx[contSduLst->numSdus] = sduIdx;
1563 contSduLst->numSdus++;
1570 * This function is used to store the sduId of the sdu in the
1571 * outstanding SDU array
1574 * Stores the Sdu Id in the outstanding SDU Array and increments
1575 * the num contained Sdus
1577 * @param[out] dlIpThPut The structure in which the outstanding sdus are
1579 * @param[in] sduIdx The Idx at which the sdu ID is stored
1580 * @param[in] sduLen The size if sdu in bytes
1581 * @param[in] newIdx Indicates if the sdu is already present in the
1587 PUBLIC Void kwUtlUpdateOutStandingSduLst
1589 KwL2MeasDlIpTh *dlIpThPut,
1596 PUBLIC Void kwUtlUpdateOutStandingSduLst(dlIpThPut, sduIdx, sduLen, sduId, newIdx)
1597 KwL2MeasDlIpTh *dlIpThPut;
1604 if (sduIdx < KW_L2MEAS_MAX_OUTSTNGSDU)
1608 dlIpThPut->outStngSduArr[sduIdx].numTb = 0;
1610 dlIpThPut->outStngSduArr[sduIdx].numTb++;
1611 dlIpThPut->outStngSduArr[sduIdx].sduId = sduId;
1612 dlIpThPut->outStngSduArr[sduIdx].sduLen = sduLen;
1617 PUBLIC KwL2MeasTb * kwUtlGetCurMeasTb
1623 PUBLIC KwL2MeasTb * kwUtlGetCurMeasTb(gCb, rbCb)
1628 KwL2MeasTb *curL2MeasTb;
1631 TRC3(kwUtlGetCurMeasTb)
1633 if((curL2MeasTb = rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx]) == NULLP)
1635 /* Intentionally avoiding the KW_ALLOC macro to avoid memset */
1636 if (SGetSBuf(gCb->init.region,
1638 (Data **)&curL2MeasTb,
1639 (Size)sizeof(KwL2MeasTb)) != ROK)
1643 rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx] = curL2MeasTb;
1644 /* Initialize the Meas Tb details */
1645 curL2MeasTb->numLcId = 0;
1646 curL2MeasTb->numLchInfo = 0;
1647 curL2MeasTb->txSegSduCnt = 0;
1648 for (idx = 0; idx < KW_MAX_ACTV_DRB; idx++)
1650 curL2MeasTb->sduInfo[idx].numSdus = 0;
1652 for (idx = 0; idx < KW_MAX_ACTV_DRB; idx++)
1654 curL2MeasTb->lchInfo[idx].numSdus = 0;
1657 RETVALUE(curL2MeasTb);
1663 * @brief Handler for Processing harq status indication
1667 * This function is called when the MAC sends a harq ind Mesage.
1668 * This is used only for UuLoss and Dl Delay and DL Ipthoughput
1671 * @param[in] staInd Harq status indication received from MAC.
1672 * @param[in] ueCb UeCb corresponding to the Tb Id.
1673 * @param[in] tbIdx TB index, 0 for SISO and 0,1 for MIMO.
1681 PUBLIC S16 kwUtlProcHarqInd
1684 RguHarqStatusInd *hqStaInd,
1689 PUBLIC S16 kwUtlProcHarqInd(gCb, hqStaInd, ueCb, tbIdx)
1691 RguHarqStatusInd *hqStaInd;
1697 KwDlRbCb *kwRbCb; /* KW Control Block */
1698 KwL2MeasTb *l2MeasTb = NULLP; /* Measurement TbCb */
1699 U8 lcIdx; /* Logical channel id index */
1700 U8 sduIndx; /* sdu index to out standing sdu list in rbCb */
1701 U32 numSdus; /* number of sdus in the outstanding sdu list */
1702 KwOutStngSduInfo *outStngSduArr; /* Outstanding sdu list */
1709 VOLATILE U32 startTime = 0;
1710 /*kw005.201 Code added for DL IP thruput measurement*/
1712 TRC3(kwUtlProcHarqInd)
1715 SStartTask(&startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1718 if(hqStaInd->tbId[tbIdx] >= KW_INVALID_TBID)
1723 /* Find the L2 measurement tbCb to process DL Ip thruput*/
1724 l2MeasTb = ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]];
1725 if(l2MeasTb == NULLP)
1729 /* For each logical channel in the tbCb, process
1730 * and get the DL IP thruput */
1731 ackTime = SGetTtiCount();
1732 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLcId) && (lcIdx < KW_MAX_ACTV_DRB)); lcIdx++)
1734 timeAddedFlag = FALSE;
1735 if((kwRbCb = ueCb->lCh[l2MeasTb->sduInfo[lcIdx].lcId - 1].dlRbCb)
1740 /* fix for DL IP stop*/
1741 if (!gCb->u.dlCb->kwL2Cb.measOn[kwRbCb->qci]
1742 || (kwRbCb->rlcId.rbType == CM_LTE_SRB))
1747 /* Get the outstanding SDUs using sdu index stored in Container sduList
1748 * and check for HARQ ACK/NACK */
1749 numSdus = l2MeasTb->sduInfo[lcIdx].numSdus;
1751 if ((numSdus >= KW_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1755 totlSduCnt += numSdus;
1757 if (KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,kwRbCb))
1759 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1761 outStngSduArr =&(kwRbCb->l2MeasIpThruput.dlIpTh.outStngSduArr[\
1762 l2MeasTb->sduInfo[lcIdx].sduIdx[sduIndx]]);
1763 if(hqStaInd->status[tbIdx] == TRUE)
1765 /* If ACK is for burst End Sdu Id set burstActive
1766 * to FALSE and accumulate time */
1767 if((kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1768 outStngSduArr->sduId) && (outStngSduArr->numTb == 1))
1770 kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1771 /*Update the l2Sts structure for calculating throughput*/
1772 kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.volSummation
1773 += outStngSduArr->sduLen;
1775 kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1776 += glblTtiCnt - kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1777 outStngSduArr->sduId = 0;
1778 outStngSduArr->sduLen = 0;
1779 outStngSduArr->numTb = 0;
1780 kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1783 /* If burst is active and this sdu is only transmitted in single TB then
1784 * accumulate volume and clear the outstanding sduList */
1785 if((kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) &&
1786 (--(outStngSduArr->numTb) == 0))
1788 kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.volSummation
1789 += outStngSduArr->sduLen;
1791 if(timeAddedFlag == FALSE)
1793 kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1794 += glblTtiCnt - kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1795 kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime = glblTtiCnt;
1796 timeAddedFlag = TRUE;
1798 outStngSduArr->sduId = 0;
1799 outStngSduArr->sduLen = 0;
1801 }/* End of status == TRUE */
1804 if(kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE)
1806 if((kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1807 outStngSduArr->sduId))
1809 kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1810 kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1812 /* Clear the outstanding sdu list */
1813 outStngSduArr->sduId = 0;
1814 outStngSduArr->sduLen = 0;
1815 outStngSduArr->numTb = 0;
1822 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLchInfo) && (lcIdx < KW_MAX_ACTV_DRB)); lcIdx++)
1824 if((kwRbCb = ueCb->lCh[l2MeasTb->lchInfo[lcIdx].lcId - 1].dlRbCb)
1829 numSdus = l2MeasTb->lchInfo[lcIdx].numSdus;
1835 if ((numSdus > KW_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1840 if(hqStaInd->status[tbIdx] == TRUE)
1842 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1844 delay = KW_TIME_DIFF(ackTime,l2MeasTb->lchInfo[lcIdx].sduInfo[sduIndx].arvlTime);
1845 KW_UPD_PDCP_L2_DLDELAY_STS(gCb,kwRbCb, delay);
1847 /* Case of sduInfo not updated */
1848 if (totlSduCnt == 0)
1850 totlSduCnt = numSdus;
1852 KW_UPD_L2_UU_LOSS_POS_PKTS(gCb,kwRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1856 /* Case of sduInfo not updated */
1857 if (totlSduCnt == 0)
1859 totlSduCnt = numSdus;
1861 KW_UPD_L2_UU_LOSS_PKTS(gCb,kwRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1864 /* Free this tb, deallocate the memory */
1865 KW_FREE(gCb, l2MeasTb, sizeof(KwL2MeasTb));
1866 ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]] = NULLP;
1869 SStopTask(startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1872 }/* end of kwUtlProcHarqInd */
1876 * @brief Handler for Sending L2 Measurement confirm.
1880 * This function sends a consolidates the mesaurements taken during
1881 * this time and sends the confirm .
1883 * @param[in] measEvtCb Measurement Event Control Block.
1891 PUBLIC S16 kwUtlSndDlL2MeasCfm
1894 KwL2MeasEvtCb *measEvtCb
1897 PUBLIC S16 kwUtlSndDlL2MeasCfm(gCb, measEvtCb)
1899 KwL2MeasEvtCb *measEvtCb;
1903 KwL2MeasCb *measCb = NULLP;
1904 KwL2MeasCfmEvt measCfmEvt;
1911 /* Discard new changes starts */
1914 /* Discard new changes ends */
1916 TRC3(kwUtlSndL2MeasCfm)
1918 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
1920 RLOG1(L_DEBUG,"kwUtlSndL2MeasCfm(transId(%ld))", measEvtCb->transId);
1922 RLOG1(L_DEBUG,"kwUtlSndL2MeasCfm(transId(%d))", measEvtCb->transId);
1925 /* Clean up the RB data structures */
1926 measCb = &measEvtCb->measCb;
1928 cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt));
1929 measCfmEvt.transId = measEvtCb->transId;
1931 measCfmEvt.measType = measCb->measType;
1932 measCfmEvt.status.status = LCM_PRIM_OK;
1933 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
1935 if(measCb->measType & LKW_L2MEAS_DL_IP)
1937 KwL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
1938 KwL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
1940 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
1942 pUeInfoLstCfm[cfmIdx].numCfm = 0;
1943 if (pUeInfoLstCb[cntr].isValid == TRUE)
1945 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
1946 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
1947 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
1949 qci = pUeInfoLstCb[cntr].qci[qciIdx];
1950 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
1952 dlDataVol = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation;
1953 dlTime = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation;
1955 if((0 == dlTime) || !(gCb->u.dlCb->kwL2Cb.measOn[qci] & LKW_L2MEAS_DL_IP) )
1957 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 0;
1961 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut =
1962 (dlDataVol / dlTime);
1964 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut *= 8;
1966 /* Reset the values after reporting to Application */
1967 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation = 0;
1968 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation = 0;
1970 measCfmEvt.val.ipThMeas.ueInfoLst[cfmIdx].numCfm++;
1975 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
1979 KwL2Cntr *pMeasData = measCb->val.nonIpThMeas.measData;
1980 KwL2MeasCfmNonIpThMeas *pMeasCfmNonIp = &measCfmEvt.val.nonIpThMeas;
1982 pMeasCfmNonIp->numCfm = 0;
1984 for(qciIdx = 0; qciIdx < LKW_MAX_QCI; qciIdx++)
1986 qci = measCb->val.nonIpThMeas.qci[qciIdx];
1989 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].qci = qci;
1991 if(measCb->measType & LKW_L2MEAS_UU_LOSS)
1993 dLoss = pMeasData[qci].uuLoss.dLoss;
1994 posPkts = pMeasData[qci].uuLoss.posPkts;
1995 if(((posPkts + dLoss) != 0))
1997 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.uuLoss =
1998 ((dLoss * 1000000) / (posPkts + dLoss));
2000 pMeasData[qci].uuLoss.dLoss = 0;
2001 pMeasData[qci].uuLoss.posPkts = 0;
2003 if(measCb->measType & LKW_L2MEAS_DL_DISC)
2006 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 0;
2007 if(pMeasData[qci].dlDisc.totSdus != 0)
2009 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate =
2010 (((pMeasData[qci].dlDisc.discSdus) * 1000000) / (pMeasData[qci].dlDisc.totSdus));
2013 pMeasData[qci].dlDisc.totSdus = 0;
2014 pMeasData[qci].dlDisc.discSdus = 0;
2016 if(measCb->measType & LKW_L2MEAS_DL_DELAY)
2018 if (pMeasData[qci].dlPjSduDelay.numSdus > 0)
2020 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlSduDelay =
2021 (pMeasData[qci].dlPjSduDelay.sduDelay / pMeasData[qci].dlPjSduDelay.numSdus);
2022 pMeasData[qci].dlPjSduDelay.sduDelay = 0;
2023 pMeasData[qci].dlPjSduDelay.numSdus = 0;
2026 pMeasCfmNonIp->numCfm++;
2030 /* Fix Klock warning */
2031 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
2033 } /* kwUtlSndL2MeasCfm */
2036 * @brief Handler for Sending Negative confirm .
2040 * This function is called when the l2 measurement cannot be started
2041 * This function sends negative confirm for all the requests
2043 * @param[in] measReqEvt Measurement Req Structure
2051 PUBLIC S16 kwUtlSndDlL2MeasNCfm
2054 KwL2MeasReqEvt *measReqEvt,
2055 KwL2MeasCfmEvt *measCfmEvt
2058 PUBLIC S16 kwUtlSndDlL2MeasNCfm(gCb,measReqEvt, measCfmEvt)
2060 KwL2MeasReqEvt *measReqEvt;
2061 KwL2MeasCfmEvt *measCfmEvt;
2064 TRC3(kwUtlSndDlL2MeasNCfm)
2066 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
2068 } /* kwUtlSndL2MeasNCfm */
2071 * @brief Handler for resetting the RB data structures
2075 * This function resets the RB data structure after the expiry of
2076 * measurement timer.
2078 * @param[in] measCb Measurement Control Block.
2085 PUBLIC Void kwUtlResetDlL2MeasInKwRb
2092 PUBLIC Void kwUtlResetDlL2MeasInKwRb(gCb, measCb, measType)
2100 KwDlUeCb *ueCb = NULL;
2104 if (measCb->measType & LKW_L2MEAS_DL_IP)
2106 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
2108 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
2110 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
2112 if (measType & LKW_L2MEAS_DL_IP)
2114 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.volSummation = 0;
2115 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.timeSummation = 0;
2116 gCb->u.dlCb->kwL2Cb.measOn[qciIdx] &= ~measType;
2120 if(ROK != kwDbmFetchDlUeCb(gCb,measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
2121 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
2131 /* for now the only meas should be DL discard in this case */
2132 if (measCb->measType & LKW_L2MEAS_DL_DISC)
2135 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2137 U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2139 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.discSdus = 0;
2140 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.totSdus = 0;
2144 if (measCb->measType & LKW_L2MEAS_DL_DELAY)
2147 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2149 U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2151 measCb->val.nonIpThMeas.measData[qciVal].dlPjSduDelay.sduDelay = 0;
2154 measCb->val.nonIpThMeas.numQci = 0;
2156 } /* kwUtlResetDlL2MeasInKwRb */
2159 PRIVATE Void dumpRLCDlRbInformation(KwDlRbCb* dlRbCb)
2161 if(dlRbCb->mode == CM_LTE_MODE_UM)
2163 RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2164 "UM Downlink UEID:%d CELLID:%d Q size = %d",
2166 dlRbCb->rlcId.cellId,
2167 (int)dlRbCb->m.umDl.sduQ.count);
2169 else if(dlRbCb->mode == CM_LTE_MODE_AM)
2172 for(j = 0; j <= (KW_AM_GET_WIN_SZ(dlRbCb->m.amDl.snLen)); j++)
2174 KwTx *txBuf = kwUtlGetTxBuf(dlRbCb->m.amDl.txBufLst, j);
2180 RLOG_ARG4(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2181 "AM Downlink UEID:%d CELLID:%d Sizes SDU Q = %d TX Q = %d ",
2183 dlRbCb->rlcId.cellId,
2184 (int)dlRbCb->m.amDl.sduQ.count,
2186 RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2187 "AM Downlink UEID:%d CELLID:%d RETX Q= %d",
2189 dlRbCb->rlcId.cellId,
2190 (int)dlRbCb->m.amDl.retxLst.count);
2194 Void DumpRLCDlDebugInformation(Void)
2196 KwCb* dlInst = kwCb[1]; /* TODO : Check whether DL is 0 or 1 */
2198 KwDlCb *dlCb = dlInst->u.dlCb;
2200 KwDlUeCb *ueCb = NULLP;
2201 RTLIN_DUMP_DEBUG("RLC Information\n");
2202 RTLIN_DUMP_DEBUG("===============\n");
2203 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
2204 while (ROK == cmHashListGetNext(&dlCb->ueLstCp,
2209 for(i = 0; i< KW_MAX_SRB_PER_UE; i++)
2211 KwDlRbCb* dlRbCb = ueCb->srbCb[i];
2212 if( dlRbCb != NULLP)
2214 dumpRLCDlRbInformation(dlRbCb);
2217 for(i = 0; i< KW_MAX_DRB_PER_UE; i++)
2219 KwDlRbCb* dlRbCb = ueCb->drbCb[i];
2220 if( dlRbCb != NULLP)
2222 dumpRLCDlRbInformation(dlRbCb);
2227 KwDlDataToBeFreed* pToBeFreed = &dlCb->toBeFreed;
2229 RTLIN_DUMP_DEBUG("toBeFreed RETX list size = %d\n",(int)pToBeFreed->reTxLst.count);
2230 RTLIN_DUMP_DEBUG("toBeFreed TX list size = %d\n",(int)pToBeFreed->txLst.count);
2231 RTLIN_DUMP_DEBUG("toBeFreed SDU list size = %d\n",(int)pToBeFreed->sduLst.count);
2232 RTLIN_DUMP_DEBUG("toBeFreed RB list size = %d\n",(int)pToBeFreed->rbLst.count);
2238 * This function frees downlink memory
2252 void kwUtlFreeDlMem()
2256 kwUtlFreeDlMemory(KW_GET_KWCB(KW_DL_INST));
2262 * This function returns current time
2271 void kwUtlGetCurrTime
2276 void kwUtlGetCurrTime(U32 *currTime)
2280 TRC2(kwUtlGetCurrTime)
2282 /* Need t define else part for PAL */
2283 *currTime = SGetTtiCount();
2286 #if defined(MAC_RLC_HARQ_STA_RBUF) || defined (SS_RBUF)
2289 void kwUtlDlBatchProcHqStaInd
2294 void kwUtlDlBatchProcHqStaInd()
2298 /* Read from Ring Buffer and process PDCP packets */
2301 Void *elmIndx = NULLP;
2302 RguHarqStaInd *staInd = NULLP;
2304 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2305 isDatReqProcessed = TRUE;
2307 elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ);
2308 while(NULLP != elmIndx)
2310 staInd = (RguHarqStaInd *)elmIndx;
2311 KwLiRguHqStaInd(&(staInd->pst), 0, &(staInd->hqStatusInd));
2315 SRngIncrRIndx(SS_RNG_BUF_MAC_HARQ);
2317 if((elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ)) == NULLP)
2319 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2320 isDatReqProcessed = FALSE;
2330 * @brief evaluate and trigger PDB based flow control to PDCP
2334 * @param[in] rbCb RB control block
2341 PUBLIC Void kwUtlTrigPdbFlowCntrl
2348 PUBLIC Void kwUtlTrigPdbFlowCntrl(gCb,rbCb,pktAdmitCnt)
2354 KwuFlowCntrlIndInfo *flowCntrlInfo;
2357 kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP;
2359 KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region,
2362 sizeof(KwuFlowCntrlIndInfo));
2363 flowCntrlInfo->rlcId = rbCb->rlcId;
2364 flowCntrlInfo->pktAdmitCnt = pktAdmitCnt;
2365 KwUiKwuFlowCntrlInd(&kwuSap->pst, kwuSap->suId, flowCntrlInfo);
2370 * @brief Store the DL buffer in hashList
2375 * Use the SN % binSize as key and store the received UL buffer
2376 * @param[in] txBufLst List CP array
2377 * @param[in] txBuf transmitted buffer
2378 * @param[in] sn sn of the received buffer
2384 PUBLIC Void kwUtlStoreTxBuf
2386 CmLListCp *txBufLst,
2391 PUBLIC Void kwUtlStoreTxBuf(txBufLst, txBuf, sn)
2392 CmLListCp *txBufLst;
2399 TRC3(kwUtlStoretxBuf)
2400 //printf("S-sn(%d)\n", sn);
2401 hashKey = (sn % KW_TX_BUF_BIN_SIZE );
2403 txBuf->lnk.node = (PTR)txBuf;
2404 cmLListAdd2Tail(&(txBufLst[hashKey]), &txBuf->lnk);
2407 } /* kwUtlStoreRecBuf */
2411 * @brief Retrieve the DL buffer from the list
2416 * Use the SN % binSize as key and retrieve the DL buffer
2417 * @param[in] txBufLst List CP array
2418 * @param[in] sn sn of the transmitted buffer
2424 PUBLIC KwTx* kwUtlGetTxBuf
2426 CmLListCp *txBufLst,
2430 PUBLIC KwTx* kwUtlGetTxBuf(txBufLst, sn)
2431 CmLListCp *txBufLst;
2436 CmLListCp *txBufLstCp;
2438 CmLList *node = NULLP;
2441 //printf("G-sn(%d)\n", sn);
2443 hashKey = (sn % KW_TX_BUF_BIN_SIZE );
2445 txBufLstCp = &txBufLst[hashKey];
2446 CM_LLIST_FIRST_NODE(txBufLstCp, node);
2449 txBuf = (KwTx *) node->node;
2454 CM_LLIST_NEXT_NODE(txBufLstCp, node);
2457 } /* kwUtlStoreTxBuf */
2460 * @brief Delete the DL buffer from the list
2465 * Use the SN % binSize as key and retrieve the DL buffer
2466 * @param[in] txBufLst List CP array
2467 * @param[in] sn sn of the transmitted bffer
2473 PUBLIC Void kwUtlDelTxBuf
2475 CmLListCp *txBufLst,
2480 PUBLIC Void kwUtlDelTxBuf(txBufLst, txBuf, gCb)
2481 CmLListCp *txBufLst;
2487 CmLListCp *txBufLstCp;
2491 hashKey = (txBuf->sn % KW_TX_BUF_BIN_SIZE );
2493 txBufLstCp = &txBufLst[hashKey];
2494 //printf("D-sn(%d)\n", txBuf->hdr.sn);
2495 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2496 KW_FREE_WC(gCb, txBuf, sizeof(KwTx));
2498 } /* kwUtlDelTxBuf */
2502 * @brief Remove the DL buffer from the list
2507 * Use the SN % binSize as key and retrieve the DL buffer
2508 * @param[in] txBufLst List CP array
2509 * @param[in] sn sn of the transmitted bffer
2515 PUBLIC Void kwUtlRemovTxBuf
2517 CmLListCp *txBufLst,
2522 PUBLIC Void kwUtlRemovTxBuf(txBufLst, txBuf, gCb)
2523 CmLListCp *txBufLst;
2529 CmLListCp *txBufLstCp;
2531 TRC3(kwUtlRemovTxBuf)
2533 hashKey = (txBuf->sn % KW_TX_BUF_BIN_SIZE );
2535 txBufLstCp = &txBufLst[hashKey];
2536 //printf("D-sn(%d)\n", txBuf->hdr.sn);
2537 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2539 } /* kwUtlRemovTxBuf */
2543 /********************************************************************30**
2545 **********************************************************************/