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