U8, U16, U32 data type changes
[o-du/l2.git] / src / 5gnrrlc / kw_tmm_dl.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
21      Name:     LTE-RLC Layer 
22   
23      Type:     C file
24   
25      Desc:     Source code for RLC Transparent mode assembly and
26                reassembly.This file contains following functions
27                 
28                   --rlcTmmQSdu
29                   --rlcTmmSendToMac
30                   --rlcTmmRcvFrmMac
31                   --kwTmmReEstablish 
32
33      File:     kw_tmm_dl.c
34
35 **********************************************************************/
36 /** 
37  * @file kw_tmm_dl.c
38  * @brief RLC Transparent Mode module
39 */
40 \f
41 /* header (.h) include files */
42 #include "common_def.h"
43 #include "lkw.h"           /* LKW defines */
44 #include "ckw.h"           /* CKW defines */
45 #include "kwu.h"           /* KWU defines */
46 #include "rgu.h"           /* RGU defines */
47 #include "kw_env.h"        /* RLC environment options */
48
49 #include "kw.h"            /* RLC defines */
50 #include "kw_err.h"            /* RLC defines */
51 #include "kw_udx.h"
52 #include "kw_dl.h"
53
54 /* extern (.x) include files */
55 #include "lkw.x"           /* LKW */
56 #include "ckw.x"           /* CKW */
57 #include "kwu.x"           /* KWU */
58 #include "rgu.x"           /* RGU */
59
60 #include "kw.x"
61 #include "kw_udx.x"
62 #include "kw_dl.x"
63 #include "rlc_utils.h"
64 #include "rlc_mac_inf.h"
65 #include "rlc_lwr_inf_api.h"
66
67 #define RLC_MODULE (RLC_DBGMASK_TM | RLC_DBGMASK_DL)
68
69 PRIVATE Void rlcTmmSendBoSta ARGS((RlcCb *gCb, RlcDlRbCb *rbCb, 
70                                  MsgLen bo, KwuDatReqInfo *datReqInfo));
71 extern uint32_t rgMacGT ;  
72 /** @addtogroup tmmode */
73 /*@{*/
74
75 /**
76  * @brief 
77  *    Handler to queue the SDU in the SDU queue and update BO and report it to
78  *    the lower layer.
79  *
80  * @details 
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. 
84  *            
85  *  @param[in] rbCb         RB control block. 
86  *  @param[in] datReqInfo   Data Request Information.
87  *  @param[in] mBuf         SDU Buffer.
88  *
89  *  @return  S16
90  *      -# ROK 
91  *      -# RFAILED 
92  */
93 #ifdef ANSI
94 Void rlcTmmQSdu
95 (
96 RlcCb            *gCb,
97 RlcDlRbCb        *rbCb,      
98 KwuDatReqInfo   *datReqInfo, 
99 Buffer          *mBuf       
100 )
101 #else
102 Void rlcTmmQSdu(gCb,rbCb,datReqInfo,mBuf)
103 RlcCb            *gCb;
104 RlcDlRbCb        *rbCb;       
105 KwuDatReqInfo   *datReqInfo;  
106 Buffer          *mBuf;         
107 #endif
108 {
109    RlcSdu   *sdu;              
110  
111    RLC_ALLOC(gCb,sdu,sizeof(RlcSdu));
112 #if (ERRCLASS & ERRCLS_ADD_RES)
113    if ( sdu == NULLP )
114    {
115       RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
116             "Memory Allocation failed UEID:%d CELLID:%d",   
117             rbCb->rlcId.ueId,
118             rbCb->rlcId.cellId);   
119       return;
120    }
121 #endif /* ERRCLASS & ERRCLS_ADD_RES */
122 #ifdef CCPU_OPT   
123    if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || 
124         rbCb->lch.lChType == CM_LTE_LCH_PCCH )
125    {
126       sdu->mode.tm.sfn = datReqInfo->tm.tmg.sfn;
127       sdu->mode.tm.slot = datReqInfo->tm.tmg.slot;
128 #ifdef EMTC_ENABLE
129      if(rbCb->lch.lChType == CM_LTE_LCH_PCCH)
130      {
131         sdu->mode.tm.pnb = datReqInfo->pnb;
132      }
133 #endif
134    }
135    else
136    {
137       sdu->mode.tm.rnti = datReqInfo->tm.rnti;
138    }
139 #endif
140    sdu->arrTime = rgMacGT;
141    SFndLenMsg(mBuf,&sdu->sduSz); 
142    sdu->mBuf = mBuf;
143    
144    cmLListAdd2Tail(&(rbCb->m.tm.sduQ), &(sdu->lstEnt));  
145    sdu->lstEnt.node = (PTR)sdu; 
146
147    rlcTmmSendBoSta(gCb, rbCb, sdu->sduSz, datReqInfo); 
148    return;
149 }
150
151 /**
152 * @brief 
153 *    Handler to form a pdu and send it to the lower layer.
154
155 * @details 
156 *    This function forms one pdu from the first SDU in the SDU queue and sends 
157 *    it to the lower layer.
158 *             
159 * @param[in] gCb     RLC Instance Control Block
160 * @param[in] rbCb    RB control block. 
161 * @param[in] staInd  Status Indication of common logical channel 
162 *
163 * @return  S16
164 *    -# ROK 
165 *    -# RFAILED         
166 */
167 void rlcTmmSendToMac(RlcCb *gCb, SuId suId, RlcDlRbCb *rbCb, RguCStaIndInfo *staInd)
168 {
169    Pst              pst;
170    CmLList          *node;          /* Current Link List Node */
171    RlcSdu           *sdu;           /* SDU */
172    RlcData          *dlData;
173    uint16_t         pduLen;
174    uint16_t         copyLen;
175    int16_t          timeDiff = 0;
176    Ticks            curTime  = 0;
177
178    CM_LLIST_FIRST_NODE(&(rbCb->m.tm.sduQ), 
179                        node);
180
181    /* (Sfn,slot) at which the message should be transmitted is 
182     * validated with alloted (sfn,slot)in the MAC layer */
183    while (node != NULLP)
184    {
185       sdu = (RlcSdu *)(node->node);
186       if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH ||
187             rbCb->lch.lChType == CM_LTE_LCH_PCCH )
188       {
189          uint16_t sfn, slot;
190          /* MS_FIX: syed sfn is of 10 bytes rather than 8 */
191 #ifdef EMTC_ENABLE
192          /* As part of CATM feature cross slot scheduling is implemented , so there is some delta(currently 2)
193             between MPDCCH and PDSCH,RLC expects cell crntTime of transmission of control dlsf, so one extra 
194             information is provided in staInd, so that sfn,slot should calculate from paging Timing information 
195             in case of EMTC paging, instead of transId */
196          if(staInd->isEmtcPaging)
197          {
198             sfn      = staInd->pagingTimingInfo.sfn;
199             slot = staInd->pagingTimingInfo.slot;
200          }
201          else
202 #endif
203          {
204             sfn = (staInd->transId >> 8) & 0x3FF;
205             slot = staInd->transId & 0xFF;
206          }
207
208          /* Table
209           * tm.slot - current slot 
210           * 0,sfn        7,sfn-1
211           * 4,sfn        1,sfn
212           * 5,sfn        2,sfn
213           * 9,sfn        6,sfn
214           */
215          /* MS_FIX: syed Incorrect sfn determination. 
216           * Take care of SFN wraparound. TODO: It is better for RLC
217           * not to be aware of SCH DELTAs. So we should look for 
218           * sending actual transmission time to RLC. */
219          if ((slot + TFU_DELTA) >= 10)
220          {
221             sfn = (sfn + 1)%1024;
222          }
223
224          if ((sdu->mode.tm.sfn != sfn) ||
225                (sdu->mode.tm.slot != ((slot+TFU_DELTA)%10)))
226          {
227             node = node->next;
228             DU_LOG("\nRLC: rlcTmmSendToMac: Releasing SDU of RNTI = %d for RNTI = %d \
229                UEID:%d CELLID:%d", sdu->mode.tm.rnti, staInd->rnti, rbCb->rlcId.ueId,
230                rbCb->rlcId.cellId);   
231             DU_LOG("\nRLC: rlcTmmSendToMac: sfn %d slot %d  UEID:%d CELLID:%d",
232                   sfn, slot, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
233             cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
234             RLC_FREE_BUF(sdu->mBuf);
235             RLC_FREE(gCb, sdu, sizeof(RlcSdu));
236          }
237          else
238          {
239             break;
240          }
241       }
242       else
243       {
244          curTime = rgMacGT;
245          if (curTime < sdu->arrTime)
246          {
247             timeDiff = (10240 - sdu->arrTime) + curTime;
248          }
249          else
250          {
251             timeDiff = curTime - sdu->arrTime;
252          }
253          DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu Sta Indication received \
254             for Rnti %d Sdu Rnti %d UEID:%d CELLID:%d", staInd->rnti, 
255             sdu->mode.tm.rnti, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
256          DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu Sta Indication received : \
257             timeDiff %d SduQCnt %d UEID:%d CELLID:%d", timeDiff, rbCb->m.tm.sduQ.count,
258             rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
259          if (timeDiff > 40)
260          {
261             /* Memory leak needs to be fixed */
262             node = node->next;
263             DU_LOG("\nRLC: rlcTmmSendToMac: timeDiff greater than 40, so deleting\
264                the Sdu %u UEID:%d CELLID:%d", sdu->mode.tm.rnti, rbCb->rlcId.ueId,
265                rbCb->rlcId.cellId);   
266             cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
267             RLC_FREE_BUF(sdu->mBuf);
268             RLC_FREE(gCb, sdu, sizeof(RlcSdu));
269             continue;
270          }
271
272          if (sdu->mode.tm.rnti != staInd->rnti)
273          {
274             /* Memory leak needs to be fixed */
275             node = node->next;
276             DU_LOG("\nRLC: rlcTmmSendToMac: TMM: Searching for Rnti %d Skipping \
277                Sdu for Rnti %d UEID:%d CELLID:%d", staInd->rnti, sdu->mode.tm.rnti, 
278                rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
279             DU_LOG("\nRLC: rlcTmmSendToMac: timeDiff %d sdu->arrTime %d UEID:%d CELLID:%d", 
280                 timeDiff, sdu->arrTime, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
281             DU_LOG("\nRLC: rlcTmmSendToMac: curTime %d SduQCnt %d and continuing"
282                " UEID:%d CELLID:%d", curTime, rbCb->m.tm.sduQ.count, rbCb->rlcId.ueId,
283                rbCb->rlcId.cellId);   
284             continue;
285          }
286          else
287          {
288             DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu found %u UEID:%d CELLID:%d",
289                sdu->mode.tm.rnti, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
290             break;
291          }
292       }
293
294    }
295    if ( node == NULLP )
296    {
297       DU_LOG("\nRLC: rlcTmmSendToMac: SDU not found TM Queue is empty UEID:%d CELLID:%d",
298          rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
299       return;
300    }
301    sdu = (RlcSdu *)node->node;
302
303     RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
304                         dlData,(Size)sizeof(RlcData));
305 #if (ERRCLASS & ERRCLS_ADD_RES)
306    if ( dlData == NULLP )
307    {
308       DU_LOG("\nRLC: rlcTmmSendToMac: Memory Allocation failed UEID:%d CELLID:%d",   
309          rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
310       return; 
311    }
312 #endif /* ERRCLASS & ERRCLS_ADD_RES */
313
314    dlData->slotInfo.sfn = sdu->mode.tm.sfn;
315    dlData->slotInfo.slot = sdu->mode.tm.slot;
316    dlData->cellId = rbCb->rlcId.cellId;
317    dlData->rnti = sdu->mode.tm.rnti;
318    dlData->numPdu = 1;
319    dlData->pduInfo[0].commCh = TRUE;
320    dlData->pduInfo[0].lcId = rbCb->lch.lChId;
321
322    /* Copy Message to fixed buffer to send */
323    ODU_GET_MSG_LEN(sdu->mBuf, (MsgLen *)&pduLen);
324    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
325       dlData->pduInfo[0].pduBuf, pduLen);
326    if (dlData->pduInfo[0].pduBuf == NULLP )
327    {
328       DU_LOG("Memory allocation failed");
329       return;
330    }
331    ODU_COPY_MSG_TO_FIX_BUF(sdu->mBuf, 0, pduLen, \
332       dlData->pduInfo[0].pduBuf, (MsgLen *)&copyLen);
333    dlData->pduInfo[0].pduLen = pduLen;
334
335    /* Free message */
336    ODU_PUT_MSG_BUF(sdu->mBuf);
337
338    /* kw005.201 ccpu00117318, updating the statistics */
339    gCb->genSts.bytesSent += sdu->sduSz;
340    gCb->genSts.pdusSent++;
341
342    rlcUtlIncrementKwuStsSduTx(gCb->u.dlCb->rlcKwuDlSap + rbCb->k1wuSapId);   
343
344    /* remove SDU from queue */ 
345    sdu->mBuf = NULLP;
346    cmLListDelFrm(&(rbCb->m.tm.sduQ),
347                  &sdu->lstEnt); 
348    RLC_FREE(gCb,sdu, sizeof(RlcSdu));
349
350    /* Fill Pst structure. Copying rguSap->pst to pst to avoid any
351     * changes in rguSap->pst */
352    memset(&pst, 0, sizeof(Pst));
353    FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
354
355    if(RlcSendDlDataToMac(&pst, dlData) != ROK)
356    {
357       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[0].pduBuf, \
358          dlData->pduInfo[0].pduLen);
359       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
360    } 
361
362    return;
363 }
364
365 /**
366  *
367  * @brief 
368  *    Handler to process the re-establishment request received from the upper 
369  *    layer. 
370  *
371  * @details
372  *    This function empties the SDU queue for the RB in the downlink.
373  *            
374  * @param[in] gCb   RLC Instance Control Block 
375  * @param[in] rbCb  RB control block. 
376  *
377  * @return  S16
378  *    -# ROK 
379  */
380 #ifdef ANSI
381 Void rlcDlTmmReEstablish
382 (
383 RlcCb       *gCb,
384 RlcDlRbCb   *rbCb    
385 )
386 #else
387 Void rlcDlTmmReEstablish(gCb,rbCb)
388 RlcCb       *gCb;
389 RlcDlRbCb   *rbCb;     
390 #endif
391 {
392
393 #ifdef LTE_L2_MEAS_RLC
394    rlcUtlEmptySduQ(gCb, rbCb, &rbCb->m.tm.sduQ);
395 #else
396    rlcUtlEmptySduQ(gCb,&rbCb->m.tm.sduQ);
397 #endif
398    
399    return;
400 }
401 /**
402  *
403  * @brief 
404  *    Handler to send Status Response to the lower layer.
405  *
406  * @details
407  *    This function is used to the BO to the lower layer after receiving a data
408  *    request from the upper layer. 
409  *            
410  * @param[in] gCb          RLC Instance Control Block 
411  * @param[in] rbCb         RB control block. 
412  * @param[in] bo           Buffer Occupancy 
413  * @param[in] datReqInfo   Data Request Information.
414  *
415  * @return  S16
416  *    -# ROK 
417  *    -# RFAILED 
418  */
419
420 void rlcTmmSendBoSta(RlcCb *gCb, RlcDlRbCb *rbCb, MsgLen bo, KwuDatReqInfo *datReqInfo)
421 {
422    Pst              pst;            /* Post structure */    
423    RlcBoStatus      *boStatus;      /* Buffer occupancy status information */
424
425    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
426                        boStatus, sizeof(RlcBoStatus));
427    if ( boStatus == NULLP )
428    {
429       DU_LOG("Memory Allocation failed UEID:%d CELLID:%d",\
430             rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
431       return;
432    }
433
434    boStatus->cellId = rbCb->rlcId.cellId;
435    boStatus->ueIdx = rbCb->rlcId.ueId;
436    boStatus->commCh = TRUE;
437    boStatus->lcId = rbCb->lch.lChId;
438    boStatus->bo = bo;
439
440    /* If trace flag is enabled send the trace indication */
441    if(gCb->init.trc == TRUE)
442    {
443       /* Populate the trace params */
444       rlcLmmSendTrc(gCb, EVENT_BO_STATUS_TO_MAC, NULLP);
445    }
446
447    /* Fill Pst structure. Copying rguSap->pst to pst to avoid any
448     * changes in rguSap->pst */
449    memset(&pst, 0, sizeof(Pst));
450    FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
451
452    if(RlcSendBoStatusToMac(&pst, boStatus) != ROK)
453    {
454       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus));
455    }
456
457    return;
458
459
460 #ifdef _cplusplus
461 }
462 #endif
463 /*@}*/
464 /********************************************************************30**
465          End of file
466 **********************************************************************/