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