7ad2d1487fa2beeb48b945f61009854cd9b9098b
[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 PUBLIC int   rlcDDatIndRcvd;
213 PUBLIC int   rlcCDatIndRcvd;
214 /**
215  * @brief Handler to process PDU received from MAC for common logical channels. 
216  *
217  * @details
218  *    This function receives the PDU from MAC for common logical channels
219  *    does checks before handing over the PDU to the TM module
220  *
221  * @param[in] pst     Post structure
222  * @param[in] suId    Service User ID
223  * @param[in] datInd  Data Indication Information 
224  *
225  * @return  S16
226  *    -# ROK 
227  *    -# RFAILED 
228  *
229 */
230 #ifdef ANSI
231 PUBLIC S16 KwLiRguCDatInd
232 (
233 Pst              *pst,   
234 SuId             suId,  
235 RguCDatIndInfo   *datInd
236 )
237 #else
238 PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd)
239 Pst              *pst; 
240 SuId             suId;
241 RguCDatIndInfo   *datInd;
242 #endif
243 {
244    KwUlRbCb   *rbCb; 
245    KwCb       *tKwCb; 
246
247    rlcCDatIndRcvd++;
248    TRC3(KwLiRguCDatInd)
249
250 #if (ERRCLASS & ERRCLS_INT_PAR)
251    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
252    {
253       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
254       RETVALUE (RFAILED);
255    }
256 #endif
257
258    tKwCb = KW_GET_KWCB(pst->dstInst);
259
260
261 #if (ERRCLASS & ERRCLS_DEBUG)
262    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
263    {
264       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
265       RETVALUE(RFAILED);
266    }
267 #endif
268
269    /* kw006.201 ccpu00120058, Added array boundary condition check */
270 #if (ERRCLASS & ERRCLS_DEBUG)
271    if(KW_MAX_LCH_PER_CELL <= datInd->lcId)
272    {
273       RLOG_ARG1(L_ERROR,DBG_LCID,datInd->lcId, "Invalid LcId, Max is [%d]",
274          KW_MAX_LCH_PER_CELL);
275       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
276       RETVALUE(RFAILED);
277    }
278 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
279
280    /* Fetch RbCb from lcId */
281    kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb);
282    if (!rbCb)
283    {
284       RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found",
285          datInd->lcId);
286       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
287       RETVALUE(RFAILED);
288    }
289
290    /* Dispatch to TM Module */
291 #ifdef CCPU_OPT
292    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu);
293 #else /* CCPU_OPT */
294    kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu);
295 #endif /* CCPU_OPT */
296
297    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
298
299    RETVALUE(ROK);
300 } /* KwLiRguCDatInd */
301
302 /**
303  * @brief Handler to process PDU received from MAC for 
304  *        dedicated logical channels. 
305  *
306  * @details
307  *    This function receives the PDU from MAC for one or more dedicated 
308  *    logical channels and passes it to the UTL module for further processing
309  *
310  * @param[in] pst     Post structure
311  * @param[in] suId    Service User ID
312  * @param[in] datInd  Data Indication Information 
313  *
314  * @return  S16
315  *    -# ROK 
316  *    -# RFAILED 
317  *
318 */
319  
320 #ifdef ANSI
321 PUBLIC S16 KwLiRguDDatInd
322 (
323 Pst              *pst,   
324 SuId             suId,  
325 RguDDatIndInfo   *datInd
326 )
327 #else
328 PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd)
329 Pst              *pst; 
330 SuId             suId;
331 RguDDatIndInfo   *datInd;
332 #endif
333 {
334    TRC3(KwLiRguDDatInd)
335
336    rlcDDatIndRcvd++;
337 #if (ERRCLASS & ERRCLS_INT_PAR)
338    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
339    {
340        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
341        RETVALUE (RFAILED);
342    }
343 #endif
344
345 #if (ERRCLASS & ERRCLS_DEBUG)
346    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
347    {
348        RLOG1(L_DEBUG,"KwLiRguDDatInd(pst, suId(%d))recieved in DL Inst",suId);
349        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
350        RETVALUE(RFAILED);
351    }
352 #endif
353    kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd);
354 #ifndef SS_RBUF 
355 #ifdef SS_LOCKLESS_MEMORY
356    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
357 #else
358    KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
359 #endif
360 #endif
361
362    RETVALUE(ROK);
363 } /* KwLiRguDDatInd */
364
365 /**
366  * @brief Handler for trigerring the data transfer from RLC to MAC
367  *        for common logical channels.
368  *
369  * @details
370  *    This function receives the size of the PDU to be transmitted
371  *    and acts as a trigger for forming PDU and sending it to MAC. 
372  *
373  * @param[in] pst       Post structure
374  * @param[in] suId      Service User ID
375  * @param[in] staInd    Status Indication Information for Common Logical 
376  *                      Channels
377  *
378  * @return  S16
379  *    -# ROK 
380  *    -# RFAILED 
381  *
382 */ 
383 #ifdef ANSI
384 PUBLIC S16 KwLiRguCStaInd
385 (
386 Pst              *pst,  
387 SuId             suId,
388 RguCStaIndInfo   *staInd  
389 )
390 #else
391 PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd)
392 Pst              *pst;   
393 SuId             suId; 
394 RguCStaIndInfo   *staInd; 
395 #endif
396 {
397    KwDlRbCb   *rbCb;  
398    KwCb       *tKwCb;
399
400    TRC3(KwLiRguCStaInd)
401
402 #if (ERRCLASS & ERRCLS_INT_PAR)
403    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
404    {
405       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
406       RETVALUE (RFAILED);
407    }
408 #endif
409
410    tKwCb = KW_GET_KWCB(pst->dstInst);
411
412
413 #if (ERRCLASS & ERRCLS_INT_PAR)
414    if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
415    {
416       KWLOGERROR(tKwCb,
417             ERRCLS_INT_PAR, 
418             EKW040, 
419             (ErrVal) suId,
420             "KwLiRguCStaInd: Invalid RGU suId\n");
421       RETVALUE(RFAILED); 
422    }
423    if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
424    {
425        RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId,
426              "Received in RLC UL CELLID:%d",
427              staInd->cellId);
428        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
429        RETVALUE(RFAILED);
430    }
431 #endif
432
433    rbCb = NULLP;
434
435    /* kw006.201 ccpu00120058, added boundary condition check */
436 #if (ERRCLASS & ERRCLS_DEBUG)
437    if(KW_MAX_LCH_PER_CELL < staInd->lcId)
438    {
439       RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId, 
440             "Invalid LcId, Max is [%d] CELLID:%d",
441             KW_MAX_LCH_PER_CELL,
442             staInd->cellId);
443       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
444       RETVALUE(RFAILED);
445    }
446 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
447    /* Fertch RbCb from lcId */
448    kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb);
449    if(!rbCb)                                               
450    {
451       RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId, 
452             "LcId [%d] not found CELLID:%d",
453             staInd->lcId);
454       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
455       RETVALUE(RFAILED);
456    }
457
458    /* Dispatch to TM Module */
459    rbCb->transId = staInd->transId;
460    /* ccpu00136940 */
461   /* If trace flag is enabled send the trace indication */
462    if(tKwCb->init.trc == TRUE)
463    {
464      /* Populate the trace params */
465       kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP);
466    }                            
467    kwTmmSndToLi(tKwCb, suId, rbCb, staInd);
468 #ifndef SS_RBUF
469 #ifdef SS_LOCKLESS_MEMORY
470    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
471 #else
472    KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
473 #endif
474 #else
475    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
476 #endif
477    RETVALUE(ROK);
478 } /* KwLiRguCStaInd */
479
480 /**
481  * @brief Handler for trigerring the data transfer from RLC to MAC
482  *        for dedicated logical channels.
483  *
484  * @details
485  *    This function receives the size of the PDUs to be transmitted to
486  *    MAC via one or more dedicated logical channels and acts as a trigger
487  *    for forming PDUs and sending them to MAC. 
488  *
489  * @param[in] pst       Post structure
490  * @param[in] suId      Service User ID
491  * @param[in] staInd    Status Indication Information for Dedicated Logical 
492  *                      Channels
493  *
494  * @return  S16
495  *    -# ROK 
496  *    -# RFAILED 
497  *
498 */ 
499 #ifdef ANSI
500 PUBLIC S16 KwLiRguDStaInd
501 (
502 Pst              *pst,  
503 SuId             suId,
504 RguDStaIndInfo   *staInd 
505 )
506 #else
507 PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd)
508 Pst              *pst; 
509 SuId             suId; 
510 RguDStaIndInfo   *staInd; 
511 #endif
512 {
513    KwCb        *gCb;
514    TRC3(KwLiRguDStaInd)
515
516 #if (ERRCLASS & ERRCLS_INT_PAR)
517    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
518    {
519       KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
520       RETVALUE (RFAILED);
521    }
522 #endif
523
524    gCb = KW_GET_KWCB(pst->dstInst);
525
526 #if (ERRCLASS & ERRCLS_INT_PAR)
527    if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
528    {
529        RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"Received in RLC UL ");
530        KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
531        RETVALUE(RFAILED);
532    }
533    if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
534    {
535       KWLOGERROR(gCb,
536             ERRCLS_INT_PAR, 
537             EKW040, 
538             (ErrVal) suId,
539             "KwLiRguDStaInd: Invalid RGU suId\n");
540       RETVALUE(RFAILED); 
541    }
542 #endif
543    kwUtlSndToLi(gCb, suId, staInd);
544
545    /* kw002.201 :Freeing from proper region */
546    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
547    RETVALUE(ROK);
548 } /* KwLiRguDStaInd */
549
550 /**
551  * @brief Handler for handling the flow cntrl Ind from MAC
552  *  to RLC      
553  *
554  * @details
555  *   This function receives the flow control indication from
556  *   MAC and calls kwUtlTrigPdbFlowCntrl
557  *
558  * @param[in] pst       Post structure
559  * @param[in] suId      Service User ID
560  * @param[in] flowCntrlInd flow control Indication Information 
561  *           from MAC  
562  *
563  * @return  S16
564  *    -# ROK 
565  *    -# RFAILED 
566  *
567 */ 
568 #ifdef ANSI
569 PUBLIC S16 KwLiRguFlowCntrlInd
570 (
571 Pst              *pst,  
572 SuId             suId,
573 RguFlowCntrlInd *flowCntrlInd
574 )
575 #else
576 PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
577 Pst              *pst; 
578 SuId             suId; 
579 RguFlowCntrlInd  *flowCntrlInd; 
580 #endif
581 {
582    KwCb       *tKwCb; 
583    KwDlRbCb   *rbCb = NULLP;
584    U32        idx;
585    U32        lcIdx;
586
587    tKwCb = KW_GET_KWCB(pst->dstInst);
588    for (idx = 0; idx < flowCntrlInd->numUes; idx++)
589    {
590       for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)  
591       {
592          RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]); 
593          kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
594          if (rbCb)
595          {
596            
597             if (lcInfo->pktAdmitCnt == 0) /* Special case */
598             {
599                kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
600                continue;
601             }
602             if (rbCb->mode == CM_LTE_MODE_AM)
603             {
604                if ((rbCb->m.amDl.retxLst.count != 0) || 
605                    ((rbCb->m.amDl.bo == 0) || 
606                     (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
607                {
608                   continue;
609                }
610             }
611             else /* UM */
612             {
613                if ((rbCb->m.umDl.bo == 0) ||
614                    (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
615                {
616                   continue;
617                }
618             }
619             kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
620          }
621       }
622    }
623    RETVALUE(ROK);
624 }
625 /* kw005.201 added support for L2 Measurement */
626 #ifdef LTE_L2_MEAS
627 \f
628 /**
629  *
630  * @brief  
631  *
632  *        Handler for indicating the Harq Status of the data sent.
633  *
634  * @b Description:
635  *
636  *        This function receives the harq status of the data sent to MAC.
637  *        This information is used for two things.
638  *        1. Computing the UuLoss of UM
639  *        2. Computing the DL Delay for UM and AM.
640  *
641  *  @param[in] pst     -   Post structure  
642  *  @param[in] suId    -   Service User ID
643  *  @param[in] staInd  -   Harq Status Indication Information. 
644  *
645  *  @return  S16
646  *      -# ROK 
647  *      -# RFAILED
648  *
649  */
650 #ifdef ANSI
651 PUBLIC S16 KwLiRguHqStaInd
652 (
653 Pst                *pst, 
654 SuId               suId,
655 RguHarqStatusInd   *staInd 
656 )
657 #else
658 PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd)
659 Pst                *pst;  
660 SuId               suId; 
661 RguHarqStatusInd   *staInd;
662 #endif
663 {
664
665    KwUeKey   ueKey;
666    S16       ret; 
667    KwDlUeCb    *ueCb;
668    U8        tbIdx;
669    KwCb       *tKwCb; 
670
671    TRC3(KwLiRguHqStaInd)
672
673    tKwCb = KW_GET_KWCB(pst->dstInst);
674    ueKey.cellId = staInd->cellId;
675    ueKey.ueId   = staInd->ueId;
676
677    ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb);
678    if (ret != ROK )
679    {
680       RETVALUE(RFAILED);
681    }
682
683    /*Call kwUtlProcHarqInd as many times as number of Tbs present*/
684    for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
685    {
686       kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx);
687    }
688
689    RETVALUE(ROK);
690 } /* KwLiRguHqStaInd */
691 #endif /* LTE_L2_MEAS */
692
693 #ifdef __cplusplus
694 }
695 #endif /* __cplusplus */
696
697 /********************************************************************30**
698          End of file
699 **********************************************************************/