E2AP review changes part1
[o-du/l2.git] / src / 5gnrrlc / kw_lim.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**
20   
21      Name:    LTE-RLC Layer - Lower Interface Functions
22     
23      Type:    C file
24   
25      Desc:     Source code for RLC Lower Interface Module.
26                This file contains following functions
27       
28         --KwLiRguBndCfm
29         --KwLiRguCDatInd
30         --KwLiRguDDatInd
31         --KwLiRguCStaInd
32         --KwLiRguDStaInd
33         --KwLiRguHqStaInd
34
35      File:     kw_lim.c
36
37 **********************************************************************/
38 static const char* RLOG_MODULE_NAME="LIM";
39 static int RLOG_MODULE_ID=2048;
40 static int RLOG_FILE_ID=196;
41
42 /** 
43  * @file kw_lim.c
44  * @brief RLC Lower Interface module
45 */
46
47 #define KW_MODULE KW_DBGMASK_INF
48
49 \f
50 /* header (.h) include files */
51 #include "envopt.h"        /* environment options */
52 #include "envdep.h"        /* environment dependent */
53 #include "envind.h"        /* environment independent */
54
55 #include "gen.h"           /* general */
56 #include "ssi.h"           /* system services */
57 #include "cm5.h"           /* common timer defines */
58 #include "cm_tkns.h"       /* common tokens defines */
59 #include "cm_mblk.h"       /* common memory allocation library defines */
60 #include "cm_llist.h"      /* common link list  defines  */
61 #include "cm_hash.h"       /* common hash list  defines */
62 #include "cm_lte.h"        /* common LTE defines */
63 #include "lkw.h"           /* LKW defines */
64 #include "ckw.h"           /* CKW defines */
65 #include "kwu.h"           /* KWU defines */
66 #include "rgu.h"           /* RGU defines */
67 #include "kw_err.h"
68 #include "kw_env.h"        /* RLC environment options */
69
70 #include "kw.h"            /* RLC defines */
71 #include "kw_udx.h"
72 #include "kw_dl.h"
73 #include "kw_ul.h"
74
75 /* extern (.x) include files */
76 #include "gen.x"           /* general */
77 #include "ssi.x"           /* system services */
78
79 #include "cm5.x"           /* common timer library */
80 #include "cm_tkns.x"       /* common tokens */
81 #include "cm_mblk.x"       /* common memory allocation */
82 #include "cm_llist.x"      /* common link list */
83 #include "cm_hash.x"       /* common hash list */
84 #include "cm_lte.x"        /* common LTE includes */
85 #include "cm_lib.x"        /* common memory allocation library */
86 #include "lkw.x"           /* LKW */
87 #include "ckw.x"           /* CKW */
88 #include "kwu.x"           /* KWU */
89 #include "rgu.x"           /* RGU */
90
91 #include "kw.x"
92 #include "kw_udx.x"
93 #include "kw_dl.x"
94 #include "kw_ul.x"
95
96 #ifdef __cplusplus
97 EXTERN "C" {
98 #endif /* __cplusplus */
99
100 \f
101 /*****************************************************************************
102  *                          RGU INTERFACE
103  ****************************************************************************/
104 /**
105  * @brief Handler for bind confirmation from MAC.
106  *
107  * @details
108  *    This function handles the bind confirmation received from MAC. If the 
109  *    bind was successful changes the state of the SAP to KW_SAP_BND 
110  *    else KW_SAP_CFG. Sends an alarm to LM in any case
111  *
112  * @param[in] pst     Post structure
113  * @param[in] suId    Service User ID
114  * @param[in] status  Status whether the bind was successful or not
115  *
116  * @return  S16
117  *    -# ROK 
118  *    -# RFAILED 
119  *
120 */
121 #ifdef ANSI
122 PUBLIC S16 KwLiRguBndCfm
123 (
124 Pst    *pst,   
125 SuId   suId, 
126 U8     status 
127 )
128 #else
129 PUBLIC S16 KwLiRguBndCfm (pst, suId, status)
130 Pst    *pst; 
131 SuId   suId;
132 U8     status;
133 #endif
134 {
135    U16          event;     /* Event */
136    U16          cause;     /* Cause */
137    KwRguSapCb   *rguSap;   /* RGU SAP Control Block */
138    KwCb         *tKwCb;
139
140    TRC3(KwLiRguBndCfm)
141
142 #if (ERRCLASS & ERRCLS_INT_PAR)
143    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
144    {
145       RETVALUE (RFAILED);
146    }
147 #endif
148    tKwCb = KW_GET_KWCB(pst->dstInst);
149
150    RLOG2(L_DEBUG,"KwLiRguBndCfm(suId(%d), status(%d)", suId, status);
151
152 #if (ERRCLASS & ERRCLS_INT_PAR)
153    if (tKwCb->init.cfgDone != TRUE)
154    {
155       RLOG0(L_FATAL,"General configuration not done");
156       
157       KW_SEND_SAPID_ALARM(tKwCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
158
159       RETVALUE(RFAILED);
160    }
161
162    if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
163    {
164       RLOG0(L_ERROR, "Invalid suId");
165       
166       KW_SEND_SAPID_ALARM(tKwCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
167
168       RETVALUE(RFAILED);
169    }
170 #endif /* ERRCLASS & ERRCLS_INT_PAR */
171
172    rguSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
173             &(tKwCb->u.dlCb->rguDlSap[suId]) : &(tKwCb->u.ulCb->rguUlSap[suId]);
174
175    RLOG1(L_DEBUG, "KwLiRguBndCfm: For RGU SAP state=%d", rguSap->state)
176
177    switch (rguSap->state)
178    {
179       case KW_SAP_BINDING:
180       {
181          kwStopTmr (tKwCb,(PTR)rguSap, KW_EVT_WAIT_BNDCFM);
182
183          rguSap->retryCnt = 0;
184           
185          if (status == CM_BND_OK)
186          {
187             rguSap->state = KW_SAP_BND;
188             event = LCM_EVENT_BND_OK;
189             cause = LKW_CAUSE_SAP_BNDENB;
190          }
191          else
192          {
193             rguSap->state = KW_SAP_CFG;
194             event = LCM_EVENT_BND_FAIL;
195             cause = LKW_CAUSE_UNKNOWN;
196          }
197
198          break;
199       }
200       default:
201          event = LKW_EVENT_RGU_BND_CFM;
202          cause = LCM_CAUSE_INV_STATE;
203          break;
204    }
205
206    /* Send an alarm with proper event and cause */
207    KW_SEND_SAPID_ALARM(tKwCb, suId, event, cause);
208
209    RETVALUE(ROK);
210 } /* KwLiRguBndCfm */
211
212 /**
213  * @brief Handler to process PDU received from MAC
214  *
215  * @details
216  *    This function receives the PDU from MAC.
217  *    seggregates common and dedicated logical channel
218  *    PDU and call respective handler.
219  *
220  * @param[in] pst     Post structure
221  * @param[in] suId    Service User ID
222  * @param[in] datInd  Data Indication Information 
223  *
224  * @return  S16
225  *    -# ROK 
226  *    -# RFAILED 
227  *
228 */
229
230 PUBLIC S16 RlcMacProcUlData(Pst *pst, SuId suId, RlcMacData *ulData)
231 {
232    U8              idx;
233    U8              lcId;                    /* Logical Channel */
234    U8              numDLch = 0;             /* Number of dedicated logical channel */
235    Bool            dLchPduPres;             /* PDU received on dedicated logical channel */
236    RguLchDatInd    dLchData[RGU_MAX_LC];  /* PDU info on dedicated logical channel */
237    RguDDatIndInfo  dLchUlDat;               /* UL data on dedicated logical channel */
238    RguCDatIndInfo  cLchUlDat;               /* UL data on common logical channel */
239
240    /* Initializing dedicated logical channel Database */
241    for(idx = 0; idx < RGU_MAX_LC; idx++)
242    {
243       dLchData[idx].lcId = idx;
244       dLchData[idx].pdu.numPdu = 0;
245    }
246    
247    dLchPduPres = FALSE;
248   
249    /* Seggregate PDUs received on common and dedicated channels
250     * and call common channel's handler */
251    for(idx = 0; idx< ulData->nmbPdu; idx++)
252    {
253       if(ulData->pduInfo[idx].commCh)
254       {
255          cmMemset((U8*)&cLchUlDat, (U8)0, sizeof(RguCDatIndInfo));
256        
257          cLchUlDat.cellId = ulData->cellId;
258          cLchUlDat.rnti   = ulData->rnti;
259          cLchUlDat.lcId   = ulData->pduInfo[idx].lcId;
260          cLchUlDat.pdu    = ulData->pduInfo[idx].pduBuf;
261          
262          KwLiRguCDatInd(pst, suId, &cLchUlDat);
263       } 
264       else
265       {
266          if(!dLchPduPres)
267          {
268             dLchPduPres = TRUE;
269          }
270
271          lcId = ulData->pduInfo[idx].lcId;
272          dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu] = ulData->pduInfo[idx].pduBuf;
273          dLchData[lcId].pdu.numPdu++; 
274       }
275    }
276  
277    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
278     * and call its handler */ 
279    if(dLchPduPres)
280    {
281       dLchUlDat.cellId = ulData->cellId;
282       dLchUlDat.rnti   = ulData->rnti;
283
284       for(idx = 0; idx < RGU_MAX_LC; idx++)
285       {
286          if(dLchData[idx].pdu.numPdu)
287          {
288             cmMemcpy((U8 *)&dLchUlDat.lchData[numDLch], (U8 *)&dLchData[idx], sizeof(RguLchDatInd));
289             numDLch++;      
290          }
291       }
292       dLchUlDat.numLch = numDLch;
293       KwLiRguDDatInd(pst, suId, &dLchUlDat);
294    }
295
296    RETVALUE(ROK);
297    
298 }/* End of RlcMacProcUlData */
299
300 PUBLIC int   rlcDDatIndRcvd;
301 PUBLIC int   rlcCDatIndRcvd;
302 /**
303  * @brief Handler to process PDU received from MAC for common logical channels. 
304  *
305  * @details
306  *    This function receives the PDU from MAC for common logical channels
307  *    does checks before handing over the PDU to the TM module
308  *
309  * @param[in] pst     Post structure
310  * @param[in] suId    Service User ID
311  * @param[in] datInd  Data Indication Information 
312  *
313  * @return  S16
314  *    -# ROK 
315  *    -# RFAILED 
316  *
317 */
318 #ifdef ANSI
319 PUBLIC S16 KwLiRguCDatInd
320 (
321 Pst              *pst,   
322 SuId             suId,  
323 RguCDatIndInfo   *datInd
324 )
325 #else
326 PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd)
327 Pst              *pst; 
328 SuId             suId;
329 RguCDatIndInfo   *datInd;
330 #endif
331 {
332    KwUlRbCb   *rbCb; 
333    KwCb       *tKwCb; 
334
335    rlcCDatIndRcvd++;
336    TRC3(KwLiRguCDatInd)
337
338 #if (ERRCLASS & ERRCLS_INT_PAR)
339    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
340    {
341       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
342       RETVALUE (RFAILED);
343    }
344 #endif
345
346    tKwCb = KW_GET_KWCB(pst->dstInst);
347
348
349 #if (ERRCLASS & ERRCLS_DEBUG)
350    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
351    {
352       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
353       RETVALUE(RFAILED);
354    }
355 #endif
356
357    /* kw006.201 ccpu00120058, Added array boundary condition check */
358 #if (ERRCLASS & ERRCLS_DEBUG)
359    if(KW_MAX_LCH_PER_CELL <= datInd->lcId)
360    {
361       RLOG_ARG1(L_ERROR,DBG_LCID,datInd->lcId, "Invalid LcId, Max is [%d]",
362          KW_MAX_LCH_PER_CELL);
363       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
364       RETVALUE(RFAILED);
365    }
366 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
367
368    /* Fetch RbCb from lcId */
369    kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb);
370    if (!rbCb)
371    {
372       RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found",
373          datInd->lcId);
374       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
375       RETVALUE(RFAILED);
376    }
377
378    /* Dispatch to TM Module */
379 #ifdef CCPU_OPT
380    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu);
381 #else /* CCPU_OPT */
382    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu);
383 #endif /* CCPU_OPT */
384
385    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
386
387    RETVALUE(ROK);
388 } /* KwLiRguCDatInd */
389
390 /**
391  * @brief Handler to process PDU received from MAC for 
392  *        dedicated logical channels. 
393  *
394  * @details
395  *    This function receives the PDU from MAC for one or more dedicated 
396  *    logical channels and passes it to the UTL module for further processing
397  *
398  * @param[in] pst     Post structure
399  * @param[in] suId    Service User ID
400  * @param[in] datInd  Data Indication Information 
401  *
402  * @return  S16
403  *    -# ROK 
404  *    -# RFAILED 
405  *
406 */
407  
408 #ifdef ANSI
409 PUBLIC S16 KwLiRguDDatInd
410 (
411 Pst              *pst,   
412 SuId             suId,  
413 RguDDatIndInfo   *datInd
414 )
415 #else
416 PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd)
417 Pst              *pst; 
418 SuId             suId;
419 RguDDatIndInfo   *datInd;
420 #endif
421 {
422    TRC3(KwLiRguDDatInd)
423
424    rlcDDatIndRcvd++;
425 #if (ERRCLASS & ERRCLS_INT_PAR)
426    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
427    {
428        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
429        RETVALUE (RFAILED);
430    }
431 #endif
432
433 #if (ERRCLASS & ERRCLS_DEBUG)
434    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
435    {
436        RLOG1(L_DEBUG,"KwLiRguDDatInd(pst, suId(%d))recieved in DL Inst",suId);
437        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
438        RETVALUE(RFAILED);
439    }
440 #endif
441    kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd);
442 #ifndef SS_RBUF 
443 #ifdef SS_LOCKLESS_MEMORY
444    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
445 #else
446    KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
447 #endif
448 #endif
449
450    RETVALUE(ROK);
451 } /* KwLiRguDDatInd */
452
453
454 /*******************************************************************
455  *
456  * @brief Handler for extracting common and dedicated channel
457  *      Scheduling result report. 
458  *
459  * @details
460  *
461  *    Function : RlcMacProcSchedRep
462  *
463  *    Functionality:
464  *     Handler for extracting common and dedicated channel
465  *      Scheduling result report
466  *
467  * @params[in] 
468  * @return ROK     - success
469  *         RFAILED - failure
470  *
471  * ****************************************************************/
472 PUBLIC S16 RlcMacProcSchedRep(Pst *pst, SuId suId,RlcMacSchedRep *schRep)
473 {
474    U8 idx;                     /* Iterator */
475    U8 nmbDLch = 0;                 /* Number of dedicated logical channles */
476    RguCStaIndInfo   cLchSchInfo;    /* Common logical channel scheduling result */
477    RguDStaIndInfo   dLchSchInfo;  /* Dedicated logical channel scheduling result */
478
479    for(idx=0; idx < schRep->nmbLch; idx++)
480    {
481        /* If it is common channel, fill status indication information 
482         * and trigger the handler for each common lch separately */
483        if(schRep->lchSta[idx].commCh)
484        {
485           cmMemset((U8*)&cLchSchInfo, (U8)0, sizeof(RguCStaIndInfo)); 
486
487           cLchSchInfo.cellId  = schRep->cellId;
488           cLchSchInfo.lcId    = schRep->lchSta[idx].lchStaInd.lcId;
489           //cLchSchInfo.transId = schRep->timeToTx;  /* TODO : fill transId suing timeToTx */
490           cLchSchInfo.rnti    = schRep->rnti;
491
492           KwLiRguCStaInd(pst, suId, &cLchSchInfo);
493           
494        }
495        else
496        {
497           /* Fill status info structure if at least one dedicated channel 
498            * scheduling report is received */
499           if(nmbDLch == 0)
500           {
501              dLchSchInfo.cellId = schRep->cellId;
502              dLchSchInfo.nmbOfUeGrantPerTti = 1;
503              dLchSchInfo.staInd[0].rnti = schRep->rnti;
504              //dLchSchInfo.staInd[0].transId = schRep->timeToTx;  /* TODO : fill transId suing timeToTx */
505              dLchSchInfo.staInd[0].nmbOfTbs = 1;
506              //dLchSchInfo.staInd[0].fillCrlPdu = /* TODO : Check the value needed to be filled */
507           }
508
509           /* Fill logical channel scheduling info */
510           cmMemcpy((U8 *)&dLchSchInfo.staInd[0].staIndTb[0].lchStaInd[nmbDLch], (U8 *)&schRep->lchSta[idx].lchStaInd, sizeof(RguLchStaInd));
511           nmbDLch++;
512
513        }
514
515    }
516
517    /* Calling handler for all dedicated channels scheduling*/
518    if(nmbDLch)
519    {
520       dLchSchInfo.staInd[0].staIndTb[0].nmbLch = nmbDLch;
521       KwLiRguDStaInd(pst, suId, &dLchSchInfo);
522    }
523
524    RETVALUE(ROK);
525 }
526
527 /**
528  * @brief Handler for trigerring the data transfer from RLC to MAC
529  *        for common logical channels.
530  *
531  * @details
532  *    This function receives the size of the PDU to be transmitted
533  *    and acts as a trigger for forming PDU and sending it to MAC. 
534  *
535  * @param[in] pst       Post structure
536  * @param[in] suId      Service User ID
537  * @param[in] staInd    Status Indication Information for Common Logical 
538  *                      Channels
539  *
540  * @return  S16
541  *    -# ROK 
542  *    -# RFAILED 
543  *
544 */ 
545 #ifdef ANSI
546 PUBLIC S16 KwLiRguCStaInd
547 (
548 Pst              *pst,  
549 SuId             suId,
550 RguCStaIndInfo   *staInd  
551 )
552 #else
553 PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd)
554 Pst              *pst;   
555 SuId             suId; 
556 RguCStaIndInfo   *staInd; 
557 #endif
558 {
559    KwDlRbCb   *rbCb;  
560    KwCb       *tKwCb;
561
562    TRC3(KwLiRguCStaInd)
563
564 #if (ERRCLASS & ERRCLS_INT_PAR)
565    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
566    {
567       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
568       RETVALUE (RFAILED);
569    }
570 #endif
571
572    tKwCb = KW_GET_KWCB(pst->dstInst);
573
574
575 #if (ERRCLASS & ERRCLS_INT_PAR)
576    if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
577    {
578       KWLOGERROR(tKwCb,
579             ERRCLS_INT_PAR, 
580             EKW040, 
581             (ErrVal) suId,
582             "KwLiRguCStaInd: Invalid RGU suId\n");
583       RETVALUE(RFAILED); 
584    }
585    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
586    {
587        RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId,
588              "Received in RLC UL CELLID:%d",
589              staInd->cellId);
590        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
591        RETVALUE(RFAILED);
592    }
593 #endif
594
595    rbCb = NULLP;
596
597    /* kw006.201 ccpu00120058, added boundary condition check */
598 #if (ERRCLASS & ERRCLS_DEBUG)
599    if(KW_MAX_LCH_PER_CELL < staInd->lcId)
600    {
601       RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId, 
602             "Invalid LcId, Max is [%d] CELLID:%d",
603             KW_MAX_LCH_PER_CELL,
604             staInd->cellId);
605       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
606       RETVALUE(RFAILED);
607    }
608 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
609    /* Fertch RbCb from lcId */
610    kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb);
611    if(!rbCb)                                               
612    {
613       RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId, 
614             "LcId [%d] not found CELLID:%d",
615             staInd->lcId);
616       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
617       RETVALUE(RFAILED);
618    }
619
620    /* Dispatch to TM Module */
621    rbCb->transId = staInd->transId;
622    /* ccpu00136940 */
623   /* If trace flag is enabled send the trace indication */
624    if(tKwCb->init.trc == TRUE)
625    {
626      /* Populate the trace params */
627       kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP);
628    }                            
629    kwTmmSndToLi(tKwCb, suId, rbCb, staInd);
630 #ifndef SS_RBUF
631 #ifdef SS_LOCKLESS_MEMORY
632    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
633 #else
634    KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
635 #endif
636 #else
637    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
638 #endif
639    RETVALUE(ROK);
640 } /* KwLiRguCStaInd */
641
642 /**
643  * @brief Handler for trigerring the data transfer from RLC to MAC
644  *        for dedicated logical channels.
645  *
646  * @details
647  *    This function receives the size of the PDUs to be transmitted to
648  *    MAC via one or more dedicated logical channels and acts as a trigger
649  *    for forming PDUs and sending them to MAC. 
650  *
651  * @param[in] pst       Post structure
652  * @param[in] suId      Service User ID
653  * @param[in] staInd    Status Indication Information for Dedicated Logical 
654  *                      Channels
655  *
656  * @return  S16
657  *    -# ROK 
658  *    -# RFAILED 
659  *
660 */ 
661 #ifdef ANSI
662 PUBLIC S16 KwLiRguDStaInd
663 (
664 Pst              *pst,  
665 SuId             suId,
666 RguDStaIndInfo   *staInd 
667 )
668 #else
669 PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd)
670 Pst              *pst; 
671 SuId             suId; 
672 RguDStaIndInfo   *staInd; 
673 #endif
674 {
675    KwCb        *gCb;
676    TRC3(KwLiRguDStaInd)
677
678 #if (ERRCLASS & ERRCLS_INT_PAR)
679    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
680    {
681       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
682       RETVALUE (RFAILED);
683    }
684 #endif
685
686    gCb = KW_GET_KWCB(pst->dstInst);
687
688 #if (ERRCLASS & ERRCLS_INT_PAR)
689    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
690    {
691        RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"Received in RLC UL ");
692        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
693        RETVALUE(RFAILED);
694    }
695    if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
696    {
697       KWLOGERROR(gCb,
698             ERRCLS_INT_PAR, 
699             EKW040, 
700             (ErrVal) suId,
701             "KwLiRguDStaInd: Invalid RGU suId\n");
702       RETVALUE(RFAILED); 
703    }
704 #endif
705    kwUtlSndToLi(gCb, suId, staInd);
706
707    /* kw002.201 :Freeing from proper region */
708    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
709    RETVALUE(ROK);
710 } /* KwLiRguDStaInd */
711
712 /**
713  * @brief Handler for handling the flow cntrl Ind from MAC
714  *  to RLC      
715  *
716  * @details
717  *   This function receives the flow control indication from
718  *   MAC and calls kwUtlTrigPdbFlowCntrl
719  *
720  * @param[in] pst       Post structure
721  * @param[in] suId      Service User ID
722  * @param[in] flowCntrlInd flow control Indication Information 
723  *           from MAC  
724  *
725  * @return  S16
726  *    -# ROK 
727  *    -# RFAILED 
728  *
729 */ 
730 #ifdef ANSI
731 PUBLIC S16 KwLiRguFlowCntrlInd
732 (
733 Pst              *pst,  
734 SuId             suId,
735 RguFlowCntrlInd *flowCntrlInd
736 )
737 #else
738 PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
739 Pst              *pst; 
740 SuId             suId; 
741 RguFlowCntrlInd  *flowCntrlInd; 
742 #endif
743 {
744    KwCb       *tKwCb; 
745    KwDlRbCb   *rbCb = NULLP;
746    U32        idx;
747    U32        lcIdx;
748
749    tKwCb = KW_GET_KWCB(pst->dstInst);
750    for (idx = 0; idx < flowCntrlInd->numUes; idx++)
751    {
752       for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)  
753       {
754          RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]); 
755          kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
756          if (rbCb)
757          {
758            
759             if (lcInfo->pktAdmitCnt == 0) /* Special case */
760             {
761                kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
762                continue;
763             }
764             if (rbCb->mode == CM_LTE_MODE_AM)
765             {
766                if ((rbCb->m.amDl.retxLst.count != 0) || 
767                    ((rbCb->m.amDl.bo == 0) || 
768                     (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
769                {
770                   continue;
771                }
772             }
773             else /* UM */
774             {
775                if ((rbCb->m.umDl.bo == 0) ||
776                    (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
777                {
778                   continue;
779                }
780             }
781             kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
782          }
783       }
784    }
785    RETVALUE(ROK);
786 }
787 /* kw005.201 added support for L2 Measurement */
788 #ifdef LTE_L2_MEAS
789 \f
790 /**
791  *
792  * @brief  
793  *
794  *        Handler for indicating the Harq Status of the data sent.
795  *
796  * @b Description:
797  *
798  *        This function receives the harq status of the data sent to MAC.
799  *        This information is used for two things.
800  *        1. Computing the UuLoss of UM
801  *        2. Computing the DL Delay for UM and AM.
802  *
803  *  @param[in] pst     -   Post structure  
804  *  @param[in] suId    -   Service User ID
805  *  @param[in] staInd  -   Harq Status Indication Information. 
806  *
807  *  @return  S16
808  *      -# ROK 
809  *      -# RFAILED
810  *
811  */
812 #ifdef ANSI
813 PUBLIC S16 KwLiRguHqStaInd
814 (
815 Pst                *pst, 
816 SuId               suId,
817 RguHarqStatusInd   *staInd 
818 )
819 #else
820 PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd)
821 Pst                *pst;  
822 SuId               suId; 
823 RguHarqStatusInd   *staInd;
824 #endif
825 {
826
827    KwUeKey   ueKey;
828    S16       ret; 
829    KwDlUeCb    *ueCb;
830    U8        tbIdx;
831    KwCb       *tKwCb; 
832
833    TRC3(KwLiRguHqStaInd)
834
835    tKwCb = KW_GET_KWCB(pst->dstInst);
836    ueKey.cellId = staInd->cellId;
837    ueKey.ueId   = staInd->ueId;
838
839    ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb);
840    if (ret != ROK )
841    {
842       RETVALUE(RFAILED);
843    }
844
845    /*Call kwUtlProcHarqInd as many times as number of Tbs present*/
846    for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
847    {
848       kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx);
849    }
850
851    RETVALUE(ROK);
852 } /* KwLiRguHqStaInd */
853 #endif /* LTE_L2_MEAS */
854
855 #ifdef __cplusplus
856 }
857 #endif /* __cplusplus */
858
859 /********************************************************************30**
860          End of file
861 **********************************************************************/