Committing in PDCP code
[o-du/l2.git] / src / 5gnrpdcp / pj_dlm.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-PDCP Layer 
22   
23      Type:     C file
24   
25      Desc:     Source code for PDCP Downlink module.
26                This file contains following functions
27
28                   --pjDlmProcessSdus
29                   --pjDlmBldPdu
30                   --pjDlmReEstSrb
31                   --pjDlmReEstDrbUm
32                   --pjDlmReEstDrbAm
33                   --pjDlmProcessCfm
34                   --pjDlmHndlStaRep
35                   --pjDlmDiscSdu
36                   --pjDlmDeliverPdu
37                   --pjDlmReEstHoDrbAm
38                   --pjDlmHndlDatFwdReq
39                   --pjDlmProcSrb
40                   --pjDlmProcDrb
41
42      File:     pj_dlm.c
43
44 **********************************************************************/
45
46 static const char* RLOG_MODULE_NAME="PDCP";
47 static int RLOG_FILE_ID=241;
48 static int RLOG_MODULE_ID=1024;
49 /** @file pj_dlm.c
50 @brief PDCP Downlink module
51 */
52
53 /* header (.h) include files */
54 #include "envopt.h"             /* environment options */
55 #include "envdep.h"             /* environment dependent */
56 #include "envind.h"             /* environment independent */
57
58 #include "gen.h"                /* general */
59 #include "ssi.h"                /* system services interface */
60 #include "cm5.h"                /* Timer Functions */
61 #include "cm_lte.h"             /* common LTE header file */
62 #include "cm_hash.h"            /* common hash module  file */
63 #include "cm_llist.h"           /* common list header file */
64 #include "cpj.h"                /* RRC layer */
65 #include "pju.h"                /* PDCP service user */
66 #include "lpj.h"                /* LPJ defines */
67 #include "pj_env.h"             /* RLC environment options */
68 #include "pj.h"                 /* RLC layer */
69 #include "pj_dl.h"
70 #include "pj_err.h"
71 #include "pj_ptsec.h"
72 #ifndef TENB_T2K3K_SPECIFIC_CHANGES 
73 void prc_trace_format_string(U32 group_mask, U16 level, const char *format, ...);
74 #endif
75
76
77 /* header/extern include files (.x) */
78 #include "gen.x"                /* general */
79 #include "ssi.x"                /* system services interface */
80 #include "cm_lib.x"             /* common library */
81 #include "cm5.x"                /* Timer Functions */
82 #include "cm_hash.x"            /* common hash module */
83 #include "cm_lte.x"             /* common LTE file */
84 #include "cm_llist.x"           /* common list header file */
85 #include "cpj.x"                /* RRC layer */
86 #include "pju.x"                /* PDCP service user */
87 #include "lpj.x"                /* LPJ defines */
88 #include "pj.x"                 /* RLC layer */
89 #include "pj_udx.h"
90 #include "pj_udx.x"
91 #include "pj_dl.x"
92 #include "pj_ul.x"
93
94 EXTERN U32 pjTotDlPckCntPerCell;
95 #ifdef TENB_AS_SECURITY 
96 EXTERN U8 isSecBatchMode;
97 #endif
98
99
100 #ifdef TENB_T2K3K_SPECIFIC_CHANGES
101 EXTERN Ticks SGetT2KTtiCount(Void);
102 #endif
103 /* kw005.201 Moved definition of PJ_ASYNC_WIN to kw.h file */
104 /** @addtogroup dldata */
105 /*@{*/
106 EXTERN S16 pjUtlChekTxEnqReq ARGS(( PjCb *gCb, PjDlRbCb *pjRbCb, PjTxEnt *txEnt));
107
108 PRIVATE S16 pjDlmBldPdu(PjCb *gCb,PjDlRbCb *pjRbCb,PjTxEnt *txEnt);
109 PRIVATE Void pjDlmDelTxEntUptoFmc ARGS ((PjCb *gCb, PjDlRbCb *pjRbCb, U32 fmc, PjuDatCfmInfo *datCfm));
110
111 /**
112  *
113  * @brief 
114  *
115  *        Handler to free all sdus present in datCfmQ till the First Missing
116  *        Segment. 
117  *
118  *  @param[in] pjRbCb   PDCP control block.
119  *  @param[in] fmc      First Missing Segment count
120  *  @param[in] datCfm   datCfm 
121  *
122  *  @return  S16
123  *      -# ROK 
124  *      -# RFAILED
125  */
126 #ifdef ANSI
127 PRIVATE Void pjDlmDelTxEntUptoFmc
128 (
129 PjCb            *gCb,
130 PjDlRbCb        *pjRbCb,
131 U32             count,
132 PjuDatCfmInfo   *datCfm
133 )
134 #else
135 PRIVATE Void pjDlmDelTxEntUptoFmc(gCb, pjRbCb, count, datCfm)
136 PjCb            *gCb;
137 PjDlRbCb        *pjRbCb;
138 U32             count;
139 PjuDatCfmInfo   *datCfm;
140 #endif
141 {
142    PjTxEnt   *txEnt;
143
144
145    cmLListFirst(&pjRbCb->dlCb.txBuf.datCfmQ);
146    while (cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ))
147    {
148      txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ));
149      if (txEnt != NULLP)
150      {
151         if (txEnt->count < count)
152         { 
153            if (pjRbCb->dlCb.cfmReqd && datCfm!= NULLP)
154            {
155               /* As of now, DATCFM is sent only for the 1st 25 PDUs. Once we      */
156               /* enable cfmReqd, we need to add code to send for all PDUs in loop */
157               if(datCfm->numSdus < PJU_MAX_SDU_CFM) 
158               {
159                  datCfm->cfmSta[datCfm->numSdus].sduId  = txEnt->sduId;
160                  datCfm->cfmSta[datCfm->numSdus].status = PJ_CFM_OK;
161                  datCfm->numSdus++;
162               }
163            }
164            pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count);
165         }
166         else
167         {
168            /* fmc reached break out of the loop */
169            break;
170         }
171      } 
172      cmLListNext(&pjRbCb->dlCb.txBuf.datCfmQ);
173    }
174
175    RETVOID;
176 }
177
178 /**
179  *
180  * @brief 
181  *
182  *        Handler to process the SDU received from upper layer, form a PDU
183  *        and send the PDU to the lower layer.
184  *
185  * @b Description: 
186  *
187  *        1. This function places the SDU in the transmission buffer and performs
188  *        Compression for DRB SDUs and Integrity Protection for SRB SDUs.  @n
189  *        2. After compression/integrity protection, it performs ciphering and then 
190  *        constructs the PDU and sends it to the lower layer. @n
191  *        3. The first DL message of SRBs is not ciphered and is just integrity 
192  *        protected.  @n 
193  *        4. This function checks the UE CB control block to check the flag for the 
194  *        first DL message and performs only integrity protection and unsets 
195  *        the flag.       @n 
196  *            
197  *  @param[in] pjRbCb   PDCP control block.
198  *  @param[in] sdu      SDU to be processed.
199  *  @param[in] sduId    SDU ID. 
200  *
201  *  @return  S16
202  *      -# ROK 
203  *      -# RFAILED
204  */
205
206 U32 pjTxSdu;
207
208 #ifdef ANSI
209 PUBLIC S16 pjDlmProcessSdus
210 (
211 PjCb       *gCb,
212 PjDlRbCb   *pjRbCb,                   /* !< PDCP Control Block */
213 Buffer     *sdu,                      /* !< SDU to be processed */
214 U32        sduId,                      /* !< PDCP SDU ID */
215 U32        count                      /* !< count to be assigned */
216 )
217 #else 
218 PUBLIC S16 pjDlmProcessSdus(gCb, pjRbCb, sdu, sduId, count)
219 PjCb       *gCb;
220 PjDlRbCb   *pjRbCb;                   /* !< PDCP Control Block */
221 Buffer     *sdu;                      /* !< SDU to be processed */
222 U32        sduId;                     /* !< PDCP SDU ID */
223 U32        count;                     /* !< count to be assigned */
224 #endif
225 {
226    S16      ret;                  /* Return Value */
227    PjTxEnt  *txEnt;               /* Transmission Entity for sdu*/
228 #ifdef L2_PDCP_OPTMZ   
229    U8       hashKey;          /* Computed HashKey */
230    PjBuf       *buf; 
231 #endif   
232
233    TRC2(pjDlmProcessSdus)
234
235 #ifndef ALIGN_64BIT
236    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
237          (gCb->init.prntBuf, "pjDlmProcessSdus(pjRbCb(%d), sdu, sduId(%ld), \
238                     txHfn) \n)", pjRbCb->rbId, sduId));
239 #else
240    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
241          (gCb->init.prntBuf, "pjDlmProcessSdus(pjRbCb(%d), sdu, sduId(%d), \
242                      txHfn) \n)", pjRbCb->rbId, sduId));
243 #endif
244
245
246    ret = ROK;
247    
248    /* Allocate the transmission entity */
249    PJ_ALLOC(gCb,txEnt, sizeof(PjTxEnt));
250
251 #if (ERRCLASS & ERRCLS_ADD_RES)
252    if (txEnt == NULLP)
253    {
254       RLOG0(L_FATAL, "Memory Allocation failed.");
255       PJ_FREE_BUF(sdu);
256       RETVALUE(RFAILED);
257    }
258 #endif /* ERRCLASS & ERRCLS_RES */
259
260    /* Update COUNT to the current count in dlCb*/
261    pjRbCb->dlCb.count = count;
262    /* Fill TxEnt values */
263    PJ_DLM_GET_SN(pjRbCb,count,txEnt->sn);
264    //txEnt->count = count;
265    //txEnt->txHfn = txHfn;
266    txEnt->count = count;
267    txEnt->state = PJ_SDU_RECEIVED;
268    txEnt->sduId = sduId;
269    /* The received buffer is stored in the SDU and the output from 
270     * Compression/Ciphering is stored in the PDU.
271     */
272    txEnt->sdu   = sdu;
273    txEnt->pdu   = NULLP;
274
275    /* Process the SDU based on rbType */
276    if (pjRbCb->rbType == PJ_SRB)
277    {
278       /* Insert TxEnt into the transmission buffer */
279       pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
280       ret = pjDlmProcSrb(gCb, pjRbCb, txEnt);
281    }
282    else
283    {
284 #ifndef RGL_SPECIFIC_CHANGES      
285 #ifndef TENB_ACC
286 #ifndef LTE_PAL_ENB
287       EXTERN U32 dlrate_pju;
288    MsgLen len;
289    SFndLenMsg(sdu, (MsgLen *) &len);
290    dlrate_pju += len;
291 #endif 
292 #endif
293 #endif
294 #ifndef L2_PDCP_OPTMZ
295       pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
296 #else
297       /* Fix for NULL ciphering. For null ciphering add PDUs to sduSubmitQ*/
298       if(pjRbCb->ueCb->secInfo.secAct && pjRbCb->ueCb->secInfo.cipherInfo.algoType != 0)
299       {
300          txEnt->datCfmEnt.node = NULLP;
301          txEnt->reEstPktEnt.node = NULLP;
302          txEnt->sduSubmitEnt.node = (PTR)NULLP;
303
304          buf=&(pjRbCb->dlCb.txBuf);
305          hashKey = (U8)PJ_HASH_FN(buf, txEnt->count); /*KW_FIX*/
306
307          txEnt->lstEnt.node = (PTR)txEnt;
308          cmLListAdd2Tail(&buf->datQ[hashKey], &txEnt->lstEnt);
309          buf->numEntries ++;
310          /* Dont add PDUs to datCfmQ in case of UM mode*/
311          if (pjRbCb->mode == PJ_DRB_AM ) 
312          {
313             txEnt->datCfmEnt.node = (PTR)txEnt;
314             cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.datCfmQ, &txEnt->datCfmEnt);
315          }
316          txEnt->state  = PJ_PDU_SUBMITTED;
317       }
318       else
319       {
320          pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
321       }
322 #endif   
323       ret = pjDlmProcDrb(gCb, pjRbCb, txEnt);
324    }
325
326    RETVALUE(ret);
327 }
328
329 /**
330  *
331  * @brief 
332  *
333  *        Handler to Re-establish a SRB.
334  *
335  * @b Description: 
336  *
337  *        1. This function is called when re-establishment request is
338  *        received for a SRB.   @n
339  *        2. The stored PDUs and SDUs are freed and the variables are reset. @n
340  *            
341  *  @param[in] pjRbCb   PDCP control block.
342  *
343  */
344
345 #ifdef ANSI
346 PUBLIC Void pjDlmRbDataResume
347 (
348 PjCb   *gCb,
349 PjDlRbCb *pjRbCb
350 )
351 #else
352 PUBLIC Void pjDlmRbDataResume(gCb, pjRbCb)
353 PjCb   *gCb;
354 PjDlRbCb *pjRbCb;
355 #endif
356 {
357    S16      ret;
358    PjTxEnt *txEnt;
359    TRC3(pjDlmRbDataResume)
360
361    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmRbDataResume(pjRbCb ()) ");
362                        
363    cmLListFirst(&pjRbCb->dlCb.txBuf.reEstPktQ);
364    while (cmLListCrnt(&pjRbCb->dlCb.txBuf.reEstPktQ))
365    {
366       txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.reEstPktQ));
367 #if (ERRCLASS & ERRCLS_DEBUG)  /* KW_FIX */
368          if(txEnt == NULLP)
369          {
370             RLOG_ARG0(L_ERROR,DBG_RBID,pjRbCb->rbId, 
371                   "pjDlmRbDataResume:Transmission Entity is NULL ");
372    /*ccpu00136858 : Void function returning RFAILED */      
373             RETVOID;
374          }
375 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
376 /* Free the existing PDU and cpy the SDU to PDU */
377
378 #ifdef FLAT_BUFFER_OPT
379 #ifndef XEON_SPECIFIC_CHANGES
380          {
381             /* Check whether the spacc q has space to hold
382                this packet.. else dropping */
383             if(FALSE == (pjMsCheckSpaccQueue(FALSE)))
384             {
385                {
386                   extern U32 spaccDropCount;
387                   spaccDropCount++;
388                }
389                PJ_FREE_FLAT_BUF(pjCb[1],&(txEnt->fb));
390                gPdcpStats.numPdcpSdusDiscarded++;
391                PJ_UPD_L2_DLDISC_STS(pjCb[1], pjRbCb);
392
393                if(txEnt->pdu != NULL)
394                  printf("PDU is not null while deletion");
395
396                if(txEnt->sdu != NULL)
397                  printf("SDU is not null while deletion");
398                pjDbmDelTxEnt(pjCb[1], &(pjRbCb->dlCb.txBuf), txEnt->count);
399                //txEnt->reEstPktEnt.node = NULLP;
400                //cmLListDelFrm(&pjRbCb->dlCb.txBuf.reEstPktQ, &txEnt->reEstPktEnt);
401
402                cmLListFirst(&pjRbCb->dlCb.txBuf.reEstPktQ);
403                continue;
404             }
405          }
406 #endif
407 #endif
408 #ifdef FLAT_BUFFER_OPT
409          if(txEnt->sdu == NULLP)
410          {
411             PJ_FREE_BUF(txEnt->pdu);
412          }
413          else
414 #endif
415          if ( txEnt->pdu != txEnt->sdu )
416          {
417             PJ_FREE_BUF(txEnt->pdu);
418          }
419          else
420          {
421             txEnt->pdu = NULLP;
422          }
423 #ifdef L2_PDCP_OPTMZ
424          txEnt->state = PJ_PDU_SUBMITTED;
425 #else
426          txEnt->state = PJ_SDU_RECEIVED;
427 #endif         
428          /* Fix for ccpu00135798 */
429          txEnt->reEstPktEnt.node = NULLP;
430          cmLListDelFrm(&pjRbCb->dlCb.txBuf.reEstPktQ, &txEnt->reEstPktEnt);
431 #ifndef L2_PDCP_OPTMZ         
432          txEnt->sduSubmitEnt.node = (PTR)txEnt;
433          cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.sduSubmitQ, &txEnt->sduSubmitEnt);
434 #else
435          if( pjRbCb->mode == PJ_DRB_AM)
436          {
437          txEnt->datCfmEnt.node = (PTR)txEnt;
438          cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.datCfmQ, &txEnt->datCfmEnt);
439          }
440 #endif   
441
442          ret = pjDlmProcDrb(gCb, pjRbCb, txEnt);
443          if ( ret != ROK )
444          {
445              RLOG_ARG0(L_ERROR,DBG_RBID,pjRbCb->rbId, 
446                    "pjDlmRbDataResume: pjDlmProcDrb Failed ");
447          }
448       cmLListFirst(&pjRbCb->dlCb.txBuf.reEstPktQ);
449    }
450
451    pjDlmProcessDlPktQ(gCb,pjRbCb);
452    
453    RETVOID;
454 }
455
456 #ifdef FLAT_BUFFER_OPT
457
458 /**
459  *
460  * @brief 
461  *
462  *        Handler to process the SDU received from upper layer, form a PDU
463  *        and send the PDU to the lower layer.
464  *
465  * @b Description: 
466  *
467  *        1. This function places the SDU in the transmission buffer and performs
468  *        Compression for DRB SDUs and Integrity Protection for SRB SDUs.  @n
469  *        2. After compression/integrity protection, it performs ciphering and then 
470  *        constructs the PDU and sends it to the lower layer. @n
471  *        3. The first DL message of SRBs is not ciphered and is just integrity 
472  *        protected.  @n 
473  *        4. This function checks the UE CB control block to check the flag for the 
474  *        first DL message and performs only integrity protection and unsets 
475  *        the flag.       @n 
476  *            
477  *  @param[in] pjRbCb   PDCP control block.
478  *  @param[in] sdu      SDU to be processed.
479  *  @param[in] sduId    SDU ID. 
480  *
481  *  @return  S16
482  *      -# ROK 
483  *      -# RFAILED
484  */
485
486 #ifdef ANSI
487 PUBLIC S16 pjDlmProcessSdusFB
488 (
489 PjCb   *gCb,                        /* !< Global control Block*/
490 PjDlRbCb *pjRbCb,                   /* !< PDCP Control Block */
491 FlatBuffer *sdu,                    /* !< SDU to be processed */
492 U32    sduId,                       /* !< PDCP SDU ID */
493 U32        count                    /* !< TX_HFN to be assigned */
494 )
495 #else 
496 PUBLIC S16 pjDlmProcessSdusFB(gCb, pjRbCb, sdu, sduId, count)
497 PjCb   *gCb;                        /* !< Global control Block*/
498 PjDlRbCb *pjRbCb;                   /* !< PDCP Control Block */
499 FlatBuffer *sdu;                    /* !< SDU to be processed */
500 U32    sduId;                       /* !< PDCP SDU ID */
501 U32        count;                   /* !< TX_HFN to be assigned */
502 #endif
503 {
504    S16      ret;                  /* Return Value */
505    PjTxEnt  *txEnt;               /* Transmission Entity for sdu*/
506 #ifdef L2_PDCP_OPTMZ   
507    U8       hashKey;          /* Computed HashKey */
508    PjBuf       *buf; 
509 #endif   
510
511
512    TRC2(pjDlmProcessSdusFB)
513       
514 #ifndef ALIGN_64BIT
515    RLOG_ARG2(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
516          "pjDlmProcessSdusFB(pjRbCb(), sdu, sduId(%ld), count(%ld) )",
517                          sduId, count);
518 #else
519    RLOG_ARG2(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
520          "pjDlmProcessSdusFB(pjRbCb(), sdu, sduId(%d), count(%d) )",
521                          sduId, count);
522 #endif
523
524
525    ret = ROK;
526    
527    /* Allocate the transmission entity */
528    PJ_ALLOC(gCb,txEnt, sizeof(PjTxEnt));
529
530 #if (ERRCLASS & ERRCLS_ADD_RES)
531    if (txEnt == NULLP)
532    {
533       RLOG0(L_FATAL, "Memory Allocation failed.");
534       PJ_FREE_FLAT_BUF(gCb,sdu);
535       RETVALUE(RFAILED);
536    }
537 #endif /* ERRCLASS & ERRCLS_RES */
538
539    /* Update COUNT to the current count in dlCb*/
540
541    PJ_DLM_UPD_VAR(pjRbCb,txEnt->count);
542    PJ_DLM_GET_SN(pjRbCb,txEnt->count,txEnt->sn);
543    pjRbCb->dlCb.count = txEnt->count;
544    /* Fill TxEnt values */
545    txEnt->state = PJ_SDU_RECEIVED;
546    txEnt->sduId = sduId;
547    /* The received buffer is stored in the SDU and the output from 
548     * Compression/Ciphering is stored in the PDU.
549     */
550    txEnt->fb   = *sdu;
551    txEnt->pdu   = NULLP;
552    txEnt->sdu   = NULLP;
553    /* Insert TxEnt into the transmission buffer */
554    /* kw005.201 added support for L2 Measurement */
555 #ifndef L2_PDCP_OPTMZ
556       pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
557 #else
558       /* Fix for NULL ciphering. For null ciphering add PDUs to sduSubmitQ*/
559       if(pjRbCb->ueCb->secInfo.secAct && pjRbCb->ueCb->secInfo.cipherInfo.algoType != 0)
560       {
561          txEnt->datCfmEnt.node = NULLP;
562          txEnt->reEstPktEnt.node = NULLP;
563          txEnt->sduSubmitEnt.node = (PTR)NULLP;
564
565          buf=&(pjRbCb->dlCb.txBuf);
566          hashKey = (U8)PJ_HASH_FN(buf, txEnt->count); /*KW_FIX*/
567
568          txEnt->lstEnt.node = (PTR)txEnt;
569          cmLListAdd2Tail(&buf->datQ[hashKey], &txEnt->lstEnt);
570          buf->numEntries ++;
571
572          /* Dont add PDUs to datCfmQ in case of UM mode*/
573          if (pjRbCb->mode == PJ_DRB_AM ) 
574          {
575             txEnt->datCfmEnt.node = (PTR)txEnt;
576             cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.datCfmQ, &txEnt->datCfmEnt);
577          }
578
579          txEnt->state  = PJ_PDU_SUBMITTED;
580       }
581       else
582       {
583          pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
584       }
585 #endif   
586
587    /* Process the SDU based on rbType */
588    {
589 #ifndef RGL_SPECIFIC_CHANGES
590 #ifdef MSPD
591       {
592          extern U32 dlrate_pju;
593          dlrate_pju += sdu->len;
594       }
595 #endif
596 #endif
597       ret = pjDlmProcDrb(gCb, pjRbCb, txEnt);
598    }
599
600    RETVALUE(ret);
601 }
602 #endif
603
604 /**
605 *
606  * @brief 
607  *
608  *        Handler to construct a data PDU/Control PDU.
609  *
610  * @b Description: 
611  *
612  *        1. This function constructs the PDU header based on the SN length
613  *        configured.    @n
614  *        2. The header is inserted at the start of the PDU and
615  *        the constructed PDU is returned to the calling function. @n
616  *            
617  *  @param[in] pjRbCb   PDCP control block. 
618  *  @param[in] txEnt    Transmission Entity.
619  *                 
620  *  @return  S16
621  *      -# ROK 
622  *      -# RFAILED
623  *
624  */
625 #ifdef ANSI
626 PRIVATE S16 pjDlmBldPdu
627 (
628 PjCb    *gCb,
629 PjDlRbCb  *pjRbCb,
630 PjTxEnt *txEnt
631 )
632 #else
633 PRIVATE S16 pjDlmBldPdu(gCb,pjRbCb,txEnt)
634 PjCb    *gCb;
635 PjDlRbCb  *pjRbCb;
636 PjTxEnt *txEnt;
637 #endif
638 {
639    U32        hdr;                /* Header field */
640    S16        ret;                /* Return Value */
641    U32        numBytes;           /* Number of bytes to be added to the PDU */
642
643    TRC3(pjDlmBldPdu)
644 #ifndef ALIGN_64BIT
645    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
646                 (gCb->init.prntBuf, "pjDlmBldPdu(pjRbCb, txEnt (%ld)) \n", txEnt->sduId));
647 #else
648    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
649                 (gCb->init.prntBuf, "pjDlmBldPdu(pjRbCb, txEnt (%d)) \n", txEnt->sduId));
650 #endif
651   
652    hdr       = txEnt->sn;
653    ret       = ROK;
654    numBytes  = 2; /* for SRB it is 1 byte and even for 7 bit SN  on DRB it is 1 byte */
655
656    //hdr = 0x234;
657
658    /* Build a Data PDU */
659    if ( pjRbCb->rbType != PJ_SRB )
660    {
661       
662       /* The two byte header has the SN and MSB as '1' */
663       if (pjRbCb->snLen == PJ_12_BIT_SN) 
664       {
665          hdr |= PJ_DRB_12BIT_SN_HDR;
666          numBytes = 2;
667       }
668       else if (pjRbCb->snLen == PJ_18_BIT_SN)
669       {
670          hdr |= PJ_DRB_18BIT_SN_HDR;
671          numBytes = 3;
672       }
673    }
674
675    /* Add the hdr(based on numBytes) at the start of the PDU */
676    PJ_ADD_PRE_MSG( txEnt->pdu, hdr, numBytes, ret);
677
678 #if (ERRCLASS & ERRCLS_ADD_RES)
679    if (ret != ROK)
680    {
681       RLOG_ARG1(L_ERROR, DBG_RBID, pjRbCb->rbId, 
682             "SAddPreMsg failed SN [%u]",
683             txEnt->sn );
684       RETVALUE(RFAILED);
685    }
686 #endif /* ERRCLASS & ERRCLS_RES */
687    RETVALUE(ret);
688 }
689
690 /**
691  *
692  * @brief 
693  *
694  *        Handler to Re-establish a SRB.
695  *
696  * @b Description: 
697  *
698  *        1. This function is called when re-establishment request is
699  *        received for a SRB.   @n
700  *        2. The stored PDUs and SDUs are freed and the variables are reset. @n
701  *            
702  *  @param[in] pjRbCb   PDCP control block.
703  *
704  */
705
706 #ifdef ANSI
707 PUBLIC Void pjDlmReEstSrb
708 (
709 PjCb   *gCb,
710 PjDlRbCb *pjRbCb
711 )
712 #else
713 PUBLIC Void pjDlmReEstSrb(gCb, pjRbCb)
714 PjCb   *gCb;
715 PjDlRbCb *pjRbCb;
716 #endif
717 {
718
719    TRC3(pjDlmResetSrb)
720
721    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmResetSrb(pjRbCb ()) ");
722   
723
724    /* Stop the off-board and discard timer if running */
725 #if (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))
726    if (pjRbCb->dlCb.obdTmr.tmrEvnt == PJ_EVT_DL_OBD_TMR)
727    {
728        pjStopTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR);
729    }
730 #endif
731    /* Clean up all the SDUs present */ 
732    pjDbmTxDelAll(gCb, &(pjRbCb->dlCb.txBuf));
733
734    /* Reset the variables in rbCb */
735    PJ_RESET_ALL_VAR(pjRbCb);
736    /*kw004.201 Adding of Missing Trace in LTE RLC PDCP*/
737    RETVOID;
738 }
739
740 /**
741  *
742  * @brief 
743  *
744  *        Handler to Re-establish a UM DRB.
745  *
746  * @b Description: 
747  *
748  *        1. This function is called when re-establishment request is
749  *           received for a UM DRB.   @n
750  *        2. The stored PDUs are freed and the variables are reset.  @n
751  *        3. The PDUs which were associated with a SN and were not sent 
752  *           to the lower layer are now sent with the new ciphering 
753  *           algorithm and keys. @n
754  *            
755  *  @param[in] pjRbCb   PDCP control block. 
756  *
757  *  @return  S16
758  *      -# ROK 
759  *      -# RFAILED
760  *
761  */
762
763 #ifdef ANSI
764 PUBLIC S16 pjDlmReEstDrbUm
765 (
766 PjCb   *gCb,
767 PjDlRbCb *pjRbCb
768 )
769 #else
770 PUBLIC S16 pjDlmReEstDrbUm(gCb,pjRbCb)
771 PjCb   *gCb;
772 PjDlRbCb *pjRbCb;
773 #endif
774 {
775    S16            ret;                     /* Return Value */ 
776    PjTxEnt        *txEnt;                  /* Transmission Entity */
777    PjBuf          tmpTxBuf;                /* Tx Buffer */ 
778  
779    TRC3(pjDlmReEstDrbUm)
780
781    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmReEstDrbUm(pjRbCb ()) ");
782    ret      = ROK; /* KW_FIX */
783    txEnt    =  NULLP;
784
785    /* Reset all the variable */
786    PJ_RESET_ALL_VAR(pjRbCb);
787 #if (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))
788    /* Stop the off board timer if running */
789    if (pjRbCb->dlCb.obdTmr.tmrEvnt == PJ_EVT_DL_OBD_TMR)
790    {
791        pjStopTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR);
792    } 
793 #endif
794
795    if(pjRbCb->dlCb.txBuf.numEntries == 0)
796    {
797       RETVALUE(ROK);
798    }
799
800    /* Create the new buffer list  and store the old pointer in datQ */
801    PJ_CREATE_NEW_LIST(gCb,pjRbCb, tmpTxBuf, ret);
802 #if (ERRCLASS & ERRCLS_ADD_RES) 
803    if (ret != ROK)
804    {
805       RLOG0(L_FATAL, "Memory Allocation failed");
806       RETVALUE(RFAILED);
807    }
808 #endif /* ERRCLASS & ERRCLS_RES */
809
810    /* Process all the existing PDUs as received from above layer */
811    cmLListFirst(&tmpTxBuf.sduSubmitQ);
812    while (cmLListCrnt(&tmpTxBuf.sduSubmitQ))
813    {
814       U8   hashKey = 0;
815       txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&tmpTxBuf.sduSubmitQ));
816       /* Assign the new SN, TX_HFN and insert in the new transmission
817        * buffer.
818        */
819       if ( txEnt != NULLP )
820       {
821 #if (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))
822          if ( txEnt->pdu != txEnt->sdu )
823          {
824             PJ_FREE_BUF(txEnt->pdu);
825          }
826          else
827          {
828             txEnt->pdu = NULLP;
829          }
830 #endif
831          hashKey = (U8)PJ_HASH_FN((&tmpTxBuf), txEnt->count);
832          PJ_DLM_UPD_VAR(pjRbCb,txEnt->count);     
833          PJ_DLM_GET_SN(pjRbCb,txEnt->count,txEnt->sn);
834          pjRbCb->dlCb.count = txEnt->count; 
835          txEnt->state = PJ_SDU_RECEIVED;
836          txEnt->pdu = NULLP;
837
838          cmLListDelFrm(&tmpTxBuf.datQ[hashKey], &txEnt->lstEnt);
839          cmLListDelFrm(&tmpTxBuf.sduSubmitQ, &txEnt->sduSubmitEnt);
840
841          tmpTxBuf.numEntries --;
842
843          pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
844
845          txEnt->reEstPktEnt.node = (PTR)txEnt;
846          cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.reEstPktQ, &txEnt->reEstPktEnt);
847
848          txEnt->sduSubmitEnt.node=NULLP;
849          cmLListDelFrm(&pjRbCb->dlCb.txBuf.sduSubmitQ, &txEnt->sduSubmitEnt);
850       }
851       cmLListFirst(&tmpTxBuf.sduSubmitQ);
852    }
853    /* Free up the old transmission buffer */
854    pjDbmTxDeInit(gCb,&tmpTxBuf);
855    RETVALUE(ret);    
856 }
857
858 /**
859  *
860  * @brief 
861  *
862  *        Handler to Re-establish a AM DRB.
863  *
864  * @b Description: 
865  *
866  *        1. This function is called when re-establishment request is
867  *        received for a AM DRB.     @n
868  *        2. The stored PDUs are freed.   @n
869  *        3. The PDUs which were not submitted to the lower
870  *        layer and for which a confirm has not been received
871  *        are now sent with the new ciphering algorithm and keys. @n
872  *            
873  *  @param[in] pjRbCb   PDCP control block. 
874  *
875  *  @return  S16
876  *      -# ROK 
877  *      -# RFAILED
878  *
879  */
880 #ifdef ANSI
881 PUBLIC S16 pjDlmReEstDrbAm
882 (
883 PjCb   *gCb,
884 PjDlRbCb *pjRbCb
885 )
886 #else
887 PUBLIC S16 pjDlmReEstDrbAm(gCb,pjRbCb)
888 PjCb   *gCb;
889 PjDlRbCb *pjRbCb;
890 #endif
891 {
892    PjTxEnt        *txEnt;
893
894    TRC3(pjDlmReEstDrbAm)
895
896    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmReEstDrbAm(pjRbCb ()) ");
897  
898   
899    if (pjRbCb->dlCb.txBuf.numEntries == 0)
900    {
901       RETVALUE(ROK);
902    }
903  
904    cmLListFirst(&pjRbCb->dlCb.txBuf.datCfmQ);
905    while (cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ))
906    {
907       txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ));
908 #if (ERRCLASS & ERRCLS_DEBUG)  /* KW_FIX */
909          if(txEnt == NULLP)
910          {
911             RLOG_ARG0(L_ERROR,DBG_RBID,pjRbCb->rbId, 
912                   "pjDlmReEstDrbAm:Transmission Entity is NULL ");
913             RETVALUE(RFAILED);
914          }
915 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
916       if (txEnt != NULLP)
917       {
918           txEnt->reEstPktEnt.node = (PTR)txEnt;
919           cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.reEstPktQ, &txEnt->reEstPktEnt);
920           pjTotDlPckCntPerCell--;          
921       }
922       txEnt->datCfmEnt.node = NULLP;
923       cmLListDelFrm(&pjRbCb->dlCb.txBuf.datCfmQ, &txEnt->datCfmEnt);
924       cmLListFirst(&pjRbCb->dlCb.txBuf.datCfmQ);
925    }
926
927    cmLListFirst(&pjRbCb->dlCb.txBuf.sduSubmitQ);
928    while (cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ))
929    {
930       txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ));
931       if (txEnt != NULLP)      /*KW_FIX : ccpu00136902*/
932       {
933          txEnt->reEstPktEnt.node = (PTR)txEnt;
934          cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.reEstPktQ, &txEnt->reEstPktEnt);
935          txEnt->sduSubmitEnt.node=NULLP;
936          cmLListDelFrm(&pjRbCb->dlCb.txBuf.sduSubmitQ, &txEnt->sduSubmitEnt);
937          cmLListFirst(&pjRbCb->dlCb.txBuf.sduSubmitQ);
938       }
939       else
940       {
941          RLOG_ARG0(L_ERROR,DBG_RBID,pjRbCb->rbId, "This should not be hit ");
942          break;
943       }
944    }
945
946    RETVALUE(ROK);
947 }
948
949 /**
950  *
951  * @brief 
952  *
953  *        Handler to send data confirmation to RRC.
954  *
955  * @b Description: 
956  *
957  *        1. This function is called when a status indication or a confirm is 
958  *        received from the lower layer.  @n
959  *        2. The confirm type can be a success or failure. @n 
960  *        3. The corresponding SDUs and PDUs are cleaned up and
961  *        if cfmReqd is configured, a confirm is sent to the upper layer. @n
962  *            
963  *  @param[in] pjRbCb    PDCP control block. 
964  *  @param[in] staInd  Status Indication Information.
965  *  @param[in] cfmType Confirm Type can be SUCCESS or FAILURE.
966  *
967  *  @return  S16
968  *      -# ROK 
969  *      -# RFAILED
970  *
971  */
972
973 U32 pjRxCfm;
974
975 #ifdef ANSI
976 PUBLIC S16 pjDlmProcessCfm
977 (
978 PjCb          *gCb,
979 PjDlRbCb        *pjRbCb,
980 PjDatCfm      *pjDatCfm,
981 U8            cfmType
982 )
983 #else
984 PUBLIC S16 pjDlmProcessCfm(gCb,pjRbCb,pjDatCfm,cfmType)
985 PjCb          *gCb;
986 PjDlRbCb        *pjRbCb;
987 PjDatCfm      *pjDatCfm;
988 U8            cfmType;
989 #endif
990 {
991    PjuDatCfmInfo  *datCfm;        /* Data Cfm to be sent to upper layer */
992    U32            cnt;            /* Counter for number of SDUs in datCfm*/
993    U16            datCfmCnt;      /* Counter for number of SDUs in datCfm*/ /*KW_FIX*/
994    PjPjuSapCb     *pjuSap;        /* Upper Sap of PDCP User */
995    CmLtePdcpId    *pdcpId;        /* PDCP ID */
996    PjTxEnt        *txEnt;          /* Transmission entity */
997
998    TRC3(pjDlmProcessCfm)
999
1000    gCb->pjPerfSts.pjSduRcvCnt += pjDatCfm->numSdu;
1001
1002    pdcpId   = NULLP;
1003    cnt      = 0;
1004    pjuSap   = NULLP;
1005    datCfm   = NULLP;
1006    txEnt    = NULLP;
1007
1008    /* If cfmReqd flag is sent a confirmation is sent to the above layer.
1009     * For each SDU, get the sduId and status and fill in the datCfm
1010     * structure and discard the txEnt. Also update cfmExp count.
1011     */
1012    if ( (pjRbCb->dlCb.cfmReqd) || (PJ_CFM_NOK == cfmType))
1013    {
1014       PjuDatCfmInfo datCfmTmp;
1015       CmLtePdcpId pdcpIdTmp;
1016       datCfm = &datCfmTmp;
1017       pdcpId = &pdcpIdTmp;
1018       pdcpId->rbId   = pjRbCb->rbId;
1019       pdcpId->rbType = pjRbCb->rbType;
1020       pdcpId->ueId   = pjRbCb->ueCb->key.ueId;
1021       pdcpId->cellId = pjRbCb->ueCb->key.cellId;
1022
1023       if (pjRbCb->rbType == PJ_SRB)
1024          pjuSap = &(gCb->u.dlCb->pjuSap[PJ_SRB_SAP]);
1025       else
1026          pjuSap = &(gCb->u.dlCb->pjuSap[PJ_DRB_SAP]);
1027
1028       datCfmCnt = 0;
1029       for ( cnt = 0; cnt < pjDatCfm->numSdu; cnt++)
1030       {
1031          txEnt = (PjTxEnt *)pjDbmGetTxEnt(gCb,&(pjRbCb->dlCb.txBuf), 
1032                                        pjDatCfm->sduId[cnt]);
1033          if ( txEnt != NULLP )
1034          {
1035             datCfm->cfmSta[datCfmCnt].sduId  = txEnt->sduId;
1036             /* RLC_DL_MAX_RETX fix */
1037             if (PJ_CFM_OK != cfmType)
1038             {
1039                datCfm->cfmSta[datCfmCnt].status = PJU_RLC_TRANS_FAIL;
1040             }
1041             else
1042             {
1043                datCfm->cfmSta[datCfmCnt].status = cfmType;
1044             }
1045
1046             datCfm->cfmSta[datCfmCnt].status = cfmType;
1047             datCfmCnt ++;
1048             pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count);
1049          }
1050       }
1051       datCfm->numSdus = datCfmCnt;
1052       if(datCfm->numSdus)
1053       {
1054          /* If trace flag is enabled send the trace indication */
1055          if(gCb->init.trc == TRUE)
1056          {
1057             /* Populate the trace params */
1058             pjLmmSendTrc(gCb, EVTPJUDATCFM, NULLP);
1059          }
1060
1061          PjUiPjuDatCfm(&pjuSap->pst, pjuSap->suId, pdcpId, datCfm);
1062       }
1063    }
1064    /* If cfmReqd is not set, discard the txEnts and update the cfmExp count */
1065    else
1066    {
1067       for ( cnt = 0; cnt < pjDatCfm->numSdu; cnt++)
1068       {
1069          pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), pjDatCfm->sduId[cnt]);
1070       }
1071    
1072    }
1073
1074    RETVALUE(ROK);
1075 }
1076
1077 /**
1078  *
1079  * @brief 
1080  *
1081  *        Handler to send process the status report.
1082  *
1083  * @b Description: 
1084  *
1085  *        1. This function is called when a status report is received from the
1086  *        peer.    @n
1087  *        2. This function process the status report and sends a confirmation
1088  *        to the above layer and removes the PDUs and SDUs for which positive 
1089  *        acknowledgement is received.  @n
1090  *            
1091  *  @param[in] pjRbCb      PDCP control block. 
1092  *  @param[in] staPdu      Status report.
1093  *
1094  *  @return  S16
1095  *      -# ROK 
1096  *      -# RFAILED
1097  *
1098  */
1099
1100 #ifdef ANSI
1101 PUBLIC S16 pjDlmHndlStaRep
1102 (
1103 PjCb     *gCb,
1104 PjDlRbCb   *pjRbCb,
1105 PjSn     fmc,
1106 Buffer   *staPdu
1107 )
1108 #else
1109 PUBLIC S16 pjDlmHndlStaRep(gCb,pjRbCb,fmc,staPdu)
1110 PjCb     *gCb;
1111 PjDlRbCb   *pjRbCb;
1112 PjSn     fmc;
1113 Buffer   *staPdu;
1114 #endif
1115 {
1116    PjuDatCfmInfo *datCfm;       /* Dat Cfm to be sent to the upper layer */
1117    PjuDatCfmInfo datCfmTmp;     /* Tmp variable allocated to assign local memory to the datCfm pointer */
1118    CmLtePdcpId pdcpIdTmp;       /* Tmp variable allocated to assign local memory to the pdcpId pointer */
1119    S16           ret;           /* Return Value */
1120    PjPjuSapCb    *pjuSap;       /* PJU SAP Control Block */
1121    CmLtePdcpId   *pdcpId;       /* PDCP ID */
1122    U32           bitPos;        /* Bit position in the Status PDU */
1123    U8            cnt;           /* Counter for the bits in a byte */
1124    U8            sduSta;        /* SDU Status of reception at the Peer */
1125    PjTxEnt       *txEnt;        /* Transmission entity */
1126    U8            byte;          /* One Byte of a Status Pdu */
1127    MsgLen        bMapLen;       /* StaPdu Length in bytes */
1128    PjSn          count;            /* count of the PDU */
1129
1130    TRC3(pjDlmHndlStaRep)
1131
1132    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmHndlStaRep(pjRbCb (), fmc (%lu), staPdu) ",fmc);
1133
1134    datCfm  = NULLP;
1135    ret     = ROK;
1136    pjuSap  = NULLP;
1137    pdcpId  = NULLP;
1138
1139    
1140    /* Allocate for datCfm structure is cfmReqd is set */
1141    if ( pjRbCb->dlCb.cfmReqd )
1142    {
1143     datCfm = &datCfmTmp;
1144    }
1145
1146    /* Fills the confirm information for all the PDUs whose COUNT < COUNT(FMC) 
1147     * and sets cfmExp to fmc
1148     */
1149    pjDlmDelTxEntUptoFmc(gCb, pjRbCb, fmc, datCfm);
1150
1151
1152    cnt     = 0;
1153    bitPos  = 1;
1154    byte    = 0;
1155    bMapLen = 0;
1156    SFndLenMsg(staPdu, &bMapLen);
1157
1158    /* Read one byte at a time from Status PDU */
1159    while ( bMapLen != 0 )
1160    {
1161       ret = SRemPreMsg(&byte,staPdu);
1162 #if (ERRCLASS & ERRCLS_ADD_RES)
1163       if (ret != ROK)
1164       {
1165          RLOG0(L_ERROR, "SRemPreMsg Failed for staPdu");
1166          PJ_FREE_BUF(staPdu);
1167          RETVALUE(RFAILED);
1168       }
1169 #endif /* ERRCLASS & ERRCLS_RES */
1170
1171       /* Check if each bit in a byte is set or not.
1172        * If cfmReqd is set fill in the cfm info.
1173        * Discard the txEnt if the bit is set to 1.
1174        */
1175       for ( cnt = 0; cnt < PJ_BYTE_LEN; cnt++, bitPos++ )
1176       {
1177          sduSta  = (byte << cnt) & PJ_FIRST_BIT;
1178          if (sduSta)
1179          {
1180             count      = (fmc + bitPos) % PJ_TX_BUF_LEN;
1181             txEnt   = (PjTxEnt *)pjDbmGetTxEnt(gCb, &(pjRbCb->dlCb.txBuf), count);
1182             if ( txEnt != NULLP )
1183             {
1184                if ((pjRbCb->dlCb.cfmReqd)&& (datCfm->numSdus < PJU_MAX_SDU_CFM))
1185                {
1186                    
1187                   datCfm->cfmSta[datCfm->numSdus].sduId  = txEnt->sduId;
1188                   datCfm->cfmSta[datCfm->numSdus].status = sduSta;
1189                   datCfm->numSdus++;;
1190                }
1191                pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count); 
1192             }
1193          }
1194       }
1195       bMapLen--;
1196    }
1197    /* Send a confirmation to the upper layer */
1198    if ((pjRbCb->dlCb.cfmReqd) && (datCfm->numSdus > 0))
1199    {
1200      pdcpId = &pdcpIdTmp;
1201
1202      pdcpId->rbId   = pjRbCb->rbId;
1203      pdcpId->rbType = pjRbCb->rbType;
1204      pdcpId->ueId   = pjRbCb->ueCb->key.ueId;
1205      pdcpId->cellId = pjRbCb->ueCb->key.cellId;
1206
1207      pjuSap   =  &gCb->u.dlCb->pjuSap[PJ_DRB_SAP];
1208      /* If trace flag is enabled send the trace indication */
1209      if(gCb->init.trc == TRUE)
1210      {
1211        /* Populate the trace params */
1212        pjLmmSendTrc(gCb, EVTPJUDATCFM, NULLP);
1213      }
1214      PjUiPjuDatCfm(&pjuSap->pst, pjuSap->suId, pdcpId, datCfm);
1215    }
1216
1217    PJ_FREE_BUF(staPdu);
1218
1219    RETVALUE(ret); 
1220 }
1221
1222 /**
1223  *
1224  * @brief 
1225  *
1226  *        Handler to forward the downlink data to the upper layer.
1227  *
1228  * @b Description: 
1229  *
1230  *        1. This function is used to send the downlink data to the upper layer
1231  *        during handover.  @n
1232  *        2. The unacknowledged data SDUs are sent to the upper
1233  *        layer.    @n
1234  *            
1235  *  @param[in] pjRbCb      PDCP control block. 
1236  *
1237  *  @return  S16
1238  *      -# ROK 
1239  *      -# RFAILED
1240  *
1241  */
1242
1243 #ifdef ANSI
1244 PUBLIC S16 pjDlmReEstHoDrbAm
1245 (
1246 PjCb   *gCb,
1247 PjDlRbCb *pjRbCb
1248 )
1249 #else
1250 PUBLIC S16 pjDlmReEstHoDrbAm(gCb,pjRbCb)
1251 PjCb    *gCb;
1252 PjDlRbCb  *pjRbCb;
1253 #endif
1254 {
1255    TRC3(pjDlmReEstHoDrbAm)
1256    
1257    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmReEstHoDrbAm(pjRbCb ()) ");
1258
1259
1260    pjRbCb->pktAdmitCnt = 0;
1261    pjRbCb->ueCb->hoInfo->hoCfmInfo[pjRbCb->rbId].pres = TRUE;
1262    pjRbCb->ueCb->hoInfo->hoCfmInfo[pjRbCb->rbId].rbId = pjRbCb->rbId;
1263    pjRbCb->ueCb->hoInfo->hoCfmInfo[pjRbCb->rbId].dir  = PJ_DIR_DL;
1264    pjRbCb->ueCb->hoInfo->hoCfmInfo[pjRbCb->rbId].count = pjRbCb->dlCb.count + 1;
1265
1266    RETVALUE(ROK);
1267 }
1268
1269
1270 /**
1271  *
1272  * @brief 
1273  *
1274  *        Handler to forward the downlink data to the upper layer.
1275  *
1276  * @b Description: 
1277  *
1278  *        1. This function is used to send the downlink data to the upper layer
1279  *        during handover.  @n
1280  *        2. The unacknowledged data SDUs are sent to the upper
1281  *        layer.    @n
1282  *            
1283  *  @param[in] pjRbCb      PDCP control block. 
1284  *
1285  *  @return  S16
1286  *      -# ROK 
1287  *      -# RFAILED
1288  *
1289  */
1290
1291 #ifdef ANSI
1292 PUBLIC S16 pjDlmStartDataFrwdPerRb
1293 (
1294 PjCb       *gCb,
1295 PjDlRbCb   *pjRbCb
1296 )
1297 #else
1298 PUBLIC S16 pjDlmStartDataFrwdPerRb(gCb,pjRbCb)
1299 PjCb       *gCb;
1300 PjDlRbCb   *pjRbCb;
1301 #endif
1302 {
1303
1304    U32              numSdu =0;
1305    U16              count;   /*KW_FIX*/
1306    U32              numSduCnt =0,numSduTx = 0;
1307    PjTxEnt          *txEnt = NULLP;       
1308    PjuDatFwdIndInfo *datFwdInd = NULLP;  
1309    PjPjuSapCb   *pjuSap;
1310    PjDlPkt    *pkt = NULLP;
1311
1312    TRC3(pjDlmStartDataFrwdPerRb)
1313    
1314    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmStartDataFrwdPerRb(pjRbCb ()) ");
1315
1316    pjuSap   = &(gCb->u.dlCb->pjuSap[PJ_DRB_SAP]);
1317    /* Update hoCfmInfo, used to fill SduStaCfm */
1318    if(pjRbCb->dlCb.txNext == 0)
1319    {
1320     //  PJ_ALLOC(gCb,datFwdInd, sizeof(PjuDatFwdIndInfo));
1321    if(SGetSBuf(pjuSap->pst.region,pjuSap->pst.pool,(Data **)&datFwdInd, 
1322             sizeof (PjuDatFwdIndInfo)) != ROK)
1323    {
1324 #if (ERRCLASS & ERRCLS_ADD_RES)
1325       if (datFwdInd == NULLP)
1326       {
1327          /*ccpu00136858 */      
1328          RLOG0(L_FATAL, "Memory Allocation failed.");
1329       }
1330 #endif /* ERRCLASS & ERRCLS_ADD_RES */
1331          RETVALUE(RFAILED);
1332    }
1333       datFwdInd->dir = PJ_DIR_DL;
1334       datFwdInd->numSdus = 0;
1335       datFwdInd->isLastDatFwdInd = TRUE;
1336
1337       /* sending DatFwdInd even if numSdu is zero */
1338       pjUtlDlSndDatFwdInd(gCb,pjRbCb, datFwdInd);
1339       RETVALUE(ROK);
1340    }
1341
1342    /* Find the total count of the txEnts present */
1343    numSdu = pjRbCb->dlCb.txBuf.numEntries + pjRbCb->dlCb.dlPktQ.count;
1344    numSduCnt = numSdu;
1345
1346    /* This was added from Hotfix branch when Data Fwding was not supported */
1347
1348    cmLListFirst(&pjRbCb->dlCb.txBuf.datCfmQ);
1349    cmLListFirst(&pjRbCb->dlCb.txBuf.sduSubmitQ);
1350    cmLListFirst(&pjRbCb->dlCb.dlPktQ);
1351
1352
1353 while(numSduCnt >0)
1354 {
1355    count = 0;
1356    /* For BRDCM PJ_FWD_MAX_SDU_CNT = 16, for MSPD PJ_FWD_MAX_SDU_CNT=1 */
1357
1358    if(numSduCnt > PJ_FWD_MAX_SDU_CNT)
1359    {
1360       numSduTx  = PJ_FWD_MAX_SDU_CNT;
1361       numSduCnt = numSduCnt - PJ_FWD_MAX_SDU_CNT;
1362    }
1363    else
1364    {
1365       numSduTx = numSduCnt;
1366       numSduCnt = 0;
1367    }
1368
1369    if(SGetSBuf(pjuSap->pst.region,pjuSap->pst.pool,(Data **)&datFwdInd, 
1370             sizeof (PjuDatFwdIndInfo)) != ROK)
1371    {
1372       /*ccpu00136858 */      
1373       RLOG0(L_FATAL, "Memory Allocation failed.");
1374       RETVALUE(RFAILED);
1375    }
1376
1377    if(SGetSBuf(pjuSap->pst.region,pjuSap->pst.pool,(Data **)&datFwdInd->datFwdInfo, 
1378             (sizeof(PjuDatFwdInfo) * numSduTx)) != ROK)
1379    {
1380       /* Free memory for DatFwdInfo */
1381       PJ_PST_FREE(pjuSap->pst.region, pjuSap->pst.pool,datFwdInd->datFwdInfo,  
1382             numSdu * sizeof(PjuDatFwdIndInfo));
1383       RLOG0(L_FATAL, "Memory Allocation failed.");
1384       RETVALUE(RFAILED);
1385    }
1386
1387    while (numSduTx>0)
1388    {
1389
1390       if(NULLP != cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ))
1391       {
1392          txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.datCfmQ));
1393          datFwdInd->datFwdInfo[count].sduId = txEnt->sduId;
1394          datFwdInd->datFwdInfo[count].sn    = txEnt->sn;
1395 #ifdef SS_RBUF
1396          datFwdInd->datFwdInfo[count].sdu = txEnt->sdu;
1397 #else
1398 #ifdef FLAT_BUFFER_OPT
1399          if(txEnt->sdu == NULLP)
1400          {
1401             pjUtlCopyFbToBuf(gCb, &(txEnt->fb), &(datFwdInd->datFwdInfo[count].sdu));
1402          }
1403          else
1404 #endif
1405          {
1406             SCpyMsgMsg(txEnt->sdu, 0, 0, &datFwdInd->datFwdInfo[count].sdu);
1407          }
1408 #endif
1409          cmLListNext(&pjRbCb->dlCb.txBuf.datCfmQ);
1410          numSduTx--;
1411          count++;
1412          continue;
1413       }
1414
1415
1416       if(NULLP != cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ))
1417       {
1418          txEnt = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ));
1419          datFwdInd->datFwdInfo[count].sduId = txEnt->sduId;
1420          datFwdInd->datFwdInfo[count].sn    = txEnt->sn;
1421 #ifdef SS_RBUF
1422          datFwdInd->datFwdInfo[count].sdu = txEnt->sdu;
1423 #else
1424 #ifdef FLAT_BUFFER_OPT
1425          if(txEnt->sdu == NULLP)
1426          {
1427             pjUtlCopyFbToBuf(gCb, &(txEnt->fb), &(datFwdInd->datFwdInfo[count].sdu));
1428          }
1429          else
1430 #endif
1431          {
1432             SCpyMsgMsg(txEnt->sdu, 0, 0, &datFwdInd->datFwdInfo[count].sdu);
1433          }
1434 #endif
1435          cmLListNext(&pjRbCb->dlCb.txBuf.sduSubmitQ);
1436          numSduTx--;
1437          count++;
1438          continue;
1439       }
1440
1441
1442       if(NULLP != cmLListCrnt(&pjRbCb->dlCb.dlPktQ))
1443       {
1444          pkt = (PjDlPkt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.dlPktQ));
1445          datFwdInd->datFwdInfo[count].sduId = pkt->sduId;
1446          datFwdInd->datFwdInfo[count].sn    = pkt->sn;
1447 #ifdef SS_RBUF
1448          datFwdInd->datFwdInfo[count].sdu = pkt->pdu;
1449 #else
1450 #ifdef FLAT_BUFFER_OPT
1451          if(pkt->pdu == NULLP)
1452          {
1453             pjUtlCopyFbToBuf(gCb, &(pkt->fb), &(datFwdInd->datFwdInfo[count].sdu));
1454          }
1455          else
1456 #endif
1457          {
1458             SCpyMsgMsg(pkt->pdu, 0, 0, &datFwdInd->datFwdInfo[count].sdu);
1459          }
1460 #endif
1461
1462          cmLListNext(&pjRbCb->dlCb.dlPktQ);
1463          numSduTx--;
1464          count++;
1465       }
1466
1467    }
1468    datFwdInd->dir = PJ_DIR_DL;
1469    datFwdInd->numSdus = count;
1470    datFwdInd->isLastDatFwdInd = FALSE;
1471    pjUtlDlSndDatFwdInd(gCb,pjRbCb, datFwdInd);
1472 }
1473
1474    pjuSap   = &(gCb->u.dlCb->pjuSap[PJ_DRB_SAP]);
1475    if(SGetSBuf(pjuSap->pst.region,pjuSap->pst.pool,(Data **)&datFwdInd, 
1476           sizeof (PjuDatFwdIndInfo)) != ROK)
1477    {
1478       /*ccpu00136858 */      
1479       RLOG0(L_FATAL, "Memory Allocation failed.");
1480       RETVALUE(RFAILED);
1481    }
1482    datFwdInd->dir = PJ_DIR_DL;
1483    datFwdInd->numSdus = 0;
1484    datFwdInd->isLastDatFwdInd = TRUE;
1485
1486    /* sending DatFwdInd even if numSdu is zero */
1487    pjUtlDlSndDatFwdInd(gCb,pjRbCb, datFwdInd);
1488    RETVALUE(ROK);
1489
1490 }
1491
1492
1493 /**
1494  *
1495  * @brief 
1496  *
1497  *        Handler to process the forwarded data received from upper layer.
1498  *
1499  * @b Description: 
1500  *
1501  *        1. This function is used to process the SDUs received from the upper
1502  *        layer as part of handover.   @n
1503  *        2. This function calls pjDlmProcessSdus function with the correct 
1504  *        SN and HFN values.     @n
1505  *            
1506  *  @param[in] gCb         PDCP Instance control block. 
1507  *  @param[in] pjRbCb      Rb control block. 
1508  *  @param[in] datFwdReq   Data Forward Info.
1509  *
1510  *  @return  S16
1511  *      -# ROK 
1512  *      -# RFAILED
1513  *
1514  */
1515 #ifdef ANSI
1516 PUBLIC S16 pjDlmHndlDatFwdReq
1517 (
1518 PjCb               *gCb,
1519 PjDlRbCb           *pjRbCb,
1520 PjuDatFwdReqInfo   *datFwdReq
1521 )
1522 #else
1523 PUBLIC S16 pjDlmHndlDatFwdReq(gCb,pjRbCb,datFwdReq)
1524 PjCb               *gCb;
1525 PjDlRbCb           *pjRbCb;
1526 PjuDatFwdReqInfo   *datFwdReq;
1527 #endif
1528 {
1529
1530    U32      sduCount;            /* Number of received SDUs */
1531    U32      numSdus;             /* Counter for SDUs */
1532    //U32      txHfn;               /* TX_HFN of a SDU */
1533    PjTxEnt  *txEnt;              /* Transmission Entity */ 
1534 #ifdef L2_PDCP_OPTMZ   
1535    U8       hashKey;          /* Computed HashKey */
1536    PjBuf       *buf; 
1537 #endif   
1538
1539    TRC3(pjDlmHdlDatFwdReq)
1540
1541    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmHndlDatFwdReq(pjRbCb (),datFwdReq(%d)) ", 
1542                              datFwdReq->numSdus);
1543
1544    sduCount = datFwdReq->numSdus;
1545    //txHfn    = pjRbCb->dlCb.txHfn;
1546    numSdus  = 0;
1547    
1548    /* FIXME is this required , TC 11.10 */
1549    /* FIXME NOT a proper fix also */
1550    if(pjRbCb->dlCb.txNext == 0)
1551    {
1552       //pjRbCb->dlCb.nxtTxSn =  datFwdReq->datFwdInfo[sduCount - 1].sn;
1553       pjRbCb->dlCb.count   =  datFwdReq->datFwdInfo[sduCount - 1].sn;
1554    }
1555    gCb->pjGenSts.numPktsRcvd += sduCount;
1556    /* Process each of the SDUs with received SN and sduId */ 
1557    for ( numSdus = 0; numSdus < sduCount; numSdus++ )
1558    {
1559       /* 
1560          The variables nxtTxSn and COUNT are assumed to be 
1561          already updated in dlCb to continue with the 
1562          transmission ( in the target eNodeB ).
1563       */
1564       PJ_ALLOC(gCb,txEnt, sizeof(PjTxEnt)); 
1565
1566 #if (ERRCLASS & ERRCLS_ADD_RES)
1567       if (txEnt == NULLP)
1568       {
1569          RLOG0(L_FATAL, "Memory Allocation failed.");
1570          PJ_FREE_BUF(datFwdReq->datFwdInfo[numSdus].sdu);
1571          RETVALUE(RFAILED);
1572       }
1573 #endif /* ERRCLASS & ERRCLS_RES */
1574
1575
1576       /* Fill TxEnt values */
1577       txEnt->sn = datFwdReq->datFwdInfo[numSdus].sn;
1578       txEnt->sduId = datFwdReq->datFwdInfo[numSdus].sduId;
1579       txEnt->state = PJ_SDU_RECEIVED;
1580       txEnt->sdu   = datFwdReq->datFwdInfo[numSdus].sdu;
1581       txEnt->pdu   = NULLP;
1582
1583 #ifndef L2_PDCP_OPTMZ
1584       pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
1585 #else
1586       /* Fix for NULL ciphering. For null ciphering add PDUs to sduSubmitQ*/
1587       if(pjRbCb->ueCb->secInfo.secAct && pjRbCb->ueCb->secInfo.cipherInfo.algoType != 0)
1588       {
1589          txEnt->datCfmEnt.node = NULLP;
1590          txEnt->reEstPktEnt.node = NULLP;
1591          txEnt->sduSubmitEnt.node = (PTR)NULLP;
1592
1593          buf=&(pjRbCb->dlCb.txBuf);
1594          hashKey = (U8)PJ_HASH_FN(buf, txEnt->count); /*KW_FIX*/
1595
1596          txEnt->lstEnt.node = (PTR)txEnt;
1597          cmLListAdd2Tail(&buf->datQ[hashKey], &txEnt->lstEnt);
1598          buf->numEntries ++;
1599
1600          /* Dont add PDUs to datCfmQ in case of UM mode*/
1601          if (pjRbCb->mode == PJ_DRB_AM ) 
1602          {
1603             txEnt->datCfmEnt.node = (PTR)txEnt;
1604             cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.datCfmQ, &txEnt->datCfmEnt);
1605          }
1606
1607          txEnt->state  = PJ_PDU_SUBMITTED;
1608       }
1609       else
1610       {
1611          pjDbmInsTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt);
1612       }
1613 #endif   
1614       pjDlmProcDrb(gCb,pjRbCb,txEnt);
1615
1616    }
1617  
1618
1619    RETVALUE(ROK);
1620 }
1621
1622 /**
1623  *
1624  * @brief 
1625  *
1626  *        Handler to construct a PDU and send it to the lower layer.
1627  *
1628  * @b Description: 
1629  *
1630  *        1. This function is used to deliver a PDU to the lower layer.@n
1631  *        2. It calls pjDlmBldPdu function and sends the PDU to 
1632  *        the lower layer using pjDlmSendDatReq function. @n
1633  *        3. The txBuf is freed up if the cfmReqd is not configured or 
1634  *        if the rbType is UM.@n
1635  *            
1636  *  @param[in] pjRbCb   PDCP control block.
1637  *  @param[in] txEnt    Transmission Entity.
1638  *  @param[in] mBuf     The PDU to be transmitted.
1639  *  @param[in] pduType  Type of the PDU.
1640  *  @return  S16
1641  *      -# ROK 
1642  *      -# RFAILED
1643  */
1644
1645 #ifdef ANSI
1646 PUBLIC S16 pjDlmDeliverPdu
1647 (
1648 PjCb       *gCb,
1649 PjDlRbCb     *pjRbCb,
1650 PjTxEnt    *txEnt
1651 )
1652 #else
1653 PUBLIC S16 pjDlmDeliverPdu(gCb,pjRbCb,txEnt)
1654 PjCb       *gCb;
1655 PjDlRbCb     *pjRbCb;
1656 PjTxEnt    *txEnt;
1657 #endif
1658 {
1659    S16            ret;            /* Return Value */
1660    S16            ret1;            /* Return Value */
1661    PjTxEnt    *txFirstEntity;
1662
1663
1664    TRC3(pjDlmDeliverPdu)
1665
1666
1667    ret    = ROK;
1668
1669
1670    /* Constructs a PDU */
1671    if ( txEnt->state != PJ_PDU_CONSTRUCTED )
1672    {
1673       ret = pjDlmBldPdu(gCb, pjRbCb, txEnt);
1674    }
1675
1676    if ( ret != ROK )
1677    {
1678       RLOG_ARG2(L_ERROR, DBG_RBID, pjRbCb->rbId, "PDCP DL Build PDU Failed SN [%u] , Count [%lu]",  
1679          txEnt->sn, txEnt->count);
1680       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
1681       if ( pjRbCb->dlCb.cfmReqd)
1682       {
1683          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_PDU_CONSTRUCT_FAILED);
1684       }
1685       RETVALUE(RFAILED);
1686    }
1687    txEnt->state = PJ_PDU_CONSTRUCTED;
1688
1689    /* Deliver the PDU to the lower layer only if it is nxtToSub.
1690     * Also deliver the consecutive PDUs if they are constructed.
1691     * If not just store the PDU.
1692     */
1693    cmLListFirst(&pjRbCb->dlCb.txBuf.sduSubmitQ);
1694
1695    while (cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ))
1696    {
1697       txFirstEntity = (PjTxEnt *) cmLListNode(cmLListCrnt(&pjRbCb->dlCb.txBuf.sduSubmitQ));
1698       if (txFirstEntity->state == PJ_PDU_CONSTRUCTED )
1699       {
1700      ret1 =
1701          pjDlmSendDatReq(gCb, pjRbCb, txFirstEntity->count, 
1702                txFirstEntity->pdu);
1703          gCb->pjGenSts.txPdus++;
1704          txFirstEntity->pdu   = NULLP;
1705          txFirstEntity->state = PJ_PDU_SUBMITTED;
1706
1707          txFirstEntity->sduSubmitEnt.node = (PTR)NULLP;
1708          cmLListDelFrm(&pjRbCb->dlCb.txBuf.sduSubmitQ, &txFirstEntity->sduSubmitEnt);
1709
1710          if ((pjRbCb->mode == PJ_DRB_UM ) 
1711                || (!(pjRbCb->dlCb.cfmReqd) && pjRbCb->rbType == PJ_SRB)
1712               || (ret1 != ROK))
1713          {
1714               pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txFirstEntity->count);
1715          }
1716          else
1717          {
1718             /* Add to the DatCfm Q */
1719             txFirstEntity->datCfmEnt.node = (PTR)txEnt;
1720             cmLListAdd2Tail(&pjRbCb->dlCb.txBuf.datCfmQ, &txFirstEntity->datCfmEnt);
1721             pjTotDlPckCntPerCell++;
1722          }
1723          cmLListFirst(&pjRbCb->dlCb.txBuf.sduSubmitQ);
1724       }
1725       else
1726       {
1727          break;
1728       }
1729    }
1730    
1731    RETVALUE(ret);
1732 }
1733 /**
1734 *
1735  * @brief  
1736  * 
1737  *        Handler to construct a process a SRB SDU.
1738  * 
1739  * @b Description: 
1740  * 
1741  *        1. This function performs integrity protection if it is
1742  *        configured.    @n
1743  *        2. The first DL message of SRBs is not ciphered and is just integrity 
1744  *        protected.  @n 
1745  *        3. This function checks the UE CB control block to check the flag for the 
1746  *        first DL message and performs only integrity protection and unsets 
1747  *        the flag.       @n 
1748  *        4. Ciphering is performed if applicable.
1749  *        5. The PDU is constructed and then delivered to the lower
1750  *        layer. @n
1751  *            
1752  *  @param[in] pjRbCb   PDCP control block. 
1753  *  @param[in] txEnt    Transmission Entity.
1754  *                 
1755  *  @return  S16
1756  *      -# ROK 
1757  *      -# RFAILED
1758  *
1759  */
1760
1761
1762 #ifdef ANSI
1763 PUBLIC S16 pjDlmProcSrb
1764 (
1765 PjCb    *gCb,
1766 PjDlRbCb  *pjRbCb,
1767 PjTxEnt *txEnt
1768 )
1769 #else
1770 PUBLIC S16 pjDlmProcSrb(gCb, pjRbCb, txEnt)
1771 PjCb    *gCb;
1772 PjDlRbCb  *pjRbCb;
1773 PjTxEnt *txEnt;
1774 #endif
1775 {
1776    S16             ret;           /* Return Value */
1777    U32             macI;          /* MAC-I value to be padded to the PDU */
1778    Buffer          *pdu;          /* Pointer for the PDU in txEnt */
1779
1780    TRC3(pjDlmProcSrb)
1781 #ifndef ALIGN_64BIT
1782    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmProcSrb(pjRbCb (), txEnt(%ld)) ", 
1783                               txEnt->count);
1784 #else
1785    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmProcSrb(pjRbCb (), txEnt(%d)) ",
1786                               txEnt->count);
1787 #endif
1788
1789
1790    pdu    = txEnt->sdu;
1791    macI   = 0;
1792    ret    = ROK;
1793
1794    /* Perform security operation only if configured */
1795    if ( pjRbCb->ueCb->secInfo.secAct && pjRbCb->ueCb->secInfo.intInfo.algoType != 0)
1796    {
1797       /* Perform integrity/ciphering */
1798       ret = pjDlmHdlIntProt(gCb, pjRbCb, txEnt);
1799       if ( ret != ROK )
1800       {
1801          RLOG_ARG2(L_ERROR, DBG_RBID, pjRbCb->rbId, "Integrity Prot failed SN [%u] TXNEXT [%lu]", txEnt->sn, txEnt->count);
1802       }
1803    }
1804    else
1805    {
1806       /* If security is not configured, pad the PDU with 4 bytes 
1807        * and deliver to the lower layer
1808        */
1809       PJ_PACK_MACI(pdu, macI);
1810       ret = pjDlmHdlCiph(gCb, pjRbCb, txEnt);
1811 /*      ret = pjDlmDeliverPdu(gCb, pjRbCb, txEnt);*/
1812    }
1813
1814    RETVALUE(ret);
1815 }
1816
1817 /**
1818  *
1819  * @brief 
1820  * 
1821
1822  *        Handler to construct a process a DRB SDU.
1823  * 
1824  * @b Description: 
1825  * 
1826  *        1. This function performs header compression if it is
1827  *        configured.    @n
1828  *        2. If security is configured, ciphering is performed. @n
1829  *        3. The PDU is constructed and then delivered to the lower
1830  *        layer. @n
1831  *            
1832  *  @param[in] pjRbCb   PDCP control block. 
1833  *  @param[in] txEnt    Transmission Entity.
1834  *                 
1835  *  @return  S16
1836  *      -# ROK 
1837  *      -# RFAILED
1838  *
1839  */
1840
1841 #ifdef ANSI
1842 PUBLIC S16 pjDlmProcDrb
1843 (
1844 PjCb     *gCb,
1845 PjDlRbCb   *pjRbCb,
1846 PjTxEnt  *txEnt
1847 )
1848 #else
1849 PUBLIC S16 pjDlmProcDrb(gCb,pjRbCb,txEnt)
1850 PjCb     *gCb;
1851 PjDlRbCb   *pjRbCb;
1852 PjTxEnt  *txEnt;
1853 #endif
1854 {
1855    TRC3(pjDlmProcDrb)
1856 #ifndef ALIGN_64BIT
1857    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, 
1858          "pjDlmProcDrb(pjRbCb (), txEnt(%ld)) ", txEnt->count);
1859 #else
1860    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, 
1861          "pjDlmProcDrb(pjRbCb (), txEnt(%d)) ", txEnt->count);
1862 #endif
1863
1864    RETVALUE(pjDlmHdlCmp(gCb, pjRbCb, txEnt));
1865 }
1866
1867 /**
1868  *
1869  * @brief 
1870  * 
1871  *        Handler to process the Integrity Protection Request
1872  * 
1873  * @b Description: 
1874  * 
1875  *        1. This function performs integrity protection
1876  *        of a SDU by prepending the header.    @n
1877  *        2. If ciphering is applicable, it is performed after removing
1878  *        the header. @n
1879  *        3. The PDU is constructed and then delivered to the lower
1880  *        layer. @n
1881  *            
1882  *  @param[in] pjRbCb   PDCP control block. 
1883  *  @param[in] txEnt    Transmission Entity.
1884  *                 
1885  *  @return  S16
1886  *      -# ROK 
1887  *      -# RFAILED
1888  *
1889  */
1890
1891 #ifdef ANSI
1892 PUBLIC S16 pjDlmHdlIntProt
1893 (
1894 PjCb    *gCb,
1895 PjDlRbCb  *pjRbCb,
1896 PjTxEnt *txEnt
1897 )
1898 #else
1899 PUBLIC S16 pjDlmHdlIntProt(gCb,pjRbCb,txEnt)
1900 PjCb    *gCb;
1901 PjDlRbCb  *pjRbCb;
1902 PjTxEnt *txEnt;
1903 #endif
1904 {
1905    S16             ret;           /* Return Value */
1906    U32              hdr;           /* Header Value */
1907 #ifndef TENB_AS_SECURITY
1908    U32             macI = 0;      /* MAC-I value to be padded to the PDU */
1909 #endif
1910    Buffer          *pdu = NULLP;          /* Pointer for the PDU in txEnt */
1911    PjSecInp        secInp;        /* Security Input for Ciphering and Int Prot */
1912
1913    TRC3(pjDlmHdlIntProt)
1914 #ifndef ALIGN_64BIT
1915    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
1916          "pjDlmHdlIntProt(pjRbCb (), txEnt (%ld)) ",   txEnt->count);
1917 #else
1918    RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
1919          "pjDlmHdlIntProt(pjRbCb (), txEnt (%d)) ",  txEnt->count);
1920 #endif
1921
1922    pdu    = txEnt->sdu;
1923
1924    ret    = ROK;
1925    hdr    = 0;
1926
1927    /* If firstDL msg after secCfg, unset the ueCb flag ans set
1928     * rbCb flag and set the SN
1929     */
1930    if (pjRbCb->ueCb->secInfo.selSecAct == TRUE &&
1931             pjRbCb->ueCb->secInfo.firstMsg == TRUE )
1932    {
1933       pjRbCb->firstDlMsg = TRUE;
1934       pjRbCb->firstSn    = txEnt->sn;
1935       pjRbCb->ueCb->secInfo.firstMsg = FALSE;
1936    }
1937    secInp.dir  = PJ_SEC_DIR_DL;
1938    secInp.rbId = pjRbCb->rbId;
1939    secInp.count= txEnt->count;
1940
1941    /* Add the header and then send it for Integrity Protection */
1942    hdr = txEnt->sn;
1943    PJ_ADD_PRE_MSG(pdu, hdr, 2, ret);
1944 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
1945    txEnt->sdu = pdu;
1946 #endif
1947
1948 #if (ERRCLASS & ERRCLS_ADD_RES)
1949    if ( ret != ROK )
1950    {
1951       RLOG1(L_ERROR, "SAddPreMsg failed  Tx Count[%lu]", txEnt->count);
1952       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
1953       if ( pjRbCb->dlCb.cfmReqd)
1954       {
1955          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_REM_MSG_FAILED);
1956       }
1957       RETVALUE(RFAILED);
1958    }
1959 #endif
1960
1961    txEnt->state = PJ_WAIT_FOR_INTPROT;
1962    ret = pjUtlIntProtReq(gCb, pjRbCb, secInp, &pdu);
1963
1964
1965    if ( ret != ROK )
1966    {
1967       RLOG1(L_ERROR, "Integrity Protection Req failed Tx Count[%lu]", txEnt->count);
1968       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
1969       if ( pjRbCb->dlCb.cfmReqd)
1970       {
1971          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJU_INTPROT_FAILED);
1972       }
1973       gCb->pjGenSts.numIntgPrtFails++; 
1974       RETVALUE(RFAILED);
1975    }
1976 #ifdef INTEL_QAT_DP
1977    if (pjRbCb->ueCb->secInfo.intInfo.algoType == 0)
1978 #endif
1979    {
1980 #ifndef PJ_SEC_ASYNC
1981    /* Append the macI at the end */
1982 #ifdef TENB_AS_SECURITY
1983    /*PJ_PACK_MACI(pdu, macI);*/
1984 #else
1985    PJ_PACK_MACI(pdu, macI);
1986 #endif
1987    txEnt->pdu = pdu;
1988 #ifndef TENB_ACC
1989 #ifndef TENB_T2K3K_SPECIFIC_CHANGES 
1990 #ifdef SS_RBUF
1991 //   prc_trace_format_string(0x40,3,"[%ld] ",macI);
1992 #endif
1993 #endif
1994 #endif
1995
1996    /* Remove the header and then only send for ciphering */
1997    ret = SRemPreMsg((Data *)&hdr, txEnt->pdu);
1998 #if (ERRCLASS & ERRCLS_ADD_RES)
1999    if ( ret != ROK )
2000    {
2001       RLOG1(L_ERROR, "SRemPreMsg failed  Tx Count [%lu]", txEnt->count);
2002       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2003       if ( pjRbCb->dlCb.cfmReqd)
2004       {
2005          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_REM_MSG_FAILED);
2006       }
2007       RETVALUE(RFAILED);
2008    }
2009 #endif /* ERRCLASS & ERRCLS_RES */
2010     ret = SRemPreMsg((Data *)&hdr, txEnt->pdu);
2011 #if (ERRCLASS & ERRCLS_ADD_RES)
2012    if ( ret != ROK )
2013    {
2014       RLOG1(L_ERROR, "SRemPreMsg failed  Tx Count [%lu]", txEnt->count);
2015       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2016       if ( pjRbCb->dlCb.cfmReqd)
2017       {
2018          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_REM_MSG_FAILED);
2019       }
2020       RETVALUE(RFAILED);
2021    }
2022 #endif /* ERRCLASS & ERRCLS_RES */
2023
2024    /* If rbCb flag is set => firstDL msg. So skip ciphering */
2025    if ( pjRbCb->firstDlMsg == TRUE  && pjRbCb->firstSn == txEnt->sn)
2026    {
2027       pjRbCb->firstDlMsg = FALSE;
2028 #ifndef SS_RBUF
2029       PJ_FREE_BUF(txEnt->sdu);
2030 #endif 
2031       txEnt->sdu = NULLP;
2032       ret = pjDlmDeliverPdu(gCb, pjRbCb, txEnt);
2033    }
2034    else
2035    {
2036       ret = pjDlmHdlCiph(gCb, pjRbCb, txEnt);
2037    }
2038 #endif
2039    }
2040    RETVALUE(ret);
2041 }
2042
2043
2044 /**
2045  *
2046  * @brief 
2047  *
2048  *        Handler to process NULL Ciphering. 
2049  *
2050  * @b Description: 
2051  *        This function handles the PDU for NULL ciphering.
2052  *            
2053  *  @param[in] gCb      Global control block.
2054  *  @param[in] pjRbCb   RB control block.
2055  *  @param[in] txEnt    Transmission Entity.
2056  *  @return  S16
2057  *      -# ROK 
2058  *      -# RFAILED
2059  */
2060
2061 #ifdef ANSI
2062 PUBLIC S16 pjDlmHdlNullCiph
2063 (
2064 PjCb       *gCb,
2065 PjDlRbCb     *pjRbCb,
2066 PjTxEnt    *txEnt
2067 )
2068 #else
2069 PUBLIC S16 pjDlmHdlNullCiph(gCb,pjRbCb,txEnt)
2070 PjCb       *gCb;
2071 PjDlRbCb     *pjRbCb;
2072 PjTxEnt    *txEnt;
2073 #endif
2074 {
2075    S16            ret;            /* Return Value */
2076
2077    TRC3(pjDlmHdlNullCiph);
2078
2079    ret=ROK;
2080
2081    /* If Ciphering is enabled, txEnt->pdu will point to a mBuf */
2082 #ifdef FLAT_BUFFER_OPT
2083    if(txEnt->sdu == NULLP)
2084    {
2085       ret = pjUtlCopyFbToBuf(gCb, &(txEnt->fb), &(txEnt->pdu));
2086       if (ret != ROK)
2087       {
2088          RLOG1(L_ERROR, "Cpoying to Flat Buf Failed Tx Count [%lu]", txEnt->count);
2089          PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2090          if ( pjRbCb->dlCb.cfmReqd)
2091          {
2092             PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_CPY_MSG_FAILED);
2093          }
2094          RETVALUE(RFAILED);
2095       }
2096    }
2097 #endif
2098
2099    if (txEnt->pdu == NULLP )
2100    {
2101       if ( pjRbCb->mode == PJ_DRB_AM
2102 #if (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))
2103             || pjRbCb->mode == PJ_DRB_UM
2104 #endif
2105          )
2106       {
2107          PJ_CPY_MSG(gCb,txEnt->sdu, &(txEnt->pdu), ret);
2108 #if (ERRCLASS & ERRCLS_ADD_RES)
2109          if (ret != ROK)
2110          {
2111             RLOG1(L_ERROR, "SAddMsgRef Failed Tx Count [%lu]", txEnt->count);
2112
2113             PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2114             if ( pjRbCb->dlCb.cfmReqd)
2115             {
2116                PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_CPY_MSG_FAILED);
2117             }
2118             RETVALUE(RFAILED);
2119          }
2120 #endif
2121       }
2122       else
2123       {
2124          txEnt->pdu = txEnt->sdu;
2125          txEnt->sdu = NULLP;
2126       }
2127    }
2128
2129    RETVALUE(ret);
2130 }
2131
2132 /**
2133  *
2134  * @brief  
2135  * 
2136  *        Handler to process the Compression Request.
2137  * 
2138  * @b Description: 
2139  * 
2140  *        1. This function performs header compression if configured. @n
2141  *        2. If ciphering is applicable, it is performed. @n
2142  *        3. The PDU is constructed and then delivered to the lower
2143  *        layer. @n
2144  *            
2145  *  @param[in] pjRbCb   PDCP control block. 
2146  *  @param[in] txEnt    Transmission Entity.
2147  *                 
2148  *  @return  S16
2149  *      -# ROK 
2150  *      -# RFAILED
2151  *
2152  */
2153
2154
2155 #ifdef ANSI
2156 PUBLIC S16 pjDlmHdlCmp
2157 (
2158 PjCb    *gCb,
2159 PjDlRbCb  *pjRbCb,
2160 PjTxEnt *txEnt
2161 )
2162 #else
2163 PUBLIC S16 pjDlmHdlCmp(gCb,pjRbCb,txEnt)
2164 PjCb    *gCb;
2165 PjDlRbCb  *pjRbCb;
2166 PjTxEnt *txEnt;
2167 #endif
2168 {
2169    S16            ret;         /* Return Value */
2170    Buffer         *opSdu;      /* Pointer for Output of Compression */
2171    U32             macI;          /* MAC-I value to be padded to the PDU */
2172    TRC3(pjDlmHdlCmp)
2173 #ifndef ALIGN_64BIT
2174    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, "pjDlmHdlCmp(pjRbCb (), txEnt (%ld)) ", 
2175             txEnt->count);
2176 #else
2177    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, "pjDlmHdlCmp(pjRbCb (), txEnt (%d)) ",
2178             txEnt->count);
2179 #endif
2180
2181    ret     = ROK;
2182    opSdu   = NULLP;
2183
2184    /* Perform compression if ocnfigured */
2185    if ( pjRbCb->rohc.hdrCmpUsed )
2186    {
2187       txEnt->pdu = txEnt->sdu;
2188       txEnt->state = PJ_WAIT_FOR_CMP;
2189       ret =   pjUtlCmpReq(gCb, pjRbCb, txEnt->pdu, &opSdu, txEnt->count);
2190       if ( ret != ROK )
2191       {
2192
2193          RLOG1(L_ERROR, "Compression Req Failed Tx Count [%lu]", txEnt->count);
2194          PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2195          if ( pjRbCb->dlCb.cfmReqd)
2196          {
2197             PJ_SND_CFM(gCb,pjRbCb, txEnt, PJU_COMP_FAILED);
2198          }
2199          gCb->pjGenSts.numCmpFails++;
2200          RETVALUE(RFAILED);
2201       }
2202 #ifdef PJ_CMP_ASYNC
2203       RETVALUE(ret);
2204 #else
2205       txEnt->pdu = opSdu;
2206 #endif
2207    }
2208    if(pjRbCb->ueCb->secInfo.intProtEnbForDrb)
2209    {
2210       macI   = 0;
2211       PJ_PACK_MACI(txEnt->sdu, macI);
2212    }
2213    /* Perform ciphering if security is configured */
2214    ret = pjDlmHdlCiph(gCb, pjRbCb, txEnt);
2215    RETVALUE(ret);
2216 }
2217
2218 #ifdef LTE_PAL_ENB
2219 /**
2220  *  @brief This fn cheks whether the RING buffer is used and therefore DL pkts
2221  *         need to be enqueued before forwarding it for ciphering.
2222  *         Note: It acts as a dummy fn so far in case of Mindspeed pltfm
2223  *
2224  *  @details
2225  *      Function : pjUtlChekTxEnqReq
2226  *
2227  *          Processing Steps:
2228  *
2229  *
2230  * @return  S16
2231  *        -# Success : ROK
2232  *        -# Failure : RFAILED
2233 */
2234 #ifdef ANSI
2235 PUBLIC S16 pjUtlChekTxEnqReq
2236 (
2237 PjCb       *gCb,
2238 PjDlRbCb   *pjRbCb,
2239 PjTxEnt    *txEnt
2240 )
2241 #else
2242 PUBLIC S16 pjUtlChekTxEnqReq(gCb,pjRbCb, txEnt)
2243 PjCb       *gCb;
2244 PjDlRbCb   *pjRbCb;
2245 PjTxEnt    *txEnt;
2246 #endif
2247 {
2248   RETVALUE(ROK);
2249 }
2250 #endif
2251 /**
2252  * 
2253  * @brief  
2254  * 
2255  *        Handler to process the Ciphering Request.
2256  * 
2257  * @b Description: 
2258  * 
2259  *        1. This function performs ciphering.  @n
2260  *        2. If asynchronous flag is defined, the function returns . @n
2261  *        3. Else the function updates the PDU field in txEnt and returns. @n 
2262  *            
2263  *  @param[in] pjRbCb   PDCP control block. 
2264  *  @param[in] txEnt    Transmission Entity.
2265  *                 
2266  *  @return  S16
2267  *      -# ROK 
2268  *      -# RFAILED 
2269  *
2270  */
2271 #ifdef ANSI
2272 PUBLIC S16 pjDlmHdlCiph
2273 (
2274 PjCb    *gCb,
2275 PjDlRbCb  *pjRbCb,
2276 PjTxEnt *txEnt
2277 )
2278 #else
2279 PUBLIC S16 pjDlmHdlCiph(gCb,pjRbCb,txEnt)
2280 PjCb    *gCb;
2281 PjDlRbCb  *pjRbCb;
2282 PjTxEnt *txEnt;
2283 #endif
2284 {
2285    S16            ret;         /* Return Value */
2286    Buffer         *ciphSdu;    /* Pointer for Output of Ciphering */
2287    PjSec *secInfo;
2288
2289    TRC3(pjDlmHdlCiph)
2290 #ifndef SS_RBUF
2291 #ifndef TENB_ACC
2292    pjUtlChekTxEnqReq(gCb, pjRbCb, txEnt);
2293 #endif   
2294 #if CIPH_BATCH_PROC
2295    RETVALUE(ROK);
2296 #endif
2297 #endif
2298 #ifndef ALIGN_64BIT
2299    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, "pjDlmHdlCiph(pjRbCb (), txEnt (%ld)) ", 
2300             txEnt->count);
2301 #else
2302    RLOG_ARG1(L_UNUSED,DBG_RBID,pjRbCb->rbId, "pjDlmHdlCiph(pjRbCb (), txEnt (%d)) ",
2303             txEnt->count);
2304 #endif
2305    ret     = ROK;
2306    ciphSdu = NULLP;
2307 #ifndef L2_PDCP_OPTMZ
2308 txEnt->state  = PJ_WAIT_FOR_CIPHER;
2309 #endif
2310
2311
2312    secInfo = &(pjRbCb->ueCb->secInfo);
2313
2314    if ( secInfo->secAct && secInfo->cipherInfo.algoType != 0)   /* If its not NULL Ciphering and Security is enabled */
2315    {
2316       if ( txEnt->pdu == NULLP )
2317       {
2318          txEnt->pdu = txEnt->sdu;
2319       }
2320       /* Note: FB is only for DRB data in DL direction. SRB data after  */
2321       /* integrity protection will use the NON-FB version of code.      */
2322       /* The below "if" check is to identify whether it is for SRB data */
2323       /* or DRB data.                                                   */
2324 #ifdef CIPH_BATCH_PROC
2325 #ifndef TENB_ACC
2326    pjUtlChekTxEnqReq(gCb, pjRbCb, txEnt);
2327 #endif  
2328    RETVALUE(ROK);
2329 #endif
2330
2331 #ifdef FLAT_BUFFER_OPT
2332       if (txEnt->sdu == NULLP)
2333       {
2334           ret = pjUtlCipherReqFB(gCb, pjRbCb, txEnt->count, &(txEnt->fb), &ciphSdu);         
2335       }
2336       else
2337 #endif
2338       {
2339          ret = pjUtlCipherReq(gCb, pjRbCb, txEnt->count, txEnt->pdu, &ciphSdu);
2340       }
2341
2342       /*There can be failures in creating the input for SPACC*/
2343       if ( ret != ROK )
2344       {
2345          RLOG1(L_ERROR, "Ciphering Req failed Tx Count [%lu]", txEnt->count);
2346          PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2347          if ( pjRbCb->dlCb.cfmReqd)
2348          {
2349             PJ_SND_CFM(gCb,pjRbCb, txEnt, PJU_CIPHER_FAILED);
2350          }
2351          gCb->pjGenSts.numCiphFails++;
2352          RETVALUE(RFAILED);
2353       }
2354 #ifdef INTEL_SW_SEC
2355        if(ciphSdu)
2356        {
2357            //printf("Ciphered PDU\n");
2358            //SPrntMsg(ciphSdu,0,0);
2359            if(txEnt->pdu)
2360            {
2361               PJ_FREE_BUF(txEnt->pdu);
2362            }
2363            txEnt->pdu = ciphSdu;
2364        }
2365        else
2366        {
2367            PJLOGERROR(gCb, ERRCLS_ADD_RES, EPJXXX, (ErrVal)sduId,
2368                    "pjSendToSwCipherFB:Ciphering failed for txEnt\n");
2369            pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count);
2370            RETVALUE(RFAILED);
2371        }
2372 #endif
2373
2374 #ifdef TENB_AS_SECURITY
2375       if(isSecBatchMode)
2376       {
2377          txEnt->state = PJ_PDU_SUBMITTED;
2378 #ifdef L2_PDCP_OPTMZ      
2379   /* Delete Tx entity in case of UM mode*/
2380    if (pjRbCb->mode == PJ_DRB_UM ) 
2381    {
2382       pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count);
2383    }
2384 #endif    
2385          RETVALUE(ret);
2386       }
2387       else
2388 #endif
2389       {
2390          txEnt->pdu = ciphSdu;
2391       }
2392
2393    }
2394    else
2395    {
2396 #ifdef L2_PDCP_OPTMZ      
2397    txEnt->state  = PJ_WAIT_FOR_CIPHER;
2398 #endif
2399
2400 #ifdef SS_RBUF
2401       txEnt->pdu = NULLP;
2402 #endif
2403       ret = pjDlmHdlNullCiph(gCb, pjRbCb, txEnt);
2404    }
2405
2406    txEnt->state = PJ_PDU_SUBMITTED;
2407    ret = pjDlmDeliverPdu(gCb, pjRbCb, txEnt);
2408   
2409   
2410    RETVALUE(ROK);
2411 }
2412
2413 #ifdef FLAT_BUFFER_OPT
2414 /**
2415  * 
2416  * @brief  
2417  * 
2418  *        Handler to process the Ciphering Request.
2419  * 
2420  * @b Description: 
2421  * 
2422  *        1. This function performs ciphering.  @n
2423  *        2. If asynchronous flag is defined, the function returns . @n
2424  *        3. Else the function updates the PDU field in txEnt and returns. @n 
2425  *            
2426  *  @param[in] pjRbCb   PDCP control block. 
2427  *  @param[in] txEnt    Transmission Entity.
2428  *                 
2429  *  @return  S16
2430  *      -# ROK 
2431  *      -# RFAILED 
2432  *
2433  */
2434
2435 #ifdef ANSI
2436 PUBLIC S16 pjDlmHdlCiphFB
2437 (
2438 PjCb    *gCb,
2439 PjDlRbCb  *pjRbCb,
2440 PjTxEnt *txEnt
2441 )
2442 #else
2443 PUBLIC S16 pjDlmHdlCiphFB(gCb,pjRbCb,txEnt)
2444 PjCb    *gCb;
2445 PjDlRbCb  *pjRbCb;
2446 PjTxEnt *txEnt;
2447 #endif
2448 {
2449    S16            ret;         /* Return Value */
2450    Buffer         *ciphSdu;    /* Pointer for Output of Ciphering */
2451
2452    TRC3(pjDlmHdlCiphFB)
2453 #ifndef ALIGN_64BIT
2454    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
2455            (gCb->init.prntBuf, "pjDlmHdlCiphFB(pjRbCb (%d), txEnt (%ld)) \n", 
2456            pjRbCb->rbId, txEnt->count));
2457 #else
2458    PJDBGP(gCb,(PJ_DBGMASK_DLM | PJ_DBGMASK_BRIEF | PJ_DBGMASK_DL),
2459            (gCb->init.prntBuf, "pjDlmHdlCiphFB(pjRbCb (%d), txEnt (%d)) \n",
2460            pjRbCb->rbId, txEnt->count));
2461 #endif
2462    ret     = ROK;
2463    ciphSdu = NULLP;
2464
2465    txEnt->state  = PJ_WAIT_FOR_CIPHER;
2466    ret = pjUtlCipherReqFB(gCb, pjRbCb, txEnt->count, &(txEnt->fb), &ciphSdu);
2467
2468    /*There can be failures in creating the input for SPACC*/
2469    if ( ret != ROK )
2470    {
2471       RLOG1(L_ERROR, "Ciphering Req failed Tx Count [%lu]", txEnt->count);
2472       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2473       if ( pjRbCb->dlCb.cfmReqd)
2474       {
2475          PJ_SND_CFM(gCb,pjRbCb, txEnt, PJU_CIPHER_FAILED);
2476       }
2477       gCb->pjGenSts.numCiphFails++;
2478       RETVALUE(RFAILED);
2479    }
2480
2481    
2482    txEnt->state = PJ_PDU_SUBMITTED;
2483
2484
2485    RETVALUE(ROK);
2486 }
2487 #endif
2488
2489
2490 /**
2491  *
2492  * @brief
2493  *
2494  *  @param[in] pjRbCb   PDCP control block.
2495     @param[in] PjRxEnt  *rxEnt
2496  *
2497  *  @return  Void
2498  */
2499
2500 #ifdef ANSI
2501 PUBLIC Void pjDlmEnqueueDlPkt
2502 (
2503 PjCb               *gCb, 
2504 PjDlRbCb           *pjRbCb,          /* !< PDCP Control Block */
2505 U8                 datType,
2506 PjuDatFwdReqInfo   *datFwd,          /* !< SN value of PDU */
2507 PjuSduId           sduId,
2508 Buffer             *pdu              /* !< PDU message buffer */
2509 )
2510 #else
2511 PUBLIC Void pjDlmEnqueueDlPkt(gCb,pjRbCb,datType,datFwd,suId,pdu)
2512 PjCb               *gCb; 
2513 PjDlRbCb           *pjRbCb;          /* !< PDCP Control Block */
2514 U8                 datType;
2515 PjuDatFwdReqInfo   *datFwd;               /* !< SN value of PDU */
2516 PjuSduId           sduId;
2517 Buffer             *pdu;             /* !< PDU message buffer */
2518 #endif
2519 {
2520    PjDlPkt    *pkt;
2521    U32          numSdu;
2522
2523    TRC2(pjDlmEnqueueDlPkt)
2524
2525    if (datType == PJ_DATA_FWD_PKT)
2526    {
2527       for (numSdu=0; numSdu < datFwd->numSdus; numSdu++)
2528       {
2529           PJ_ALLOC(gCb, pkt, sizeof(PjDlPkt));
2530           if (pkt != NULLP)
2531           {
2532              pkt->type     = datType;
2533              pkt->sn       = datFwd->datFwdInfo[numSdu].sn; 
2534              pkt->sduId    = datFwd->datFwdInfo[numSdu].sduId;
2535              pkt->pdu      = datFwd->datFwdInfo[numSdu].sdu;
2536              pkt->lnk.node = (PTR)pkt;
2537              cmLListAdd2Tail (&pjRbCb->dlCb.dlPktQ, &pkt->lnk);
2538           }
2539       }
2540    }
2541    else
2542    {
2543       PJ_ALLOC(gCb, pkt, sizeof(PjDlPkt));
2544       if (pkt != NULLP)
2545       {
2546          pkt->type = datType;
2547          pkt->pdu = pdu;
2548          pkt->sduId = sduId;
2549          pkt->lnk.node = (PTR)pkt;
2550          cmLListAdd2Tail (&pjRbCb->dlCb.dlPktQ, &pkt->lnk);
2551       }
2552       else
2553       {
2554          RLOG0(L_FATAL, "Memory Allocation failed.");
2555          PJ_FREE_BUF(pdu);
2556       }
2557    }
2558
2559    RETVOID;
2560 }/* end of pjDlmEnqueueHoPkt */
2561
2562 #ifdef FLAT_BUFFER_OPT
2563 /**
2564  *
2565  * @brief
2566  *
2567  *  @param[in] pjRbCb   PDCP control block.
2568     @param[in] PjRxEnt  *rxEnt
2569  *
2570  *  @return  Void
2571  */
2572 #ifdef ANSI
2573 PUBLIC Void pjDlmEnqueueDlPktFB
2574 (
2575 PjCb               *gCb, 
2576 PjDlRbCb           *pjRbCb,          /* !< PDCP Control Block */
2577 U8                 datType,
2578 PjuDatFwdReqInfo   *datFwd,          /* !< SN value of PDU */
2579 PjuSduId           sduId,
2580 FlatBuffer         *pdu             /* !< Flat Buffer PDU */ 
2581 )
2582 #else
2583 PUBLIC Void pjDlmEnqueueDlPktFB(gCb,pjRbCb,datType,datFwd,suId,pdu)
2584 PjCb               *gCb; 
2585 PjDlRbCb           *pjRbCb;          /* !< PDCP Control Block */
2586 U8                 datType;
2587 PjuDatFwdReqInfo   *datFwd;               /* !< SN value of PDU */
2588 PjuSduId           sduId;
2589 FlatBuffer         *pdu;             /* !< Flat Buffer PDU */ 
2590 #endif
2591 {
2592    PjDlPkt    *pkt;
2593
2594    TRC2(pjDlmEnqueueDlPktFB)
2595
2596    if (datType == PJ_DATA_FWD_PKT)
2597    {
2598       /* printf("pjDlmEnqueueDlPktFB: datType = PJ_DATA_FWD_PKT. TODO !!!!! "); */
2599    }
2600    else
2601    {
2602       PJ_ALLOC(gCb, pkt, sizeof(PjDlPkt));
2603       if (pkt != NULLP)
2604       {
2605          pkt->type = datType;
2606          pkt->fb.startAddr = pdu->startAddr;
2607          pkt->fb.ptr = pdu->ptr;
2608          pkt->fb.len = pdu->len;
2609          pkt->pdu = NULLP;
2610          pkt->sduId = sduId;
2611          pkt->lnk.node = (PTR)pkt;
2612          cmLListAdd2Tail (&pjRbCb->dlCb.dlPktQ, &pkt->lnk);
2613          /*printf("pjDlmEnqueueDlPktFB: Enqueue DL Flat Buffer Packets. Sdu Id is %d ",
2614  pkt->sduId);*/
2615       }
2616       else
2617       {
2618          RLOG0(L_FATAL, "Memory Allocation failed.");
2619          PJ_FREE_FLAT_BUF(gCb, pdu);
2620       }
2621    }
2622
2623    RETVOID;
2624 }/* end of pjDlmEnqueueDlPktFB */
2625 #endif
2626
2627 /**
2628  *
2629  * @brief It processes the packets queued up in DLPktQ
2630  *
2631  * @Description
2632  *      This DlPktQ queues the Normal and forwarded message during
2633  *      reestablishment/handover. 
2634  *
2635  *  @param[in] pjCb     PDCP Instance control block.
2636  *  @param[in] pjRbCb   Rb Control block 
2637  *
2638  *  @return  Void
2639  */
2640 #ifdef ANSI
2641 PUBLIC Void pjDlmProcessDlPktQ
2642 (
2643 PjCb       *gCb,
2644 PjDlRbCb   *pjRbCb           /* !< PDCP Control Block */
2645 )
2646 #else
2647 PUBLIC Void pjDlmProcessDlPktQ(gCb, pjRbCb)
2648 PjCb       *gCb;
2649 PjDlRbCb   *pjRbCb;          /* !< PDCP Control Block */
2650 #endif
2651 {
2652    PjDlPkt *pkt;
2653    CmLList *node;
2654    S16     ret;   /*KW_FIX*/
2655
2656    TRC2(pjDlmProcessDlPktQ)
2657
2658    /* first send the status report if any enqueued */
2659
2660    if (pjRbCb->dlCb.staRep != NULL)
2661    {
2662       pjDlmSendDatReq(gCb, pjRbCb, 0xffffffff, pjRbCb->dlCb.staRep);
2663       pjRbCb->dlCb.staRep = NULL;
2664    }
2665
2666    CM_LLIST_FIRST_NODE(&(pjRbCb->dlCb.dlPktQ), node);
2667    while (node != NULLP)
2668    {
2669       pkt = (PjDlPkt *) node->node;
2670       if (pkt->type == PJ_DATA_FWD_PKT)
2671       {
2672          PjuDatFwdReqInfo datFwdReq;
2673          PjuDatFwdInfo     datFwd;
2674          datFwdReq.numSdus = 1;
2675          datFwd.sn =  pkt->sn;
2676          datFwd.sdu = pkt->pdu;
2677          datFwd.sduId = pkt->sduId;
2678          datFwdReq.datFwdInfo = &datFwd;
2679          pjDlmHndlDatFwdReq(gCb, pjRbCb, &datFwdReq);
2680       }
2681       else
2682       {
2683
2684
2685 #ifdef FLAT_BUFFER_OPT
2686 #ifndef XEON_SPECIFIC_CHANGES
2687          {
2688              /* Check whether the spacc q has space to hold
2689              this packet.. else dropping */
2690              if(FALSE == (pjMsCheckSpaccQueue(FALSE)))
2691              {
2692                 PJ_FREE_FLAT_BUF(pjCb[1],&(pkt->fb));
2693                 gPdcpStats.numPdcpSdusDiscarded++;
2694                 PJ_UPD_L2_DLDISC_STS(pjCb[1], pjRbCb);
2695
2696                 cmLListDelFrm(&(pjRbCb->dlCb.dlPktQ), node);
2697                 PJ_FREE(gCb, pkt, sizeof (PjDlPkt));
2698                 node = NULLP;
2699                 CM_LLIST_FIRST_NODE(&(pjRbCb->dlCb.dlPktQ), node);
2700                 continue;
2701              }
2702          }
2703 #endif
2704          if((pkt->fb.len !=0) && (pkt->fb.ptr != NULLP))
2705          {
2706             ret = pjDlmProcessSdusFB(gCb, pjRbCb, &(pkt->fb), pkt->sduId, pjRbCb->dlCb.txNext);
2707          }
2708          else
2709 #endif
2710          {
2711             ret = pjDlmProcessSdus(gCb, pjRbCb, pkt->pdu, pkt->sduId, pjRbCb->dlCb.txNext);
2712          }
2713          if ( ret != ROK )
2714          {
2715 #if (ERRCLASS & ERRCLS_INT_PAR)
2716              RLOG_ARG1(L_ERROR, DBG_RBID, pjRbCb->rbId, "Processing of SDU [%lu] failed", pkt->sduId);
2717 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2718          }
2719       }
2720
2721       cmLListDelFrm(&(pjRbCb->dlCb.dlPktQ), node);
2722       PJ_FREE(gCb, pkt, sizeof (PjDlPkt));
2723       node = NULLP;
2724       CM_LLIST_FIRST_NODE(&(pjRbCb->dlCb.dlPktQ), node);
2725   }
2726
2727    RETVOID;
2728 }/* end of pjDlmProcessDlPktQ */
2729
2730
2731
2732
2733 #if (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))
2734 /**
2735  *
2736  * @brief Handler for  downlink off-board timer expiry.
2737  *       
2738  *
2739  * @b Description
2740  *        This function is called when the off-board timer expires.
2741  *        This function discards the txEnt of dlCb.obdCount if it is 
2742  *        is not submitted and sends the constructed PDUs to the lower
2743  *        layer and start the timer for the next valid txEnt.
2744  *
2745  *  @param[in] pjRbCb    PDCP control block.
2746  *
2747  * 
2748  *  @return  S16
2749  *      -# ROK 
2750  */
2751 #ifdef ANSI
2752 PUBLIC S16 pjDlmObdTmrExp
2753 (
2754 PjCb   *gCb,
2755 PjDlRbCb *pjRbCb
2756 )
2757 #else
2758 PUBLIC S16 pjDlmObdTmrExp(gCb, pjRbCb)
2759 PjCb    *gCb;
2760 PjDlRbCb  *pjRbCb;
2761 #endif
2762 {
2763    U32           count;
2764    U32           curCount;
2765    PjTxEnt       *txEnt;
2766    PjuDatCfmInfo *datCfm;
2767    S16           ret;
2768
2769    TRC3(pjDlmObdTmrExp)
2770    
2771    RLOG_ARG0(L_DEBUG,DBG_RBID,pjRbCb->rbId, "pjDlmObdTmrExp(pjRbCb()) ");
2772
2773    count      = pjRbCb->dlCb.obdCount;
2774    curCount   = pjRbCb->dlCb.count;
2775    txEnt      = pjDbmGetTxEnt(gCb, &(pjRbCb->dlCb.txBuf), count);
2776    datCfm     = NULLP;
2777    ret        = ROK;
2778
2779    if ( txEnt && txEnt->state != PJ_PDU_SUBMITTED )
2780    {
2781 #ifndef ALIGN_64BIT
2782       RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
2783             "pjDlmObdTmrExp(pjRbCb()) : discarding txEnt withcount(%ld)",
2784                          txEnt->count);
2785 #else
2786       RLOG_ARG1(L_DEBUG,DBG_RBID,pjRbCb->rbId, 
2787             "pjDlmObdTmrExp(pjRbCb()) : discarding txEnt withcount(%d)",
2788                          txEnt->count);
2789 #endif
2790       PJ_UPD_DL_VAR(gCb, pjRbCb, txEnt->count);
2791       PJ_SND_CFM(gCb,pjRbCb, txEnt, PJ_OBD_TIMEOUT);
2792       gCb->pjGenSts.numSdusDiscObdTmrExp++;
2793       count++;
2794       while ( count <= curCount )
2795       {
2796          txEnt = pjDbmGetTxEnt(gCb, &(pjRbCb->dlCb.txBuf), count);
2797          if ( txEnt != NULLP )
2798          {
2799             if ( txEnt->state == PJ_PDU_CONSTRUCTED )
2800             {
2801                ret = pjDlmDeliverPdu(gCb, pjRbCb, txEnt);
2802                count = pjRbCb->dlCb.nxtToSub;
2803             }
2804             break;
2805          }
2806          else
2807          {
2808             PJ_UPD_DL_VAR(gCb, pjRbCb, count);
2809          }
2810          count++;
2811       }
2812    }
2813    else
2814    {
2815       count = pjRbCb->dlCb.nxtToSub;
2816    }
2817    if ( pjDbmGetTxEnt(gCb, &(pjRbCb->dlCb.txBuf), count) != NULLP )
2818    {
2819       pjRbCb->dlCb.obdCount = count;
2820       pjStartTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR);
2821    }
2822
2823    RETVALUE(ret);
2824 }
2825
2826 #endif
2827
2828 /*@}*/
2829 /********************************************************************30**
2830  *          End of file
2831 **********************************************************************/