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 /**********************************************************************
25 Desc: Source code for RLC Transparent mode assembly and
26 reassembly.This file contains following functions
35 **********************************************************************/
36 static const char* RLOG_MODULE_NAME="TMM";
37 static int RLOG_MODULE_ID=2048;
38 static int RLOG_FILE_ID=200;
41 * @brief RLC Transparent Mode module
44 /* header (.h) include files */
45 #include "common_def.h"
46 #include "lkw.h" /* LKW defines */
47 #include "ckw.h" /* CKW defines */
48 #include "kwu.h" /* KWU defines */
49 #include "rgu.h" /* RGU defines */
50 #include "kw_env.h" /* RLC environment options */
52 #include "kw.h" /* RLC defines */
53 #include "kw_err.h" /* RLC defines */
57 /* extern (.x) include files */
58 #include "lkw.x" /* LKW */
59 #include "ckw.x" /* CKW */
60 #include "kwu.x" /* KWU */
61 #include "rgu.x" /* RGU */
67 #define KW_MODULE (KW_DBGMASK_TM | KW_DBGMASK_DL)
69 PRIVATE Void kwTmmSndStaRsp ARGS((RlcCb *gCb, RlcDlRbCb *rbCb,
70 MsgLen bo, KwuDatReqInfo *datReqInfo));
72 /** @addtogroup tmmode */
77 * Handler to queue the SDU in the SDU queue and update BO and report it to
81 * This function is used to queue the received SDU in the SDU queue
82 * maintained in the radio bearer control block. After queuing the SDU, BO
83 * is updated and is reported to the lower layer.
85 * @param[in] rbCb RB control block.
86 * @param[in] datReqInfo Data Request Information.
87 * @param[in] mBuf SDU Buffer.
98 KwuDatReqInfo *datReqInfo,
102 PUBLIC Void kwTmmQSdu(gCb,rbCb,datReqInfo,mBuf)
105 KwuDatReqInfo *datReqInfo;
114 RLC_ALLOC(gCb,sdu,sizeof(KwSdu));
115 #if (ERRCLASS & ERRCLS_ADD_RES)
118 RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
119 "Memory Allocation failed UEID:%d CELLID:%d",
124 #endif /* ERRCLASS & ERRCLS_ADD_RES */
126 if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH ||
127 rbCb->lch.lChType == CM_LTE_LCH_PCCH )
129 sdu->mode.tm.sfn = datReqInfo->tm.tmg.sfn;
130 sdu->mode.tm.slot = datReqInfo->tm.tmg.slot;
132 if(rbCb->lch.lChType == CM_LTE_LCH_PCCH)
134 sdu->mode.tm.pnb = datReqInfo->pnb;
140 sdu->mode.tm.rnti = datReqInfo->tm.rnti;
143 sdu->arrTime = rgMacGT;
144 SFndLenMsg(mBuf,&sdu->sduSz);
147 cmLListAdd2Tail(&(rbCb->m.tm.sduQ), &(sdu->lstEnt));
148 sdu->lstEnt.node = (PTR)sdu;
150 kwTmmSndStaRsp(gCb, rbCb, sdu->sduSz, datReqInfo);
156 * Handler to form a pdu and send it to the lower layer.
159 * This function forms one pdu from the first SDU in the SDU queue and sends
160 * it to the lower layer.
162 * @param[in] gCb RLC Instance Control Block
163 * @param[in] rbCb RB control block.
164 * @param[in] staInd Status Indication of common logical channel
171 PUBLIC Void kwTmmSndToLi
176 RguCStaIndInfo *staInd
179 PUBLIC Void kwTmmSndToLi(gCb, suId, rbCb, staInd)
183 RguCStaIndInfo *staInd;
186 CmLList *node; /* Current Link List Node */
187 KwSdu *sdu; /* SDU */
195 CM_LLIST_FIRST_NODE(&(rbCb->m.tm.sduQ),
198 /* (Sfn,slot) at which the message should be transmitted is
199 * validated with alloted (sfn,slot)in the MAC layer */
200 while (node != NULLP)
202 sdu = (KwSdu *)(node->node);
203 if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH ||
204 rbCb->lch.lChType == CM_LTE_LCH_PCCH )
207 /* MS_FIX: syed sfn is of 10 bytes rather than 8 */
209 /* As part of CATM feature cross slot scheduling is implemented , so there is some delta(currently 2)
210 between MPDCCH and PDSCH,RLC expects cell crntTime of transmission of control dlsf, so one extra
211 information is provided in staInd, so that sfn,slot should calculate from paging Timing information
212 in case of EMTC paging, instead of transId */
213 if(staInd->isEmtcPaging)
215 sfn = staInd->pagingTimingInfo.sfn;
216 slot = staInd->pagingTimingInfo.slot;
221 sfn = (staInd->transId >> 8) & 0x3FF;
222 slot = staInd->transId & 0xFF;
226 * tm.slot - current slot
232 /* MS_FIX: syed Incorrect sfn determination.
233 * Take care of SFN wraparound. TODO: It is better for RLC
234 * not to be aware of SCH DELTAs. So we should look for
235 * sending actual transmission time to RLC. */
236 if ((slot + TFU_DELTA) >= 10)
238 sfn = (sfn + 1)%1024;
241 if ((sdu->mode.tm.sfn != sfn) ||
242 (sdu->mode.tm.slot != ((slot+TFU_DELTA)%10)))
245 RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,
246 "Releasing SDU of RNTI = %d for RNTI = %d UEID:%d CELLID:%d",
251 RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,
252 "sfn %d slot %d UEID:%d CELLID:%d",
257 cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
258 RLC_FREE_BUF(sdu->mBuf);
259 RLC_FREE(gCb, sdu, sizeof(KwSdu));
269 if (curTime < sdu->arrTime)
271 timeDiff = (10240 - sdu->arrTime) + curTime;
275 timeDiff = curTime - sdu->arrTime;
277 RLOG_ARG4(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId,
278 "TMM: TmSdu Sta Indication received for Rnti %d Sdu Rnti %d "
279 " UEID:%d CELLID:%d",
284 RLOG_ARG4(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId,
285 "TMM: TmSdu Sta Indication received : timeDiff %d SduQCnt %lu"
286 " UEID:%d CELLID:%d",
288 rbCb->m.tm.sduQ.count,
293 /* Memory leak needs to be fixed */
295 RLOG_ARG3(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId,
296 " timeDiff greater than 40, so deleting the Sdu %u "
297 " UEID:%d CELLID:%d",
301 cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
302 RLC_FREE_BUF(sdu->mBuf);
303 RLC_FREE(gCb, sdu, sizeof(KwSdu));
307 if (sdu->mode.tm.rnti != staInd->rnti)
309 /* Memory leak needs to be fixed */
311 RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,
312 "TMM: Searching for Rnti %d Skipping Sdu for Rnti %d"
313 " UEID:%d CELLID:%d",
318 RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,
319 " timeDiff %d sdu->arrTime %d"
320 " UEID:%d CELLID:%d",
325 RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,
326 "curTime %d SduQCnt %lu and continuing"
327 " UEID:%d CELLID:%d",
329 rbCb->m.tm.sduQ.count,
336 RLOG_ARG3(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId,
337 "TMM: TmSdu found %u UEID:%d CELLID:%d",
348 RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId,
349 "SDU not found TM Queue is empty UEID:%d CELLID:%d",
354 sdu = (KwSdu *)node->node;
356 RLC_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap[suId].pst.region,
357 gCb->u.dlCb->rguDlSap[suId].pst.pool,
358 dlData,(Size)sizeof(RlcMacData));
359 #if (ERRCLASS & ERRCLS_ADD_RES)
360 if ( dlData == NULLP )
362 RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
363 "Memory Allocation failed UEID:%d CELLID:%d",
368 #endif /* ERRCLASS & ERRCLS_ADD_RES */
370 dlData->slotInfo.sfn = sdu->mode.tm.sfn;
371 dlData->slotInfo.slot = sdu->mode.tm.slot;
372 dlData->cellId = rbCb->rlcId.cellId;
373 dlData->rnti = sdu->mode.tm.rnti;
375 dlData->pduInfo[0].commCh = TRUE;
376 dlData->pduInfo[0].lcId = rbCb->lch.lChId;
377 dlData->pduInfo[0].pduBuf = sdu->mBuf;
379 /* kw005.201 ccpu00117318, updating the statistics */
380 gCb->genSts.bytesSent += sdu->sduSz;
381 gCb->genSts.pdusSent++;
383 kwUtlIncrementKwuStsSduTx(gCb->u.dlCb->kwuDlSap + rbCb->kwuSapId);
385 /* remove SDU from queue */
387 cmLListDelFrm(&(rbCb->m.tm.sduQ),
389 RLC_FREE(gCb,sdu, sizeof(KwSdu));
391 /* If trace flag is enabled send the trace indication */
392 if(gCb->init.trc == TRUE)
394 /* Populate the trace params */
395 kwLmmSendTrc(gCb,EVTRLCDLDAT, NULLP);
398 RlcMacSendDlData(&(gCb->u.dlCb->rguDlSap[suId].pst),
399 gCb->u.dlCb->rguDlSap[suId].spId,
407 * Handler to process the re-establishment request received from the upper
411 * This function empties the SDU queue for the RB in the downlink.
413 * @param[in] gCb RLC Instance Control Block
414 * @param[in] rbCb RB control block.
420 PUBLIC Void rlcDlTmmReEstablish
426 PUBLIC Void rlcDlTmmReEstablish(gCb,rbCb)
431 TRC2(rlcDlTmmReEstablish)
434 #ifdef LTE_L2_MEAS_RLC
435 kwUtlEmptySduQ(gCb, rbCb, &rbCb->m.tm.sduQ);
437 kwUtlEmptySduQ(gCb,&rbCb->m.tm.sduQ);
445 * Handler to send Status Response to the lower layer.
448 * This function is used to the BO to the lower layer after receiving a data
449 * request from the upper layer.
451 * @param[in] gCb RLC Instance Control Block
452 * @param[in] rbCb RB control block.
453 * @param[in] bo Buffer Occupancy
454 * @param[in] datReqInfo Data Request Information.
462 PRIVATE Void kwTmmSndStaRsp
467 KwuDatReqInfo *datReqInfo
470 PRIVATE Void kwTmmSndStaRsp(rbCb,bo,datReqInfo)
474 KwuDatReqInfo *datReqInfo;
477 // RguCStaRspInfo *staRspInfo; /* Status Response Information */
478 RlcMacBOStatus *boStatus; /* Buffer occupancy status information */
479 KwRguSapCb *rguSap; /* SAP Information */
484 rguSap = &(gCb->u.dlCb->rguDlSap[rbCb->rguSapId]);
486 RLC_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap[rbCb->rguSapId].pst.region,
487 gCb->u.dlCb->rguDlSap[rbCb->rguSapId].pst.pool,
488 boStatus, sizeof(RguCStaRspInfo));
489 #if (ERRCLASS & ERRCLS_ADD_RES)
490 if ( boStatus == NULLP )
492 RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
493 "Memory Allocation failed UEID:%d CELLID:%d",
498 #endif /* ERRCLASS & ERRCLS_ADD_RES */
500 boStatus->cellId = rbCb->rlcId.cellId;
501 boStatus->rnti = rbCb->rlcId.ueId;
502 boStatus->commCh = TRUE;
503 boStatus->lcId = rbCb->lch.lChId;
506 /* If trace flag is enabled send the trace indication */
507 if(gCb->init.trc == TRUE)
509 /* Populate the trace params */
510 kwLmmSendTrc(gCb, EVTRLCBOSTA, NULLP);
513 RlcMacSendBOStatus(&rguSap->pst, rguSap->spId, boStatus);
522 /********************************************************************30**
524 **********************************************************************/