62adb4e28e3571b7464a988b977da08b6451487d
[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          KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, cLchUlDat, sizeof(RguCDatIndInfo));
256          cmMemset((U8*)cLchUlDat, (U8)0, sizeof(RguCDatIndInfo));
257        
258          cLchUlDat->cellId = ulData->cellId;
259          cLchUlDat->rnti   = ulData->rnti;
260          cLchUlDat->lcId   = ulData->pduInfo[idx].lcId;
261          cLchUlDat->pdu    = ulData->pduInfo[idx].pduBuf;
262          
263          KwLiRguCDatInd(pst, suId, cLchUlDat);
264       } 
265       else
266       {
267          if(!dLchPduPres)
268          {
269             KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, dLchUlDat, sizeof(RguDDatIndInfo));
270             dLchPduPres = TRUE;
271          }
272
273          lcId = ulData->pduInfo[idx].lcId;
274          dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu] = ulData->pduInfo[idx].pduBuf;
275          dLchData[lcId].pdu.numPdu++; 
276       }
277    }
278  
279    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
280     * and call its handler */ 
281    if(dLchPduPres)
282    {
283       dLchUlDat->cellId = ulData->cellId;
284       dLchUlDat->rnti   = ulData->rnti;
285
286       for(idx = 0; idx < RGU_MAX_LC; idx++)
287       {
288          if(dLchData[idx].pdu.numPdu)
289          {
290             cmMemcpy((U8 *)&dLchUlDat->lchData[numDLch], (U8 *)&dLchData[idx], sizeof(RguLchDatInd));
291             numDLch++;      
292          }
293       }
294       dLchUlDat->numLch = numDLch;
295       KwLiRguDDatInd(pst, suId, dLchUlDat);
296    }
297     
298
299    KW_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcMacData));
300    RETVALUE(ROK);
301    
302 }/* End of RlcMacProcUlData */
303
304 PUBLIC int   rlcDDatIndRcvd;
305 PUBLIC int   rlcCDatIndRcvd;
306 /**
307  * @brief Handler to process PDU received from MAC for common logical channels. 
308  *
309  * @details
310  *    This function receives the PDU from MAC for common logical channels
311  *    does checks before handing over the PDU to the TM module
312  *
313  * @param[in] pst     Post structure
314  * @param[in] suId    Service User ID
315  * @param[in] datInd  Data Indication Information 
316  *
317  * @return  S16
318  *    -# ROK 
319  *    -# RFAILED 
320  *
321 */
322 #ifdef ANSI
323 PUBLIC S16 KwLiRguCDatInd
324 (
325 Pst              *pst,   
326 SuId             suId,  
327 RguCDatIndInfo   *datInd
328 )
329 #else
330 PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd)
331 Pst              *pst; 
332 SuId             suId;
333 RguCDatIndInfo   *datInd;
334 #endif
335 {
336    KwUlRbCb   *rbCb; 
337    KwCb       *tKwCb; 
338
339    rlcCDatIndRcvd++;
340    TRC3(KwLiRguCDatInd)
341
342 #if (ERRCLASS & ERRCLS_INT_PAR)
343    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
344    {
345       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
346       RETVALUE (RFAILED);
347    }
348 #endif
349
350    tKwCb = KW_GET_KWCB(pst->dstInst);
351
352
353 #if (ERRCLASS & ERRCLS_DEBUG)
354    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
355    {
356       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
357       RETVALUE(RFAILED);
358    }
359 #endif
360
361    /* kw006.201 ccpu00120058, Added array boundary condition check */
362 #if (ERRCLASS & ERRCLS_DEBUG)
363    if(KW_MAX_LCH_PER_CELL <= datInd->lcId)
364    {
365       RLOG_ARG1(L_ERROR,DBG_LCID,datInd->lcId, "Invalid LcId, Max is [%d]",
366          KW_MAX_LCH_PER_CELL);
367       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
368       RETVALUE(RFAILED);
369    }
370 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
371
372    /* Fetch RbCb from lcId */
373    kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb);
374    if (!rbCb)
375    {
376       RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found",
377          datInd->lcId);
378       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
379       RETVALUE(RFAILED);
380    }
381
382    /* Dispatch to TM Module */
383 #ifdef CCPU_OPT
384    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu);
385 #else /* CCPU_OPT */
386    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu);
387 #endif /* CCPU_OPT */
388
389    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
390
391    RETVALUE(ROK);
392 } /* KwLiRguCDatInd */
393
394 /**
395  * @brief Handler to process PDU received from MAC for 
396  *        dedicated logical channels. 
397  *
398  * @details
399  *    This function receives the PDU from MAC for one or more dedicated 
400  *    logical channels and passes it to the UTL module for further processing
401  *
402  * @param[in] pst     Post structure
403  * @param[in] suId    Service User ID
404  * @param[in] datInd  Data Indication Information 
405  *
406  * @return  S16
407  *    -# ROK 
408  *    -# RFAILED 
409  *
410 */
411  
412 #ifdef ANSI
413 PUBLIC S16 KwLiRguDDatInd
414 (
415 Pst              *pst,   
416 SuId             suId,  
417 RguDDatIndInfo   *datInd
418 )
419 #else
420 PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd)
421 Pst              *pst; 
422 SuId             suId;
423 RguDDatIndInfo   *datInd;
424 #endif
425 {
426    TRC3(KwLiRguDDatInd)
427
428    rlcDDatIndRcvd++;
429 #if (ERRCLASS & ERRCLS_INT_PAR)
430    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
431    {
432        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
433        RETVALUE (RFAILED);
434    }
435 #endif
436
437 #if (ERRCLASS & ERRCLS_DEBUG)
438    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
439    {
440        RLOG1(L_DEBUG,"KwLiRguDDatInd(pst, suId(%d))recieved in DL Inst",suId);
441        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
442        RETVALUE(RFAILED);
443    }
444 #endif
445    kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd);
446 #ifndef SS_RBUF 
447 #ifdef SS_LOCKLESS_MEMORY
448    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
449 #else
450    KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
451 #endif
452 #endif
453
454    RETVALUE(ROK);
455 } /* KwLiRguDDatInd */
456
457
458 /*******************************************************************
459  *
460  * @brief Handler for extracting common and dedicated channel
461  *      Scheduling result report. 
462  *
463  * @details
464  *
465  *    Function : RlcMacProcSchedRep
466  *
467  *    Functionality:
468  *     Handler for extracting common and dedicated channel
469  *      Scheduling result report
470  *
471  * @params[in] 
472  * @return ROK     - success
473  *         RFAILED - failure
474  *
475  * ****************************************************************/
476 PUBLIC uint16_t RlcMacProcSchedRep(Pst *pst, SuId suId, RlcMacSchedRepInfo *schRep)
477 {
478    U8 idx;                     /* Iterator */
479    U8 nmbDLch = 0;                 /* Number of dedicated logical channles */
480    RguCStaIndInfo   *cLchSchInfo;    /* Common logical channel scheduling result */
481    RguDStaIndInfo   *dLchSchInfo;  /* Dedicated logical channel scheduling result */
482
483    DU_LOG("\nRLC : Received scheduling report from MAC");
484
485    for(idx=0; idx < schRep->nmbLch; idx++)
486    {
487        /* If it is common channel, fill status indication information 
488         * and trigger the handler for each common lch separately */
489        if(schRep->lchSta[idx].commCh)
490        {
491           KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, cLchSchInfo, sizeof(RguCStaIndInfo));
492           cmMemset((U8*)cLchSchInfo, (U8)0, sizeof(RguCStaIndInfo)); 
493
494           cLchSchInfo->cellId  = schRep->cellId;
495           cLchSchInfo->lcId    = schRep->lchSta[idx].lchStaInd.lcId;
496           //cLchSchInfo->transId = schRep->timeToTx;  /* TODO : fill transId suing timeToTx */
497           cLchSchInfo->rnti    = schRep->rnti;
498
499           KwLiRguCStaInd(pst, suId, cLchSchInfo);
500           
501        }
502        else
503        {
504           /* Fill status info structure if at least one dedicated channel 
505            * scheduling report is received */
506           if(nmbDLch == 0)
507           {
508              KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, dLchSchInfo, sizeof(RguDStaIndInfo));
509
510              dLchSchInfo->cellId = schRep->cellId;
511              dLchSchInfo->nmbOfUeGrantPerTti = 1;
512              dLchSchInfo->staInd[0].rnti = schRep->rnti;
513              //dLchSchInfo->staInd[0].transId = schRep->timeToTx;  /* TODO : fill transId suing timeToTx */
514              dLchSchInfo->staInd[0].nmbOfTbs = 1;
515              //dLchSchInfo->staInd[0].fillCrlPdu = /* TODO : Check the value needed to be filled */
516           }
517
518           /* Fill logical channel scheduling info */
519           cmMemcpy((U8 *)&dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch], (U8 *)&schRep->lchSta[idx].lchStaInd, sizeof(RguLchStaInd));
520           nmbDLch++;
521
522        }
523
524    }
525
526    /* Calling handler for all dedicated channels scheduling*/
527    if(nmbDLch)
528    {
529       dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
530       KwLiRguDStaInd(pst, suId, dLchSchInfo);
531    }
532    
533    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcMacSchedRepInfo));
534
535    RETVALUE(ROK);
536 }
537
538 /**
539  * @brief Handler for trigerring the data transfer from RLC to MAC
540  *        for common logical channels.
541  *
542  * @details
543  *    This function receives the size of the PDU to be transmitted
544  *    and acts as a trigger for forming PDU and sending it to MAC. 
545  *
546  * @param[in] pst       Post structure
547  * @param[in] suId      Service User ID
548  * @param[in] staInd    Status Indication Information for Common Logical 
549  *                      Channels
550  *
551  * @return  S16
552  *    -# ROK 
553  *    -# RFAILED 
554  *
555 */ 
556 #ifdef ANSI
557 PUBLIC S16 KwLiRguCStaInd
558 (
559 Pst              *pst,  
560 SuId             suId,
561 RguCStaIndInfo   *staInd  
562 )
563 #else
564 PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd)
565 Pst              *pst;   
566 SuId             suId; 
567 RguCStaIndInfo   *staInd; 
568 #endif
569 {
570    KwDlRbCb   *rbCb;  
571    KwCb       *tKwCb;
572
573    TRC3(KwLiRguCStaInd)
574
575 #if (ERRCLASS & ERRCLS_INT_PAR)
576    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
577    {
578       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
579       RETVALUE (RFAILED);
580    }
581 #endif
582
583    tKwCb = KW_GET_KWCB(pst->dstInst);
584
585
586 #if (ERRCLASS & ERRCLS_INT_PAR)
587    if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
588    {
589       KWLOGERROR(tKwCb,
590             ERRCLS_INT_PAR, 
591             EKW040, 
592             (ErrVal) suId,
593             "KwLiRguCStaInd: Invalid RGU suId\n");
594       RETVALUE(RFAILED); 
595    }
596    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
597    {
598        RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId,
599              "Received in RLC UL CELLID:%d",
600              staInd->cellId);
601        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
602        RETVALUE(RFAILED);
603    }
604 #endif
605
606    rbCb = NULLP;
607
608    /* kw006.201 ccpu00120058, added boundary condition check */
609 #if (ERRCLASS & ERRCLS_DEBUG)
610    if(KW_MAX_LCH_PER_CELL < staInd->lcId)
611    {
612       RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId, 
613             "Invalid LcId, Max is [%d] CELLID:%d",
614             KW_MAX_LCH_PER_CELL,
615             staInd->cellId);
616       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
617       RETVALUE(RFAILED);
618    }
619 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
620    /* Fertch RbCb from lcId */
621    kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb);
622    if(!rbCb)                                               
623    {
624       RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId, 
625             "LcId [%d] not found CELLID:%d",
626             staInd->lcId);
627       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
628       RETVALUE(RFAILED);
629    }
630
631    /* Dispatch to TM Module */
632    rbCb->transId = staInd->transId;
633    /* ccpu00136940 */
634   /* If trace flag is enabled send the trace indication */
635    if(tKwCb->init.trc == TRUE)
636    {
637      /* Populate the trace params */
638       kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP);
639    }                            
640    kwTmmSndToLi(tKwCb, suId, rbCb, staInd);
641 #ifndef SS_RBUF
642 #ifdef SS_LOCKLESS_MEMORY
643    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
644 #else
645    KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
646 #endif
647 #else
648    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
649 #endif
650    RETVALUE(ROK);
651 } /* KwLiRguCStaInd */
652
653 /**
654  * @brief Handler for trigerring the data transfer from RLC to MAC
655  *        for dedicated logical channels.
656  *
657  * @details
658  *    This function receives the size of the PDUs to be transmitted to
659  *    MAC via one or more dedicated logical channels and acts as a trigger
660  *    for forming PDUs and sending them to MAC. 
661  *
662  * @param[in] pst       Post structure
663  * @param[in] suId      Service User ID
664  * @param[in] staInd    Status Indication Information for Dedicated Logical 
665  *                      Channels
666  *
667  * @return  S16
668  *    -# ROK 
669  *    -# RFAILED 
670  *
671 */ 
672 #ifdef ANSI
673 PUBLIC S16 KwLiRguDStaInd
674 (
675 Pst              *pst,  
676 SuId             suId,
677 RguDStaIndInfo   *staInd 
678 )
679 #else
680 PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd)
681 Pst              *pst; 
682 SuId             suId; 
683 RguDStaIndInfo   *staInd; 
684 #endif
685 {
686    KwCb        *gCb;
687    TRC3(KwLiRguDStaInd)
688
689 #if (ERRCLASS & ERRCLS_INT_PAR)
690    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
691    {
692       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
693       RETVALUE (RFAILED);
694    }
695 #endif
696
697    gCb = KW_GET_KWCB(pst->dstInst);
698
699 #if (ERRCLASS & ERRCLS_INT_PAR)
700    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
701    {
702        RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"Received in RLC UL ");
703        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
704        RETVALUE(RFAILED);
705    }
706    if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
707    {
708       KWLOGERROR(gCb,
709             ERRCLS_INT_PAR, 
710             EKW040, 
711             (ErrVal) suId,
712             "KwLiRguDStaInd: Invalid RGU suId\n");
713       RETVALUE(RFAILED); 
714    }
715 #endif
716    kwUtlSndToLi(gCb, suId, staInd);
717
718    /* kw002.201 :Freeing from proper region */
719    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
720    RETVALUE(ROK);
721 } /* KwLiRguDStaInd */
722
723 /**
724  * @brief Handler for handling the flow cntrl Ind from MAC
725  *  to RLC      
726  *
727  * @details
728  *   This function receives the flow control indication from
729  *   MAC and calls kwUtlTrigPdbFlowCntrl
730  *
731  * @param[in] pst       Post structure
732  * @param[in] suId      Service User ID
733  * @param[in] flowCntrlInd flow control Indication Information 
734  *           from MAC  
735  *
736  * @return  S16
737  *    -# ROK 
738  *    -# RFAILED 
739  *
740 */ 
741 #ifdef ANSI
742 PUBLIC S16 KwLiRguFlowCntrlInd
743 (
744 Pst              *pst,  
745 SuId             suId,
746 RguFlowCntrlInd *flowCntrlInd
747 )
748 #else
749 PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
750 Pst              *pst; 
751 SuId             suId; 
752 RguFlowCntrlInd  *flowCntrlInd; 
753 #endif
754 {
755    KwCb       *tKwCb; 
756    KwDlRbCb   *rbCb = NULLP;
757    U32        idx;
758    U32        lcIdx;
759
760    tKwCb = KW_GET_KWCB(pst->dstInst);
761    for (idx = 0; idx < flowCntrlInd->numUes; idx++)
762    {
763       for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)  
764       {
765          RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]); 
766          kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
767          if (rbCb)
768          {
769            
770             if (lcInfo->pktAdmitCnt == 0) /* Special case */
771             {
772                kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
773                continue;
774             }
775             if (rbCb->mode == CM_LTE_MODE_AM)
776             {
777                if ((rbCb->m.amDl.retxLst.count != 0) || 
778                    ((rbCb->m.amDl.bo == 0) || 
779                     (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
780                {
781                   continue;
782                }
783             }
784             else /* UM */
785             {
786                if ((rbCb->m.umDl.bo == 0) ||
787                    (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
788                {
789                   continue;
790                }
791             }
792             kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
793          }
794       }
795    }
796    RETVALUE(ROK);
797 }
798 /* kw005.201 added support for L2 Measurement */
799 #ifdef LTE_L2_MEAS
800 \f
801 /**
802  *
803  * @brief  
804  *
805  *        Handler for indicating the Harq Status of the data sent.
806  *
807  * @b Description:
808  *
809  *        This function receives the harq status of the data sent to MAC.
810  *        This information is used for two things.
811  *        1. Computing the UuLoss of UM
812  *        2. Computing the DL Delay for UM and AM.
813  *
814  *  @param[in] pst     -   Post structure  
815  *  @param[in] suId    -   Service User ID
816  *  @param[in] staInd  -   Harq Status Indication Information. 
817  *
818  *  @return  S16
819  *      -# ROK 
820  *      -# RFAILED
821  *
822  */
823 #ifdef ANSI
824 PUBLIC S16 KwLiRguHqStaInd
825 (
826 Pst                *pst, 
827 SuId               suId,
828 RguHarqStatusInd   *staInd 
829 )
830 #else
831 PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd)
832 Pst                *pst;  
833 SuId               suId; 
834 RguHarqStatusInd   *staInd;
835 #endif
836 {
837
838    KwUeKey   ueKey;
839    S16       ret; 
840    KwDlUeCb    *ueCb;
841    U8        tbIdx;
842    KwCb       *tKwCb; 
843
844    TRC3(KwLiRguHqStaInd)
845
846    tKwCb = KW_GET_KWCB(pst->dstInst);
847    ueKey.cellId = staInd->cellId;
848    ueKey.ueId   = staInd->ueId;
849
850    ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb);
851    if (ret != ROK )
852    {
853       RETVALUE(RFAILED);
854    }
855
856    /*Call kwUtlProcHarqInd as many times as number of Tbs present*/
857    for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
858    {
859       kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx);
860    }
861
862    RETVALUE(ROK);
863 } /* KwLiRguHqStaInd */
864 #endif /* LTE_L2_MEAS */
865
866 #ifdef __cplusplus
867 }
868 #endif /* __cplusplus */
869
870 /********************************************************************30**
871          End of file
872 **********************************************************************/