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