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: LTE-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 **********************************************************************/
38 static const char* RLOG_MODULE_NAME="LIM";
39 static int RLOG_MODULE_ID=2048;
40 static int RLOG_FILE_ID=196;
44 * @brief RLC Lower Interface module
47 #define RLC_MODULE RLC_DBGMASK_INF
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 */
57 #include "kw_env.h" /* RLC environment options */
59 #include "kw.h" /* RLC defines */
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 */
74 #include "rlc_utils.h"
75 #include "rlc_mac_inf.h"
79 #endif /* __cplusplus */
82 /*****************************************************************************
84 ****************************************************************************/
86 * @brief Handler for bind confirmation from MAC.
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
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
110 S16 RlcLiRguBndCfm (pst, suId, status)
116 U16 event; /* Event */
117 U16 cause; /* Cause */
118 RlcRguSapCb *rguSap; /* RGU SAP Control Block */
123 #if (ERRCLASS & ERRCLS_INT_PAR)
124 if (pst->dstInst >= MAX_RLC_INSTANCES)
129 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
131 RLOG2(L_DEBUG,"RlcLiRguBndCfm(suId(%d), status(%d)", suId, status);
133 #if (ERRCLASS & ERRCLS_INT_PAR)
134 if (tRlcCb->init.cfgDone != TRUE)
136 RLOG0(L_FATAL,"General configuration not done");
138 RLC_SEND_SAPID_ALARM(tRlcCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
143 if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
145 RLOG0(L_ERROR, "Invalid suId");
147 RLC_SEND_SAPID_ALARM(tRlcCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
151 #endif /* ERRCLASS & ERRCLS_INT_PAR */
153 rguSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
154 &(tRlcCb->u.dlCb->rguDlSap[suId]) : &(tRlcCb->u.ulCb->rguUlSap[suId]);
156 RLOG1(L_DEBUG, "RlcLiRguBndCfm: For RGU SAP state=%d", rguSap->state)
158 switch (rguSap->state)
160 case RLC_SAP_BINDING:
162 rlcStopTmr (tRlcCb,(PTR)rguSap, RLC_EVT_WAIT_BNDCFM);
164 rguSap->retryCnt = 0;
166 if (status == CM_BND_OK)
168 rguSap->state = RLC_SAP_BND;
169 event = LCM_EVENT_BND_OK;
170 cause = LKW_CAUSE_SAP_BNDENB;
174 rguSap->state = RLC_SAP_CFG;
175 event = LCM_EVENT_BND_FAIL;
176 cause = LKW_CAUSE_UNKNOWN;
182 event = LKW_EVENT_RGU_BND_CFM;
183 cause = LCM_CAUSE_INV_STATE;
187 /* Send an alarm with proper event and cause */
188 RLC_SEND_SAPID_ALARM(tRlcCb, suId, event, cause);
191 } /* RlcLiRguBndCfm */
196 * @brief Handler to process PDU received from MAC for common logical channels.
199 * This function receives the PDU from MAC for common logical channels
200 * does checks before handing over the PDU to the TM module
202 * @param[in] pst Post structure
203 * @param[in] suId Service User ID
204 * @param[in] datInd Data Indication Information
211 uint8_t rlcProcCommLcUlData(Pst *pst, SuId suId, RguCDatIndInfo *datInd)
218 #if (ERRCLASS & ERRCLS_INT_PAR)
219 if (pst->dstInst >= MAX_RLC_INSTANCES)
221 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
226 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
228 #if (ERRCLASS & ERRCLS_DEBUG)
229 if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
231 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
236 /* kw006.201 ccpu00120058, Added array boundary condition check */
237 #if (ERRCLASS & ERRCLS_DEBUG)
238 if(RLC_MAX_LCH_PER_CELL <= datInd->lcId)
240 DU_LOG("\nRLC : rlcProcCommLcUlData : Invalid LcId [%d], Max is [%d]",\
241 datInd->lcId, RLC_MAX_LCH_PER_CELL);
242 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
245 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
247 /* Fetch RbCb from lcId */
248 rlcDbmFetchUlRbCbFromLchId(tRlcCb, datInd->rnti, datInd->cellId, datInd->lcId, &rbCb);
251 DU_LOG("\nRLC : rlcProcCommLcUlData : LcId [%d] not found",
253 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
257 /* Dispatch to TM Module */
259 rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->rnti, datInd->pdu);
261 rlcTmmRcvFrmMac(tRlcCb, rbCb, datInd->pdu);
262 #endif /* CCPU_OPT */
264 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguCDatIndInfo));
267 } /* rlcProcCommLcUlData */
270 * @brief Handler to process PDU received from MAC for
271 * dedicated logical channels.
274 * This function receives the PDU from MAC for one or more dedicated
275 * logical channels and passes it to the UTL module for further processing
277 * @param[in] pst Post structure
278 * @param[in] suId Service User ID
279 * @param[in] datInd Data Indication Information
287 uint8_t rlcProcDedLcUlData(Pst *pst, SuId suId, RguDDatIndInfo *datInd)
290 #if (ERRCLASS & ERRCLS_INT_PAR)
291 if (pst->dstInst >= MAX_RLC_INSTANCES)
293 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
298 #if (ERRCLASS & ERRCLS_DEBUG)
299 if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
301 DU_LOG("\nRLC : rlcProcDedLcUlData : suId(%d))recieved in DL Inst", suId);
302 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
306 rlcUtlRcvFrmMac(RLC_GET_RLCCB(pst->dstInst),datInd);
308 #ifdef SS_LOCKLESS_MEMORY
309 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
311 RLC_PST_FREE(RLC_MEM_REGION_UL, RLC_POOL, datInd, sizeof(RguDDatIndInfo));
316 } /* rlcProcDedLcUlData */
319 * @brief Handler for trigerring the data transfer from RLC to MAC
320 * for common logical channels.
323 * This function receives the size of the PDU to be transmitted
324 * and acts as a trigger for forming PDU and sending it to MAC.
326 * @param[in] pst Post structure
327 * @param[in] suId Service User ID
328 * @param[in] staInd Status Indication Information for Common Logical
336 uint8_t rlcProcCommLcSchedRpt(Pst *pst, SuId suId, RguCStaIndInfo *staInd)
341 #if (ERRCLASS & ERRCLS_INT_PAR)
342 if (pst->dstInst >= MAX_RLC_INSTANCES)
344 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
349 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
351 #if (ERRCLASS & ERRCLS_INT_PAR)
352 if ((suId >= tRlcCb->genCfg.maxRguSaps) || (suId < 0))
354 DU_LOG("\nRLC: rlcProcCommLcSchedRpt: Invalid RGU suId %d\n", suId);
357 if (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
359 DU_LOG("\nRLC: rlcProcCommLcSchedRpt: Received in RLC UL CELLID:%d",
361 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
368 /* kw006.201 ccpu00120058, added boundary condition check */
369 #if (ERRCLASS & ERRCLS_DEBUG)
370 if(RLC_MAX_LCH_PER_CELL < staInd->lcId)
372 DU_LOG("\nRLC: rlcProcCommLcSchedRpt: Invalid LcId, Max is [%d] CELLID:%d",
373 RLC_MAX_LCH_PER_CELL, staInd->cellId);
374 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
377 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
378 /* Fertch RbCb from lcId */
379 rlcDbmFetchDlRbCbFromLchId(tRlcCb,0, staInd->cellId, staInd->lcId, &rbCb);
382 DU_LOG("\nRLC: rlcProcCommLcSchedRpt: LcId [%d] not found CELLID:%d",
383 staInd->lcId, staInd->cellId);
384 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
388 /* Dispatch to TM Module */
389 rbCb->transId = staInd->transId;
390 rlcTmmSendToMac(tRlcCb, suId, rbCb, staInd);
392 #ifdef SS_LOCKLESS_MEMORY
393 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
395 RLC_PST_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
398 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguCStaIndInfo));
401 } /* rlcProcCommLcSchedRpt */
404 * @brief Handler for trigerring the data transfer from RLC to MAC
405 * for dedicated logical channels.
408 * This function receives the size of the PDUs to be transmitted to
409 * MAC via one or more dedicated logical channels and acts as a trigger
410 * for forming PDUs and sending them to MAC.
412 * @param[in] pst Post structure
413 * @param[in] suId Service User ID
414 * @param[in] staInd Status Indication Information for Dedicated Logical
422 uint8_t rlcProcDedLcSchedRpt(Pst *pst, SuId suId, RguDStaIndInfo *staInd)
426 #if (ERRCLASS & ERRCLS_INT_PAR)
427 if (pst->dstInst >= MAX_RLC_INSTANCES)
429 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
434 gCb = RLC_GET_RLCCB(pst->dstInst);
436 #if (ERRCLASS & ERRCLS_INT_PAR)
437 if (((RlcCb*)RLC_GET_RLCCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
439 DU_LOG("\nRLC: rlcProcDedLcSchedRpt: Received in RLC UL ");
440 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
443 if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
445 DU_LOG("\nRLC: rlcProcDedLcSchedRpt: Invalid RGU suId %d\n", suId);
449 rlcUtlSendToMac(gCb, suId, staInd);
451 /* kw002.201 :Freeing from proper region */
452 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, staInd, sizeof(RguDStaIndInfo));
454 } /* rlcProcDedLcSchedRpt */
457 * @brief Handler for handling the flow cntrl Ind from MAC
461 * This function receives the flow control indication from
462 * MAC and calls rlcUtlTrigPdbFlowCntrl
464 * @param[in] pst Post structure
465 * @param[in] suId Service User ID
466 * @param[in] flowCntrlInd flow control Indication Information
475 S16 RlcLiRguFlowCntrlInd
479 RguFlowCntrlInd *flowCntrlInd
482 S16 RlcLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
485 RguFlowCntrlInd *flowCntrlInd;
489 RlcDlRbCb *rbCb = NULLP;
493 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
494 for (idx = 0; idx < flowCntrlInd->numUes; idx++)
496 for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)
498 RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]);
499 rlcDbmFetchDlRbCbFromLchId(tRlcCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
503 if (lcInfo->pktAdmitCnt == 0) /* Special case */
505 rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
508 if (rbCb->mode == CM_LTE_MODE_AM)
510 if ((rbCb->m.amDl.retxLst.count != 0) ||
511 ((rbCb->m.amDl.bo == 0) ||
512 (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
519 if ((rbCb->m.umDl.bo == 0) ||
520 (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
525 rlcUtlTrigPdbFlowCntrl(tRlcCb, rbCb, lcInfo->pktAdmitCnt);
531 /* kw005.201 added support for L2 Measurement */
538 * Handler for indicating the Harq Status of the data sent.
542 * This function receives the harq status of the data sent to MAC.
543 * This information is used for two things.
544 * 1. Computing the UuLoss of UM
545 * 2. Computing the DL Delay for UM and AM.
547 * @param[in] pst - Post structure
548 * @param[in] suId - Service User ID
549 * @param[in] staInd - Harq Status Indication Information.
561 RguHarqStatusInd *staInd
564 S16 RlcLiRguHqStaInd(pst,suId,staInd)
567 RguHarqStatusInd *staInd;
577 TRC3(RlcLiRguHqStaInd)
579 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
580 ueKey.cellId = staInd->cellId;
581 ueKey.ueId = staInd->ueId;
583 ret = rlcDbmFetchDlUeCb(tRlcCb, ueKey.ueId, ueKey.cellId, &ueCb);
589 /*Call rlcUtlProcHarqInd as many times as number of Tbs present*/
590 for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
592 rlcUtlProcHarqInd(tRlcCb, staInd, ueCb, tbIdx);
596 } /* RlcLiRguHqStaInd */
597 #endif /* LTE_L2_MEAS */
601 #endif /* __cplusplus */
603 /********************************************************************30**
605 **********************************************************************/