Adding new commiter to ODU-High repo
[o-du/l2.git] / src / 5gnrrlc / rlc_lwr_inf_mgr.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:    NR 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         --rlcProcCommLcUlData
30         --rlcProcDedLcUlData
31         --rlcProcCommLcSchedRpt
32         --rlcProcDedLcSchedRpt
33         --RlcLiRguHqStaInd
34
35      File:     kw_lim.c
36
37 **********************************************************************/
38
39 /** 
40  * @file rlc_lwr_inf_mgr.c
41  * @brief RLC Lower Interface module
42 */
43
44 #define RLC_MODULE RLC_DBGMASK_INF
45
46 \f
47 /* header (.h) include files */
48 #include "common_def.h"
49 #include "lkw.h"           /* LKW defines */
50 #include "ckw.h"           /* CKW defines */
51 #include "kwu.h"           /* KWU defines */
52 #include "rgu.h"           /* RGU defines */
53 #include "rlc_err.h"
54 #include "rlc_env.h"        /* RLC environment options */
55
56
57
58 /* extern (.x) include files */
59 #include "lkw.x"           /* LKW */
60 #include "ckw.x"           /* CKW */
61 #include "kwu.x"           /* KWU */
62 #include "rgu.x"           /* RGU */
63
64 #include "rlc_utils.h"            /* RLC defines */
65 #include "rlc_dl_ul_inf.h"
66 #include "rlc_dl.h"
67 #include "rlc_ul.h"
68 #include "rlc_mac_inf.h"
69
70 #ifdef __cplusplus
71 extern "C" {
72 #endif /* __cplusplus */
73
74 \f
75 /*****************************************************************************
76  *                          RGU INTERFACE
77  ****************************************************************************/
78 /**
79  * @brief Handler for bind confirmation from MAC.
80  *
81  * @details
82  *    This function handles the bind confirmation received from MAC. If the 
83  *    bind was successful changes the state of the SAP to RLC_SAP_BND 
84  *    else RLC_SAP_CFG. Sends an alarm to LM in any case
85  *
86  * @param[in] pst     Post structure
87  * @param[in] suId    Service User ID
88  * @param[in] status  Status whether the bind was successful or not
89  *
90  * @return  S16
91  *    -# ROK 
92  *    -# RFAILED 
93  *
94 */
95 S16 RlcLiRguBndCfm(Pst *pst,SuId suId,uint8_t status)
96 {
97    uint16_t      event;     /* Event */
98    uint16_t      cause;     /* Cause */
99    RlcRguSapCb   *rguSap;   /* RGU SAP Control Block */
100    RlcCb         *tRlcCb;
101
102 #if (ERRCLASS & ERRCLS_INT_PAR)
103    if (pst->dstInst >= MAX_RLC_INSTANCES)
104    {
105       return  (RFAILED);
106    }
107 #endif
108    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
109
110    DU_LOG("\nDEBUG  -->  RLC UL : RlcLiRguBndCfm(suId(%d), status(%d)", suId, status);
111
112 #if (ERRCLASS & ERRCLS_INT_PAR)
113    if (tRlcCb->init.cfgDone != TRUE)
114    {
115       DU_LOG("\nERROR  -->  RLC UL : General configuration not done");
116       
117       RLC_SEND_SAPID_ALARM(tRlcCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
118
119       return RFAILED;
120    }
121
122    if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
123    {
124       DU_LOG("\nERROR  -->  RLC UL : Invalid suId");
125       
126       RLC_SEND_SAPID_ALARM(tRlcCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
127
128       return RFAILED;
129    }
130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
131
132    rguSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
133             &(tRlcCb->u.dlCb->rguDlSap[suId]) : &(tRlcCb->u.ulCb->rguUlSap[suId]);
134
135    DU_LOG("\nDEBUG  -->  RLC UL : RlcLiRguBndCfm: For RGU SAP state=%d", rguSap->state);
136
137    switch (rguSap->state)
138    {
139       case RLC_SAP_BINDING:
140       {
141          rlcStopTmr (tRlcCb,(PTR)rguSap, EVENT_RLC_WAIT_BNDCFM);
142
143          rguSap->retryCnt = 0;
144           
145          if (status == CM_BND_OK)
146          {
147             rguSap->state = RLC_SAP_BND;
148             event = LCM_EVENT_BND_OK;
149             cause = LKW_CAUSE_SAP_BNDENB;
150          }
151          else
152          {
153             rguSap->state = RLC_SAP_CFG;
154             event = LCM_EVENT_BND_FAIL;
155             cause = LKW_CAUSE_UNKNOWN;
156          }
157
158          break;
159       }
160       default:
161          event = LKW_EVENT_RGU_BND_CFM;
162          cause = LCM_CAUSE_INV_STATE;
163          break;
164    }
165
166    /* Send an alarm with proper event and cause */
167    RLC_SEND_SAPID_ALARM(tRlcCb, suId, event, cause);
168
169    return (ROK);
170 } /* RlcLiRguBndCfm */
171
172 int   rlcDDatIndRcvd;
173 int   rlcCDatIndRcvd;
174 /**
175  * @brief Handler to process PDU received from MAC for common logical channels. 
176  *
177  * @details
178  *    This function receives the PDU from MAC for common logical channels
179  *    does checks before handing over the PDU to the TM module
180  *
181  * @param[in] pst     Post structure
182  * @param[in] suId    Service User ID
183  * @param[in] datInd  Data Indication Information 
184  *
185  * @return  S16
186  *    -# ROK 
187  *    -# RFAILED 
188  *
189 */
190 uint8_t rlcProcCommLcUlData(Pst *pst, SuId suId, RguCDatIndInfo *datInd)
191 {
192    RlcUlRbCb   *rbCb; 
193    RlcCb       *tRlcCb; 
194
195    rlcCDatIndRcvd++;
196
197 #if (ERRCLASS & ERRCLS_INT_PAR)
198    if (pst->dstInst >= MAX_RLC_INSTANCES)
199    {
200       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
201       return RFAILED;
202    }
203 #endif
204
205    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
206
207 #if (ERRCLASS & ERRCLS_DEBUG)
208    if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
209    {
210       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
211       return RFAILED;
212    }
213 #endif
214
215    /* kw006.201 ccpu00120058, Added array boundary condition check */
216 #if (ERRCLASS & ERRCLS_DEBUG)
217    if(RLC_MAX_LCH_PER_CELL <= datInd->lcId)
218    {
219       DU_LOG("\nERROR  -->  RLC UL : rlcProcCommLcUlData : Invalid LcId [%d], Max is [%d]",\
220          datInd->lcId, RLC_MAX_LCH_PER_CELL);
221       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
222       return RFAILED;
223    }
224 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
225
226    /* Fetch RbCb from lcId */
227    rlcDbmFetchUlRbCbFromLchId(tRlcCb, datInd->rnti, datInd->cellId, datInd->lcId, &rbCb);
228    if (!rbCb)
229    {
230       DU_LOG("\nERROR  -->  RLC UL : rlcProcCommLcUlData : LcId [%d] not found",
231          datInd->lcId);
232       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
233       return RFAILED;
234    }
235
236    /* Dispatch to TM Module */
237 #ifdef CCPU_OPT
238    rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->rnti, datInd->pdu);
239 #else /* CCPU_OPT */
240    rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->pdu);
241 #endif /* CCPU_OPT */
242
243    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
244
245    return (ROK);
246 } /* rlcProcCommLcUlData */
247
248 /**
249  * @brief Handler to process PDU received from MAC for 
250  *        dedicated logical channels. 
251  *
252  * @details
253  *    This function receives the PDU from MAC for one or more dedicated 
254  *    logical channels and passes it to the UTL module for further processing
255  *
256  * @param[in] pst     Post structure
257  * @param[in] suId    Service User ID
258  * @param[in] datInd  Data Indication Information 
259  *
260  * @return  S16
261  *    -# ROK 
262  *    -# RFAILED 
263  *
264 */
265  
266 uint8_t rlcProcDedLcUlData(Pst *pst, SuId suId, RguDDatIndInfo *datInd)
267 {
268    rlcDDatIndRcvd++;
269 #if (ERRCLASS & ERRCLS_INT_PAR)
270    if (pst->dstInst >= MAX_RLC_INSTANCES)
271    {
272        RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
273        return RFAILED;
274    }
275 #endif
276
277 #if (ERRCLASS & ERRCLS_DEBUG)
278    if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
279    {
280        DU_LOG("\nDEBUG  -->  RLC UL : rlcProcDedLcUlData : suId(%d))recieved in DL Inst", suId);
281        RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
282        return RFAILED;
283    }
284 #endif
285    rlcUtlRcvFrmMac(RLC_GET_RLCCB(pst->dstInst),datInd);
286 #ifndef SS_RBUF 
287 #ifdef SS_LOCKLESS_MEMORY
288    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
289 #else
290    RLC_PST_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
291 #endif
292 #endif
293
294    return ROK;
295 } /* rlcProcDedLcUlData */
296
297 /**
298  * @brief Handler for trigerring the data transfer from RLC to MAC
299  *        for common logical channels.
300  *
301  * @details
302  *    This function receives the size of the PDU to be transmitted
303  *    and acts as a trigger for forming PDU and sending it to MAC. 
304  *
305  * @param[in] pst       Post structure
306  * @param[in] suId      Service User ID
307  * @param[in] staInd    Status Indication Information for Common Logical 
308  *                      Channels
309  *
310  * @return  S16
311  *    -# ROK 
312  *    -# RFAILED 
313  *
314 */ 
315 uint8_t rlcProcCommLcSchedRpt(Pst *pst, SuId suId, RguCStaIndInfo *staInd)
316 {
317    RlcDlRbCb   *rbCb;  
318    RlcCb       *tRlcCb;
319
320 #if (ERRCLASS & ERRCLS_INT_PAR)
321    if (pst->dstInst >= MAX_RLC_INSTANCES)
322    {
323       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
324       return  (RFAILED);
325    }
326 #endif
327
328    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
329
330 #if (ERRCLASS & ERRCLS_INT_PAR)
331    if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
332    {
333       DU_LOG("\nERROR  -->  RLC UL : rlcProcCommLcSchedRpt: Invalid RGU suId %d\n", suId);
334       return RFAILED; 
335    }
336    if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
337    {
338        DU_LOG("\nDEBUG  -->  RLC UL : rlcProcCommLcSchedRpt: Received in RLC UL CELLID:%d",
339              staInd->cellId);
340        RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
341        return RFAILED;
342    }
343 #endif
344
345    rbCb = NULLP;
346
347    /* kw006.201 ccpu00120058, added boundary condition check */
348 #if (ERRCLASS & ERRCLS_DEBUG)
349    if(RLC_MAX_LCH_PER_CELL < staInd->lcId)
350    {
351       DU_LOG("\nERROR  -->  RLC UL : rlcProcCommLcSchedRpt: Invalid LcId, Max is [%d] CELLID:%d",
352          RLC_MAX_LCH_PER_CELL, staInd->cellId);
353       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
354       return RFAILED;
355    }
356 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
357    /* Fertch RbCb from lcId */
358    rlcDbmFetchDlRbCbFromLchId(tRlcCb,0, staInd->cellId, staInd->lcId, &rbCb);
359    if(!rbCb)                                               
360    {
361       DU_LOG("\nERROR  -->  RLC UL : rlcProcCommLcSchedRpt: LcId [%d] not found CELLID:%d",
362          staInd->lcId, staInd->cellId);
363       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
364       return RFAILED;
365    }
366
367    /* Dispatch to TM Module */
368    rbCb->transId = staInd->transId;
369    rlcTmmSendToMac(tRlcCb, suId, rbCb, staInd);
370 #ifndef SS_RBUF
371 #ifdef SS_LOCKLESS_MEMORY
372    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
373 #else
374    RLC_PST_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
375 #endif
376 #else
377    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
378 #endif
379    return ROK;
380 } /* rlcProcCommLcSchedRpt */
381
382 /**
383  * @brief Handler for trigerring the data transfer from RLC to MAC
384  *        for dedicated logical channels.
385  *
386  * @details
387  *    This function receives the size of the PDUs to be transmitted to
388  *    MAC via one or more dedicated logical channels and acts as a trigger
389  *    for forming PDUs and sending them to MAC. 
390  *
391  * @param[in] pst       Post structure
392  * @param[in] suId      Service User ID
393  * @param[in] staInd    Status Indication Information for Dedicated Logical 
394  *                      Channels
395  *
396  * @return  S16
397  *    -# ROK 
398  *    -# RFAILED 
399  *
400 */ 
401 uint8_t rlcProcDedLcSchedRpt(Pst *pst, SuId suId, RguDStaIndInfo *staInd)
402 {
403    RlcCb        *gCb;
404
405 #if (ERRCLASS & ERRCLS_INT_PAR)
406    if (pst->dstInst >= MAX_RLC_INSTANCES)
407    {
408       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
409       return RFAILED;
410    }
411 #endif
412
413    gCb = RLC_GET_RLCCB(pst->dstInst);
414
415 #if (ERRCLASS & ERRCLS_INT_PAR)
416    if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
417    {
418        DU_LOG("\nDEBUG  -->  RLC UL : rlcProcDedLcSchedRpt: Received in RLC UL ");
419        RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
420        return RFAILED;
421    }
422    if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
423    {
424       DU_LOG("\nERROR  -->  RLC UL : rlcProcDedLcSchedRpt: Invalid RGU suId %d\n", suId);
425       return (RFAILED); 
426    }
427 #endif
428    rlcUtlSendToMac(gCb, suId, staInd);
429
430    /* kw002.201 :Freeing from proper region */
431    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
432    return ROK;
433 } /* rlcProcDedLcSchedRpt */
434
435 /**
436  * @brief Handler for handling the flow cntrl Ind from MAC
437  *  to RLC      
438  *
439  * @details
440  *   This function receives the flow control indication from
441  *   MAC and calls rlcUtlTrigPdbFlowCntrl
442  *
443  * @param[in] pst       Post structure
444  * @param[in] suId      Service User ID
445  * @param[in] flowCntrlInd flow control Indication Information 
446  *           from MAC  
447  *
448  * @return  S16
449  *    -# ROK 
450  *    -# RFAILED 
451  *
452 */ 
453 S16 RlcLiRguFlowCntrlInd(Pst *pst,SuId suId,RguFlowCntrlInd *flowCntrlInd)
454 {
455    RlcCb       *tRlcCb; 
456    RlcDlRbCb   *rbCb = NULLP;
457    uint32_t    idx;
458    uint32_t    lcIdx;
459
460    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
461    for (idx = 0; idx < flowCntrlInd->numUes; idx++)
462    {
463       for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)  
464       {
465          RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]); 
466          rlcDbmFetchDlRbCbFromLchId(tRlcCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
467          if (rbCb)
468          {
469            
470             if (lcInfo->pktAdmitCnt == 0) /* Special case */
471             {
472                rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
473                continue;
474             }
475             if (rbCb->mode == RLC_MODE_AM)
476             {
477                if ((rbCb->m.amDl.retxLst.count != 0) || 
478                    ((rbCb->m.amDl.bo == 0) || 
479                     (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
480                {
481                   continue;
482                }
483             }
484             else /* UM */
485             {
486                if ((rbCb->m.umDl.bo == 0) ||
487                    (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
488                {
489                   continue;
490                }
491             }
492             rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
493          }
494       }
495    }
496    return ROK;
497 }
498 /* kw005.201 added support for L2 Measurement */
499 #ifdef LTE_L2_MEAS
500 \f
501 /**
502  *
503  * @brief  
504  *
505  *        Handler for indicating the Harq Status of the data sent.
506  *
507  * @b Description:
508  *
509  *        This function receives the harq status of the data sent to MAC.
510  *        This information is used for two things.
511  *        1. Computing the UuLoss of UM
512  *        2. Computing the DL Delay for UM and AM.
513  *
514  *  @param[in] pst     -   Post structure  
515  *  @param[in] suId    -   Service User ID
516  *  @param[in] staInd  -   Harq Status Indication Information. 
517  *
518  *  @return  S16
519  *      -# ROK 
520  *      -# RFAILED
521  *
522  */
523 S16 RlcLiRguHqStaInd(Pst *pst, SuId suId,RguHarqStatusInd *staInd)
524 {
525
526    RlcUeKey   ueKey;
527    S16        ret; 
528    RlcDlUeCb  *ueCb;
529    uint8_t    tbIdx;
530    RlcCb      *tRlcCb; 
531
532    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
533    ueKey.cellId = staInd->cellId;
534    ueKey.ueId   = staInd->ueId;
535
536    ret = rlcDbmFetchDlUeCb(tRlcCb, ueKey.ueId, ueKey.cellId, &ueCb);
537    if (ret != ROK )
538    {
539       return RFAILED;
540    }
541
542    /*Call rlcUtlProcHarqInd as many times as number of Tbs present*/
543    for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
544    {
545       rlcUtlProcHarqInd(tRlcCb, staInd, ueCb, tbIdx);
546    }
547
548    return (ROK);
549 } /* RlcLiRguHqStaInd */
550 #endif /* LTE_L2_MEAS */
551
552 #ifdef __cplusplus
553 }
554 #endif /* __cplusplus */
555
556 /********************************************************************30**
557          End of file
558 **********************************************************************/