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
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 KW_MODULE KW_DBGMASK_INF
50 /* header (.h) include files */
51 #include "envopt.h" /* environment options */
52 #include "envdep.h" /* environment dependent */
53 #include "envind.h" /* environment independent */
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 */
68 #include "kw_env.h" /* RLC environment options */
70 #include "kw.h" /* RLC defines */
75 /* extern (.x) include files */
76 #include "gen.x" /* general */
77 #include "ssi.x" /* system services */
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 */
98 #endif /* __cplusplus */
101 /*****************************************************************************
103 ****************************************************************************/
105 * @brief Handler for bind confirmation from MAC.
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
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
122 PUBLIC S16 KwLiRguBndCfm
129 PUBLIC S16 KwLiRguBndCfm (pst, suId, status)
135 U16 event; /* Event */
136 U16 cause; /* Cause */
137 KwRguSapCb *rguSap; /* RGU SAP Control Block */
142 #if (ERRCLASS & ERRCLS_INT_PAR)
143 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
148 tKwCb = KW_GET_KWCB(pst->dstInst);
150 RLOG2(L_DEBUG,"KwLiRguBndCfm(suId(%d), status(%d)", suId, status);
152 #if (ERRCLASS & ERRCLS_INT_PAR)
153 if (tKwCb->init.cfgDone != TRUE)
155 RLOG0(L_FATAL,"General configuration not done");
157 KW_SEND_SAPID_ALARM(tKwCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
162 if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
164 RLOG0(L_ERROR, "Invalid suId");
166 KW_SEND_SAPID_ALARM(tKwCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
170 #endif /* ERRCLASS & ERRCLS_INT_PAR */
172 rguSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
173 &(tKwCb->u.dlCb->rguDlSap[suId]) : &(tKwCb->u.ulCb->rguUlSap[suId]);
175 RLOG1(L_DEBUG, "KwLiRguBndCfm: For RGU SAP state=%d", rguSap->state)
177 switch (rguSap->state)
181 kwStopTmr (tKwCb,(PTR)rguSap, KW_EVT_WAIT_BNDCFM);
183 rguSap->retryCnt = 0;
185 if (status == CM_BND_OK)
187 rguSap->state = KW_SAP_BND;
188 event = LCM_EVENT_BND_OK;
189 cause = LKW_CAUSE_SAP_BNDENB;
193 rguSap->state = KW_SAP_CFG;
194 event = LCM_EVENT_BND_FAIL;
195 cause = LKW_CAUSE_UNKNOWN;
201 event = LKW_EVENT_RGU_BND_CFM;
202 cause = LCM_CAUSE_INV_STATE;
206 /* Send an alarm with proper event and cause */
207 KW_SEND_SAPID_ALARM(tKwCb, suId, event, cause);
210 } /* KwLiRguBndCfm */
212 PUBLIC int rlcDDatIndRcvd;
213 PUBLIC int rlcCDatIndRcvd;
215 * @brief Handler to process PDU received from MAC for common logical channels.
218 * This function receives the PDU from MAC for common logical channels
219 * does checks before handing over the PDU to the TM module
221 * @param[in] pst Post structure
222 * @param[in] suId Service User ID
223 * @param[in] datInd Data Indication Information
231 PUBLIC S16 KwLiRguCDatInd
235 RguCDatIndInfo *datInd
238 PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd)
241 RguCDatIndInfo *datInd;
250 #if (ERRCLASS & ERRCLS_INT_PAR)
251 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
253 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
258 tKwCb = KW_GET_KWCB(pst->dstInst);
261 #if (ERRCLASS & ERRCLS_DEBUG)
262 if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
264 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
269 /* kw006.201 ccpu00120058, Added array boundary condition check */
270 #if (ERRCLASS & ERRCLS_DEBUG)
271 if(KW_MAX_LCH_PER_CELL <= datInd->lcId)
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));
278 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
280 /* Fetch RbCb from lcId */
281 kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb);
284 RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found",
286 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
290 /* Dispatch to TM Module */
292 kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu);
294 kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu);
295 #endif /* CCPU_OPT */
297 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
300 } /* KwLiRguCDatInd */
303 * @brief Handler to process PDU received from MAC for
304 * dedicated logical channels.
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
310 * @param[in] pst Post structure
311 * @param[in] suId Service User ID
312 * @param[in] datInd Data Indication Information
321 PUBLIC S16 KwLiRguDDatInd
325 RguDDatIndInfo *datInd
328 PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd)
331 RguDDatIndInfo *datInd;
337 #if (ERRCLASS & ERRCLS_INT_PAR)
338 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
340 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
345 #if (ERRCLASS & ERRCLS_DEBUG)
346 if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
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));
353 kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd);
355 #ifdef SS_LOCKLESS_MEMORY
356 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
358 KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
363 } /* KwLiRguDDatInd */
366 * @brief Handler for trigerring the data transfer from RLC to MAC
367 * for common logical channels.
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.
373 * @param[in] pst Post structure
374 * @param[in] suId Service User ID
375 * @param[in] staInd Status Indication Information for Common Logical
384 PUBLIC S16 KwLiRguCStaInd
388 RguCStaIndInfo *staInd
391 PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd)
394 RguCStaIndInfo *staInd;
402 #if (ERRCLASS & ERRCLS_INT_PAR)
403 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
405 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
410 tKwCb = KW_GET_KWCB(pst->dstInst);
413 #if (ERRCLASS & ERRCLS_INT_PAR)
414 if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
420 "KwLiRguCStaInd: Invalid RGU suId\n");
423 if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
425 RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId,
426 "Received in RLC UL CELLID:%d",
428 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
435 /* kw006.201 ccpu00120058, added boundary condition check */
436 #if (ERRCLASS & ERRCLS_DEBUG)
437 if(KW_MAX_LCH_PER_CELL < staInd->lcId)
439 RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId,
440 "Invalid LcId, Max is [%d] CELLID:%d",
443 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
446 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
447 /* Fertch RbCb from lcId */
448 kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb);
451 RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId,
452 "LcId [%d] not found CELLID:%d",
454 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
458 /* Dispatch to TM Module */
459 rbCb->transId = staInd->transId;
461 /* If trace flag is enabled send the trace indication */
462 if(tKwCb->init.trc == TRUE)
464 /* Populate the trace params */
465 kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP);
467 kwTmmSndToLi(tKwCb, suId, rbCb, staInd);
469 #ifdef SS_LOCKLESS_MEMORY
470 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
472 KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
475 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
478 } /* KwLiRguCStaInd */
481 * @brief Handler for trigerring the data transfer from RLC to MAC
482 * for dedicated logical channels.
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.
489 * @param[in] pst Post structure
490 * @param[in] suId Service User ID
491 * @param[in] staInd Status Indication Information for Dedicated Logical
500 PUBLIC S16 KwLiRguDStaInd
504 RguDStaIndInfo *staInd
507 PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd)
510 RguDStaIndInfo *staInd;
516 #if (ERRCLASS & ERRCLS_INT_PAR)
517 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
519 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
524 gCb = KW_GET_KWCB(pst->dstInst);
526 #if (ERRCLASS & ERRCLS_INT_PAR)
527 if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
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));
533 if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
539 "KwLiRguDStaInd: Invalid RGU suId\n");
543 kwUtlSndToLi(gCb, suId, staInd);
545 /* kw002.201 :Freeing from proper region */
546 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
548 } /* KwLiRguDStaInd */
551 * @brief Handler for handling the flow cntrl Ind from MAC
555 * This function receives the flow control indication from
556 * MAC and calls kwUtlTrigPdbFlowCntrl
558 * @param[in] pst Post structure
559 * @param[in] suId Service User ID
560 * @param[in] flowCntrlInd flow control Indication Information
569 PUBLIC S16 KwLiRguFlowCntrlInd
573 RguFlowCntrlInd *flowCntrlInd
576 PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
579 RguFlowCntrlInd *flowCntrlInd;
583 KwDlRbCb *rbCb = NULLP;
587 tKwCb = KW_GET_KWCB(pst->dstInst);
588 for (idx = 0; idx < flowCntrlInd->numUes; idx++)
590 for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)
592 RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]);
593 kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
597 if (lcInfo->pktAdmitCnt == 0) /* Special case */
599 kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
602 if (rbCb->mode == CM_LTE_MODE_AM)
604 if ((rbCb->m.amDl.retxLst.count != 0) ||
605 ((rbCb->m.amDl.bo == 0) ||
606 (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
613 if ((rbCb->m.umDl.bo == 0) ||
614 (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
619 kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
625 /* kw005.201 added support for L2 Measurement */
632 * Handler for indicating the Harq Status of the data sent.
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.
641 * @param[in] pst - Post structure
642 * @param[in] suId - Service User ID
643 * @param[in] staInd - Harq Status Indication Information.
651 PUBLIC S16 KwLiRguHqStaInd
655 RguHarqStatusInd *staInd
658 PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd)
661 RguHarqStatusInd *staInd;
671 TRC3(KwLiRguHqStaInd)
673 tKwCb = KW_GET_KWCB(pst->dstInst);
674 ueKey.cellId = staInd->cellId;
675 ueKey.ueId = staInd->ueId;
677 ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb);
683 /*Call kwUtlProcHarqInd as many times as number of Tbs present*/
684 for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
686 kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx);
690 } /* KwLiRguHqStaInd */
691 #endif /* LTE_L2_MEAS */
695 #endif /* __cplusplus */
697 /********************************************************************30**
699 **********************************************************************/