RLC BO, BO response and DL Data handling. [Issue-ID: ODUHIGH-181]
[o-du/l2.git] / src / 5gnrrlc / kw_utl_dl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /**********************************************************************
20
21      Name:     LTE-RLC Layer 
22   
23      Type:     C file
24   
25      Desc:     Source code for RLC Utility Module
26                This file contains following functions
27
28                   --rlcUtlSendToMac
29                   --rlcUtlRcvFrmMac
30                   --rlcUtlEmptySduQ
31                   --rlcUtlSendDedLcBoStatus
32                   --rlcUtlSendUlDataToDu 
33                   --kwUtlShutDown
34
35      File:     kw_utl_dl.c
36
37 **********************************************************************/
38 static const char* RLOG_MODULE_NAME="UTL";
39 static int RLOG_MODULE_ID=2048;
40 static int RLOG_FILE_ID=209;
41
42 /** @file kw_utl_dl.c
43 @brief RLC Utility Module 
44 */
45
46 /* header (.h) include files */
47
48 #include "common_def.h"
49 /* kw005.201 added support for L2 Measurement */
50 #ifdef LTE_L2_MEAS
51 #include <sys/time.h>
52 #endif
53 #include "ckw.h"           /* CKW defines */
54 #include "kwu.h"           /* CKW defines */
55 #include "lkw.h"           /* LKW defines */
56 #include "rgu.h"           /* RGU defiens */
57
58 #include "kw_env.h"        /* RLC environment options */
59 #include "kw.h"            /* RLC defines */
60 #include "kw_err.h"        /* Error defines */
61 #include "kw_udx.h"
62 #include "kw_dl.h"
63
64 /* extern (.x) include files */
65 #include "ckw.x"           /* CKW includes */
66 #include "kwu.x"           /* KWU includes */
67 #include "lkw.x"           /* LKW inlcudes */
68 #include "rgu.x"           /* RGU includes */
69
70 #include "kw.x"            /* RLC includes */
71 #include "kw_udx.x"        /* UDX interface includes */
72 #include "kw_dl.x"         /* RLC downlink includes */
73
74 #include "rlc_utils.h"
75 #include "rlc_mac_inf.h"
76 #include "rlc_lwr_inf_api.h"
77
78 #include "ss_rbuf.h"
79 #include "ss_rbuf.x" 
80
81 EXTERN SsRngBufCnt rngCb;
82
83 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS))
84 extern U32 isDatReqProcessed;
85 #endif
86 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_DL) /* for debugging purpose */
87 #if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) || defined (SS_RBUF)
88 EXTERN void rlcUtlDlBatchProcHqStaInd ARGS ((Void));
89 #endif
90 Void ResetRLCStats(Void)
91 {
92    RlcCb* dlInst = rlcCb[1]; 
93    RlcCb* ulInst = rlcCb[0]; 
94    cmMemset((U8*)&gRlcStats, 0, sizeof(RLCStats));
95    cmMemset((U8*)&dlInst->genSts,0,sizeof(RlcGenSts));
96    cmMemset((U8*)&ulInst->genSts,0,sizeof(RlcGenSts));
97 }
98
99 #ifndef ALIGN_64BIT
100 Void PrintRLCStats(Void)
101 {
102    RlcCb* dlInst = rlcCb[1]; 
103    RlcCb* ulInst = rlcCb[0]; 
104
105    RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
106                      dlInst->genSts.pdusSent,
107                      dlInst->genSts.pdusRetx,
108                      dlInst->genSts.protTimeOut,
109                      dlInst->genSts.numSduDisc);
110    RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
111                      ulInst->genSts.pdusRecv,
112                      ulInst->genSts.unexpPdusRecv,
113                      ulInst->genSts.errorPdusRecv);
114    RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
115                      "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
116                      gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, 
117                      gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
118    RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
119                      "DRB:%lu MaxRetx:%lu RetransPdus:%lu", 
120                      gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, 
121                      gRlcStats.amRlcStats.numDLRetransPdus);
122    RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
123                      " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ", 
124                      gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, 
125                      gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
126
127    RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)\n",
128                      dlInst->genSts.pdusSent,
129                      dlInst->genSts.pdusRetx,
130                      dlInst->genSts.protTimeOut,
131                      dlInst->genSts.numSduDisc);
132    RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)\n",
133                      ulInst->genSts.pdusRecv,
134                      ulInst->genSts.unexpPdusRecv,
135                      ulInst->genSts.errorPdusRecv);
136    RTLIN_DUMP_DEBUG("RLC Stats:"
137                     "AMDL: StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu DRB:%lu MaxRetx:%lu RetransPdus:%lu \n"
138                     "AMUL: PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu \n", 
139                      gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused, 
140                      gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, 
141                      gRlcStats.amRlcStats.numDLRetransPdus, gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, 
142                      gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
143 }
144 #else
145 Void PrintRLCStats(Void)
146 {
147    RlcCb* dlInst = rlcCb[1]; 
148    RlcCb* ulInst = rlcCb[0]; 
149
150    printf ("\n================================ RLC STATS ===========================\n");
151    RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)",
152                      dlInst->genSts.pdusSent,
153                      dlInst->genSts.pdusRetx,
154                      dlInst->genSts.protTimeOut,
155                      dlInst->genSts.numSduDisc);
156    RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)",
157                      ulInst->genSts.pdusRecv,
158                      ulInst->genSts.unexpPdusRecv,
159                      ulInst->genSts.errorPdusRecv);
160    RLOG4(L_ALWAYS,"RLC Stats: AMDL: "
161                      "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ",
162                      gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, 
163                      gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb);
164    RLOG3(L_ALWAYS,"RLC Stats: AMDL: "
165                      "DRB:%lu MaxRetx:%lu RetransPdus:%lu", 
166                      gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, 
167                      gRlcStats.amRlcStats.numDLRetransPdus);
168    RLOG4(L_ALWAYS,"RLC Stats: AMUL: "
169                      " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ", 
170                      gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, 
171                      gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd);
172  /*  RTLIN_DUMP_DEBUG("AM RLC Stats:"
173                     "AMDL: SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) MaxRetx:(%u) WindowStalls: (%u) \n"
174                     "AMUL: DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx :(%u) \n",
175                      gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
176                      gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmMaxRetx, gRlcStats.amRlcStats.numRlcAmCellWinStall,
177                      gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
178                      gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
179 */
180    RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)\n",
181                      dlInst->genSts.pdusSent,
182                      dlInst->genSts.pdusRetx,
183                      dlInst->genSts.protTimeOut,
184                      dlInst->genSts.numSduDisc);
185    RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)\n",
186                      ulInst->genSts.pdusRecv,
187                      ulInst->genSts.unexpPdusRecv,
188                      ulInst->genSts.errorPdusRecv);
189    RTLIN_DUMP_DEBUG("AMDL: StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u DRB:%u MaxRetx:%u RetransPdus:%u \n"
190                     "      SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) WindowStalls: (%u) \n"
191
192                     "AMUL: PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u \n"
193                     "      DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx:(%u) \n", 
194                      gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused, 
195                      gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb,
196                      gRlcStats.amRlcStats.numDLMaxRetx, gRlcStats.amRlcStats.numDLRetransPdus,
197                      gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx,
198                      gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmCellWinStall,
199                      gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, 
200                      gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd,
201                      gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx,
202                      gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx);
203 }
204 #endif
205
206 /*******************************************************************
207  *
208  * @brief 
209  *    Handler for storing all DL PDU Info into RLC-MAC interface
210  *    struct and sending to lower interface
211  *
212  * @details
213  *    This function stores DL PDU info for all logical channels
214  *    of per UE grant per TTI and sends to MAC
215  *
216  *    Function : rlcSendDedLcDlData 
217  *
218  * @params[in] 
219  * @return ROK     - success
220  *         RFAILED - failure
221  *
222  * ****************************************************************/
223 uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo)
224 {
225    uint8_t          ueIdx;      /* UE info list iterator */ 
226    uint8_t          tbIdx;      /* TB info list iterator */
227    uint8_t          lchIdx;     /* Lch info list iterator */
228    uint8_t          pduIdx;     /* RLC PDU list iterator */
229    RguDDatReqPerUe  datPerUe;   /* DL data info per UE */
230    RguDatReqTb      datPerTb;   /* DL data info per TB */
231    RguLchDatReq     datPerLch;  /* DL data info per Lch */
232    RlcData          *dlData;    /* DL data to be sent to MAC */
233    Pst              pst;        /* Post structure */
234    uint16_t         pduLen;     /* PDU length */
235    uint16_t         copyLen;    /* Number of bytes copied */
236
237    dlData = NULLP;
238    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
239                        dlData, sizeof(RlcData));
240 #if (ERRCLASS & ERRCLS_ADD_RES)
241    if ( dlData == NULLP )
242    {
243       DU_LOG("\nRLC: rlcSendDedLcDlData: Memory allocation failed for dl data");
244       RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
245           datReqInfo, sizeof(RguDDatReqInfo));
246       return RFAILED;
247    }
248 #endif /* ERRCLASS & ERRCLS_ADD_RES */
249
250    for(ueIdx = 0; ueIdx < datReqInfo->nmbOfUeGrantPerTti; ueIdx++)
251    {
252       datPerUe = datReqInfo->datReq[ueIdx];
253
254       memset((uint8_t *)dlData, 0, sizeof(RlcData));
255
256       dlData->cellId = datReqInfo->cellId;
257       dlData->rnti = datPerUe.rnti;
258
259       /* Retrieving sfn/slot from transId. It was filled in RlcProcSchedResultRpt */
260       dlData->slotInfo.sfn = datPerUe.transId >> 16;
261       dlData->slotInfo.slot = datPerUe.transId & 0xffff;
262       dlData->numPdu = 0;
263
264       for(tbIdx = 0; tbIdx < datPerUe.nmbOfTbs; tbIdx++)
265       {
266          datPerTb = datPerUe.datReqTb[tbIdx];
267          for(lchIdx = 0; lchIdx < datPerTb.nmbLch; lchIdx++)
268          {
269             datPerLch = datPerTb.lchData[lchIdx];
270             for(pduIdx = 0; pduIdx < datPerLch.pdu.numPdu; pduIdx++)
271             {
272                dlData->pduInfo[dlData->numPdu].commCh = FALSE;
273                dlData->pduInfo[dlData->numPdu].lcId = datPerLch.lcId;
274
275                /* Copy Message to fixed buffer to send */
276                ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen);
277                RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
278                   dlData->pduInfo[dlData->numPdu].pduBuf, pduLen);
279
280                if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP )
281                {
282                   DU_LOG("\nRLC: rlcSendDedLcDlData: Memory allocation failed");
283                   for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
284                   {
285                      RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
286                        dlData->pduInfo[pduIdx].pduLen);
287                   }
288                   RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
289                      dlData, sizeof(RlcData));
290                   RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
291                      datReqInfo, sizeof(RguDDatReqInfo));
292                   return RFAILED;
293                }
294
295                ODU_COPY_MSG_TO_FIX_BUF(datPerLch.pdu.mBuf[pduIdx], 0, pduLen, \
296                   dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)&copyLen);
297                dlData->pduInfo[dlData->numPdu].pduLen = pduLen;
298
299                /* Free message */
300                ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]);
301
302                dlData->numPdu++;
303             }/* For per PDU */
304          }/* For Data per Lch */
305       }/* For Data per Tb */
306
307       /* Sending DL Data per UE to MAC */
308       memset(&pst, 0, sizeof(Pst));
309       FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
310       if(RlcSendDlDataToMac(&pst, dlData) != ROK)
311       {
312          for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
313          {
314             RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
315                dlData->pduInfo[pduIdx].pduLen);
316          }
317          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
318       }
319    } /* For Data per UE */
320
321    RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
322             datReqInfo, sizeof(RguDDatReqInfo));
323    
324    return ROK;
325 }/* End of rlcSendDedLcDlData */
326
327 /**
328  *
329  * @brief 
330  *        Handler for sending the data to multiple logical channels of a UE
331  *
332  * @details:
333  *        This function sends the data for one or more logical channels
334  *        after processing the SDUs and forming the PDUs.It calls
335  *        UMM or AMM functions to form the PDUs for the requested sizes
336  *        by MAC. 
337  *
338  * @param[in] gCb          RLC instance Control block 
339  * @param[in] staIndInfo   Status Indication Information containing the 
340  *                         size of PDU(s) for one or more logical channels  
341  *
342  * @return  S16
343  *      -# ROK 
344  *      -# RFAILED
345  *
346  */
347 uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
348 {
349    uint8_t           numPdu = 0;
350    uint16_t          ueIdx;
351    RlcDlUeCb         *ueCb;         /* UE control block */
352    uint32_t          count;         /* Loop Counter */
353    uint32_t          numTb;         /* Number of Tbs */
354    RlcDlRbCb         *rbCb;         /* RB Control Block */
355    RlcDatReq         datReq;        /* PDUs Information */
356    RguDDatReqInfo   *datReqInfo;   /* Data Request Information */
357    RlcRguSapCb      *rguSap;       /* MAC SAP CB */
358    uint32_t         totNumPdu;     /* Total number of PDUS */
359    RguStaIndTb      *staIndTb = NULLP;
360    RguDatReqTb      *datReqTb = NULLP;
361    RguDStaIndPerUe  *staInd = NULLP;
362 #ifdef LTE_L2_MEAS   
363    uint32_t   grantPerLch[RGU_MAX_LC] = {0};
364 #endif
365 /* kw005.201 added support for L2 Measurement */
366 #ifdef LTE_L2_MEAS_LOSS_DELAY
367    uint8_t        snIdx1;
368    uint8_t        snIdx2;
369 #endif /* LTE_L2_MEAS */
370    uint32_t  idx;
371
372 //Debug
373    uint32_t staIndSz=0,datIndSz = 0;
374
375    datReqInfo = NULLP;
376    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
377                        datReqInfo,sizeof(RguDDatReqInfo));
378 #if (ERRCLASS & ERRCLS_ADD_RES)
379       if ( datReqInfo == NULLP )
380       {
381          DU_LOG("\nRLC: rlcUtlSendToMac: Memory allocation failed");
382          return RFAILED;
383       }
384 #endif /* ERRCLASS & ERRCLS_ADD_RES */
385    for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++)
386    {
387       staInd = &staIndInfo->staInd[idx];
388       /* Fetch Ue control block */
389       GET_UE_IDX(staInd->rnti, ueIdx);
390       if(ROK != rlcDbmFetchDlUeCb(gCb, ueIdx, staIndInfo->cellId,&ueCb))
391       {
392          /* Fetch UeCb failed */
393          DU_LOG("\nRLC: rlcUtlSendToMac: UeId[%u]:ueCb not found",
394             staInd->rnti);
395          /* If ueCb is not found for current rnti then continue to look for next rnti*/
396          continue; 
397       }
398       /* kw002.201 Removed the allocation of RlcDatReq */
399       /* kw004.201 Used SSI function to initialize the variable */
400       cmMemset( (U8 *)&datReq, 0, sizeof(RlcDatReq) ); 
401       totNumPdu = 0;
402       for (numTb = 0; numTb < staInd->nmbOfTbs; numTb++)
403       {
404          staIndTb = &(staInd->staIndTb[numTb]);
405          datReqTb = &(datReqInfo->datReq[idx].datReqTb[numTb]);
406 #ifdef LTE_L2_MEAS
407          ueCb->tbIdx = (ueCb->tbIdx+1) % RLC_MAX_TB_PER_UE;
408 #endif   
409          for (count = 0;count < staIndTb->nmbLch; count++)
410          {
411 #ifdef LTE_L2_MEAS
412             /*Calculate the total grant size from MAC */
413             if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC) 
414                 || (staIndTb->lchStaInd[count].lcId == 0))
415             {
416                /* TODO : Need to figure out why this is happening */
417                break;
418             }
419             else
420             {
421                grantPerLch[staIndTb->lchStaInd[count].lcId] += staIndTb->lchStaInd[count].totBufSize;
422             }
423 #endif   
424             rbCb = ueCb->lCh[staIndTb->lchStaInd[count].lcId - 1].dlRbCb;
425
426             if (rbCb && (!rlcDlUtlIsReestInProgress(rbCb)))
427             { 
428 //Debug
429                staIndSz += staIndTb->lchStaInd[count].totBufSize;
430                datReq.pduSz = staIndTb->lchStaInd[count].totBufSize;
431 #ifdef LTE_L2_MEAS            
432                datReq.totMacGrant = grantPerLch[staIndTb->lchStaInd[count].lcId];
433 #endif
434                rlcUtlGetCurrTime(&datReq.boRep.oldestSduArrTime);
435                if ( CM_LTE_MODE_UM == rbCb->mode )
436                {
437                   rlcUmmProcessSdus(gCb,rbCb,&datReq);
438                }
439                else if ( CM_LTE_MODE_AM == rbCb->mode )
440                {
441                   rlcAmmProcessSdus(gCb,rbCb,&datReq,staInd->fillCtrlPdu);
442                }
443 #ifdef LTE_L2_MEAS            
444                grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant;
445 #endif
446                if ( 0 == datReq.pduInfo.numPdu )
447                {
448                   continue;
449                }
450                totNumPdu += datReq.pduInfo.numPdu;
451                memcpy(&(datReqTb->lchData[count].pdu),
452                   &(datReq.pduInfo),sizeof(KwPduInfo));
453
454                for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++)
455                {
456                   MsgLen len = 0;
457                   ODU_GET_MSG_LEN(datReqTb->lchData[count].pdu.mBuf[numPdu],&len);
458                   datIndSz += len; 
459                }
460                datReqTb->lchData[count].setMaxUlPrio = FALSE;
461                if (RLC_AM_IS_POLL_BIT_SET(AMDL) && 
462                    (AMDL.sduQ.count > 1))
463                { 
464                   /* Poll bit is set indicate to MAC*/
465                   datReqTb->lchData[count].setMaxUlPrio = TRUE;
466                }
467                datReqTb->lchData[count].boReport.bo = datReq.boRep.bo;
468
469 #ifdef CCPU_OPT
470                datReqTb->lchData[count].boReport.estRlcHdrSz = 
471                   datReq.boRep.estHdrSz;
472                datReqTb->lchData[count].boReport.staPduPrsnt = 
473                   datReq.boRep.staPduPrsnt;
474 #endif /* CCPU_OPT */
475                datReqTb->lchData[count].boReport.staPduBo = 
476                   datReq.boRep.staPduBo;
477                datReqTb->lchData[count].lcId = staIndTb->lchStaInd[count].lcId;
478
479 #ifdef L2_OPTMZ
480                /* Set if Bearer is UM */
481                if ( CM_LTE_MODE_UM == rbCb->mode )
482                {
483                   datReqTb->lchData[count].freeBuff = TRUE;
484                }
485                else
486                {
487                   datReqTb->lchData[count].freeBuff = FALSE;
488                }
489 #endif
490
491                /* kw005.201 added support for L2 Measurement */
492 #ifdef LTE_L2_MEAS_LOSS_DELAY
493                datReqTb->rguSnInfo->lchMap[count].lChId =
494                   staIndTb->lchStaInd[count].lcId;
495                /* In some cases L2 Measurement for few of the lcId may be off, 
496                 * in this case we are assigning snList to 0xffff 
497                 */
498                for(snIdx1 = 0; snIdx1 < RGU_MAX_PDU; snIdx1++)
499                {
500                   datReqTb->rguSnInfo->lchMap[count].snList[snIdx1] = 0xffff;
501                }
502                if(tbSnMap->numSn != 0)
503                {
504                   snIdx2 = 0;
505                   for(snIdx1=tbSnMap->prevNumSn;snIdx1 < tbSnMap->numSn;snIdx1++)
506                   {
507                      datReqTb->rguSnInfo->lchMap[count].snList[snIdx2++] = 
508                         tbSnMap->snSduMap[snIdx1].sn;
509                   }
510                   tbSnMap->prevNumSn = tbSnMap->numSn;
511                }
512 #endif
513                datReqTb->lchData[count].boReport.oldestSduArrTime = 
514                                              datReq.boRep.oldestSduArrTime;
515                /* kw004.201 Used SSI function to initialize the variable */
516                memset(&datReq, 0, sizeof(RlcDatReq) ); 
517             }
518          }
519 #ifdef LTE_L2_MEAS
520          if(ueCb->l2MeasTbCb[ueCb->tbIdx]!= NULLP)
521          {
522             datReqTb->tbId = ueCb->tbIdx;
523          }
524          else
525          {
526             datReqTb->tbId = RLC_INVALID_TBID; 
527          }
528 #endif
529          datReqTb->nmbLch = staIndTb->nmbLch;
530          /*adding the check to make sure that lcId is not sent as 0
531           * when no data is there in datReq */
532          if ( 0 == totNumPdu )
533          {
534             datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId;
535          }
536          /* kw005.201 added support for L2 Measurement */
537 #ifdef LTE_L2_MEAS_LOSS_DELAY
538          if(tbSnMap->numSn == 0)
539          {
540             RLC_FREE(tbSnMap,sizeof(RlcTbSnMap));
541             RLC_FREE(datReqTb->rguSnInfo,sizeof(RguSnMapInfo));
542             datReqTb->rguSnInfo = NULLP;
543             rlcCb.rlcL2Cb.curTbSnMap = NULLP;
544             datReqTb->snMapPres = FALSE;
545          }
546          else
547          {
548             cmHashListInsert(&(rlcCb.rlcL2Cb.tbHlCp),(PTR)tbSnMap,
549                   (U8 *) &(tbSnMap->tbId), (U16)sizeof(tbSnMap->tbId));
550             rlcCb.rlcL2Cb.curTbSnMap = NULLP;
551          }
552 #endif /* LTE_L2_MEAS */
553       }
554       datReqInfo->datReq[idx].nmbOfTbs = staInd->nmbOfTbs;
555       datReqInfo->datReq[idx].transId = staInd->transId;
556       datReqInfo->datReq[idx].rnti    = staInd->rnti;
557    }
558    datReqInfo->cellId  = staIndInfo->cellId;
559    datReqInfo->nmbOfUeGrantPerTti = staIndInfo->nmbOfUeGrantPerTti;
560
561    rguSap = &(gCb->u.dlCb->rguDlSap[suId]);
562    rlcSendDedLcDlData(&rguSap->pst,rguSap->spId,datReqInfo); 
563    return ROK;
564 }
565
566 /**
567  *
568  * @brief 
569  *        Handler for sending Status Response to MAC. 
570  *
571  * @detail:
572  *        This function is used by  RLC entity for sending
573  *        status response to MAC after receiving a SDU from
574  *        PDCP.
575  *
576  * @param[in]  gCb           RLC instance Control block
577  * @param[in]  rbCb          Radio Bearer Control Block 
578  * @param[in]  bo            Buffer Occupancy
579  * @param[in]  estHdrSz      Estimated Header Size
580  * @param[in]  staPduPrsnt   Status PDU present or not
581  *
582  * @return  S16
583  *      -# ROK 
584  *      -# RFAILED
585  */
586 uint8_t rlcUtlSendDedLcBoStatus(RlcCb *gCb, RlcDlRbCb *rbCb, int32_t bo, \
587    int32_t estHdrSz, bool staPduPrsnt, uint32_t staPduBo)
588 {
589    Pst           pst;           /* Post info */
590    RlcBoStatus   *boStatus;      /* Buffer occupancy status information */
591
592 #ifndef TENB_ACC
593    if ((rbCb->lastRprtdBoToMac > (uint32_t)8000) && (rbCb->boUnRprtdCnt < (uint32_t)5) 
594        && (!staPduPrsnt) && ((CM_LTE_MODE_AM == rbCb->mode ) && (AMDL.nxtRetx == NULLP)))
595    {
596       rbCb->boUnRprtdCnt++;
597       return ROK;
598    }
599 #endif
600    rbCb->boUnRprtdCnt = (uint32_t)0;
601    rbCb->lastRprtdBoToMac = (uint32_t)bo;
602
603    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, \
604       boStatus, sizeof(RlcBoStatus));
605
606    boStatus->cellId = rbCb->rlcId.cellId;
607    boStatus->ueIdx = rbCb->rlcId.ueId;
608    boStatus->commCh = FALSE; 
609    boStatus->lcId = rbCb->lch.lChId;
610    boStatus->bo = bo;
611
612    FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_BO_STATUS_TO_MAC);
613    /* Send Status Response to MAC layer */
614    if(RlcSendBoStatusToMac(&pst, boStatus) != ROK)
615    {
616       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus));
617    }
618
619    return ROK;
620 }
621
622 /**
623  *
624  * @brief 
625  *        Handler for emptying the SDU queue. 
626  * 
627  * @detail:
628  *        This function is used to empty the SDU queue when
629  *        a re-establishment request is received from the 
630  *        upper layer.
631  *
632  * @param[in]  gCb    RLC instance control block
633  * @param[in]  rbCb   Radio bearer control block
634  * @param[in]  sduQ   SDU queue to be emptied
635  *
636  * @return Void 
637  */
638 /* kw005.201 added support for L2 Measurement */
639 #ifdef LTE_L2_MEAS_RLC
640 #ifdef ANSI
641 Void rlcUtlEmptySduQ
642 (
643 RlcCb        *gCb, 
644 RlcDlRbCb    *rbCb,
645 CmLListCp   *sduQ 
646 )
647 #else
648 Void rlcUtlEmptySduQ(gCb,rbCb, sduQ)
649 RlcCb        *gCb;
650 RlcDlRbCb    *rbCb;
651 CmLListCp   *sduQ;
652 #endif
653 #else
654 #ifdef ANSI
655 Void rlcUtlEmptySduQ
656 (
657 RlcCb        *gCb,
658 CmLListCp   *sduQ 
659 )
660 #else
661 Void rlcUtlEmptySduQ(gCb,sduQ)
662 RlcCb        *gCb;
663 CmLListCp   *sduQ; 
664 #endif
665 #endif
666 {
667 #ifdef LTE_L2_MEAS_RLC
668    CmLListCp   *sduSnMapQ;             /* SDU Sequence number map queue */
669    CmLList     *firstSduSnMap;         /* First Node in SDU SnMap Queue */
670    RlcSduSnMap  *sduSnMap;              /* SDU Sn Map */
671
672    TRC2(rlcUtlEmptySduQ)
673    sduSnMapQ = NULLP;
674    firstSduSnMap = NULLP;
675    sduSnMap = NULLP;
676
677
678    sduSnMapQ = &rbCb->sduSnMapQ;
679    CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
680
681    while(firstSduSnMap)
682    {
683       sduSnMap = (RlcSduSnMap *)firstSduSnMap->node;
684       if(sduSnMap != NULLP)
685       {
686          cmLListDelFrm(&(rbCb->sduSnMapQ), &(sduSnMap->lstEnt));
687          RLC_FREE(sduSnMap, sizeof(RlcSduSnMap));
688          CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap);
689       }
690       else
691       {
692          CM_LLIST_NEXT_NODE(sduSnMapQ, firstSduSnMap);
693       }
694    }
695 #endif
696    RETVOID;
697 }
698
699 /**
700  *
701  * @brief 
702  *    Handler for calculating the Length Indicator (LI) length for a SDU 
703  * 
704  * @detail:
705  *    This function is used to calculate the LI (Length Indicator) length
706  *    which has to be substracted from the pduSize to correctly match the
707  *    formed PDU(s) size with the  size requested by MAC.
708  *
709  * @param[in]      gCb      RLC instance control block 
710  * @param[in]      numLi    Number of LIs already present 
711  * @param[in]      msgLen   Size of the SDU
712  * @param[in/out]  pduSz    Size of the pDU to be formed
713  *
714  * @return  void 
715  */
716 void rlcUtlCalcLiForSdu(RlcCb *gCb, uint16_t numLi, MsgLen msgLen, int16_t *pduSz)
717 {
718    if ( (*pduSz > msgLen)  && (msgLen < RLC_2K_BYTE))
719    {
720       if(0 == (numLi & RLC_BIT0)) /* check if number of LIs are odd or even */
721       {  
722          /* if number of LI's are even 2 bytes needed */
723          *pduSz -= 2;
724       }
725       else
726       {
727          /* if number of LI's are odd one byte needed */
728          *pduSz -= 1;
729       }
730    }
731    return;
732 }
733
734 /**
735  *
736  * @brief 
737  *    Function to set that re-establishment has started for an RB
738  * 
739  * @detail:
740  *    This function is used to set the reestInProgress flag to TRUE.
741  *    This also sets the estimated header size to 0 and sends bo as
742  *    0 to MAC so that RLC does not need to transmit any data.
743  *    If the poll re-transmit timer is running for the RB;
744  *    it is stopped
745  *
746  * @param[in]      gCb      RLC instance control block 
747  * @param[in]      rbCb     RB for which re-establishment has started 
748  *
749  * @return  void 
750  */
751 #ifdef ANSI
752 Void rlcDlUtlSetReestInProgressForRB
753 (
754 RlcCb     *gCb,
755 RlcDlRbCb *rbCb
756 )
757 #else
758 Void rlcDlUtlSetReestInProgressForRB(gCb,rbCb)
759 RlcCb     *gCb;
760 RlcDlRbCb *rbCb;
761 #endif 
762 {
763    TRC2(rlcDlUtlSetReestInProgressForRB)
764       
765    rbCb->reestInProgress = TRUE;
766    
767    if(rbCb->mode == CM_LTE_MODE_AM )
768    {
769       rbCb->m.amDl.estHdrSz = 0;
770
771       if(rlcChkTmr(gCb, (PTR)rbCb, RLC_EVT_AMDL_POLL_RETX_TMR))
772       {
773          rlcStopTmr(gCb, (PTR)rbCb, RLC_EVT_AMDL_POLL_RETX_TMR);
774       }
775    }
776    else
777    {
778       rbCb->m.umDl.estHdrSz= 0;
779    }
780
781    rlcUtlSendDedLcBoStatus(gCb, rbCb, 0, 0, FALSE,0);
782
783    RETVOID;
784 }
785
786 /**
787  *
788  * @brief 
789  *    Function to check if re-establishment is ongoing for an RB
790  * 
791  * @param[in]      rbCb     RB for which re-establishment is to be checked 
792  *
793  * @return  Bool
794  *          TRUE  : Re-establishment is in progress
795  *          FALSE : Re-establishment is not in progress
796  */
797 bool rlcDlUtlIsReestInProgress(RlcDlRbCb *rbCb)
798 {
799    return (rbCb->reestInProgress);
800 }
801
802 /**
803  *
804  * @brief 
805  *    Function to set re-establishment to FALSE
806  * 
807  * @param[in]      rbCb     RB for which re-establishment is to be reset 
808  *
809  * @return  Void
810  */
811 #ifdef ANSI
812 Void rlcDlUtlResetReestInProgress
813 (
814 RlcDlRbCb *rbCb
815 )
816 #else
817 Void rlcDlUtlResetReestInProgress(rbCb)
818 RlcDlRbCb *rbCb;
819 #endif 
820 {
821    TRC2(rlcDlUtlSetReestInProgressForRB)
822
823    rbCb->reestInProgress = FALSE;
824 }
825
826 /**
827  *
828  * @brief 
829  *    Function to set that re-establishment has started for all the RBs
830  *    of an UE; except for SRB1
831  *
832  * @detail: For SRB1 only the poll-retransmit timer is stopped
833  * 
834  * @param[in]      gCb      RLC instance control block 
835  * @param[in]      ueCb     UE for which re-establishment has started 
836  *
837  * @return  void 
838  */
839 #ifdef ANSI
840 Void rlcDlUtlSetReestInProgressForAllRBs
841 (
842 RlcCb     *gCb,
843 RlcDlUeCb *ueCb
844 )
845 #else
846 Void rlcDlUtlSetReestInProgressForAllRBs(gCb,ueCb)
847 RlcCb     *gCb;
848 RlcDlUeCb *ueCb;
849 #endif 
850 {
851    U32        rbIdx;
852    
853    TRC2(rlcDlUtlSetReestInProgressForAllRBs)
854
855    for(rbIdx = 0;rbIdx < RLC_MAX_SRB_PER_UE;rbIdx++)
856    {
857       if(ueCb->srbCb[rbIdx] != NULLP)
858       {
859          if(ueCb->srbCb[rbIdx]->rlcId.rbId != 1)
860          {
861             rlcDlUtlSetReestInProgressForRB(gCb,ueCb->srbCb[rbIdx]); 
862          }
863          else
864          {
865             /* For SRB we just need to stop the poll re-transmit timer */
866             if(rlcChkTmr(gCb, (PTR)ueCb->srbCb[rbIdx], RLC_EVT_AMDL_POLL_RETX_TMR))
867             {
868                rlcStopTmr(gCb, (PTR)ueCb->srbCb[rbIdx], RLC_EVT_AMDL_POLL_RETX_TMR);
869             }
870          }
871       }
872    }
873    
874    for(rbIdx = 0;rbIdx < RLC_MAX_DRB_PER_UE;rbIdx++)
875    {
876       if(ueCb->drbCb[rbIdx] != NULLP)
877       {
878          rlcDlUtlSetReestInProgressForRB(gCb,ueCb->drbCb[rbIdx]);
879       }
880    }
881       
882    RETVOID;
883 }
884
885 /**
886  * @brief  Function to increment number of SDUs transmitted 
887  *         in KWU SAP statistics
888  *
889  *
890  * @param[in]  rlckwuSap     KWU SAP in which to increment the counter
891  *
892  * @return  Void
893  */
894 void rlcUtlIncrementKwuStsSduTx(RlcKwuSapCb *rlckwuSap)
895 {
896    rlckwuSap->sts.sduTx++;
897    return;
898 }
899
900 /**
901  * @brief  Function to increment number of bytes and PDUs transmitted 
902  *         in General statistics
903  *
904  *
905  * @param[in]  genSts   KWU SAP in which to increment the counter
906  * @param[in]  pdu      The PDU which is sent
907  *
908  * @return  Void
909  */
910 void rlcUtlIncrementGenStsBytesAndPdusSent(RlcGenSts *genSts, Buffer *pdu)
911 {
912    MsgLen bytesSent;
913    ODU_GET_MSG_LEN(pdu, &bytesSent);
914    genSts->bytesSent += bytesSent;
915    genSts->pdusSent++;
916    return;
917 }
918
919 /**
920  * @brief  Function to initialize the data structures used to free memory
921  *
922  *
923  * @param[in]  gCb        RLC instance control block
924  * @param[out] toBeFreed  Pointer to the freeing structure. This is 
925  *                        initialized here
926  *
927  * @return  Void
928  */
929 #ifdef ANSI
930 Void rlcUtlInitToBeFreed
931 (
932 RlcCb                *gCb,
933 RlcDlDataToBeFreed   *toBeFreed
934 )
935 #else
936 Void rlcUtlInitToBeFreed(gCb, toBeFreed)
937 RlcCb                *gCb;
938 RlcDlDataToBeFreed   *toBeFreed;
939 #endif
940 {
941    cmLListInit(&(toBeFreed->sduLst));
942    cmLListInit(&(toBeFreed->rbLst));
943    cmLListInit(&(toBeFreed->reTxLst));
944    cmLListInit(&(toBeFreed->txLst));
945    
946    RETVOID;
947 }
948
949 /**
950  * @brief  Function to initialize the DL self Pst structure
951  *
952  *
953  * @param[in]  gCb   RLC instance control block
954  *
955  * @return  Void
956  */
957 #ifdef ANSI
958 Void rlcUtlInitializeSelfPst
959 (
960 RlcCb *gCb  
961 )
962 #else
963 Void rlcUtlInitializeSelfPst(gCb)
964 RlcCb *gCb;
965 #endif
966 {
967    Pst *selfPst = &gCb->u.dlCb->selfPst;
968    
969    RLC_MEM_SET(selfPst, 0, sizeof(Pst));
970    selfPst->srcProcId = SFndProcId();
971    selfPst->dstProcId = SFndProcId();
972    selfPst->dstEnt = gCb->init.ent;
973    selfPst->dstInst = gCb->init.inst; /* this is for the DL instance */
974    selfPst->srcEnt = gCb->init.ent;
975    selfPst->srcInst = gCb->init.inst;  /* DL instance will send to itself */
976    selfPst->prior  = PRIOR3;
977    selfPst->event  = UDX_EVT_DL_CLEANUP_MEM;
978 }
979
980 /**
981  * @brief  Function to send a DL cleanup event
982  *
983  *
984  * @param[in]  gCb   RLC instance control block
985  *
986  * @return  Void
987  */
988 void rlcUtlRaiseDlCleanupEvent(RlcCb *gCb)
989 {
990 #ifdef KWSELFPSTDLCLEAN
991    if(!gCb->u.dlCb->eventInQueue)
992    {
993       ODU_POST_TASK(&gCb->u.dlCb->selfPst, gCb->u.dlCb->selfPstMBuf);
994       gCb->u.dlCb->eventInQueue = TRUE;
995    }
996 #endif
997    return;
998 }
999
1000 /**
1001  * @brief  Function to add a SDU to the to be freed sdu list
1002  *
1003  *
1004  * @param[in]  gCb   RLC instance control block
1005  * @param[in]  sdu   SDU to be added to the list
1006  *
1007  * @return  Void
1008  */
1009 void rlcUtlAddSduToBeFreedQueue(RlcCb *gCb, RlcSdu *sdu)
1010 {
1011    cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.sduLst), &(sdu->lstEnt));
1012    return;
1013 }
1014
1015 /**
1016  * @brief  Function to add a re-transmitted pdu to the to be freed list
1017  *
1018  *
1019  * @param[in]  gCb   RLC instance control block
1020  * @param[in]  retx  Re-transmitted pdu to be added to the list
1021  *
1022  * @return  Void
1023  */
1024 #ifdef ANSI
1025 Void rlcUtlAddReTxPduToBeFreedQueue
1026 (
1027 RlcCb     *gCb,
1028 RlcRetx   *retx
1029 )
1030 #else
1031 Void rlcUtlAddReTxPduToBeFreedQueue(gCb, retx)
1032 RlcCb     *gCb;
1033 RlcRetx   *retx;
1034 #endif
1035 {
1036    cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.reTxLst), &(retx->lstEnt));
1037    RETVOID;
1038 }
1039
1040 /**
1041  * @brief  Function to add a transmitted pdu to the to be freed list
1042  *
1043  *
1044  * @param[in]  gCb   RLC instance control block
1045  * @param[in]  pdu   PDU to be added to the list
1046  *
1047  * @return  Void
1048  */
1049 #ifdef ANSI
1050 Void rlcUtlAddTxPduToBeFreedQueue
1051 (
1052 RlcCb   *gCb,
1053 RlcTx   *pdu
1054 )
1055 #else
1056 Void rlcUtlAddTxPduToBeFreedQueue(gCb, pdu)
1057 RlcCb   *gCb;
1058 RlcTx   *pdu;
1059 #endif
1060 {
1061    pdu->rlsLnk.node = (PTR)pdu;
1062    cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.txLst), &(pdu->rlsLnk));
1063    RETVOID;
1064 }
1065
1066 /*
1067  * @brief
1068  *    function to free/release the Acknowledged mode RBCB buffers
1069  *
1070  * @details
1071  *    This primitive Frees the Acknowledged Mode RbCb transmission Buffer,
1072  *    retransmission Buffer and reciption Buffers
1073  *
1074  * @param [in]      gCb       - RLC instance control block
1075  * @param [in]      rbCb      - Downlink RB Control Block
1076  * @param [in,out]  toBeFreed - Number of buffers to be freed
1077  *
1078  * @return Bool
1079  *     - TRUE if more data to be freed
1080  *     - FALSE if all the data has been freed
1081  */
1082 #ifdef ANSI
1083 PRIVATE Bool rlcUtlFreeDlAmRbMemory
1084 (
1085 RlcCb       *gCb,
1086 RlcDlRbCb   *rbCb,
1087 U32        *toBeFreed
1088 )
1089 #else
1090 PRIVATE Bool rlcUtlFreeDlAmRbMemory(gCb, rbCb, toBeFreed)
1091 RlcCb       *gCb;
1092 RlcDlRbCb   *rbCb;
1093 U32        *toBeFreed
1094 #endif
1095 {
1096    RlcRetx   *retx;   /* retransmission buffer */
1097    RlcSn     mTxNext;    /* send state variable */
1098    RlcTx      *txBuf;
1099
1100    TRC2(rlcUtlFreeDlAmRbMemory)
1101
1102
1103    MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1104
1105    /* TODO : to be checked changed from <= to < */
1106    while ((0 < mTxNext) && *toBeFreed)
1107    {
1108       txBuf =  rlcUtlGetTxBuf(AMDL.txBufLst, AMDL.txNextAck);
1109       if (txBuf && txBuf->pduLst.first)
1110       {
1111          while(txBuf->pduLst.first)
1112          {
1113             RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(txBuf->pduLst.first->node);
1114             RLC_FREE_BUF(pduInfo->pdu);
1115             /* Delete node from the txBuf Pdu lst */
1116             cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first);
1117             RLC_FREE_WC(gCb, pduInfo, sizeof(RlcDlPduInfo));
1118          }
1119          rlcUtlDelTxBuf(AMDL.txBufLst, txBuf, gCb);
1120          if(gCb->u.dlCb->shutdownReceived == 0)
1121          {   
1122             (*toBeFreed)--;
1123          }
1124       }
1125       AMDL.txNextAck = (AMDL.txNextAck + 1) & AMDL.snModMask;
1126       MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask);
1127    }
1128    if(*toBeFreed == 0)
1129    {
1130       return (TRUE);
1131    }
1132    
1133 #ifndef LTE_TDD 
1134       RLC_FREE(gCb,AMDL.txBufLst, (RLC_TX_BUF_BIN_SIZE * sizeof(CmLListCp)));
1135 #endif
1136
1137    RLC_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1138    while (retx && (*toBeFreed)) /* Till to be freed becomes 0 */
1139    {
1140
1141       RLC_FREE_BUF(retx->seg);
1142
1143       cmLListDelFrm(&AMDL.retxLst, &retx->lstEnt);
1144       RLC_FREE_WC(gCb, retx, sizeof(RlcRetx));
1145
1146       RLC_LLIST_FIRST_RETX(AMDL.retxLst, retx);
1147       if(gCb->u.dlCb->shutdownReceived == 0)
1148       {
1149       (*toBeFreed)--;
1150    }
1151
1152    }
1153
1154    AMDL.nxtRetx = NULLP;
1155
1156    /* clean up if there is info about STATUS PDU to be sent */
1157    if(AMDL.pStaPdu)
1158    {
1159       Pst *udxPst;
1160       udxPst = &gCb->u.dlCb->udxDlSap->pst;
1161       RLC_FREE_SHRABL_BUF_WC(udxPst->region,
1162                             udxPst->pool,
1163                             AMDL.pStaPdu, 
1164                             sizeof(RlcUdxDlStaPdu));
1165       AMDL.pStaPdu = NULLP;
1166    }
1167
1168    if(*toBeFreed == 0)
1169    {
1170       return (TRUE);
1171    }  
1172    if(gCb->u.dlCb->shutdownReceived)
1173    {   
1174       (*toBeFreed)--;
1175    }
1176    
1177    return (FALSE);;
1178
1179
1180 /**
1181  * @brief  Function to free memory from the DL instance
1182  *
1183  *
1184  * @param[in]  gCb   RLC instance control block
1185  *
1186  * @return  Void
1187  */
1188 #ifdef ANSI
1189 Void rlcUtlFreeDlMemory
1190 (
1191 RlcCb *gCb  
1192 )
1193 #else
1194 Void rlcUtlFreeDlMemory(gCb)
1195 RlcCb *gCb;
1196 #endif
1197 {
1198    U32 toBeFreed; 
1199
1200    /* safety check, in case some event was still lying in the queue after
1201       the dlCb was deleted*/
1202    if(!gCb->u.dlCb)
1203    {
1204       RETVOID;
1205    }
1206
1207    RlcDlDataToBeFreed* pToBeFreed = &gCb->u.dlCb->toBeFreed;
1208    /* ccpu00136940 */
1209    if(gCb->u.dlCb->shutdownReceived)
1210    {
1211       toBeFreed = pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count + pToBeFreed->rbLst.count; 
1212    }
1213    else
1214    {
1215       if ((pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count) > (3 * RLC_MAX_TO_BE_FREED))
1216       {
1217 #if !defined(KWSELFPSTDLCLEAN) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
1218          if (isDatReqProcessed)
1219          {
1220             toBeFreed = (2 *RLC_MAX_TO_BE_FREED);
1221          }
1222          else
1223 #endif
1224          {
1225             toBeFreed = (3 *RLC_MAX_TO_BE_FREED)/2;
1226          }
1227       }
1228       else
1229       {
1230          toBeFreed = RLC_MAX_TO_BE_FREED;
1231       }
1232    }   
1233    CmLListCp        *lst;
1234
1235    gCb->u.dlCb->eventInQueue = FALSE; /* reset as we have received the event
1236                                          and are processing it */
1237
1238    /* Free from the ReTx list */
1239    lst  = &pToBeFreed->reTxLst;
1240 #ifndef L2_OPTMZ
1241    while((lst->first) && toBeFreed && (pToBeFreed->reTxLst.count > 100))
1242 #else
1243    while((lst->first) && toBeFreed)
1244 #endif
1245    {
1246       RlcRetx* seg = (RlcRetx *)(lst->first->node);
1247       cmLListDelFrm(lst, lst->first);
1248       RLC_FREE_BUF_WC(seg->seg);
1249       RLC_FREE_WC(gCb,seg, sizeof(RlcRetx));
1250       toBeFreed--;
1251    }   
1252
1253    /* Free from the Tx list */
1254    lst  = &pToBeFreed->txLst;
1255 #ifndef L2_OPTMZ
1256    while((lst->first) && toBeFreed && (pToBeFreed->txLst.count > 100))
1257 #else
1258    while((lst->first) && toBeFreed)
1259 #endif
1260    {
1261       RlcTx* pdu = (RlcTx *)(lst->first->node);
1262       cmLListDelFrm(lst, lst->first);
1263       while(pdu->pduLst.first)
1264       {
1265          RlcDlPduInfo *pduInfo = (RlcDlPduInfo *)(pdu->pduLst.first->node);
1266          
1267          cmLListDelFrm(&pdu->pduLst, pdu->pduLst.first);
1268          RLC_FREE_BUF_WC(pduInfo->pdu);
1269          RLC_FREE_WC(gCb, pduInfo, sizeof(RlcDlPduInfo));
1270       }
1271       RLC_FREE_WC(gCb,pdu, sizeof(RlcTx));
1272       toBeFreed--;
1273    }
1274
1275    /* Free from the SDU queue */
1276    lst  = &pToBeFreed->sduLst;
1277 #ifndef L2_OPTMZ
1278    while((lst->first) && toBeFreed && (pToBeFreed->sduLst.count > 100))
1279 #else
1280    while((lst->first) && toBeFreed)
1281 #endif
1282    {
1283       RlcSdu* sdu = (RlcSdu *)(lst->first->node);
1284       RLC_RMV_SDU(gCb, lst, sdu);
1285       toBeFreed--;
1286    }      
1287
1288    /* Free from the RBs */
1289    lst  = &pToBeFreed->rbLst;
1290 #ifndef L2_OPTMZ
1291    while((lst->first) && toBeFreed && (pToBeFreed->rbLst.count > 100))
1292 #else
1293    while((lst->first) && toBeFreed)
1294 #endif
1295    {
1296       RlcDlRbCb* rbCb = (RlcDlRbCb *)(lst->first->node);
1297       Bool moreToBeFreed = rlcUtlFreeDlAmRbMemory(gCb, rbCb,&toBeFreed);
1298       if(!moreToBeFreed)
1299       {
1300          cmLListDelFrm(lst, lst->first);
1301          RLC_FREE_WC(gCb, rbCb, sizeof(RlcDlRbCb));
1302       }
1303    } 
1304
1305    if ((toBeFreed == 0) && !(gCb->u.dlCb->shutdownReceived))
1306    {
1307       rlcUtlRaiseDlCleanupEvent(gCb);
1308    }
1309
1310    RETVOID;
1311 }
1312
1313
1314 #ifdef LTE_L2_MEAS
1315 /**
1316  *
1317  * @brief Function to initialise measurement
1318  *
1319  * @b Description
1320  *
1321  * @param[in]  gCb     RLC Instance Control Block
1322  *
1323  *  @return  Void
1324  *
1325  */
1326 S16 rlcUtlL2MeasDlInit(RlcCb *gCb)
1327 {
1328    U16   cntr;
1329
1330    gCb->u.dlCb->rlcL2Cb.rlcNumMeas=0;
1331    for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
1332    {
1333       cmMemset((U8 *)&(gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
1334    }
1335    gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DISC].measCb.measType = LKW_L2MEAS_DL_DISC;
1336    gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_IP].measCb.measType = LKW_L2MEAS_DL_IP;
1337    gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_DL_DELAY].measCb.measType= LKW_L2MEAS_DL_DELAY;
1338    gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UU_LOSS].measCb.measType= LKW_L2MEAS_UU_LOSS;
1339    gCb->u.dlCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_ACT_UE].measCb.measType= LKW_L2MEAS_ACT_UE;
1340
1341    return ROK;
1342 }
1343 /**
1344  *
1345  * @brief Function to detect the data Burst start Condition in a DTCH
1346  *
1347  * @b Description
1348  *
1349  * @param[in]  rbCb     RB control block
1350  * @param[in]  contSduLst  Array of Contained SDUs in the DTCH   
1351  * @param[in]  dataVol  Available data in the DTCH
1352  * @param[in]  schPduSz    Total grant Size given by MAC
1353  *
1354  *  @return  Void
1355  *
1356  */
1357 #ifdef ANSI
1358 Void rlcUtlUpdateBurstSdus
1359 (
1360 RlcCb            *gCb,
1361 RlcDlRbCb        *rbCb,
1362 RlcContSduLst    *contSduLst,
1363 S32             dataVol,
1364 U32             schPduSz
1365 )
1366 #else
1367 Void  rlcUtlUpdateBurstSdus (gCb, rbCb, contSduLst, dataVol, schPduSz)
1368 RlcCb            *gCb;
1369 RlcDlRbCb        *rbCb;
1370 RlcContSduLst    *contSduLst;
1371 S32             dataVol;
1372 U32             schPduSz;
1373 #endif
1374 {
1375
1376    RlcL2MeasDlIpTh *l2MeasDlIpThruput = NULLP;
1377    RlcL2MeasTb     *l2MeasTb = NULLP;
1378    U8              idx;
1379    U8              currTbIdx;
1380    VOLATILE U32     startTime = 0;
1381    RlcContSduLst   *dstContSduLst;
1382    TRC2(rlcUtlUpdateBurstSdus)
1383
1384
1385    /*starting Task*/
1386    SStartTask(&startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1387
1388    l2MeasDlIpThruput = &rbCb->l2MeasIpThruput.dlIpTh;
1389
1390    if(RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb))
1391    {
1392       if(dataVol > schPduSz)
1393       {
1394          if(l2MeasDlIpThruput->isBurstAct == FALSE)
1395          {
1396             l2MeasDlIpThruput->burstStartTime = glblTtiCnt;
1397             l2MeasDlIpThruput->isBurstAct = TRUE;
1398             l2MeasDlIpThruput->burstEndSduId = 0;
1399          }
1400          else
1401          {  /* This is the case when another burst started before RLC gets the 
1402                l2MeasDlIpThruput->burstEndSduId = 0; */
1403          }
1404       }
1405       else
1406       {  /* Store the burstEndSduId here */
1407          if((l2MeasDlIpThruput->isBurstAct == TRUE) &&
1408                (!l2MeasDlIpThruput->burstEndSduId))
1409          {
1410             l2MeasDlIpThruput->burstEndSduId = 
1411                l2MeasDlIpThruput->outStngSduArr[l2MeasDlIpThruput->lastSduIdx].sduId;
1412          }
1413       }
1414       if(l2MeasDlIpThruput->isBurstAct == TRUE)
1415       {
1416          l2MeasTb = rlcUtlGetCurMeasTb(gCb,rbCb);
1417          /* Get the lChId from index 0, because index 0 is always for DL */
1418          if(l2MeasTb->numLcId >= RLC_MAX_ACTV_DRB) 
1419          {
1420             /* ccpu00143043 */
1421             RETVOID;
1422          }
1423          l2MeasTb->sduInfo[l2MeasTb->numLcId].lcId = rbCb->lch.lChId;
1424          /* Copy all the sduIdx from sduInfo to tb sduInfo */
1425          currTbIdx = l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus;
1426          dstContSduLst = &l2MeasTb->sduInfo[l2MeasTb->numLcId];
1427          /* ccpu00143043 */
1428          for(idx = 0; ((idx < contSduLst->numSdus)
1429                   && (currTbIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)) ; idx++)
1430          {
1431             dstContSduLst->sduIdx[currTbIdx++] = contSduLst->sduIdx[idx];
1432          }
1433          l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus += idx;
1434          l2MeasTb->numLcId++;
1435       }/* End of isBurstAct */
1436    }/* End of if measOn */
1437
1438    /*stopping Task*/
1439    SStopTask(startTime, PID_RLC_DLIP_TPT_BURSTCALC);
1440    RETVOID;
1441 }
1442 /**
1443  * @brief
1444  *        This function is used to store locally the sduIdx of the sdu in the 
1445  *        outstanding SDU array
1446  * 
1447  * @b Description:
1448  *        Stores the Sdu Idx in the contained  SDU Array and increments 
1449  *        the num contained  Sdus 
1450  *
1451  *  @param[in]  sduIdx  the Index of the SDU in the outstanding SDU array
1452  *  @param[out] contSduLst This stores the indices of the SDUs 
1453  *
1454  *  @return  Void
1455  */
1456 #ifdef ANSI
1457 Void rlcUtlUpdateContainedSduLst
1458 (
1459 U8            sduIdx,
1460 RlcContSduLst  *contSduLst
1461 )
1462 #else
1463 Void rlcUtlUpdateContainedSduLst(sduIdx, contSduLst)
1464 U8            sduIdx;
1465 RlcContSduLst  *contSduLst;
1466 #endif
1467 {
1468    if (contSduLst->numSdus < RLC_L2MEAS_MAX_OUTSTNGSDU)
1469    {
1470     contSduLst->sduIdx[contSduLst->numSdus] = sduIdx;
1471     contSduLst->numSdus++;
1472    }
1473     RETVOID;
1474 }
1475
1476 /**
1477  * @brief
1478  *        This function is used to store the sduId of the sdu in the 
1479  *        outstanding SDU array
1480  * 
1481  * @b Description:
1482  *        Stores the Sdu Id in the outstanding SDU Array and increments 
1483  *        the num contained  Sdus 
1484  *
1485  *  @param[out] dlIpThPut  The structure in which the outstanding sdus are 
1486  *                         updated
1487  *  @param[in] sduIdx   The Idx at which the sdu ID is stored  
1488  *  @param[in] sduLen   The size if sdu in bytes  
1489  *  @param[in] newIdx   Indicates if the sdu is already present in the 
1490  *                      outstanding array  
1491  *
1492  *  @return  Void
1493  */
1494 #ifdef ANSI
1495 Void rlcUtlUpdateOutStandingSduLst
1496 (
1497 RlcL2MeasDlIpTh   *dlIpThPut, 
1498 U8               sduIdx, 
1499 MsgLen           sduLen, 
1500 U32              sduId,
1501 Bool             newIdx
1502 )
1503 #else
1504 Void rlcUtlUpdateOutStandingSduLst(dlIpThPut, sduIdx, sduLen, sduId, newIdx)
1505 RlcL2MeasDlIpTh   *dlIpThPut;
1506 U8               sduIdx;
1507 MsgLen           sduLen; 
1508 U32              sduId;
1509 Bool             newIdx;
1510 #endif
1511 {
1512    if (sduIdx < RLC_L2MEAS_MAX_OUTSTNGSDU)
1513    {
1514    if(newIdx == TRUE)
1515    {      
1516      dlIpThPut->outStngSduArr[sduIdx].numTb = 0;
1517    }
1518    dlIpThPut->outStngSduArr[sduIdx].numTb++;
1519    dlIpThPut->outStngSduArr[sduIdx].sduId = sduId;
1520    dlIpThPut->outStngSduArr[sduIdx].sduLen = sduLen;
1521    }
1522    RETVOID;
1523 }
1524 #ifdef ANSI
1525 RlcL2MeasTb * rlcUtlGetCurMeasTb
1526 (
1527 RlcCb     *gCb,
1528 RlcDlRbCb *rbCb
1529 )
1530 #else
1531 RlcL2MeasTb * rlcUtlGetCurMeasTb(gCb, rbCb)
1532 RlcCb     *gCb;
1533 RlcDlRbCb *rbCb;
1534 #endif
1535 {
1536    RlcL2MeasTb  *curL2MeasTb;
1537    U16         idx;
1538
1539    TRC3(rlcUtlGetCurMeasTb)
1540       
1541    if((curL2MeasTb = rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx]) == NULLP)
1542       {
1543          /* Intentionally avoiding the RLC_ALLOC macro to avoid  memset */
1544          if (SGetSBuf(gCb->init.region,
1545                   gCb->init.pool,
1546                   (Data **)&curL2MeasTb,
1547                   (Size)sizeof(RlcL2MeasTb)) != ROK)
1548          {
1549             return (NULLP);
1550          }
1551          rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx] = curL2MeasTb;
1552          /* Initialize the Meas Tb details */
1553          curL2MeasTb->numLcId = 0;
1554          curL2MeasTb->numLchInfo = 0;
1555          curL2MeasTb->txSegSduCnt = 0;
1556          for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1557          {
1558             curL2MeasTb->sduInfo[idx].numSdus = 0;
1559          }
1560          for (idx = 0; idx < RLC_MAX_ACTV_DRB; idx++)
1561          {
1562             curL2MeasTb->lchInfo[idx].numSdus = 0;
1563          }
1564       }
1565    return (curL2MeasTb);
1566 }
1567
1568
1569 /**
1570  *
1571  * @brief Handler for Processing harq status indication
1572  *
1573  *
1574  * @b Description
1575  *        This function is called when the MAC sends a harq ind Mesage.
1576  *        This is used only for UuLoss and Dl Delay and DL Ipthoughput
1577  *        L2 Measurements.
1578  *
1579  *  @param[in] staInd Harq status indication received from MAC.
1580  *  @param[in] ueCb   UeCb corresponding to the Tb Id.
1581  *  @param[in] tbIdx  TB index, 0 for SISO and 0,1 for MIMO.
1582  *
1583  *
1584  *  @return  S16
1585  *      -# ROK
1586  */
1587
1588 #ifdef ANSI
1589 S16 rlcUtlProcHarqInd
1590 (
1591 RlcCb             *gCb,
1592 RguHarqStatusInd *hqStaInd,
1593 RlcDlUeCb           *ueCb,
1594 U8               tbIdx
1595 )
1596 #else
1597 S16 rlcUtlProcHarqInd(gCb, hqStaInd, ueCb, tbIdx)
1598 RlcCb             *gCb;
1599 RguHarqStatusInd *hqStaInd;
1600 RlcDlUeCb           *ueCb;
1601 U8               tbIdx;
1602 #endif
1603 {
1604 #ifdef LTE_L2_MEAS
1605    RlcDlRbCb       *rlcRbCb;           /* KW Control Block */
1606    RlcL2MeasTb   *l2MeasTb = NULLP;         /* Measurement TbCb */
1607    U8           lcIdx;             /* Logical channel id index */
1608    U8           sduIndx;            /* sdu index to out standing sdu list in rbCb */
1609    U32          numSdus;           /* number of sdus in the outstanding sdu list */
1610    RlcOutStngSduInfo *outStngSduArr;  /* Outstanding sdu list */
1611    Ticks        ackTime;
1612    Ticks        delay;
1613    U32          totlSduCnt = 0;
1614 #endif
1615    U8           timeAddedFlag;
1616    S16          ret;
1617    VOLATILE U32     startTime = 0;
1618    /*kw005.201 Code added for DL IP thruput measurement*/
1619
1620    TRC3(rlcUtlProcHarqInd)
1621
1622    /*starting Task*/
1623    SStartTask(&startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1624
1625    ret = ROK;
1626    if(hqStaInd->tbId[tbIdx] >= RLC_INVALID_TBID)
1627    {
1628       return ROK;
1629    }
1630
1631    /* Find the L2 measurement tbCb to process DL Ip thruput*/
1632    l2MeasTb = ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]];
1633    if(l2MeasTb == NULLP)
1634    {
1635       return ROK;
1636    }
1637    /* For each logical channel in the tbCb, process 
1638     * and get the DL IP thruput */
1639    ackTime = SGetTtiCount();
1640    for(lcIdx = 0; ((lcIdx < l2MeasTb->numLcId) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1641    {
1642       timeAddedFlag = FALSE;
1643       if((rlcRbCb = ueCb->lCh[l2MeasTb->sduInfo[lcIdx].lcId - 1].dlRbCb)
1644             == NULLP)
1645       {
1646          continue;
1647       }
1648       /* fix for DL IP stop*/
1649       if (!gCb->u.dlCb->rlcL2Cb.measOn[rlcRbCb->qci]
1650             || (rlcRbCb->rlcId.rbType == CM_LTE_SRB))
1651       {
1652          continue;
1653       }
1654       
1655       /* Get the outstanding SDUs using sdu index stored in Container sduList
1656        * and check for HARQ ACK/NACK */
1657       numSdus = l2MeasTb->sduInfo[lcIdx].numSdus;
1658       /* ccpu00143043 */
1659       if ((numSdus >= RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1660       {
1661          break;
1662       }
1663       totlSduCnt += numSdus;
1664
1665       if (RLC_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,rlcRbCb))
1666       {
1667          for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1668          {
1669             outStngSduArr =&(rlcRbCb->l2MeasIpThruput.dlIpTh.outStngSduArr[\
1670                   l2MeasTb->sduInfo[lcIdx].sduIdx[sduIndx]]);
1671             if(hqStaInd->status[tbIdx] == TRUE)
1672             {
1673                /* If ACK is for burst End Sdu Id set burstActive 
1674                 * to FALSE  and accumulate time */
1675                if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId == 
1676                         outStngSduArr->sduId) && (outStngSduArr->numTb == 1))
1677                {
1678                   rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1679                   /*Update the l2Sts structure for calculating throughput*/
1680                   rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1681                      += outStngSduArr->sduLen;
1682
1683                   rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1684                      += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1685                   outStngSduArr->sduId = 0;
1686                   outStngSduArr->sduLen = 0;
1687                   outStngSduArr->numTb = 0;
1688                   rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1689                }
1690
1691                /* If burst is active and this sdu is only transmitted in single TB then
1692                 * accumulate volume  and clear the outstanding sduList */
1693                if((rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) &&
1694                      (--(outStngSduArr->numTb) == 0))
1695                {
1696                   rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.volSummation
1697                      += outStngSduArr->sduLen;
1698
1699                   if(timeAddedFlag == FALSE)
1700                   {
1701                      rlcRbCb->rbL2Cb.l2Sts[RLC_L2MEAS_DL_IP]->dlIpThruput.timeSummation
1702                         += glblTtiCnt - rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime;
1703                      rlcRbCb->l2MeasIpThruput.dlIpTh.burstStartTime = glblTtiCnt;
1704                      timeAddedFlag = TRUE;
1705                   }
1706                   outStngSduArr->sduId = 0;
1707                   outStngSduArr->sduLen = 0;
1708                }
1709             }/* End of status == TRUE */
1710             else
1711             {
1712                if(rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE)
1713                {
1714                   if((rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId == 
1715                            outStngSduArr->sduId))
1716                   {
1717                      rlcRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE;
1718                      rlcRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0;
1719                   }
1720                   /* Clear the outstanding sdu list */
1721                   outStngSduArr->sduId = 0;
1722                   outStngSduArr->sduLen = 0;
1723                   outStngSduArr->numTb = 0;
1724                }
1725             }
1726          }
1727       } 
1728    }
1729
1730    for(lcIdx = 0; ((lcIdx < l2MeasTb->numLchInfo) && (lcIdx < RLC_MAX_ACTV_DRB)); lcIdx++)
1731    {
1732       if((rlcRbCb = ueCb->lCh[l2MeasTb->lchInfo[lcIdx].lcId - 1].dlRbCb)
1733             == NULLP)
1734       {
1735          continue;
1736       }
1737       numSdus = l2MeasTb->lchInfo[lcIdx].numSdus;
1738       if ( numSdus == 0 )
1739       {
1740          continue;
1741       }
1742       /* ccpu00143043 */
1743       if ((numSdus > RLC_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0))
1744       {
1745          break;
1746       }
1747       /* Update stats */
1748       if(hqStaInd->status[tbIdx] == TRUE)
1749       {
1750          for(sduIndx = 0; sduIndx < numSdus; sduIndx++)
1751          {
1752             delay = RLC_TIME_DIFF(ackTime,l2MeasTb->lchInfo[lcIdx].sduInfo[sduIndx].arvlTime);
1753             RLC_UPD_PDCP_L2_DLDELAY_STS(gCb,rlcRbCb, delay); 
1754          }
1755          /* Case of sduInfo not updated */
1756          if (totlSduCnt == 0)
1757          {
1758             totlSduCnt = numSdus;
1759          }
1760          RLC_UPD_L2_UU_LOSS_POS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1761       }
1762       else
1763       {
1764          /* Case of sduInfo not updated */
1765          if (totlSduCnt == 0)
1766          {
1767             totlSduCnt = numSdus;
1768          }
1769          RLC_UPD_L2_UU_LOSS_PKTS(gCb,rlcRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt));
1770       }
1771    }
1772    /* Free this tb, deallocate the memory */
1773    RLC_FREE(gCb, l2MeasTb, sizeof(RlcL2MeasTb));
1774    ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]] = NULLP;
1775    
1776    /*stopping Task*/
1777    SStopTask(startTime, PID_RLC_DLIP_TPT_PRCHARQIND);
1778
1779    return (ret);
1780 }/* end of  rlcUtlProcHarqInd */ 
1781
1782 /**
1783  *
1784  * @brief Handler for Sending L2 Measurement confirm.
1785  *
1786  *
1787  * @b Description
1788  *        This function sends a consolidates the mesaurements taken during
1789  *        this time and sends the confirm .
1790  *
1791  *  @param[in] measEvtCb    Measurement Event Control Block.
1792  *
1793  *
1794  *  @return  S16
1795  *      -# ROK
1796  */
1797
1798 #ifdef ANSI
1799 S16 rlcUtlSndDlL2MeasCfm
1800 (
1801 RlcCb                  *gCb,
1802 RlcL2MeasEvtCb         *measEvtCb
1803 )
1804 #else
1805 S16 rlcUtlSndDlL2MeasCfm(gCb, measEvtCb)
1806 RlcCb                  *gCb;
1807 RlcL2MeasEvtCb         *measEvtCb;
1808 #endif
1809 {
1810    U32                     qciIdx;
1811    RlcL2MeasCb              *measCb = NULLP;
1812    RlcL2MeasCfmEvt          measCfmEvt;
1813    U32                     posPkts;
1814    U32                     dLoss;
1815
1816    U64                     dlDataVol;
1817    U64                     dlTime;
1818    U16                     cntr;
1819    /* Discard new changes starts */
1820    U8                      qci = 0;
1821    U32                     cfmIdx =0;
1822    /* Discard new changes ends */
1823
1824    TRC3(rlcUtlSndL2MeasCfm)
1825
1826    /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
1827 #ifndef ALIGN_64BIT
1828    RLOG1(L_DEBUG,"rlcUtlSndL2MeasCfm(transId(%ld))", measEvtCb->transId);
1829 #else
1830    RLOG1(L_DEBUG,"rlcUtlSndL2MeasCfm(transId(%d))", measEvtCb->transId);
1831 #endif
1832
1833    /* Clean up the RB data structures */
1834    measCb = &measEvtCb->measCb;
1835    
1836    cmMemset((U8*)&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
1837    measCfmEvt.transId = measEvtCb->transId;
1838
1839    measCfmEvt.measType = measCb->measType;
1840    measCfmEvt.status.status = LCM_PRIM_OK;
1841    measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
1842    
1843    if(measCb->measType & LKW_L2MEAS_DL_IP)
1844    {
1845       RlcL2MeasCbUeMeasInfo *pUeInfoLstCb  = measCb->val.ipThMeas.ueInfoLst;
1846       RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
1847
1848       for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)        
1849       {
1850          pUeInfoLstCfm[cfmIdx].numCfm = 0;
1851          if (pUeInfoLstCb[cntr].isValid == TRUE)
1852          {
1853             pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
1854             pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
1855             for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)           
1856             {
1857                qci = pUeInfoLstCb[cntr].qci[qciIdx];
1858                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
1859
1860                dlDataVol = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation;
1861                dlTime = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation;
1862
1863                if((0 == dlTime) || !(gCb->u.dlCb->rlcL2Cb.measOn[qci] & LKW_L2MEAS_DL_IP) )
1864                {
1865                   pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 0;
1866                }
1867                else
1868                {
1869                   pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 
1870                      (dlDataVol / dlTime);
1871                }
1872                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut *= 8;
1873
1874                /* Reset the values after reporting to Application */
1875                pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation = 0;
1876                pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation = 0;
1877
1878                measCfmEvt.val.ipThMeas.ueInfoLst[cfmIdx].numCfm++;
1879             }
1880             cfmIdx++;
1881          }
1882       }
1883       measCfmEvt.val.ipThMeas.numUes = cfmIdx; 
1884    }
1885    else
1886    {
1887       RlcL2Cntr *pMeasData = measCb->val.nonIpThMeas.measData;
1888       RlcL2MeasCfmNonIpThMeas *pMeasCfmNonIp = &measCfmEvt.val.nonIpThMeas;
1889
1890       pMeasCfmNonIp->numCfm = 0;
1891
1892       for(qciIdx = 0; qciIdx < LKW_MAX_QCI; qciIdx++)
1893       {
1894          qci = measCb->val.nonIpThMeas.qci[qciIdx];
1895          if (qci > 0)
1896          {
1897             pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].qci = qci;
1898
1899             if(measCb->measType & LKW_L2MEAS_UU_LOSS)
1900             {
1901                dLoss = pMeasData[qci].uuLoss.dLoss;
1902                posPkts = pMeasData[qci].uuLoss.posPkts;
1903                if(((posPkts + dLoss) != 0))
1904                {
1905                   pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.uuLoss  =
1906                      ((dLoss  * 1000000) / (posPkts + dLoss));
1907                }
1908                pMeasData[qci].uuLoss.dLoss = 0;
1909                pMeasData[qci].uuLoss.posPkts = 0;
1910             }
1911             if(measCb->measType & LKW_L2MEAS_DL_DISC)
1912             {
1913
1914                pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 0;
1915                if(pMeasData[qci].dlDisc.totSdus != 0)
1916                {
1917                   pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 
1918                      (((pMeasData[qci].dlDisc.discSdus)  * 1000000) / (pMeasData[qci].dlDisc.totSdus));
1919                }
1920
1921                pMeasData[qci].dlDisc.totSdus = 0;
1922                pMeasData[qci].dlDisc.discSdus = 0;
1923             }
1924             if(measCb->measType & LKW_L2MEAS_DL_DELAY)
1925             {
1926                if (pMeasData[qci].dlPjSduDelay.numSdus > 0)
1927                {
1928                   pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlSduDelay = 
1929                     (pMeasData[qci].dlPjSduDelay.sduDelay / pMeasData[qci].dlPjSduDelay.numSdus);
1930                   pMeasData[qci].dlPjSduDelay.sduDelay = 0;
1931                   pMeasData[qci].dlPjSduDelay.numSdus = 0;
1932                }
1933             }
1934             pMeasCfmNonIp->numCfm++;
1935          }
1936       }
1937    }
1938    /* Fix Klock warning */
1939    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
1940    return ROK;
1941 } /* rlcUtlSndL2MeasCfm */
1942 /**
1943  *
1944  * @brief Handler for Sending Negative confirm .
1945  *
1946  *
1947   @b Description
1948  *        This function is called when the l2 measurement cannot be started
1949  *        This function sends  negative confirm for all the requests
1950  *
1951  *  @param[in] measReqEvt    Measurement Req Structure
1952  *
1953  *
1954  *  @return  S16
1955  *      -# ROK
1956  */
1957
1958 #ifdef ANSI
1959 S16 rlcUtlSndDlL2MeasNCfm
1960 (
1961 RlcCb           *gCb,
1962 RlcL2MeasReqEvt *measReqEvt,
1963 RlcL2MeasCfmEvt *measCfmEvt
1964 )
1965 #else
1966 S16 rlcUtlSndDlL2MeasNCfm(gCb,measReqEvt, measCfmEvt)
1967 RlcCb           *gCb;
1968 RlcL2MeasReqEvt *measReqEvt;
1969 RlcL2MeasCfmEvt *measCfmEvt;
1970 #endif
1971 {
1972    TRC3(rlcUtlSndDlL2MeasNCfm)
1973
1974    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
1975    return ROK;
1976 } /* kwUtlSndL2MeasNCfm */
1977 /**
1978  *
1979  * @brief Handler for resetting the RB data structures
1980  *
1981  *
1982  * @b Description
1983  *        This function resets the RB data structure after the expiry of 
1984  *        measurement timer.
1985  *
1986  *  @param[in] measCb    Measurement Control Block.
1987  *
1988  *
1989  *  @return  Void
1990  */
1991 #ifdef ANSI
1992
1993 Void rlcUtlResetDlL2MeasInRlcRb
1994 (
1995 RlcCb       *gCb,
1996 RlcL2MeasCb *measCb,
1997 U8             measType
1998 )
1999 #else
2000 Void rlcUtlResetDlL2MeasInRlcRb(gCb, measCb, measType)
2001 RlcCb       *gCb;
2002 RlcL2MeasCb *measCb;
2003 U8             measType;
2004 #endif
2005 {
2006    U32           ueIdx;
2007    U32           qciIdx;
2008    RlcDlUeCb      *ueCb = NULL;
2009
2010
2011
2012    if (measCb->measType & LKW_L2MEAS_DL_IP)
2013    {
2014       for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
2015       {           
2016          if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
2017          {
2018             for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
2019             {
2020                if (measType & LKW_L2MEAS_DL_IP)
2021                {
2022                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.volSummation = 0;
2023                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.timeSummation = 0;
2024                   gCb->u.dlCb->rlcL2Cb.measOn[qciIdx] &= ~measType; 
2025                }
2026             }
2027
2028             if(ROK  != rlcDbmFetchDlUeCb(gCb,measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
2029                      measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
2030             {
2031                continue;
2032             }
2033
2034          }
2035       }
2036    }
2037    else
2038    {
2039       /* for now the only meas should be DL discard in this case */
2040       if (measCb->measType & LKW_L2MEAS_DL_DISC)
2041       {
2042          U32 i;
2043          for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2044          {
2045             U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2046
2047             measCb->val.nonIpThMeas.measData[qciVal].dlDisc.discSdus = 0;
2048             measCb->val.nonIpThMeas.measData[qciVal].dlDisc.totSdus  = 0;
2049          }
2050          
2051       }
2052       if (measCb->measType & LKW_L2MEAS_DL_DELAY)
2053       {
2054          U32 i;
2055          for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++)
2056          {
2057             U8 qciVal = measCb->val.nonIpThMeas.qci[i];
2058
2059             measCb->val.nonIpThMeas.measData[qciVal].dlPjSduDelay.sduDelay = 0;
2060          }
2061       }
2062       measCb->val.nonIpThMeas.numQci = 0;
2063    }
2064 } /* rlcUtlResetDlL2MeasInRlcRb */
2065 #endif
2066
2067 PRIVATE Void dumpRLCDlRbInformation(RlcDlRbCb* dlRbCb)
2068 {
2069    if(dlRbCb->mode == CM_LTE_MODE_UM)
2070    {
2071       RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2072                "UM Downlink UEID:%d CELLID:%d Q size = %d",
2073                        dlRbCb->rlcId.ueId,
2074                        dlRbCb->rlcId.cellId,
2075                        (int)dlRbCb->m.umDl.sduQ.count);
2076    }
2077    else if(dlRbCb->mode == CM_LTE_MODE_AM)
2078    {
2079       U32 j, numTxPdus=0;
2080       for(j = 0; j <= (RLC_AM_GET_WIN_SZ(dlRbCb->m.amDl.snLen)); j++)
2081       {
2082          RlcTx *txBuf = rlcUtlGetTxBuf(dlRbCb->m.amDl.txBufLst, j);
2083          if(txBuf != NULLP)
2084          {
2085             numTxPdus++;
2086          }
2087       }
2088       RLOG_ARG4(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2089                "AM Downlink UEID:%d CELLID:%d Sizes SDU Q = %d TX Q = %d ",
2090                        dlRbCb->rlcId.ueId,
2091                        dlRbCb->rlcId.cellId,
2092                        (int)dlRbCb->m.amDl.sduQ.count,
2093                        (int)numTxPdus);
2094       RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId,
2095                "AM Downlink UEID:%d CELLID:%d RETX Q= %d",
2096                        dlRbCb->rlcId.ueId,
2097                        dlRbCb->rlcId.cellId,
2098                        (int)dlRbCb->m.amDl.retxLst.count);
2099    }
2100 }
2101
2102 Void DumpRLCDlDebugInformation(Void)
2103 {
2104    RlcCb* dlInst = rlcCb[1]; /* TODO : Check whether DL is 0 or 1 */
2105
2106    RlcDlCb *dlCb = dlInst->u.dlCb;
2107
2108    RlcDlUeCb *ueCb = NULLP; 
2109    RTLIN_DUMP_DEBUG("RLC Information\n");
2110    RTLIN_DUMP_DEBUG("===============\n");
2111    /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
2112    while (ROK == cmHashListGetNext(&dlCb->ueLstCp, 
2113                                    (PTR) ueCb, 
2114                                    (PTR *)&ueCb))
2115    {
2116       U32 i;
2117       for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
2118       {
2119          RlcDlRbCb* dlRbCb = ueCb->srbCb[i]; 
2120          if( dlRbCb != NULLP)
2121          {
2122             dumpRLCDlRbInformation(dlRbCb);
2123          }
2124       }
2125       for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
2126       {
2127          RlcDlRbCb* dlRbCb = ueCb->drbCb[i]; 
2128          if( dlRbCb != NULLP)
2129          {
2130             dumpRLCDlRbInformation(dlRbCb);
2131          }
2132       }
2133    }
2134
2135    RlcDlDataToBeFreed* pToBeFreed = &dlCb->toBeFreed;
2136
2137    RTLIN_DUMP_DEBUG("toBeFreed RETX list size = %d\n",(int)pToBeFreed->reTxLst.count);
2138    RTLIN_DUMP_DEBUG("toBeFreed TX list size   = %d\n",(int)pToBeFreed->txLst.count);
2139    RTLIN_DUMP_DEBUG("toBeFreed SDU list size  = %d\n",(int)pToBeFreed->sduLst.count);
2140    RTLIN_DUMP_DEBUG("toBeFreed RB list size   = %d\n",(int)pToBeFreed->rbLst.count);
2141 }
2142
2143 /**
2144  *
2145  * @b Description
2146  *        This function frees downlink memory 
2147  *
2148  *  @param[in] Void
2149  *
2150  *
2151  *  @return  Void
2152  */
2153
2154 #ifdef ANSI
2155 void rlcUtlFreeDlMem
2156 (
2157  Void
2158 )
2159 #else
2160 void rlcUtlFreeDlMem()
2161 Void;
2162 #endif
2163 {
2164   rlcUtlFreeDlMemory(RLC_GET_RLCCB(RLC_DL_INST));
2165 }
2166
2167 /**
2168  *
2169  * @b Description
2170  *        This function returns current time
2171  *
2172  *  @param[in] U32 
2173  *
2174  *
2175  *  @return  Void
2176  */
2177
2178 void rlcUtlGetCurrTime(uint32_t  *currTime)
2179 {
2180    /* Need t define else part for PAL */
2181    *currTime = SGetTtiCount();
2182 }
2183
2184 #if defined(MAC_RLC_HARQ_STA_RBUF) || defined (SS_RBUF)
2185 #ifdef LTE_L2_MEAS
2186 #ifdef ANSI
2187 void rlcUtlDlBatchProcHqStaInd
2188 (
2189  Void
2190 )
2191 #else
2192 void rlcUtlDlBatchProcHqStaInd()
2193 Void;
2194 #endif
2195 {
2196    /* Read from Ring Buffer and process PDCP packets */
2197    //Pst pst = {0};
2198
2199    Void *elmIndx = NULLP;
2200    RguHarqStaInd *staInd = NULLP;
2201
2202 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2203    isDatReqProcessed = TRUE;
2204 #endif
2205    elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ);
2206    while(NULLP != elmIndx)
2207    {
2208       staInd = (RguHarqStaInd *)elmIndx;
2209       RlcLiRguHqStaInd(&(staInd->pst), 0, &(staInd->hqStatusInd));
2210
2211       elmIndx = NULLP;
2212       staInd  = NULLP;
2213       SRngIncrRIndx(SS_RNG_BUF_MAC_HARQ);
2214
2215       if((elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ)) == NULLP)
2216       {
2217 #if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)
2218          isDatReqProcessed = FALSE;
2219 #endif
2220          break;
2221       }
2222    }
2223 }
2224 #endif
2225 #endif
2226
2227 /**
2228  * @brief evaluate and trigger PDB based flow control to PDCP 
2229  *
2230  * @details 
2231  *
2232  * @param[in]   rbCb  RB control block 
2233  *
2234  *
2235  *  @return  Void
2236  *
2237  */
2238 #ifdef ANSI
2239 Void rlcUtlTrigPdbFlowCntrl
2240 (
2241 RlcCb       *gCb,
2242 RlcDlRbCb   *rbCb,
2243 U32        pktAdmitCnt
2244 )
2245 #else
2246 Void rlcUtlTrigPdbFlowCntrl(gCb,rbCb,pktAdmitCnt)
2247 RlcCb       *gCb;
2248 RlcDlRbCb   *rbCb;
2249 U32        pktAdmitCnt;
2250 #endif
2251 {
2252    KwuFlowCntrlIndInfo    *flowCntrlInfo;
2253    RlcKwuSapCb*            rlckwuSap;
2254
2255    rlckwuSap = gCb->u.dlCb->rlcKwuDlSap + RLC_UI_PDCP;
2256
2257    RLC_SHRABL_STATIC_BUF_ALLOC(rlckwuSap->pst.region, 
2258                               rlckwuSap->pst.pool, 
2259                               flowCntrlInfo, 
2260                               sizeof(KwuFlowCntrlIndInfo));
2261    flowCntrlInfo->rlcId       = rbCb->rlcId;
2262    flowCntrlInfo->pktAdmitCnt = pktAdmitCnt;
2263    RlcUiKwuFlowCntrlInd(&rlckwuSap->pst, rlckwuSap->suId, flowCntrlInfo);
2264 }
2265
2266 /**
2267  *
2268  * @brief Store the DL buffer in hashList  
2269  *
2270  *
2271  * @b Description
2272  *
2273  *   Use the SN % binSize as key and store the received UL buffer
2274  *  @param[in] txBufLst       List CP array
2275  *  @param[in] txBuf          transmitted buffer
2276  *  @param[in] sn              sn of the received buffer 
2277  *
2278  *
2279  *  @return  Void
2280  */
2281 void rlcUtlStoreTxBuf(CmLListCp *txBufLst, RlcTx *txBuf, RlcSn sn)
2282 {
2283    uint32_t   hashKey; 
2284
2285    hashKey = (sn % RLC_TX_BUF_BIN_SIZE );
2286    txBuf->sn = sn; 
2287    txBuf->lnk.node = (PTR)txBuf;
2288    cmLListAdd2Tail(&(txBufLst[hashKey]), &txBuf->lnk);
2289
2290    return;
2291 } /* rlcUtlStoreRecBuf */
2292
2293 /**
2294  *
2295  * @brief Retrieve the DL buffer from the list
2296  *
2297  *
2298  * @Description
2299  *
2300  *   Use the SN % binSize as key and retrieve the DL buffer
2301  *  @param[in] txBufLst       List CP array
2302  *  @param[in] sn              sn of the transmitted buffer 
2303  *
2304  *
2305  *  @return  Void
2306  */
2307 RlcTx* rlcUtlGetTxBuf(CmLListCp *txBufLst, RlcSn sn)
2308 {
2309    uint32_t            hashKey; 
2310    CmLListCp           *txBufLstCp;
2311    RlcTx               *txBuf;
2312    CmLList             *node = NULLP;
2313
2314    hashKey = (sn % RLC_TX_BUF_BIN_SIZE ); 
2315  
2316    txBufLstCp = &txBufLst[hashKey];
2317    CM_LLIST_FIRST_NODE(txBufLstCp, node);
2318    while(node)
2319    {
2320       txBuf = (RlcTx *) node->node;
2321       if(txBuf->sn == sn)
2322       {
2323          return (txBuf);
2324       }
2325       CM_LLIST_NEXT_NODE(txBufLstCp, node);
2326    }
2327    return NULLP;
2328 } /* rlcUtlStoreTxBuf */
2329 /**
2330  *
2331  * @brief Delete the DL buffer from the list
2332  *
2333  *
2334  * @Description
2335  *
2336  *   Use the SN % binSize as key and retrieve the DL buffer
2337  *  @param[in] txBufLst       List CP array
2338  *  @param[in] sn              sn of the transmitted bffer 
2339  *
2340  *
2341  *  @return  Void
2342  */
2343 #ifdef ANSI
2344 Void rlcUtlDelTxBuf 
2345 (
2346 CmLListCp        *txBufLst,
2347 RlcTx            *txBuf,
2348 RlcCb              *gCb                              
2349 )
2350 #else
2351 Void rlcUtlDelTxBuf(txBufLst, txBuf, gCb)
2352 CmLListCp        *txBufLst;
2353 RlcTx             *txBuf;
2354 RlcCb             *gCb;                              
2355 #endif
2356 {
2357    U32                 hashKey; 
2358    CmLListCp           *txBufLstCp;
2359
2360    TRC3(rlcUtlDelTxBuf)
2361
2362    hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE ); 
2363  
2364    txBufLstCp = &txBufLst[hashKey];
2365    //printf("D-sn(%d)\n", txBuf->hdr.sn);
2366    cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2367    RLC_FREE_WC(gCb, txBuf, sizeof(RlcTx));
2368    RETVOID;
2369 } /* rlcUtlDelTxBuf */
2370
2371 /**
2372  *
2373  * @brief Remove the DL buffer from the list
2374  *
2375  *
2376  * @Description
2377  *
2378  *   Use the SN % binSize as key and retrieve the DL buffer
2379  *  @param[in] txBufLst       List CP array
2380  *  @param[in] sn              sn of the transmitted bffer 
2381  *
2382  *
2383  *  @return  Void
2384  */
2385 #ifdef ANSI
2386 Void rlcUtlRemovTxBuf 
2387 (
2388 CmLListCp        *txBufLst,
2389 RlcTx            *txBuf,
2390 RlcCb              *gCb                              
2391 )
2392 #else
2393 Void rlcUtlRemovTxBuf(txBufLst, txBuf, gCb)
2394 CmLListCp        *txBufLst;
2395 RlcTx             *txBuf;
2396 RlcCb             *gCb;                              
2397 #endif
2398 {
2399    U32                 hashKey; 
2400    CmLListCp           *txBufLstCp;
2401
2402    TRC3(rlcUtlRemovTxBuf)
2403
2404    hashKey = (txBuf->sn % RLC_TX_BUF_BIN_SIZE ); 
2405  
2406    txBufLstCp = &txBufLst[hashKey];
2407    //printf("D-sn(%d)\n", txBuf->hdr.sn);
2408    cmLListDelFrm(txBufLstCp, &txBuf->lnk);
2409    RETVOID;
2410 } /* rlcUtlRemovTxBuf */
2411
2412
2413
2414 /********************************************************************30**
2415          End of file
2416 **********************************************************************/