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