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