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