1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /********************************************************************20**
21 Name: NR RLC Layer - Lower Interface Functions
25 Desc: Source code for RLC Lower Interface Module.
26 This file contains following functions
31 --rlcProcCommLcSchedRpt
32 --rlcProcDedLcSchedRpt
37 **********************************************************************/
40 * @file rlc_lwr_inf_mgr.c
41 * @brief RLC Lower Interface module
44 #define RLC_MODULE RLC_DBGMASK_INF
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 */
54 #include "rlc_env.h" /* RLC environment options */
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 */
64 #include "rlc_utils.h" /* RLC defines */
65 #include "rlc_dl_ul_inf.h"
68 #include "rlc_mac_inf.h"
72 #endif /* __cplusplus */
75 /*****************************************************************************
77 ****************************************************************************/
79 * @brief Handler for bind confirmation from MAC.
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
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
95 S16 RlcLiRguBndCfm(Pst *pst,SuId suId,uint8_t status)
97 uint16_t event; /* Event */
98 uint16_t cause; /* Cause */
99 RlcRguSapCb *rguSap; /* RGU SAP Control Block */
102 #if (ERRCLASS & ERRCLS_INT_PAR)
103 if (pst->dstInst >= MAX_RLC_INSTANCES)
108 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
110 DU_LOG("\nDEBUG --> RLC UL : RlcLiRguBndCfm(suId(%d), status(%d)", suId, status);
112 #if (ERRCLASS & ERRCLS_INT_PAR)
113 if (tRlcCb->init.cfgDone != TRUE)
115 DU_LOG("\nERROR --> RLC UL : General configuration not done");
117 RLC_SEND_SAPID_ALARM(tRlcCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
122 if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
124 DU_LOG("\nERROR --> RLC UL : Invalid suId");
126 RLC_SEND_SAPID_ALARM(tRlcCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
132 rguSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
133 &(tRlcCb->u.dlCb->rguDlSap[suId]) : &(tRlcCb->u.ulCb->rguUlSap[suId]);
135 DU_LOG("\nDEBUG --> RLC UL : RlcLiRguBndCfm: For RGU SAP state=%d", rguSap->state);
137 switch (rguSap->state)
139 case RLC_SAP_BINDING:
141 rlcStopTmr (tRlcCb,(PTR)rguSap, EVENT_RLC_WAIT_BNDCFM);
143 rguSap->retryCnt = 0;
145 if (status == CM_BND_OK)
147 rguSap->state = RLC_SAP_BND;
148 event = LCM_EVENT_BND_OK;
149 cause = LKW_CAUSE_SAP_BNDENB;
153 rguSap->state = RLC_SAP_CFG;
154 event = LCM_EVENT_BND_FAIL;
155 cause = LKW_CAUSE_UNKNOWN;
161 event = LKW_EVENT_RGU_BND_CFM;
162 cause = LCM_CAUSE_INV_STATE;
166 /* Send an alarm with proper event and cause */
167 RLC_SEND_SAPID_ALARM(tRlcCb, suId, event, cause);
170 } /* RlcLiRguBndCfm */
175 * @brief Handler to process PDU received from MAC for common logical channels.
178 * This function receives the PDU from MAC for common logical channels
179 * does checks before handing over the PDU to the TM module
181 * @param[in] pst Post structure
182 * @param[in] suId Service User ID
183 * @param[in] datInd Data Indication Information
190 uint8_t rlcProcCommLcUlData(Pst *pst, SuId suId, RguCDatIndInfo *datInd)
197 #if (ERRCLASS & ERRCLS_INT_PAR)
198 if (pst->dstInst >= MAX_RLC_INSTANCES)
200 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
205 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
207 #if (ERRCLASS & ERRCLS_DEBUG)
208 if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
210 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
215 /* kw006.201 ccpu00120058, Added array boundary condition check */
216 #if (ERRCLASS & ERRCLS_DEBUG)
217 if(RLC_MAX_LCH_PER_CELL <= datInd->lcId)
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));
224 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
226 /* Fetch RbCb from lcId */
227 rlcDbmFetchUlRbCbFromLchId(tRlcCb, datInd->rnti, datInd->cellId, datInd->lcId, &rbCb);
230 DU_LOG("\nERROR --> RLC UL : rlcProcCommLcUlData : LcId [%d] not found",
232 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
236 /* Dispatch to TM Module */
238 rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->rnti, datInd->pdu);
240 rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->pdu);
241 #endif /* CCPU_OPT */
243 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
246 } /* rlcProcCommLcUlData */
249 * @brief Handler to process PDU received from MAC for
250 * dedicated logical channels.
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
256 * @param[in] pst Post structure
257 * @param[in] suId Service User ID
258 * @param[in] datInd Data Indication Information
266 uint8_t rlcProcDedLcUlData(Pst *pst, SuId suId, RguDDatIndInfo *datInd)
269 #if (ERRCLASS & ERRCLS_INT_PAR)
270 if (pst->dstInst >= MAX_RLC_INSTANCES)
272 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
277 #if (ERRCLASS & ERRCLS_DEBUG)
278 if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
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));
285 rlcUtlRcvFrmMac(RLC_GET_RLCCB(pst->dstInst),datInd);
287 #ifdef SS_LOCKLESS_MEMORY
288 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
290 RLC_PST_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
295 } /* rlcProcDedLcUlData */
298 * @brief Handler for trigerring the data transfer from RLC to MAC
299 * for common logical channels.
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.
305 * @param[in] pst Post structure
306 * @param[in] suId Service User ID
307 * @param[in] staInd Status Indication Information for Common Logical
315 uint8_t rlcProcCommLcSchedRpt(Pst *pst, SuId suId, RguCStaIndInfo *staInd)
320 #if (ERRCLASS & ERRCLS_INT_PAR)
321 if (pst->dstInst >= MAX_RLC_INSTANCES)
323 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
328 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
330 #if (ERRCLASS & ERRCLS_INT_PAR)
331 if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
333 DU_LOG("\nERROR --> RLC UL : rlcProcCommLcSchedRpt: Invalid RGU suId %d\n", suId);
336 if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
338 DU_LOG("\nDEBUG --> RLC UL : rlcProcCommLcSchedRpt: Received in RLC UL CELLID:%d",
340 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
347 /* kw006.201 ccpu00120058, added boundary condition check */
348 #if (ERRCLASS & ERRCLS_DEBUG)
349 if(RLC_MAX_LCH_PER_CELL < staInd->lcId)
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));
356 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
357 /* Fertch RbCb from lcId */
358 rlcDbmFetchDlRbCbFromLchId(tRlcCb,0, staInd->cellId, staInd->lcId, &rbCb);
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));
367 /* Dispatch to TM Module */
368 rbCb->transId = staInd->transId;
369 rlcTmmSendToMac(tRlcCb, suId, rbCb, staInd);
371 #ifdef SS_LOCKLESS_MEMORY
372 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
374 RLC_PST_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
377 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
380 } /* rlcProcCommLcSchedRpt */
383 * @brief Handler for trigerring the data transfer from RLC to MAC
384 * for dedicated logical channels.
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.
391 * @param[in] pst Post structure
392 * @param[in] suId Service User ID
393 * @param[in] staInd Status Indication Information for Dedicated Logical
401 uint8_t rlcProcDedLcSchedRpt(Pst *pst, SuId suId, RguDStaIndInfo *staInd)
405 #if (ERRCLASS & ERRCLS_INT_PAR)
406 if (pst->dstInst >= MAX_RLC_INSTANCES)
408 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
413 gCb = RLC_GET_RLCCB(pst->dstInst);
415 #if (ERRCLASS & ERRCLS_INT_PAR)
416 if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
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));
422 if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
424 DU_LOG("\nERROR --> RLC UL : rlcProcDedLcSchedRpt: Invalid RGU suId %d\n", suId);
428 rlcUtlSendToMac(gCb, suId, staInd);
430 /* kw002.201 :Freeing from proper region */
431 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
433 } /* rlcProcDedLcSchedRpt */
436 * @brief Handler for handling the flow cntrl Ind from MAC
440 * This function receives the flow control indication from
441 * MAC and calls rlcUtlTrigPdbFlowCntrl
443 * @param[in] pst Post structure
444 * @param[in] suId Service User ID
445 * @param[in] flowCntrlInd flow control Indication Information
453 S16 RlcLiRguFlowCntrlInd(Pst *pst,SuId suId,RguFlowCntrlInd *flowCntrlInd)
456 RlcDlRbCb *rbCb = NULLP;
460 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
461 for (idx = 0; idx < flowCntrlInd->numUes; idx++)
463 for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)
465 RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]);
466 rlcDbmFetchDlRbCbFromLchId(tRlcCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
470 if (lcInfo->pktAdmitCnt == 0) /* Special case */
472 rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
475 if (rbCb->mode == RLC_MODE_AM)
477 if ((rbCb->m.amDl.retxLst.count != 0) ||
478 ((rbCb->m.amDl.bo == 0) ||
479 (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
486 if ((rbCb->m.umDl.bo == 0) ||
487 (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
492 rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
498 /* kw005.201 added support for L2 Measurement */
505 * Handler for indicating the Harq Status of the data sent.
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.
514 * @param[in] pst - Post structure
515 * @param[in] suId - Service User ID
516 * @param[in] staInd - Harq Status Indication Information.
523 S16 RlcLiRguHqStaInd(Pst *pst, SuId suId,RguHarqStatusInd *staInd)
532 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
533 ueKey.cellId = staInd->cellId;
534 ueKey.ueId = staInd->ueId;
536 ret = rlcDbmFetchDlUeCb(tRlcCb, ueKey.ueId, ueKey.cellId, &ueCb);
542 /*Call rlcUtlProcHarqInd as many times as number of Tbs present*/
543 for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
545 rlcUtlProcHarqInd(tRlcCb, staInd, ueCb, tbIdx);
549 } /* RlcLiRguHqStaInd */
550 #endif /* LTE_L2_MEAS */
554 #endif /* __cplusplus */
556 /********************************************************************30**
558 **********************************************************************/