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