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 **********************************************************************/
40 @brief RLC Utility Module
43 /* header (.h) include files */
45 #include "common_def.h"
46 /* kw005.201 added support for L2 Measurement */
50 #include "ckw.h" /* CKW defines */
51 #include "kwu.h" /* CKW defines */
52 #include "lkw.h" /* LKW defines */
53 #include "rgu.h" /* RGU defiens */
55 #include "kw_env.h" /* RLC environment options */
56 #include "kw.h" /* RLC defines */
57 #include "kw_err.h" /* Error defines */
61 /* extern (.x) include files */
62 #include "ckw.x" /* CKW includes */
63 #include "kwu.x" /* KWU includes */
64 #include "lkw.x" /* LKW inlcudes */
65 #include "rgu.x" /* RGU includes */
67 #include "kw.x" /* RLC includes */
68 #include "kw_udx.x" /* UDX interface includes */
69 #include "kw_dl.x" /* RLC downlink includes */
71 #include "rlc_utils.h"
72 #include "rlc_mac_inf.h"
73 #include "du_app_rlc_inf.h"
74 #include "rlc_lwr_inf_api.h"
75 #include "rlc_upr_inf_api.h"
82 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS))
83 uint32_t isDatReqProcessed;
85 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_DL) /* for debugging purpose */
86 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) || defined (SS_RBUF)
87 void rlcUtlDlBatchProcHqStaInd ARGS ((Void));
89 Void ResetRLCStats(Void)
91 RlcCb* dlInst = rlcCb[1];
92 RlcCb* ulInst = rlcCb[0];
93 memset(&gRlcStats, 0, sizeof(RLCStats));
94 memset(&dlInst->genSts,0,sizeof(RlcGenSts));
95 memset(&ulInst->genSts,0,sizeof(RlcGenSts));
99 Void PrintRLCStats(Void)
101 RlcCb* dlInst = rlcCb[1];
102 RlcCb* ulInst = rlcCb[0];
104 DU_LOG("\nINFO --> RLC_DL : RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
105 dlInst->genSts.pdusSent,
106 dlInst->genSts.pdusRetx,
107 dlInst->genSts.protTimeOut,
108 dlInst->genSts.numSduDisc);
109 DU_LOG("\nINFO --> RLC_DL : RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
110 ulInst->genSts.pdusRecv,
111 ulInst->genSts.unexpPdusRecv,
112 ulInst->genSts.errorPdusRecv);
113 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMDL: "
114 "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
115 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
116 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
117 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMDL: "
118 "DRB:%lu MaxRetx:%lu RetransPdus:%lu",
119 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
120 gRlcStats.amRlcStats.numDLRetransPdus);
121 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMUL: "
122 " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ",
123 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
124 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
126 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)\n",
127 dlInst->genSts.pdusSent,
128 dlInst->genSts.pdusRetx,
129 dlInst->genSts.protTimeOut,
130 dlInst->genSts.numSduDisc);
131 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)\n",
132 ulInst->genSts.pdusRecv,
133 ulInst->genSts.unexpPdusRecv,
134 ulInst->genSts.errorPdusRecv);
135 RTLIN_DUMP_DEBUG("RLC Stats:"
136 "RLC_AMDL: StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu DRB:%lu MaxRetx:%lu RetransPdus:%lu \n"
137 "RLC_AMUL: PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu \n",
138 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
139 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
140 gRlcStats.amRlcStats.numDLRetransPdus, gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
141 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
144 Void PrintRLCStats(Void)
146 RlcCb* dlInst = rlcCb[1];
147 RlcCb* ulInst = rlcCb[0];
149 DU_LOG ("\n ================================ RLC STATS ===========================\n");
150 DU_LOG("\nINFO --> RLC_DL : RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)",
151 dlInst->genSts.pdusSent,
152 dlInst->genSts.pdusRetx,
153 dlInst->genSts.protTimeOut,
154 dlInst->genSts.numSduDisc);
155 DU_LOG("\nINFO --> RLC_DL : RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)",
156 ulInst->genSts.pdusRecv,
157 ulInst->genSts.unexpPdusRecv,
158 ulInst->genSts.errorPdusRecv);
159 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMDL: "
160 "StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u ",
161 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu,
162 gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
163 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMDL: "
164 "DRB:%u MaxRetx:%u RetransPdus:%u",
165 gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx,
166 gRlcStats.amRlcStats.numDLRetransPdus);
167 DU_LOG("\nINFO --> RLC_DL : RLC Stats: AMUL: "
168 " PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u ",
169 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
170 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
171 /* RTLIN_DUMP_DEBUG("AM RLC Stats:"
172 "RLC_AMDL: SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) MaxRetx:(%u) WindowStalls: (%u) \n"
173 "RLC_AMUL: DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx :(%u) \n",
174 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
175 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmMaxRetx, gRlcStats.amRlcStats.numRlcAmCellWinStall,
176 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
177 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
179 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)\n",
180 dlInst->genSts.pdusSent,
181 dlInst->genSts.pdusRetx,
182 dlInst->genSts.protTimeOut,
183 dlInst->genSts.numSduDisc);
184 RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)\n",
185 ulInst->genSts.pdusRecv,
186 ulInst->genSts.unexpPdusRecv,
187 ulInst->genSts.errorPdusRecv);
188 RTLIN_DUMP_DEBUG("RLC_AMDL: StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u DRB:%u MaxRetx:%u RetransPdus:%u \n"
189 " SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) WindowStalls: (%u) \n"
191 "RLC_AMUL: PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u \n"
192 " DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx:(%u) \n",
193 gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused,
194 gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb,
195 gRlcStats.amRlcStats.numDLMaxRetx, gRlcStats.amRlcStats.numDLRetransPdus,
196 gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
197 gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmCellWinStall,
198 gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires,
199 gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd,
200 gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
201 gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
205 /*******************************************************************
208 * Handler for storing all DL PDU Info into RLC-MAC interface
209 * struct and sending to lower interface
212 * This function stores DL PDU info for all logical channels
213 * of per UE grant per TTI and sends to MAC
215 * Function : rlcSendDedLcDlData
218 * @return ROK - success
221 * ****************************************************************/
222 uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo)
224 uint8_t ueIdx; /* UE info list iterator */
225 uint8_t tbIdx; /* TB info list iterator */
226 uint8_t lchIdx; /* Lch info list iterator */
227 uint8_t pduIdx; /* RLC PDU list iterator */
228 RguDDatReqPerUe datPerUe; /* DL data info per UE */
229 RguDatReqTb datPerTb; /* DL data info per TB */
230 RguLchDatReq datPerLch; /* DL data info per Lch */
231 RlcData *dlData; /* DL data to be sent to MAC */
232 RlcDlRrcMsgRsp *dlRrcMsgRsp;/* DL Data Msg Rsp sent to DU */
233 Pst pst; /* Post structure */
234 uint16_t pduLen; /* PDU length */
235 uint16_t copyLen; /* Number of bytes copied */
239 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
240 dlData, sizeof(RlcData));
241 if ( dlData == NULLP )
243 DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for dl data");
244 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
245 datReqInfo, sizeof(RguDDatReqInfo));
249 for(ueIdx = 0; ueIdx < datReqInfo->nmbOfUeGrantPerTti; ueIdx++)
251 datPerUe = datReqInfo->datReq[ueIdx];
253 memset(dlData, 0, sizeof(RlcData));
255 dlData->cellId = datReqInfo->cellId;
256 dlData->rnti = datPerUe.rnti;
258 /* Retrieving sfn/slot from transId. It was filled in RlcProcSchedResultRpt */
259 dlData->slotInfo.sfn = datPerUe.transId >> 16;
260 dlData->slotInfo.slot = datPerUe.transId & 0xffff;
263 for(tbIdx = 0; tbIdx < datPerUe.nmbOfTbs; tbIdx++)
265 datPerTb = datPerUe.datReqTb[tbIdx];
266 for(lchIdx = 0; lchIdx < datPerTb.nmbLch; lchIdx++)
268 datPerLch = datPerTb.lchData[lchIdx];
269 for(pduIdx = 0; pduIdx < datPerLch.pdu.numPdu; pduIdx++)
271 dlData->pduInfo[dlData->numPdu].commCh = FALSE;
272 dlData->pduInfo[dlData->numPdu].lcId = datPerLch.lcId;
274 /* Copy Message to fixed buffer to send */
275 ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen);
276 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
277 dlData->pduInfo[dlData->numPdu].pduBuf, pduLen);
279 if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP )
281 DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed");
282 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
284 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
285 dlData->pduInfo[pduIdx].pduLen);
287 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
288 dlData, sizeof(RlcData));
289 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
290 datReqInfo, sizeof(RguDDatReqInfo));
294 ODU_COPY_MSG_TO_FIX_BUF(datPerLch.pdu.mBuf[pduIdx], 0, pduLen, \
295 dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)©Len);
296 dlData->pduInfo[dlData->numPdu].pduLen = pduLen;
299 ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]);
303 }/* For Data per Lch */
304 }/* For Data per Tb */
306 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
307 dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp));
308 if( dlRrcMsgRsp == NULLP )
310 DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for dlRrcMsgRsp");
311 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
313 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
314 dlData->pduInfo[pduIdx].pduLen);
316 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
317 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
318 datReqInfo, sizeof(RguDDatReqInfo));
322 dlRrcMsgRsp->cellId = dlData->cellId;
323 dlRrcMsgRsp->crnti = dlData->rnti;
325 /* Sending DL Data per UE to MAC */
326 memset(&pst, 0, sizeof(Pst));
327 FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
328 if(RlcSendDlDataToMac(&pst, dlData) != ROK)
330 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
332 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
333 dlData->pduInfo[pduIdx].pduLen);
335 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
336 /* Update DL RRC MSG Rsp State */
337 dlRrcMsgRsp->state = TRANSMISSION_FAILED;
340 dlRrcMsgRsp->state = TRANSMISSION_COMPLETE;
342 /* Send Dl RRC Msg Rsp to DU APP */
343 FILL_PST_RLC_TO_DUAPP(pst, RLC_DL_INST, EVENT_DL_RRC_MSG_RSP_TO_DU);
344 if(rlcSendDlRrcMsgRspToDu(&pst, dlRrcMsgRsp) != ROK)
346 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp));
348 } /* For Data per UE */
350 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
351 datReqInfo, sizeof(RguDDatReqInfo));
354 }/* End of rlcSendDedLcDlData */
359 * Handler for sending the data to multiple logical channels of a UE
362 * This function sends the data for one or more logical channels
363 * after processing the SDUs and forming the PDUs.It calls
364 * UMM or AMM functions to form the PDUs for the requested sizes
367 * @param[in] gCb RLC instance Control block
368 * @param[in] staIndInfo Status Indication Information containing the
369 * size of PDU(s) for one or more logical channels
376 uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
380 RlcDlUeCb *ueCb; /* UE control block */
381 uint32_t count; /* Loop Counter */
382 uint32_t numTb; /* Number of Tbs */
383 RlcDlRbCb *rbCb; /* RB Control Block */
384 RlcDatReq datReq; /* PDUs Information */
385 RguDDatReqInfo *datReqInfo; /* Data Request Information */
386 RlcRguSapCb *rguSap; /* MAC SAP CB */
387 uint32_t totNumPdu; /* Total number of PDUS */
388 RguStaIndTb *staIndTb = NULLP;
389 RguDatReqTb *datReqTb = NULLP;
390 RguDStaIndPerUe *staInd = NULLP;
392 uint32_t grantPerLch[RGU_MAX_LC] = {0};
394 /* kw005.201 added support for L2 Measurement */
395 #ifdef LTE_L2_MEAS_LOSS_DELAY
398 #endif /* LTE_L2_MEAS */
402 uint32_t staIndSz=0,datIndSz = 0;
405 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
406 datReqInfo,sizeof(RguDDatReqInfo));
407 #if (ERRCLASS & ERRCLS_ADD_RES)
408 if ( datReqInfo == NULLP )
410 DU_LOG("\nERROR --> RLC_DL : rlcUtlSendToMac: Memory allocation failed");
413 #endif /* ERRCLASS & ERRCLS_ADD_RES */
414 for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++)
416 staInd = &staIndInfo->staInd[idx];
417 /* Fetch Ue control block */
418 GET_UE_IDX(staInd->rnti, ueIdx);
419 if(ROK != rlcDbmFetchDlUeCb(gCb, ueIdx, staIndInfo->cellId,&ueCb))
421 /* Fetch UeCb failed */
422 DU_LOG("\nERROR --> RLC_DL : rlcUtlSendToMac: UeId[%u]:ueCb not found",
424 /* If ueCb is not found for current rnti then continue to look for next rnti*/
427 /* kw002.201 Removed the allocation of RlcDatReq */
428 /* kw004.201 Used SSI function to initialize the variable */
429 memset(&datReq, 0, sizeof(RlcDatReq) );
431 for (numTb = 0; numTb < staInd->nmbOfTbs; numTb++)
433 staIndTb = &(staInd->staIndTb[numTb]);
434 datReqTb = &(datReqInfo->datReq[idx].datReqTb[numTb]);
436 ueCb->tbIdx = (ueCb->tbIdx+1) % RLC_MAX_TB_PER_UE;
438 for (count = 0;count < staIndTb->nmbLch; count++)
441 /*Calculate the total grant size from MAC */
442 if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC)
443 || (staIndTb->lchStaInd[count].lcId == 0))
445 /* TODO : Need to figure out why this is happening */
450 grantPerLch[staIndTb->lchStaInd[count].lcId] += staIndTb->lchStaInd[count].totBufSize;
453 rbCb = ueCb->lCh[staIndTb->lchStaInd[count].lcId - 1].dlRbCb;
455 if (rbCb && (!rlcDlUtlIsReestInProgress(rbCb)))
458 staIndSz += staIndTb->lchStaInd[count].totBufSize;
459 datReq.pduSz = staIndTb->lchStaInd[count].totBufSize;
461 datReq.totMacGrant = grantPerLch[staIndTb->lchStaInd[count].lcId];
463 rlcUtlGetCurrTime(&datReq.boRep.oldestSduArrTime);
464 if ( RLC_MODE_UM == rbCb->mode )
466 rlcUmmProcessSdus(gCb,rbCb,&datReq);
468 else if ( RLC_MODE_AM == rbCb->mode )
470 rlcAmmProcessSdus(gCb,rbCb,&datReq,staInd->fillCtrlPdu);
473 grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant;
475 if ( 0 == datReq.pduInfo.numPdu )
479 totNumPdu += datReq.pduInfo.numPdu;
480 memcpy(&(datReqTb->lchData[count].pdu),
481 &(datReq.pduInfo),sizeof(KwPduInfo));
483 for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++)
486 ODU_GET_MSG_LEN(datReqTb->lchData[count].pdu.mBuf[numPdu],&len);
489 datReqTb->lchData[count].setMaxUlPrio = FALSE;
490 if (RLC_AM_IS_POLL_BIT_SET(RLC_AMDL) &&
491 (RLC_AMDL.sduQ.count > 1))
493 /* Poll bit is set indicate to MAC*/
494 datReqTb->lchData[count].setMaxUlPrio = TRUE;
496 datReqTb->lchData[count].boReport.bo = datReq.boRep.bo;
499 datReqTb->lchData[count].boReport.estRlcHdrSz =
500 datReq.boRep.estHdrSz;
501 datReqTb->lchData[count].boReport.staPduPrsnt =
502 datReq.boRep.staPduPrsnt;
503 #endif /* CCPU_OPT */
504 datReqTb->lchData[count].boReport.staPduBo =
505 datReq.boRep.staPduBo;
506 datReqTb->lchData[count].lcId = staIndTb->lchStaInd[count].lcId;
509 /* Set if Bearer is UM */
510 if ( RLC_MODE_UM == rbCb->mode )
512 datReqTb->lchData[count].freeBuff = TRUE;
516 datReqTb->lchData[count].freeBuff = FALSE;
520 /* kw005.201 added support for L2 Measurement */
521 #ifdef LTE_L2_MEAS_LOSS_DELAY
522 datReqTb->rguSnInfo->lchMap[count].lChId =
523 staIndTb->lchStaInd[count].lcId;
524 /* In some cases L2 Measurement for few of the lcId may be off,
525 * in this case we are assigning snList to 0xffff
527 for(snIdx1 = 0; snIdx1 < RGU_MAX_PDU; snIdx1++)
529 datReqTb->rguSnInfo->lchMap[count].snList[snIdx1] = 0xffff;
531 if(tbSnMap->numSn != 0)
534 for(snIdx1=tbSnMap->prevNumSn;snIdx1 < tbSnMap->numSn;snIdx1++)
536 datReqTb->rguSnInfo->lchMap[count].snList[snIdx2++] =
537 tbSnMap->snSduMap[snIdx1].sn;
539 tbSnMap->prevNumSn = tbSnMap->numSn;
542 datReqTb->lchData[count].boReport.oldestSduArrTime =
543 datReq.boRep.oldestSduArrTime;
544 /* kw004.201 Used SSI function to initialize the variable */
545 memset(&datReq, 0, sizeof(RlcDatReq) );
549 if(ueCb->l2MeasTbCb[ueCb->tbIdx]!= NULLP)
551 datReqTb->tbId = ueCb->tbIdx;
555 datReqTb->tbId = RLC_INVALID_TBID;
558 datReqTb->nmbLch = staIndTb->nmbLch;
559 /*adding the check to make sure that lcId is not sent as 0
560 * when no data is there in datReq */
561 if ( 0 == totNumPdu )
563 datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId;
565 /* kw005.201 added support for L2 Measurement */
566 #ifdef LTE_L2_MEAS_LOSS_DELAY
567 if(tbSnMap->numSn == 0)
569 RLC_FREE(tbSnMap,sizeof(RlcTbSnMap));
570 RLC_FREE(datReqTb->rguSnInfo,sizeof(RguSnMapInfo));
571 datReqTb->rguSnInfo = NULLP;
572 rlcCb.rlcL2Cb.curTbSnMap = NULLP;
573 datReqTb->snMapPres = FALSE;
577 cmHashListInsert(&(rlcCb.rlcL2Cb.tbHlCp),(PTR)tbSnMap,
578 (uint8_t *) &(tbSnMap->tbId), (uint16_t)sizeof(tbSnMap->tbId));
579 rlcCb.rlcL2Cb.curTbSnMap = NULLP;
581 #endif /* LTE_L2_MEAS */
583 datReqInfo->datReq[idx].nmbOfTbs = staInd->nmbOfTbs;
584 datReqInfo->datReq[idx].transId = staInd->transId;
585 datReqInfo->datReq[idx].rnti = staInd->rnti;
587 datReqInfo->cellId = staIndInfo->cellId;
588 datReqInfo->nmbOfUeGrantPerTti = staIndInfo->nmbOfUeGrantPerTti;
590 rguSap = &(gCb->u.dlCb->rguDlSap[suId]);
591 rlcSendDedLcDlData(&rguSap->pst,rguSap->spId,datReqInfo);
598 * Handler for sending Status Response to MAC.
601 * This function is used by RLC entity for sending
602 * status response to MAC after receiving a SDU from
605 * @param[in] gCb RLC instance Control block
606 * @param[in] rbCb Radio Bearer Control Block
607 * @param[in] bo Buffer Occupancy
608 * @param[in] estHdrSz Estimated Header Size
609 * @param[in] staPduPrsnt Status PDU present or not
615 uint8_t rlcUtlSendDedLcBoStatus(RlcCb *gCb, RlcDlRbCb *rbCb, int32_t bo, \
616 int32_t estHdrSz, bool staPduPrsnt, uint32_t staPduBo)
618 Pst pst; /* Post info */
619 RlcBoStatus *boStatus; /* Buffer occupancy status information */
622 if ((rbCb->lastRprtdBoToMac > (uint32_t)8000) && (rbCb->boUnRprtdCnt < (uint32_t)5)
623 && (!staPduPrsnt) && ((RLC_MODE_AM == rbCb->mode ) && (RLC_AMDL.nxtRetx == NULLP)))
625 rbCb->boUnRprtdCnt++;
629 rbCb->boUnRprtdCnt = (uint32_t)0;
630 rbCb->lastRprtdBoToMac = (uint32_t)bo;
632 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, \
633 boStatus, sizeof(RlcBoStatus));
635 boStatus->cellId = rbCb->rlcId.cellId;
636 boStatus->ueIdx = rbCb->rlcId.ueId;
637 boStatus->commCh = FALSE;
638 boStatus->lcId = rbCb->lch.lChId;
641 FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_BO_STATUS_TO_MAC);
642 /* Send Status Response to MAC layer */
643 if(RlcSendBoStatusToMac(&pst, boStatus) != ROK)
645 RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus));
654 * Handler for emptying the SDU queue.
657 * This function is used to empty the SDU queue when
658 * a re-establishment request is received from the
661 * @param[in] gCb RLC instance control block
662 * @param[in] rbCb Radio bearer control block
663 * @param[in] sduQ SDU queue to be emptied
667 /* kw005.201 added support for L2 Measurement */
668 #ifdef LTE_L2_MEAS_RLC
683 #ifdef LTE_L2_MEAS_RLC
684 CmLListCp *sduSnMapQ; /* SDU Sequence number map queue */
685 CmLList *firstSduSnMap; /* First Node in SDU SnMap Queue */
686 RlcSduSnMap *sduSnMap; /* SDU Sn Map */
689 firstSduSnMap = NULLP;
693 sduSnMapQ = &rbCb->sduSnMapQ;
694 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
698 sduSnMap = (RlcSduSnMap *)firstSduSnMap->node;
699 if(sduSnMap != NULLP)
701 cmLListDelFrm(&(rbCb->sduSnMapQ), &(sduSnMap->lstEnt));
702 RLC_FREE(sduSnMap, sizeof(RlcSduSnMap));
703 CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
707 CM_LLIST_NEXT_NODE(sduSnMapQ, firstSduSnMap);
717 * Handler for calculating the Length Indicator (LI) length for a SDU
720 * This function is used to calculate the LI (Length Indicator) length
721 * which has to be substracted from the pduSize to correctly match the
722 * formed PDU(s) size with the size requested by MAC.
724 * @param[in] gCb RLC instance control block
725 * @param[in] numLi Number of LIs already present
726 * @param[in] msgLen Size of the SDU
727 * @param[in/out] pduSz Size of the pDU to be formed
731 void rlcUtlCalcLiForSdu(RlcCb *gCb, uint16_t numLi, MsgLen msgLen, int16_t *pduSz)
733 if ( (*pduSz > msgLen) && (msgLen < RLC_2K_BYTE))
735 if(0 == (numLi & RLC_BIT0)) /* check if number of LIs are odd or even */
737 /* if number of LI's are even 2 bytes needed */
742 /* if number of LI's are odd one byte needed */
752 * Function to set that re-establishment has started for an RB
755 * This function is used to set the reestInProgress flag to TRUE.
756 * This also sets the estimated header size to 0 and sends bo as
757 * 0 to MAC so that RLC does not need to transmit any data.
758 * If the poll re-transmit timer is running for the RB;
761 * @param[in] gCb RLC instance control block
762 * @param[in] rbCb RB for which re-establishment has started
766 Void rlcDlUtlSetReestInProgressForRB(RlcCb *gCb,RlcDlRbCb *rbCb)
769 rbCb->reestInProgress = TRUE;
771 if(rbCb->mode == RLC_MODE_AM )
773 rbCb->m.amDl.estHdrSz = 0;
775 if(rlcChkTmr(gCb, (PTR)rbCb, EVENT_RLC_AMDL_POLL_RETX_TMR))
777 rlcStopTmr(gCb, (PTR)rbCb, EVENT_RLC_AMDL_POLL_RETX_TMR);
782 rbCb->m.umDl.estHdrSz= 0;
785 rlcUtlSendDedLcBoStatus(gCb, rbCb, 0, 0, FALSE,0);
793 * Function to check if re-establishment is ongoing for an RB
795 * @param[in] rbCb RB for which re-establishment is to be checked
798 * TRUE : Re-establishment is in progress
799 * FALSE : Re-establishment is not in progress
801 bool rlcDlUtlIsReestInProgress(RlcDlRbCb *rbCb)
803 return (rbCb->reestInProgress);
809 * Function to set re-establishment to FALSE
811 * @param[in] rbCb RB for which re-establishment is to be reset
815 Void rlcDlUtlResetReestInProgress(RlcDlRbCb *rbCb)
818 rbCb->reestInProgress = FALSE;
824 * Function to set that re-establishment has started for all the RBs
825 * of an UE; except for SRB1
827 * @detail: For SRB1 only the poll-retransmit timer is stopped
829 * @param[in] gCb RLC instance control block
830 * @param[in] ueCb UE for which re-establishment has started
834 Void rlcDlUtlSetReestInProgressForAllRBs(RlcCb *gCb,RlcDlUeCb *ueCb)
838 for(rbIdx = 0;rbIdx < RLC_MAX_SRB_PER_UE;rbIdx++)
840 if(ueCb->srbCb[rbIdx] != NULLP)
842 if(ueCb->srbCb[rbIdx]->rlcId.rbId != 1)
844 rlcDlUtlSetReestInProgressForRB(gCb,ueCb->srbCb[rbIdx]);
848 /* For SRB we just need to stop the poll re-transmit timer */
849 if(rlcChkTmr(gCb, (PTR)ueCb->srbCb[rbIdx], EVENT_RLC_AMDL_POLL_RETX_TMR))
851 rlcStopTmr(gCb, (PTR)ueCb->srbCb[rbIdx], EVENT_RLC_AMDL_POLL_RETX_TMR);
857 for(rbIdx = 0;rbIdx < RLC_MAX_DRB_PER_UE;rbIdx++)
859 if(ueCb->drbCb[rbIdx] != NULLP)
861 rlcDlUtlSetReestInProgressForRB(gCb,ueCb->drbCb[rbIdx]);
869 * @brief Function to increment number of SDUs transmitted
870 * in KWU SAP statistics
873 * @param[in] rlckwuSap KWU SAP in which to increment the counter
877 void rlcUtlIncrementKwuStsSduTx(RlcKwuSapCb *rlckwuSap)
879 rlckwuSap->sts.sduTx++;
884 * @brief Function to increment number of bytes and PDUs transmitted
885 * in General statistics
888 * @param[in] genSts KWU SAP in which to increment the counter
889 * @param[in] pdu The PDU which is sent
893 void rlcUtlIncrementGenStsBytesAndPdusSent(RlcGenSts *genSts, Buffer *pdu)
896 ODU_GET_MSG_LEN(pdu, &bytesSent);
897 genSts->bytesSent += bytesSent;
903 * @brief Function to initialize the data structures used to free memory
906 * @param[in] gCb RLC instance control block
907 * @param[out] toBeFreed Pointer to the freeing structure. This is
912 Void rlcUtlInitToBeFreed(RlcCb *gCb,RlcDlDataToBeFreed *toBeFreed)
914 cmLListInit(&(toBeFreed->sduLst));
915 cmLListInit(&(toBeFreed->rbLst));
916 cmLListInit(&(toBeFreed->reTxLst));
917 cmLListInit(&(toBeFreed->txLst));
923 * @brief Function to initialize the DL self Pst structure
926 * @param[in] gCb RLC instance control block
930 Void rlcUtlInitializeSelfPst(RlcCb *gCb)
932 Pst *selfPst = &gCb->u.dlCb->selfPst;
934 RLC_MEM_SET(selfPst, 0, sizeof(Pst));
935 selfPst->srcProcId = SFndProcId();
936 selfPst->dstProcId = SFndProcId();
937 selfPst->dstEnt = gCb->init.ent;
938 selfPst->dstInst = gCb->init.inst; /* this is for the DL instance */
939 selfPst->srcEnt = gCb->init.ent;
940 selfPst->srcInst = gCb->init.inst; /* DL instance will send to itself */
941 selfPst->prior = PRIOR3;
942 selfPst->event = UDX_EVT_DL_CLEANUP_MEM;
946 * @brief Function to send a DL cleanup event
949 * @param[in] gCb RLC instance control block
953 void rlcUtlRaiseDlCleanupEvent(RlcCb *gCb)
955 #ifdef KWSELFPSTDLCLEAN
956 if(!gCb->u.dlCb->eventInQueue)
958 ODU_POST_TASK(&gCb->u.dlCb->selfPst, gCb->u.dlCb->selfPstMBuf);
959 gCb->u.dlCb->eventInQueue = TRUE;
966 * @brief Function to add a SDU to the to be freed sdu list
969 * @param[in] gCb RLC instance control block
970 * @param[in] sdu SDU to be added to the list
974 void rlcUtlAddSduToBeFreedQueue(RlcCb *gCb, RlcSdu *sdu)
976 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.sduLst), &(sdu->lstEnt));
981 * @brief Function to add a re-transmitted pdu to the to be freed list
984 * @param[in] gCb RLC instance control block
985 * @param[in] retx Re-transmitted pdu to be added to the list
989 Void rlcUtlAddReTxPduToBeFreedQueue(RlcCb *gCb,RlcRetx *retx)
991 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.reTxLst), &(retx->lstEnt));
996 * @brief Function to add a transmitted pdu to the to be freed list
999 * @param[in] gCb RLC instance control block
1000 * @param[in] pdu PDU to be added to the list
1004 Void rlcUtlAddTxPduToBeFreedQueue(RlcCb *gCb,RlcTx *pdu)
1006 pdu->rlsLnk.node = (PTR)pdu;
1007 cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.txLst), &(pdu->rlsLnk));
1013 * function to free/release the Acknowledged mode RBCB buffers
1016 * This primitive Frees the Acknowledged Mode RbCb transmission Buffer,
1017 * retransmission Buffer and reciption Buffers
1019 * @param [in] gCb - RLC instance control block
1020 * @param [in] rbCb - Downlink RB Control Block
1021 * @param [in,out] toBeFreed - Number of buffers to be freed
1024 * - TRUE if more data to be freed
1025 * - FALSE if all the data has been freed
1027 static Bool rlcUtlFreeDlAmRbMemory(RlcCb *gCb,RlcDlRbCb *rbCb,uint32_t *toBeFreed)
1029 RlcRetx *retx; /* retransmission buffer */
1030 RlcSn mTxNext; /* send state variable */
1033 MODAMT(RLC_AMDL.txNext, mTxNext, RLC_AMDL.txNextAck,RLC_AMDL.snModMask);
1035 /* TODO : to be checked changed from <= to < */
1036 while ((0 < mTxNext) && *toBeFreed)
1038 txBuf = rlcUtlGetTxBuf(RLC_AMDL.txBufLst, RLC_AMDL.txNextAck);
1039 if (txBuf && txBuf->pduLst.first)
1041 while(txBuf->pduLst.first)
1043 RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(txBuf->pduLst.first->node);
1044 ODU_PUT_MSG_BUF(pduInfo->pdu);
1045 /* Delete node from the txBuf Pdu lst */
1046 cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first);
1047 RLC_FREE(gCb, pduInfo, sizeof(RlcDlPduInfo));
1049 rlcUtlDelTxBuf(RLC_AMDL.txBufLst, txBuf, gCb);
1050 if(gCb->u.dlCb->shutdownReceived == 0)
1055 RLC_AMDL.txNextAck = (RLC_AMDL.txNextAck + 1) & RLC_AMDL.snModMask;
1056 MODAMT(RLC_AMDL.txNext, mTxNext, RLC_AMDL.txNextAck,RLC_AMDL.snModMask);
1064 RLC_FREE(gCb,RLC_AMDL.txBufLst, (RLC_TX_BUF_BIN_SIZE * sizeof(CmLListCp)));
1067 RLC_LLIST_FIRST_RETX(RLC_AMDL.retxLst, retx);
1068 while (retx && (*toBeFreed)) /* Till to be freed becomes 0 */
1071 ODU_PUT_MSG_BUF(retx->seg);
1073 cmLListDelFrm(&RLC_AMDL.retxLst, &retx->lstEnt);
1074 RLC_FREE(gCb, retx, sizeof(RlcRetx));
1076 RLC_LLIST_FIRST_RETX(RLC_AMDL.retxLst, retx);
1077 if(gCb->u.dlCb->shutdownReceived == 0)
1084 RLC_AMDL.nxtRetx = NULLP;
1086 /* clean up if there is info about STATUS PDU to be sent */
1087 if(RLC_AMDL.pStaPdu)
1090 udxPst = &gCb->u.dlCb->udxDlSap->pst;
1091 RLC_FREE_SHRABL_BUF_WC(udxPst->region,
1094 sizeof(RlcUdxDlStaPdu));
1095 RLC_AMDL.pStaPdu = NULLP;
1102 if(gCb->u.dlCb->shutdownReceived)
1111 * @brief Function to free memory from the DL instance
1114 * @param[in] gCb RLC instance control block
1118 Void rlcUtlFreeDlMemory(RlcCb *gCb)
1122 /* safety check, in case some event was still lying in the queue after
1123 the dlCb was deleted*/
1129 RlcDlDataToBeFreed* pToBeFreed = &gCb->u.dlCb->toBeFreed;
1131 if(gCb->u.dlCb->shutdownReceived)
1133 toBeFreed = pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count + pToBeFreed->rbLst.count;
1137 if ((pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count) > (3 * RLC_MAX_TO_BE_FREED))
1139 #if !defined(KWSELFPSTDLCLEAN) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
1140 if (isDatReqProcessed)
1142 toBeFreed = (2 *RLC_MAX_TO_BE_FREED);
1147 toBeFreed = (3 *RLC_MAX_TO_BE_FREED)/2;
1152 toBeFreed = RLC_MAX_TO_BE_FREED;
1157 gCb->u.dlCb->eventInQueue = FALSE; /* reset as we have received the event
1158 and are processing it */
1160 /* Free from the ReTx list */
1161 lst = &pToBeFreed->reTxLst;
1163 while((lst->first) && toBeFreed && (pToBeFreed->reTxLst.count > 100))
1165 while((lst->first) && toBeFreed)
1168 RlcRetx* seg = (RlcRetx *)(lst->first->node);
1169 cmLListDelFrm(lst, lst->first);
1170 ODU_PUT_MSG_BUF(seg->seg);
1171 RLC_FREE(gCb,seg, sizeof(RlcRetx));
1175 /* Free from the Tx list */
1176 lst = &pToBeFreed->txLst;
1178 while((lst->first) && toBeFreed && (pToBeFreed->txLst.count > 100))
1180 while((lst->first) && toBeFreed)
1183 RlcTx* pdu = (RlcTx *)(lst->first->node);
1184 cmLListDelFrm(lst, lst->first);
1185 while(pdu->pduLst.first)
1187 RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(pdu->pduLst.first->node);
1189 cmLListDelFrm(&pdu->pduLst, pdu->pduLst.first);
1190 ODU_PUT_MSG_BUF(pduInfo->pdu);
1191 RLC_FREE(gCb, pduInfo, sizeof(RlcDlPduInfo));
1193 RLC_FREE(gCb,pdu, sizeof(RlcTx));
1197 /* Free from the SDU queue */
1198 lst = &pToBeFreed->sduLst;
1200 while((lst->first) && toBeFreed && (pToBeFreed->sduLst.count > 100))
1202 while((lst->first) && toBeFreed)
1205 RlcSdu* sdu = (RlcSdu *)(lst->first->node);
1206 RLC_RMV_SDU(gCb, lst, sdu);
1210 /* Free from the RBs */
1211 lst = &pToBeFreed->rbLst;
1213 while((lst->first) && toBeFreed && (pToBeFreed->rbLst.count > 100))
1215 while((lst->first) && toBeFreed)
1218 RlcDlRbCb* rbCb = (RlcDlRbCb *)(lst->first->node);
1219 Bool moreToBeFreed = rlcUtlFreeDlAmRbMemory(gCb, rbCb,&toBeFreed);
1222 cmLListDelFrm(lst, lst->first);
1223 RLC_FREE(gCb, rbCb, sizeof(RlcDlRbCb));
1227 if ((toBeFreed == 0) && !(gCb->u.dlCb->shutdownReceived))
1229 rlcUtlRaiseDlCleanupEvent(gCb);
1239 * @brief Function to initialise measurement
1243 * @param[in] gCb RLC Instance Control Block
1248 S16 rlcUtlL2MeasDlInit(RlcCb *gCb)
1252 gCb->u.dlCb->rlcL2Cb.rlcNumMeas=0;
1253 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
1255 memset(&(gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
1257 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DISC].measCb.measType = LKW_L2MEAS_DL_DISC;
1258 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_IP].measCb.measType = LKW_L2MEAS_DL_IP;
1259 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DELAY].measCb.measType= LKW_L2MEAS_DL_DELAY;
1260 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UU_LOSS].measCb.measType= LKW_L2MEAS_UU_LOSS;
1261 gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_ACT_UE].measCb.measType= LKW_L2MEAS_ACT_UE;
1267 * @brief Function to detect the data Burst start Condition in a DTCH
1271 * @param[in] rbCb RB control block
1272 * @param[in] contSduLst Array of Contained SDUs in the DTCH
1273 * @param[in] dataVol Available data in the DTCH
1274 * @param[in] schPduSz Total grant Size given by MAC
1279 Void rlcUtlUpdateBurstSdus
1283 RlcContSduLst *contSduLst,
1289 RlcL2MeasDlIpTh *l2MeasDlIpThruput = NULLP;
1290 RlcL2MeasTb *l2MeasTb = NULLP;
1293 volatile uint32_t startTime = 0;
1294 RlcContSduLst *dstContSduLst;
1298 SStartTask(&startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1300 l2MeasDlIpThruput = &rbCb->l2MeasIpThruput.dlIpTh;
1302 if(RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb))
1304 if(dataVol > schPduSz)
1306 if(l2MeasDlIpThruput->isBurstAct == FALSE)
1308 l2MeasDlIpThruput->burstStartTime = glblTtiCnt;
1309 l2MeasDlIpThruput->isBurstAct = TRUE;
1310 l2MeasDlIpThruput->burstEndSduId = 0;
1313 { /* This is the case when another burst started before RLC gets the
1314 l2MeasDlIpThruput->burstEndSduId = 0; */
1318 { /* Store the burstEndSduId here */
1319 if((l2MeasDlIpThruput->isBurstAct == TRUE) &&
1320 (!l2MeasDlIpThruput->burstEndSduId))
1322 l2MeasDlIpThruput->burstEndSduId =
1323 l2MeasDlIpThruput->outStngSduArr[l2MeasDlIpThruput->lastSduIdx].sduId;
1326 if(l2MeasDlIpThruput->isBurstAct == TRUE)
1328 l2MeasTb = rlcUtlGetCurMeasTb(gCb,rbCb);
1329 /* Get the lChId from index 0, because index 0 is always for DL */
1330 if(l2MeasTb->numLcId >= RLC_MAX_ACTV_DRB)
1335 l2MeasTb->sduInfo[l2MeasTb->numLcId].lcId = rbCb->lch.lChId;
1336 /* Copy all the sduIdx from sduInfo to tb sduInfo */
1337 currTbIdx = l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus;
1338 dstContSduLst = &l2MeasTb->sduInfo[l2MeasTb->numLcId];
1340 for(idx = 0; ((idx < contSduLst->numSdus)
1341 && (currTbIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)) ; idx++)
1343 dstContSduLst->sduIdx[currTbIdx++] = contSduLst->sduIdx[idx];
1345 l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus += idx;
1346 l2MeasTb->numLcId++;
1347 }/* End of isBurstAct */
1348 }/* End of if measOn */
1351 SStopTask(startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1356 * This function is used to store locally the sduIdx of the sdu in the
1357 * outstanding SDU array
1360 * Stores the Sdu Idx in the contained SDU Array and increments
1361 * the num contained Sdus
1363 * @param[in] sduIdx the Index of the SDU in the outstanding SDU array
1364 * @param[out] contSduLst This stores the indices of the SDUs
1368 Void rlcUtlUpdateContainedSduLst(uint8_t sduIdx,RlcContSduLst *contSduLst)
1370 if (contSduLst->numSdus < RLC_L2MEAS_MAX_OUTSTNGSDU)
1372 contSduLst->sduIdx[contSduLst->numSdus] = sduIdx;
1373 contSduLst->numSdus++;
1380 * This function is used to store the sduId of the sdu in the
1381 * outstanding SDU array
1384 * Stores the Sdu Id in the outstanding SDU Array and increments
1385 * the num contained Sdus
1387 * @param[out] dlIpThPut The structure in which the outstanding sdus are
1389 * @param[in] sduIdx The Idx at which the sdu ID is stored
1390 * @param[in] sduLen The size if sdu in bytes
1391 * @param[in] newIdx Indicates if the sdu is already present in the
1396 Void rlcUtlUpdateOutStandingSduLst
1398 RlcL2MeasDlIpTh *dlIpThPut,
1405 if (sduIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)
1409 dlIpThPut->outStngSduArr[sduIdx].numTb = 0;
1411 dlIpThPut->outStngSduArr[sduIdx].numTb++;
1412 dlIpThPut->outStngSduArr[sduIdx].sduId = sduId;
1413 dlIpThPut->outStngSduArr[sduIdx].sduLen = sduLen;
1417 RlcL2MeasTb * rlcUtlGetCurMeasTb(RlcCb *gCb,RlcDlRbCb *rbCb)
1419 RlcL2MeasTb *curL2MeasTb;
1422 if((curL2MeasTb = rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx]) == NULLP)
1424 /* Intentionally avoiding the RLC_ALLOC macro to avoid memset */
1425 if (SGetSBuf(gCb->init.region,
1427 (Data **)&curL2MeasTb,
1428 (Size)sizeof(RlcL2MeasTb)) != ROK)
1432 rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx] = curL2MeasTb;
1433 /* Initialize the Meas Tb details */
1434 curL2MeasTb->numLcId = 0;
1435 curL2MeasTb->numLchInfo = 0;
1436 curL2MeasTb->txSegSduCnt = 0;
1437 for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1439 curL2MeasTb->sduInfo[idx].numSdus = 0;
1441 for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1443 curL2MeasTb->lchInfo[idx].numSdus = 0;
1446 return (curL2MeasTb);
1452 * @brief Handler for Processing harq status indication
1456 * This function is called when the MAC sends a harq ind Mesage.
1457 * This is used only for UuLoss and Dl Delay and DL Ipthoughput
1460 * @param[in] staInd Harq status indication received from MAC.
1461 * @param[in] ueCb UeCb corresponding to the Tb Id.
1462 * @param[in] tbIdx TB index, 0 for SISO and 0,1 for MIMO.
1469 S16 rlcUtlProcHarqInd
1472 RguHarqStatusInd *hqStaInd,
1478 RlcDlRbCb *rlcRbCb; /* KW Control Block */
1479 RlcL2MeasTb *l2MeasTb = NULLP; /* Measurement TbCb */
1480 uint8_t lcIdx; /* Logical channel id index */
1481 uint8_t sduIndx; /* sdu index to out standing sdu list in rbCb */
1482 uint32_t numSdus; /* number of sdus in the outstanding sdu list */
1483 RlcOutStngSduInfo *outStngSduArr; /* Outstanding sdu list */
1486 uint32_t totlSduCnt = 0;
1488 uint8_t timeAddedFlag;
1490 volatile uint32_t startTime = 0;
1491 /*kw005.201 Code added for DL IP thruput measurement*/
1494 SStartTask(&startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1497 if(hqStaInd->tbId[tbIdx] >= RLC_INVALID_TBID)
1502 /* Find the L2 measurement tbCb to process DL Ip thruput*/
1503 l2MeasTb = ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]];
1504 if(l2MeasTb == NULLP)
1508 /* For each logical channel in the tbCb, process
1509 * and get the DL IP thruput */
1510 ackTime = SGetTtiCount();
1511 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLcId) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1513 timeAddedFlag = FALSE;
1514 if((rlcRbCb = ueCb->lCh[l2MeasTb->sduInfo[lcIdx].lcId - 1].dlRbCb)
1519 /* fix for DL IP stop*/
1520 if (!gCb->u.dlCb->rlcL2Cb.measOn[rlcRbCb->qci]
1521 || (rlcRbCb->rlcId.rbType == CM_LTE_SRB))
1526 /* Get the outstanding SDUs using sdu index stored in Container sduList
1527 * and check for HARQ ACK/NACK */
1528 numSdus = l2MeasTb->sduInfo[lcIdx].numSdus;
1530 if ((numSdus >= RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1534 totlSduCnt += numSdus;
1536 if (RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,rlcRbCb))
1538 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1540 outStngSduArr =&(rlcRbCb->l2MeasIpThruput.dlIpTh.outStngSduArr[\
1541 l2MeasTb->sduInfo[lcIdx].sduIdx[sduIndx]]);
1542 if(hqStaInd->status[tbIdx] == TRUE)
1544 /* If ACK is for burst End Sdu Id set burstActive
1545 * to FALSE and accumulate time */
1546 if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1547 outStngSduArr->sduId) && (outStngSduArr->numTb == 1))
1549 rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1550 /*Update the l2Sts structure for calculating throughput*/
1551 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1552 += outStngSduArr->sduLen;
1554 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1555 += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1556 outStngSduArr->sduId = 0;
1557 outStngSduArr->sduLen = 0;
1558 outStngSduArr->numTb = 0;
1559 rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1562 /* If burst is active and this sdu is only transmitted in single TB then
1563 * accumulate volume and clear the outstanding sduList */
1564 if((rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) &&
1565 (--(outStngSduArr->numTb) == 0))
1567 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1568 += outStngSduArr->sduLen;
1570 if(timeAddedFlag == FALSE)
1572 rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1573 += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1574 rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime = glblTtiCnt;
1575 timeAddedFlag = TRUE;
1577 outStngSduArr->sduId = 0;
1578 outStngSduArr->sduLen = 0;
1580 }/* End of status == TRUE */
1583 if(rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE)
1585 if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId ==
1586 outStngSduArr->sduId))
1588 rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1589 rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1591 /* Clear the outstanding sdu list */
1592 outStngSduArr->sduId = 0;
1593 outStngSduArr->sduLen = 0;
1594 outStngSduArr->numTb = 0;
1601 for(lcIdx = 0; ((lcIdx < l2MeasTb->numLchInfo) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1603 if((rlcRbCb = ueCb->lCh[l2MeasTb->lchInfo[lcIdx].lcId - 1].dlRbCb)
1608 numSdus = l2MeasTb->lchInfo[lcIdx].numSdus;
1614 if ((numSdus > RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1619 if(hqStaInd->status[tbIdx] == TRUE)
1621 for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1623 delay = RLC_TIME_DIFF(ackTime,l2MeasTb->lchInfo[lcIdx].sduInfo[sduIndx].arvlTime);
1624 RLC_UPD_PDCP_L2_DLDELAY_STS(gCb,rlcRbCb, delay);
1626 /* Case of sduInfo not updated */
1627 if (totlSduCnt == 0)
1629 totlSduCnt = numSdus;
1631 RLC_UPD_L2_UU_LOSS_POS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1635 /* Case of sduInfo not updated */
1636 if (totlSduCnt == 0)
1638 totlSduCnt = numSdus;
1640 RLC_UPD_L2_UU_LOSS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1643 /* Free this tb, deallocate the memory */
1644 RLC_FREE(gCb, l2MeasTb, sizeof(RlcL2MeasTb));
1645 ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]] = NULLP;
1648 SStopTask(startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1651 }/* end of rlcUtlProcHarqInd */
1655 * @brief Handler for Sending L2 Measurement confirm.
1659 * This function sends a consolidates the mesaurements taken during
1660 * this time and sends the confirm .
1662 * @param[in] measEvtCb Measurement Event Control Block.
1669 S16 rlcUtlSndDlL2MeasCfm(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
1672 RlcL2MeasCb *measCb = NULLP;
1673 RlcL2MeasCfmEvt measCfmEvt;
1679 /* Discard new changes starts */
1682 /* Discard new changes ends */
1684 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
1686 DU_LOG("\nDEBUG --> RLC_DL : rlcUtlSndL2MeasCfm(transId(%ld))", measEvtCb->transId);
1688 DU_LOG("\nDEBUG --> RLC_DL : rlcUtlSndL2MeasCfm(transId(%d))", measEvtCb->transId);
1691 /* Clean up the RB data structures */
1692 measCb = &measEvtCb->measCb;
1694 memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
1695 measCfmEvt.transId = measEvtCb->transId;
1697 measCfmEvt.measType = measCb->measType;
1698 measCfmEvt.status.status = LCM_PRIM_OK;
1699 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
1701 if(measCb->measType & LKW_L2MEAS_DL_IP)
1703 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
1704 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
1706 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
1708 pUeInfoLstCfm[cfmIdx].numCfm = 0;
1709 if (pUeInfoLstCb[cntr].isValid == TRUE)
1711 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
1712 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
1713 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
1715 qci = pUeInfoLstCb[cntr].qci[qciIdx];
1716 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
1718 dlDataVol = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation;
1719 dlTime = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation;
1721 if((0 == dlTime) || !(gCb->u.dlCb->rlcL2Cb.measOn[qci] & LKW_L2MEAS_DL_IP) )
1723 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 0;
1727 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut =
1728 (dlDataVol / dlTime);
1730 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut *= 8;
1732 /* Reset the values after reporting to Application */
1733 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation = 0;
1734 pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation = 0;
1736 measCfmEvt.val.ipThMeas.ueInfoLst[cfmIdx].numCfm++;
1741 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
1745 RlcL2Cntr *pMeasData = measCb->val.nonIpThMeas.measData;
1746 RlcL2MeasCfmNonIpThMeas *pMeasCfmNonIp = &measCfmEvt.val.nonIpThMeas;
1748 pMeasCfmNonIp->numCfm = 0;
1750 for(qciIdx = 0; qciIdx < LKW_MAX_QCI; qciIdx++)
1752 qci = measCb->val.nonIpThMeas.qci[qciIdx];
1755 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].qci = qci;
1757 if(measCb->measType & LKW_L2MEAS_UU_LOSS)
1759 dLoss = pMeasData[qci].uuLoss.dLoss;
1760 posPkts = pMeasData[qci].uuLoss.posPkts;
1761 if(((posPkts + dLoss) != 0))
1763 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.uuLoss =
1764 ((dLoss * 1000000) / (posPkts + dLoss));
1766 pMeasData[qci].uuLoss.dLoss = 0;
1767 pMeasData[qci].uuLoss.posPkts = 0;
1769 if(measCb->measType & LKW_L2MEAS_DL_DISC)
1772 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 0;
1773 if(pMeasData[qci].dlDisc.totSdus != 0)
1775 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate =
1776 (((pMeasData[qci].dlDisc.discSdus) * 1000000) / (pMeasData[qci].dlDisc.totSdus));
1779 pMeasData[qci].dlDisc.totSdus = 0;
1780 pMeasData[qci].dlDisc.discSdus = 0;
1782 if(measCb->measType & LKW_L2MEAS_DL_DELAY)
1784 if (pMeasData[qci].dlPjSduDelay.numSdus > 0)
1786 pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlSduDelay =
1787 (pMeasData[qci].dlPjSduDelay.sduDelay / pMeasData[qci].dlPjSduDelay.numSdus);
1788 pMeasData[qci].dlPjSduDelay.sduDelay = 0;
1789 pMeasData[qci].dlPjSduDelay.numSdus = 0;
1792 pMeasCfmNonIp->numCfm++;
1796 /* Fix Klock warning */
1797 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
1799 } /* rlcUtlSndL2MeasCfm */
1802 * @brief Handler for Sending Negative confirm .
1806 * This function is called when the l2 measurement cannot be started
1807 * This function sends negative confirm for all the requests
1809 * @param[in] measReqEvt Measurement Req Structure
1816 S16 rlcUtlSndDlL2MeasNCfm(RlcCb *gCb,RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
1819 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
1821 } /* kwUtlSndL2MeasNCfm */
1824 * @brief Handler for resetting the RB data structures
1828 * This function resets the RB data structure after the expiry of
1829 * measurement timer.
1831 * @param[in] measCb Measurement Control Block.
1837 Void rlcUtlResetDlL2MeasInRlcRb(RlcCb *gCb,RlcL2MeasCb *measCb,uint8_t measType)
1841 RlcDlUeCb *ueCb = NULL;
1845 if (measCb->measType & LKW_L2MEAS_DL_IP)
1847 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
1849 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
1851 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
1853 if (measType & LKW_L2MEAS_DL_IP)
1855 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.volSummation = 0;
1856 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.timeSummation = 0;
1857 gCb->u.dlCb->rlcL2Cb.measOn[qciIdx] &= ~measType;
1861 if(ROK != rlcDbmFetchDlUeCb(gCb,measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
1862 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
1872 /* for now the only meas should be DL discard in this case */
1873 if (measCb->measType & LKW_L2MEAS_DL_DISC)
1876 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
1878 uint8_t qciVal = measCb->val.nonIpThMeas.qci[i];
1880 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.discSdus = 0;
1881 measCb->val.nonIpThMeas.measData[qciVal].dlDisc.totSdus = 0;
1885 if (measCb->measType & LKW_L2MEAS_DL_DELAY)
1888 for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
1890 uint8_t qciVal = measCb->val.nonIpThMeas.qci[i];
1892 measCb->val.nonIpThMeas.measData[qciVal].dlPjSduDelay.sduDelay = 0;
1895 measCb->val.nonIpThMeas.numQci = 0;
1897 } /* rlcUtlResetDlL2MeasInRlcRb */
1900 static Void dumpRLCDlRbInformation(RlcDlRbCb* dlRbCb)
1902 if(dlRbCb->mode == RLC_MODE_UM)
1904 DU_LOG("\nDEBUG --> RLC_DL : UM Downlink UEID:%d CELLID:%d Q size = %d",
1906 dlRbCb->rlcId.cellId,
1907 (int)dlRbCb->m.umDl.sduQ.count);
1909 else if(dlRbCb->mode == RLC_MODE_AM)
1911 uint32_t j, numTxPdus=0;
1912 for(j = 0; j <= (RLC_AM_GET_WIN_SZ(dlRbCb->m.amDl.snLen)); j++)
1914 RlcTx *txBuf = rlcUtlGetTxBuf(dlRbCb->m.amDl.txBufLst, j);
1920 DU_LOG("\nDEBUG --> RLC_DL : AM Downlink UEID:%d CELLID:%d Sizes SDU Q = %d TX Q = %d ",
1922 dlRbCb->rlcId.cellId,
1923 (int)dlRbCb->m.amDl.sduQ.count,
1925 DU_LOG("\nDEBUG --> RLC_DL : AM Downlink UEID:%d CELLID:%d RETX Q= %d",
1927 dlRbCb->rlcId.cellId,
1928 (int)dlRbCb->m.amDl.retxLst.count);
1932 Void DumpRLCDlDebugInformation(Void)
1934 RlcCb* dlInst = rlcCb[1]; /* TODO : Check whether DL is 0 or 1 */
1936 RlcDlCb *dlCb = dlInst->u.dlCb;
1938 RlcDlUeCb *ueCb = NULLP;
1939 RTLIN_DUMP_DEBUG("RLC Information\n");
1940 RTLIN_DUMP_DEBUG("===============\n");
1941 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
1942 while (ROK == cmHashListGetNext(&dlCb->ueLstCp,
1947 for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
1949 RlcDlRbCb* dlRbCb = ueCb->srbCb[i];
1950 if( dlRbCb != NULLP)
1952 dumpRLCDlRbInformation(dlRbCb);
1955 for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
1957 RlcDlRbCb* dlRbCb = ueCb->drbCb[i];
1958 if( dlRbCb != NULLP)
1960 dumpRLCDlRbInformation(dlRbCb);
1965 RlcDlDataToBeFreed* pToBeFreed = &dlCb->toBeFreed;
1967 RTLIN_DUMP_DEBUG("toBeFreed RETX list size = %d\n",(int)pToBeFreed->reTxLst.count);
1968 RTLIN_DUMP_DEBUG("toBeFreed TX list size = %d\n",(int)pToBeFreed->txLst.count);
1969 RTLIN_DUMP_DEBUG("toBeFreed SDU list size = %d\n",(int)pToBeFreed->sduLst.count);
1970 RTLIN_DUMP_DEBUG("toBeFreed RB list size = %d\n",(int)pToBeFreed->rbLst.count);
1976 * This function frees downlink memory
1984 void rlcUtlFreeDlMem( Void)
1986 rlcUtlFreeDlMemory(RLC_GET_RLCCB(RLC_DL_INST));
1992 * This function returns current time
1994 * @param[in] uint32_t
2000 void rlcUtlGetCurrTime(uint32_t *currTime)
2002 /* Need t define else part for PAL */
2003 *currTime = SGetTtiCount();
2006 #if defined(MAC_RLC_HARQ_STA_RBUF) || defined (SS_RBUF)
2008 void rlcUtlDlBatchProcHqStaInd( Void)
2010 /* Read from Ring Buffer and process PDCP packets */
2013 Void *elmIndx = NULLP;
2014 RguHarqStaInd *staInd = NULLP;
2016 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2017 isDatReqProcessed = TRUE;
2019 elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ);
2020 while(NULLP != elmIndx)
2022 staInd = (RguHarqStaInd *)elmIndx;
2023 RlcLiRguHqStaInd(&(staInd->pst), 0, &(staInd->hqStatusInd));
2027 SRngIncrRIndx(SS_RNG_BUF_MAC_HARQ);
2029 if((elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ)) == NULLP)
2031 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2032 isDatReqProcessed = FALSE;
2042 * @brief evaluate and trigger PDB based flow control to PDCP
2046 * @param[in] rbCb RB control block
2052 Void rlcUtlTrigPdbFlowCntrl(RlcCb *gCb,RlcDlRbCb *rbCb,uint32_t pktAdmitCnt)
2054 KwuFlowCntrlIndInfo *flowCntrlInfo;
2055 RlcKwuSapCb* rlckwuSap;
2057 rlckwuSap = gCb->u.dlCb->rlcKwuDlSap + RLC_UI_PDCP;
2059 RLC_SHRABL_STATIC_BUF_ALLOC(rlckwuSap->pst.region,
2060 rlckwuSap->pst.pool,
2062 sizeof(KwuFlowCntrlIndInfo));
2063 flowCntrlInfo->rlcId = rbCb->rlcId;
2064 flowCntrlInfo->pktAdmitCnt = pktAdmitCnt;
2065 RlcUiKwuFlowCntrlInd(&rlckwuSap->pst, rlckwuSap->suId, flowCntrlInfo);
2070 * @brief Store the DL buffer in hashList
2075 * Use the SN % binSize as key and store the received UL buffer
2076 * @param[in] txBufLst List CP array
2077 * @param[in] txBuf transmitted buffer
2078 * @param[in] sn sn of the received buffer
2083 void rlcUtlStoreTxBuf(CmLListCp *txBufLst, RlcTx *txBuf, RlcSn sn)
2087 hashKey = (sn % RLC_TX_BUF_BIN_SIZE );
2089 txBuf->lnk.node = (PTR)txBuf;
2090 cmLListAdd2Tail(&(txBufLst[hashKey]), &txBuf->lnk);
2093 } /* rlcUtlStoreRecBuf */
2097 * @brief Retrieve the DL buffer from the list
2102 * Use the SN % binSize as key and retrieve the DL buffer
2103 * @param[in] txBufLst List CP array
2104 * @param[in] sn sn of the transmitted buffer
2109 RlcTx* rlcUtlGetTxBuf(CmLListCp *txBufLst, RlcSn sn)
2112 CmLListCp *txBufLstCp;
2114 CmLList *node = NULLP;
2116 hashKey = (sn % RLC_TX_BUF_BIN_SIZE );
2118 txBufLstCp = &txBufLst[hashKey];
2119 CM_LLIST_FIRST_NODE(txBufLstCp, node);
2122 txBuf = (RlcTx *) node->node;
2127 CM_LLIST_NEXT_NODE(txBufLstCp, node);
2130 } /* rlcUtlStoreTxBuf */
2133 * @brief Delete the DL buffer from the list
2138 * Use the SN % binSize as key and retrieve the DL buffer
2139 * @param[in] txBufLst List CP array
2140 * @param[in] sn sn of the transmitted bffer
2145 Void rlcUtlDelTxBuf (CmLListCp *txBufLst,RlcTx *txBuf,RlcCb *gCb)
2148 CmLListCp *txBufLstCp;
2150 hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE );
2152 txBufLstCp = &txBufLst[hashKey];
2153 //DU_LOG("\nINFO --> RLC_DL : D-sn(%d)\n", txBuf->hdr.sn);
2154 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2155 RLC_FREE(gCb, txBuf, sizeof(RlcTx));
2157 } /* rlcUtlDelTxBuf */
2161 * @brief Remove the DL buffer from the list
2166 * Use the SN % binSize as key and retrieve the DL buffer
2167 * @param[in] txBufLst List CP array
2168 * @param[in] sn sn of the transmitted bffer
2173 Void rlcUtlRemovTxBuf(CmLListCp *txBufLst,RlcTx *txBuf,RlcCb *gCb)
2176 CmLListCp *txBufLstCp;
2178 hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE );
2180 txBufLstCp = &txBufLst[hashKey];
2181 //DU_LOG("\nINFO --> RLC_DL : D-sn(%d)\n", txBuf->hdr.sn);
2182 cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2184 } /* rlcUtlRemovTxBuf */
2188 /********************************************************************30**
2190 **********************************************************************/