[Epic-ID: ODUHIGH-464][Task-ID: ODUHIGH-483] Memeory related fix in FDD and TDD mode
[o-du/l2.git] / src / 5gnrmac / rg_mux.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-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for Entry point fucntions
26   
27      File:     rg_mux.c 
28   
29 **********************************************************************/
30
31 /** @file rg_mux.c
32 @brief MAC Multiplexing API.
33 */
34
35
36 /* header include files -- defines (.h) */
37 #include "common_def.h"
38 #include "rg_env.h"        /* MAC Environment Defines */
39 #include "tfu.h"           /* TFU Interface defines */
40 #include "crg.h"           /* CRG Interface defines */
41 #include "rg_sch_inf.h"           /* RGR Interface defines */
42 #include "rgu.h"           /* RGU Interface defines */
43 #include "lrg.h"           /* LRG Interface defines */
44
45 #include "rg_err.h"        /* MAC error defines */
46 #include "rg.h"            /* MAC defines */
47
48 /* header/extern include files (.x) */
49
50 #include "rgu.x"           /* RGU Interface includes */
51 #include "tfu.x"           /* CRG Interface includes */
52 #include "crg.x"           /* CRG Interface includes */
53 #include "rg_sch_inf.x"    /* SCH Interface includes */
54 #include "rg_prg.x"        /* PRG Interface includes */
55 #include "rgu.x"           /* RGU Interface includes */
56 #include "lrg.x"           /* LRG Interface includes */
57
58 #include "du_app_mac_inf.h"
59 #include "rg.x"            /* MAC includes */
60 #include "ss_queue.h"
61 #include "ss_queue.x"
62 #include "ss_task.x"
63 #include "ss_msg.x"            /* MAC includes */
64 /* local defines */
65 #ifndef T2K_MEM_LEAK_DBG
66  S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
67 #else
68 char* file = __FILE__;
69 uint32_t line = __LINE__;
70 #endif
71
72 /* local typedefs */
73
74 /* global variables */
75 uint32_t rgDlrate_rgu;
76
77 /* local externs */
78
79 static Void rgMUXGet20bitRarGrnt ARGS((uint8_t ulBw,
80                                         RgInfRarUlGrnt *msg3Grnt,
81                                         uint8_t *grnt));
82 uint16_t rgMUXCalcRiv ARGS((uint8_t bw,
83                                 uint8_t rbStart,
84                                 uint8_t numRb));
85  
86 #ifndef MS_MBUF_CORRUPTION
87 #define MS_BUF_ADD_ALLOC_CALLER()
88 #endif
89 /* forward references */
90
91 #define RG_PACK_SHDR_FIXD_SZ(_subHdr, _lcId, _mBuf, _ret) {\
92    _subHdr.shLen = RG_FIXDSZ_CE_SHDR_LEN;\
93    _subHdr.shData[0] = (0x3F & _lcId);\
94    MS_BUF_ADD_ALLOC_CALLER(); \
95    _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
96 }
97
98 #define RG_PACK_CE(_ce, _len, _ceBuf, _ret) {\
99    MS_BUF_ADD_ALLOC_CALLER(); \
100    _ret = SAddPstMsgMult((uint8_t *)(&(_ce)), _len, _ceBuf);\
101 }
102
103 #define RG_MUX_CALC_LEN(_len,_lenBytes,_elmTotLen) {\
104    uint8_t _hdrLen;\
105    _lenBytes    = (_len <= 255) ? 1 : 2;\
106    _hdrLen      = _lenBytes + RG_SDU_SHDR_LEN;\
107    _elmTotLen   = _hdrLen + _len;\
108 }
109
110 #define RG_PACK_VAR_SZ_CE_SDU_SHDR(_subHdr, _lcId, _len,_mBuf, _ret) {\
111    _ret = ROK;\
112    if(_len <= 255)\
113    {\
114       _subHdr.shData[0] = (0x3F & _lcId);\
115       _subHdr.shLen = 2;\
116       _subHdr.shData[1] = (0xFF & _len);\
117       _subHdr.shData[2] = 0;\
118    }\
119    else\
120    {\
121    _subHdr.shData[0] = (0x7F & ((0x40) | _lcId));\
122       _subHdr.shLen = 3;\
123       _subHdr.shData[1] = (0xFF & (_len >> 8));\
124       _subHdr.shData[2] = (0xFF & _len);\
125    }\
126    MS_BUF_ADD_ALLOC_CALLER(); \
127    _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
128 }
129
130 #define RG_PACK_PAD_SHDR(_mBuf, _ret) {\
131       _ret = SAddPreMsg(0x3F, _mBuf);\
132 }
133
134 #define RG_PACK_RAR_SHDR(_byte, _mBuf, _ret) {\
135    _ret = SAddPstMsg(_byte, _mBuf);\
136 }
137
138
139 /**
140  * @brief Function to add ces along with subhdrs.
141  * This function packs first CE sub-hdr and then CE in ceBuf pointer 
142  *
143  * @details
144  *
145  *     Function : rgMUXAddCes
146  *     
147  *  @param[in]  Inst        inst
148  *  @param[in] RgBldPduInfo   *pdu
149  *  @param[in] Buffer        *ceBuf 
150  *  @param[in] RgErrInfo     *err 
151  *  @return    S16
152  *      -# ROK 
153  *      -# RFAILED 
154  **/
155 static S16 rgMUXAddCes
156 (
157 Inst           inst,
158 RgBldPduInfo   *pdu,
159 Buffer         *ceBuf,
160 RgErrInfo      *err
161 )
162 {
163    S16            ret;
164    RgMUXSubHdr    subHdr;
165
166    if (NULLP != pdu->contResId)
167    {
168       if(pdu->schdTbSz >= RG_CRES_ELM_LEN)
169       {
170          RG_PACK_SHDR_FIXD_SZ(subHdr, RG_CRES_LCID_IDX, ceBuf, ret);
171
172          if(ret != ROK)
173          {
174             err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
175             DU_LOG("\nERROR  -->  MAC : Muxing of Contention Resolution CE sub-header is failed");
176             return RFAILED;
177          }
178
179          RG_PACK_CE(pdu->contResId->resId[0], RG_CRES_LEN, ceBuf, ret);
180
181          if(ret != ROK)
182          {
183             err->errCause = RGERR_MUX_BLD_CE_FAIL;
184             DU_LOG("\nERROR  -->  MAC : Muxing of Contention Resolution CE is failed");
185             return RFAILED;
186          }
187          pdu->schdTbSz -= RG_CRES_ELM_LEN;
188       }
189    }
190    if (TRUE == pdu->ta.pres)
191    {
192       if(pdu->schdTbSz >= RG_TA_ELM_LEN)
193       {
194          uint8_t taVal; /* Moving from outer scope to available scope */
195          RG_PACK_SHDR_FIXD_SZ(subHdr, RG_TA_LCID_IDX, ceBuf, ret);
196
197          if(ret != ROK)
198          {
199             err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
200             DU_LOG("\nERROR  -->  MAC : Muxing of TA CE sub-hdr is failed");
201             return RFAILED;
202          }
203
204          taVal = pdu->ta.val;
205          RG_PACK_CE(taVal, RG_TA_LEN, ceBuf, ret);
206
207          if(ret != ROK)
208          {
209             err->errCause = RGERR_MUX_BLD_CE_FAIL;
210             DU_LOG("\nERROR  -->  MAC : Muxing of TA CE is failed");
211             return RFAILED;
212          }
213          pdu->schdTbSz -= RG_TA_ELM_LEN;
214          DU_LOG("\nDEBUG  -->  MAC : TA muxed by MAC: %u", pdu->ta.val);
215       }
216    }
217 #ifdef LTE_ADV
218    if(TRUE == pdu->sCellActCe.pres)
219    {
220       if(pdu->schdTbSz >= RG_SCELL_CE_ELM_LEN)
221       {
222          /* Adding the subheader for ACT CE */
223          RG_PACK_SHDR_FIXD_SZ(subHdr, RG_SCELL_LCID_IDX, ceBuf, ret);
224
225          if(ret != ROK)
226          {
227             err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
228             DU_LOG("\nERROR  -->  MAC : Muxing of SCELL Activation CE sub-hdr is failed")
229             return RFAILED;
230          }
231
232          /* Adding the ACT CE */
233          RG_PACK_CE(pdu->sCellActCe.val, RG_SCELL_ACT_CE_LEN, ceBuf, ret);
234
235          if(ret != ROK)
236          {
237             err->errCause = RGERR_MUX_BLD_CE_FAIL;
238             DU_LOG("\nERROR  -->  MAC : Muxing of SCELL Activation CE is failed")
239             return RFAILED;
240          }
241          pdu->schdTbSz -= RG_SCELL_CE_ELM_LEN;
242
243       }
244    }
245 #endif
246   
247   /*LcId is not yet decided in 5G-NR spec for MAC CEs Hence, not writing code
248    * new MAC CEs. */
249
250    return ROK;
251 } /* rgMUXAddCes */
252
253 /**
254  * @brief Function to insert SDU along with sub headers.
255  *
256  * @details
257  *
258  *     Function : rgMUXInsSdu
259  *     
260  *  @param[in]       Inst        inst
261  *  @param[in]       MsgLen      *schdTbSz
262  *  @param[in]       uint8_t          lcId
263  *  @param[in]       Buffer      *sdu
264  *  @param[out]      Buffer      *sduBuf 
265  *  @param[out]      RgErrInfo   *err 
266  *  @return    S16
267  *      -# ROK 
268  *      -# RFAILED
269  **/
270 static S16 rgMUXInsSdu
271 (
272 Inst           inst,
273 MsgLen         *schdTbSz,
274 uint8_t        lcId,
275 Buffer         *sdu,
276 Buffer         *sduBuf,
277 RgErrInfo      *err
278 )
279 {
280    S16            ret;
281    MsgLen         msgLen = 0;
282    uint8_t        lenBytes;
283    MsgLen         elmTotLen;
284
285    SFndLenMsg(sdu, &msgLen);
286
287    RG_MUX_CALC_LEN(msgLen,lenBytes,elmTotLen);
288    
289    if (lcId == 3)
290    {
291      rgDlrate_rgu += msgLen; 
292    }
293    if (*schdTbSz >= elmTotLen)
294    {
295       RgMUXSubHdr    subHdr;
296       RG_PACK_VAR_SZ_CE_SDU_SHDR(subHdr, lcId, msgLen,sduBuf, ret);
297       if(ret != ROK)
298       {
299          err->errCause = RGERR_MUX_BLD_SDUHDR_FAIL;
300          DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_SDUHDR_FAIL for LCID:%d",lcId);
301          return RFAILED;
302       }
303
304 #ifndef L2_OPTMZ /* no need to pack as passing not muxing all LCs PDUs to 1*/
305       RG_PACK_SDU(sduBuf, sdu, ret);
306 #else
307   //UDAY
308       ret = ROK;
309       UNUSED(sduBuf);
310 #endif
311
312       if(ret != ROK)
313       {
314          err->errCause = RGERR_MUX_BLD_SDU_FAIL;
315          DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_SDU_FAIL for LCID:%d",lcId);
316          return RFAILED;
317       }
318
319       *schdTbSz -= elmTotLen;
320    }
321    else
322    {
323       /* This Sub-PDU can not be accodmodated at all */
324       DU_LOG("\nERROR  -->  MAC : Failed lcId %u, elmTotLen %d lenBytes %d LCID:%d",
325                lcId, ((S16)elmTotLen), lenBytes,lcId);
326       DU_LOG("\nERROR  -->  MAC : msglen %d schdTbSz %d LCID:%d",
327                ((S16)msgLen), ((S16)*schdTbSz),lcId);
328       return RFAILED;
329    }
330    return ROK;
331 }
332
333 /**
334  * @brief Function to insert SDU along with sub headers.
335  *
336  * @details
337  *
338  *     Function : rgMUXAddPadd
339  *     
340  *  @param[in]  Inst        inst
341  *  @param[in]       RgBldPduInfo   *pdu
342  *  @param[out]      Buffer        *mBuf 
343  *  @param[out]      Buffer        *sduBuf 
344  *  @return    S16
345  *      -# ROK 
346  *      -# RFAILED
347  **/
348 #ifdef L2_OPTMZ
349 uint32_t padSize = 0;
350 #endif
351 S16 rgMUXAddPadd
352 (
353 Inst           inst,
354 MsgLen         *schdTbSz,
355 Buffer         *sduBuf,
356 Bool           isRar,
357 RgErrInfo      *err
358 )
359 {
360    S16     ret = ROK;
361    Buffer         *padBuf = NULLP;
362    RgMUXSubHdr    subHdr;
363
364 #ifdef L2_OPTMZ
365    padSize = 0;
366 #endif
367    if(*schdTbSz)
368    {
369 #ifndef L2_OPTMZ
370       if(FALSE == isRar)
371 #else
372       if((FALSE == isRar) && (NULL != sHdrBuf))
373 #endif
374
375       {
376          RG_PACK_SHDR_FIXD_SZ(subHdr, RG_PAD_LCID_IDX, sduBuf, ret);  
377
378          if(ret != ROK)
379          {
380             err->errCause = RGERR_MUX_BLD_PADHDR_FAIL;
381             DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_PADHDR_FAIL");
382             return RFAILED;
383          }
384
385          *schdTbSz -= 1;
386       }
387
388       if (*schdTbSz)
389       {
390          if (*schdTbSz <= RG_MAX_PAD_ARR_SZ)
391          {
392 #ifndef L2_OPTMZ
393             RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
394 #else
395             if(sduBuf)
396             {
397                RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
398             }
399             else
400                padSize += *schdTbSz;
401 #endif
402             if(ret != ROK)
403             {
404                err->errCause = RGERR_MUX_BLD_PAD_FAIL;
405                DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_PAD_FAIL");
406                return RFAILED;
407             }
408             *schdTbSz = 0;
409          }
410          else
411          {
412             while (*schdTbSz)
413             {
414                if (*schdTbSz > RG_MAX_PAD_ARR_SZ)
415                {
416 #ifndef L2_OPTMZ
417                   RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
418 #else
419                   if(sduBuf)
420                   {
421                      RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
422                   }
423                   else
424                      padSize += RG_MAX_PAD_ARR_SZ;
425 #endif
426
427                   if(ret != ROK)
428                   {
429                      err->errCause = RGERR_MUX_BLD_PAD_FAIL;
430                      DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_PAD_FAIL");
431                      return RFAILED;
432                   }
433
434                   *schdTbSz -= RG_MAX_PAD_ARR_SZ;
435                }
436                else
437                {
438 #ifndef L2_OPTMZ
439                   RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
440 #else
441                   if(sduBuf)
442                   {
443                      RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
444                   }
445                   else
446                      padSize += *schdTbSz;
447 #endif
448
449                   if(ret != ROK)
450                   {
451                      err->errCause = RGERR_MUX_BLD_PAD_FAIL;
452                      DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_PAD_FAIL");
453                      return RFAILED;
454
455                   }
456                   *schdTbSz = 0;
457                }
458             }
459          }
460       }
461    }
462
463    return ROK;
464 } /* rgMUXAddPadd */
465
466 #ifndef L2_OPTMZ
467 /**
468  * @brief Function to add SDU along with sub headers.
469  *
470  * @details
471  *
472  *     Function : rgMUXAddSdus
473  *     
474  *  @param[in]  Inst        inst
475  *  @param[in]       RgBldPduInfo   *pdu
476  *  @param[out]      Buffer        *mBuf 
477  *  @param[out]      Buffer        *sduBuf 
478  *  @return    S16
479  *      -# ROK 
480  *      -# RFAILED
481  **/
482 static S16 rgMUXAddSdus
483 (
484 Inst           inst,
485 RgBldPduInfo   *pdu,
486 Buffer         *sduBuf,
487 RgErrInfo      *err
488 )
489 {
490    RgRguDDatReqPerUe *dDatReq;
491    RgRguCmnDatReq    *cDatReq;
492
493    switch(pdu->reqType)
494    {
495       case EVTRGUCDATREQ:
496          cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
497          /* Add sdu(s) to the Message Buffer */
498          if (NULLP != cDatReq)
499          {
500             if(rgMUXInsSdu(inst,&pdu->schdTbSz, 
501                      RG_CCCH_LCID, cDatReq->pdu, sduBuf, err) != ROK)
502             {
503                return RFAILED;
504             }
505             RG_FREE_MSG(cDatReq->pdu);
506          }
507          break;
508
509       case EVTRGUDDATREQ:
510          dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
511          /* Add sdu(s) to the Message Buffer */
512          if (NULLP != dDatReq)
513          {
514             if(pdu->tbIndex == 1)
515             {
516                uint16_t idx1, idx2;
517                /* Adding this temporary variable for optimization */
518                RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
519
520                for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
521                {
522                   for(idx2=0;
523                      (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
524                      idx2++)
525                   {
526                      if(pdu->schdTbSz)
527                      {
528                         if(rgMUXInsSdu(inst,&pdu->schdTbSz,
529                            datReqTb->lchData[idx1].lcId, 
530                            datReqTb->lchData[idx1].pdu.mBuf[idx2],
531                            sduBuf, err) != ROK)
532                         {
533                            DU_LOG("\nERROR  -->  MAC : FAILED for LCID:%d",datReqTb->lchData[idx1].lcId);
534                            return RFAILED;
535                         }
536                      }
537                      RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
538                   }
539                }
540             }
541             else if(pdu->tbIndex == 2)
542             {
543                uint16_t idx1, idx2;
544                RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
545                for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
546                {
547                   for(idx2=0;
548                      (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
549                      idx2++)
550                   {
551                      if(pdu->schdTbSz)
552                      {
553                         if(rgMUXInsSdu(inst,&pdu->schdTbSz,
554                            datReqTb->lchData[idx1].lcId, 
555                            datReqTb->lchData[idx1].pdu.mBuf[idx2],
556                            sduBuf, err) != ROK)
557                         {
558                            DU_LOG("\nERROR  -->  MAC : FAILED TB Size %d LCID:%d",
559                                     ((S16)pdu->schdTbSz),datReqTb->lchData[idx1].lcId);
560                            return RFAILED;
561                         }
562                      }
563                      RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
564                   }
565                }
566             }
567          }
568          break;
569
570       default:
571          break;
572    } /* End of switch(reqType) */
573    if(rgMUXAddPadd(inst,&pdu->schdTbSz, sduBuf, FALSE, err) != ROK)
574    {
575       DU_LOG("\nERROR  -->  MAC : FAILED for TB Size:%d",(S16)pdu->schdTbSz);
576       return RFAILED;
577    }
578    return ROK;
579 }
580
581 /**
582  * @brief Function to create MAC PDU from RLC SDUs and control elements, if any. 
583  *
584  * @details
585  *
586  *     Function : rgMUXBldPdu
587  *     
588  *     -# This function shall be invoked by Downlink Harq Module as soon as a
589  *        Data request is received from RLC for a UE along with its stored 
590  *        control elements to create a MAC PDU.
591  *     -# It shall create subheaders for the control elements (timing advance
592  *        and contention resolution ID) and pack sub-header before each CE,
593  *        if given, and then shall run through all the logical channels and
594  *        create subheader for each of the SDUs given on that logical channel
595  *        and pack corresponding sub-header before the each SDU 
596  *     -# It shall invoke rgMUXPadPdu if the total length of the created 
597  *        buffer is less than the scheduled TB size. 
598  *     
599  *           
600  *  @param[in]  Inst           *inst
601  *  @param[in]  RgBldPduInfo   *bldPdu
602  *  @param[in]  Buffer         **txPdu
603  *  @param[out] RgErrInfo      *err
604  *  @return  S16
605  *      -# ROK 
606  *      -# RFAILED 
607  **/
608 S16 rgMUXBldPdu
609 (
610 Inst           inst,
611 RgBldPduInfo   *pdu,
612 Buffer         **txPdu,
613 RgErrInfo      *err
614 )
615 {
616    Buffer         *mBuf = NULLP;
617
618    if (rgGetMsg(inst, &mBuf) != ROK)
619    {
620       /* Buffer couldnt get allocated. Return a failure */
621       err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
622       err->errType = RGERR_MUX_BLD_PDU;
623       DU_LOG("\nERROR  -->  MAC : Memory allocation failed during MUXing of MAC TB: MacInst %d", inst);
624       return RFAILED;
625    }
626
627    if(rgMUXAddCes(inst, pdu, mBuf, err) != ROK)
628    {
629       RG_FREE_MSG(mBuf);
630       err->errType = RGERR_MUX_BLD_PDU;
631       DU_LOG("\nERROR  -->  MAC : Failed to Multiplex MAC CEs: MacInst %d", inst);
632       return RFAILED;
633    }
634
635    if(rgMUXAddSdus(inst, pdu, mBuf, err) != ROK)
636    {
637       RG_FREE_MSG(mBuf);
638       err->errType = RGERR_MUX_BLD_PDU;
639       DU_LOG("\nERROR  -->  MAC : FAILED to Multiplex MAC SDU: MacInst %d", inst);
640       return RFAILED;
641    }
642
643    *txPdu = mBuf;
644
645    return ROK;
646
647 }  /* rgMUXBldPdu */
648
649 #else /* else of ifndef L2_OPTMZ */
650
651 /**
652  * @brief Function to add SDU along with sub headers.
653  *
654  * @details
655  *
656  *     Function : rgMUXAddSdus
657  *     
658  *  @param[in]       RgBldPduInfo   *pdu
659  *  @param[out]      Buffer        *mBuf 
660  *  @param[out]      Buffer        *sduBuf 
661  *  @return    S16
662  *      -# ROK 
663  *      -# RFAILED
664  **/
665 static S16 rgMUXAddSdus
666 (
667 Inst                inst,
668 RgBldPduInfo        *pdu,
669 Buffer              *sHdrBuf,
670 RgTfuDatReqTbInfo   *tb,
671 RgErrInfo           *err
672 )
673 {
674    RgRguDDatReqPerUe  *dDatReq;
675    RgRguCmnDatReq     *cDatReq;
676    uint32_t lchIdx, pduIdx;
677
678    switch(pdu->reqType)
679    {
680       case EVTRGUCDATREQ:
681          cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
682          /* Add sdu(s) to the Message Buffer */
683          if (NULLP != cDatReq)
684          {
685             if(rgMUXInsSdu(inst, &pdu->schdTbSz, 
686                      RG_CCCH_LCID, cDatReq->pdu, 
687                      sHdrBuf, NULLP, err) != ROK)
688             {
689                return RFAILED;
690             }
691             /* L2 Optimization for mUe/Tti: RLC pdu mbuf pointer will be passed
692              * to CL it is stored in DlHqProc->TbInfo and it will be used in
693              * case of harq retransmission. Store CCCH data at 0th index of
694              * lch array*/
695             tb->lchInfo[tb->numLch].mBuf[(tb->lchInfo[tb->numLch].numPdu)]\
696                = cDatReq->pdu;
697             tb->lchInfo[tb->numLch].numPdu++;
698             tb->numLch++;
699             DU_LOG("\nINFO   -->  MAC : MSG4 is muxed  numLch=%ld numPdu=%ld tbaddr =%p",\
700             tb->numLch,tb->lchInfo[tb->numLch-1].numPdu, (uint32_t)tb);
701          }
702          break;
703
704       case EVTRGUDDATREQ:
705          dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
706          /* Add sdu(s) to the Message Buffer */
707          if (NULLP != dDatReq)
708          {
709             if(pdu->tbIndex == 1)
710             {
711                uint16_t idx1, idx2;
712                /* Adding this temporary variable for optimization */
713                RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
714              
715                tb->numLch = lchIdx = 0;
716
717                for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
718                {
719                   tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
720
721                   for(idx2=0;
722                      (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
723                      idx2++)
724                   {
725                      if(pdu->schdTbSz)
726                      {
727                         if(rgMUXInsSdu(inst, &pdu->schdTbSz,
728                            datReqTb->lchData[idx1].lcId, 
729                            datReqTb->lchData[idx1].pdu.mBuf[idx2],
730                            sHdrBuf, NULLP, err) != ROK)
731                         {
732                            DU_LOG("\nERROR   -->  MAC : Failed to insert SDU in rgMUXAddSdus\n");
733                            return RFAILED;
734                         }
735
736                         /* L2 Optimization for mUe/Tti:Increment numPdu by 1
737                          * Store pdu buffer in tb to send it to CL/PHY. Increment
738                          * numPdu by 1*/
739                         tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
740
741 #ifdef L2_OPTMZ
742                         if(datReqTb->lchData[idx1].freeBuff == FALSE)
743                         {/* Not incrementing refCnt for UM Mode. */
744                            tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
745                         }
746 #endif
747 //UDAY 
748                         if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
749                         {
750                              Buffer *tmp;
751                              tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
752                              if(NULL == tmp->b_rptr)
753                              {
754                                 DU_LOG("\nERROR   -->  MAC : rgMUXAddSdus failed in EVTRGUDDATREQ");
755                              }
756                         }
757                         else
758                         {
759                             DU_LOG("\nERROR   -->  MAC : rgMUXAddSdus failed in EVTRGUDDATREQ");
760                         }
761                         pduIdx++;
762                         //tb->lchInfo[tb->numLch].numPdu++;
763                         //tb->numLch++;
764
765                     }
766                   }
767                   
768                   if(pduIdx)
769                   {
770                     tb->lchInfo[lchIdx].numPdu = pduIdx;
771                     /* If Bearer is UM then MBUF to be free by MAC layer */
772                     tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
773                     lchIdx++;
774                   }
775                }
776                tb->numLch = lchIdx;
777             }
778             else if(pdu->tbIndex == 2)
779             {
780                uint16_t idx1, idx2;
781                RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
782                tb->numLch = lchIdx = 0;
783          //      prc_trace_format_string(0x40,3,": AddSdus: numOfLch=%d numOfPdu=%d, schdSz=%d", datReqTb->nmbLch, datReqTb->lchData[0].pdu.numPdu, pdu->schdTbSz);
784               for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
785                {
786                  tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
787                  for(idx2=0;
788                      (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
789                      idx2++)
790                   {
791                      if(pdu->schdTbSz)
792                      {
793                         if(rgMUXInsSdu(inst, &pdu->schdTbSz,
794                            datReqTb->lchData[idx1].lcId, 
795                            datReqTb->lchData[idx1].pdu.mBuf[idx2],
796                            sHdrBuf, NULLP, err) != ROK)
797                         {
798                            DU_LOG("\nERROR  -->  MAC : FAILED TB Size %d\n",
799                                     ((S16)pdu->schdTbSz));
800                            return RFAILED;
801                         }
802                          /* L2 Optimization for mUe/Tti:Increment numPdu by 1
803                          * Store pdu buffer in tb to send it to CL/PHY. Increment
804                          * numPdu by 1*/
805                         tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
806 #ifdef L2_OPTMZ
807                         if(datReqTb->lchData[idx1].freeBuff == FALSE)
808                         {/* Not incrementing refCnt for UM Mode. */
809                            tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
810                         }
811 #endif
812                         if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
813                         {
814                              Buffer *tmp;
815                              tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
816                              if(NULL == tmp->b_rptr)
817                              {
818                                 DU_LOG("\nERROR   -->  MAC : rgMUXAddSdus failed in EVTRGUDDATREQ");
819                              }
820                         }
821                         else
822                         {
823                             DU_LOG("\nERROR   -->  MAC : rgMUXAddSdus failed in EVTRGUDDATREQ");
824                         }
825                         pduIdx++;
826                        // tb->lchInfo[tb->numLch].numPdu++;
827                        // tb->numLch++;
828
829                      }
830                   }
831
832                   if(pduIdx)
833                   {
834                     tb->lchInfo[lchIdx].numPdu = pduIdx;
835                     /* If Bearer is UM then MBUF to be free by MAC layer */
836                     tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
837                     lchIdx++;
838                   }
839                }
840
841                tb->numLch = lchIdx;
842            }
843          }
844          break;
845
846       case EVENT_SLOT_IND_TO_MAC:
847          break;
848       default:
849          break;
850    } /* End of switch(reqType) */
851
852    
853    if(rgMUXAddPadd(inst, &pdu->schdTbSz, sduBuf, NULLP, FALSE, err) != ROK)
854    {
855       //RGDBGERRNEW((rgPBuf, "FAILED"));
856       return RFAILED;
857    }
858    tb->padSize = padSize;
859
860    return ROK;
861 }
862
863 /**
864  * @brief Function to create MAC PDU from RLC SDUs and control elements, if any. 
865  *
866  * @details
867  *
868  *     Function : rgMUXBldPdu
869  *     -# This function shall be invoked by Downlink Harq Module as soon as a
870  *        Data request is received from RLC for a UE along with its stored 
871  *        control elements to create a MAC PDU.
872  *     -# It shall create subheaders for the control elements (timing advance
873  *        and contention resolution ID), if given, and then shall run through
874  *        all the logical channels and create subheader for each of the SDUs
875  *        given on that logical channel.
876  *     -# L2 Optimization for mUe/Tti: Avoiding muxing to reduce overhead of 
877  *           additional Mbuf allocation memory related operation.
878        -# MAC header, MAC CEs, MAC PDUs and MAC padding are stored in pre-
879             allocated mBufs. These pointers will not be freed by CL    
880  *     -# It shall invoke rgMUXPadPdu if the total length of the created 
881  *        buffer is less than the scheduled TB size.
882  *     -# At successfull operation of this function tb->macHdr, will have
883  *        complete MAC Header. tb->macCes will have MAC CEs if any. tb->
884  *        lchInfo[idx].mBuf[idx] will have MAC SDU per LCH per TB per UE 
885  *     
886  *           
887  *  @param[in]  RgBldPduInfo   *bldPdu
888  *  @param[out] RgTbInfo       *tb
889  *  @param[out] RgErrInfo      *err
890  *  @return  S16
891  *      -# ROK 
892  *      -# RFAILED 
893  **/
894 S16 rgMUXBldPdu
895 (
896 Inst               inst,
897 RgBldPduInfo       *pdu,
898 RgTfuDatReqTbInfo  *tb,
899 RgErrInfo          *err
900 )
901 {
902    Buffer         *mBuf1; /* MAC hearder */
903    Buffer         *mBuf2; /* MAC CEs */
904    //uint32_t            lchIdx, pduIdx;
905
906   /* Reseting macHdr and macCes pointers */
907   if(tb->macHdr)
908    SResetMBuf(tb->macHdr);
909    if(tb->macCes)
910    SResetMBuf(tb->macCes);
911    
912    mBuf1 = tb->macHdr; /* MAC hearder */
913    mBuf2 = tb->macCes; /* MAC CEs */
914    tb->tbSize  = pdu->schdTbSz;
915
916    if(rgMUXAddCes(inst, pdu, mBuf1, mBuf2, err) != ROK)
917    {
918       /* Reset rPtr and wPtr to the base of data buffer(db_base)*/
919       DU_LOG("\nERROR  -->  MAC : rgMUXBldPdu: rgMUXAddCes is Failed \n");
920       RG_FREE_TB(tb);
921       err->errType = RGERR_MUX_BLD_PDU;
922       //RGDBGERRNEW((rgPBuf, "FAILED"));
923       return RFAILED;
924    }
925    if(rgMUXAddSdus(inst, pdu, mBuf1, tb, err) != ROK)
926    {
927       /*TODO:MP Reset rPtr and wPtr to the base of data buffer(db_base)
928        * Reset numLch and numPdu to zero and set MAC SDU buf to NULLP */
929       DU_LOG("\nERROR  -->  MAC : rgMUXBldPdu: rgMUXAddSdus is Failed \n");
930       RG_FREE_TB(tb);
931
932       err->errType = RGERR_MUX_BLD_PDU;
933       //RGDBGERRNEW((rgPBuf, "FAILED"));
934       return RFAILED;
935    }
936 // UDAY 
937 //      SPrntMsg(tb->macHdr, 0, 0);
938 //   prc_trace_format_string(0x40,3,": padSize=%ld", tb->padSize);
939
940    tb->tbPres = TRUE;
941    return ROK;
942
943 }  /* rgMUXBldPdu */
944
945 #endif /* end of L2_OPTMZ */
946
947 /**
948  * @brief Function to create RAR PDU. 
949  *
950  * @details
951  *
952  *     Function : rgMUXBldRarPdu
953  *                This function is used to build RAR PDUs and is being 
954  *                invoked by the scheduler.
955  *     
956  *  @param[out]RgCellCb       *cellCb
957  *  @param[in] RgRaRspAlloc   *bldPdu
958  *  @param[in] Buffer         **txPdu 
959  *  @param[out] RgErrInfo     *err
960  *  @return    S16
961  *      -# ROK 
962  *      -# RFAILED 
963  **/
964 S16 rgMUXBldRarPdu
965 (
966 RgCellCb        *cell,
967 RgInfRaRntiInfo *alloc,
968 Buffer          **txPdu,
969 RgErrInfo       *err
970 )
971 {
972    Buffer      *datBuf = NULLP;
973    S16         ret; 
974    uint8_t     data[RG_RAR_ELEM_LEN];
975    uint8_t     hdrByte;
976    MsgLen      schdTbSz;
977    uint8_t     idx;
978    Inst        inst = cell->macInst - RG_INST_START;
979
980    schdTbSz = alloc->schdTbSz;
981    /* RAR PDU Requirements */
982    /*
983    1. SubHeader - R/T/RAPID. //5GNR, changed E to R
984    2. TA ( if applicable)
985    3. Ul Grant:
986          a. Hopping Flag - 1 Bit.
987          b. Fixed Size RB Assignment. - 10 Bits.
988          c. Truncated Modulation and coding scheme - 4 Bits.
989          d. TPC command for scheduled PUSCH. - 3 Bits.
990          e. UL Delay - 1 Bit.
991          f. CQI Request - 1 Bit.
992    4. Temporary Crnti.
993    */
994
995    /* Initialize the error type */
996    err->errType = RGERR_MUX_BLD_RAR_PDU;
997   
998    if ((ret = rgGetMsg(inst,&datBuf)) != ROK)
999    {
1000       /* Buffer couldnt get allocated. Return a failure */
1001       err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
1002       DU_LOG("\nERROR  -->  MAC : FAILED to getMsg");
1003       return RFAILED;
1004    }
1005
1006    if (TRUE == alloc->backOffInd.pres)
1007    {
1008       /*Set T Bit , NO E bit Required */
1009       hdrByte = 0x00;
1010       /* Add the bi */
1011       hdrByte |= (0x0F & (alloc->backOffInd.val));
1012
1013       /* Add the header */
1014       RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
1015       if(ret != ROK)
1016       {
1017          err->errCause = RGERR_MUX_BLD_BI_FAIL;
1018          DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_BI_FAIL");
1019          RG_FREE_MSG(datBuf);
1020          return RFAILED;
1021       }
1022       schdTbSz--;
1023    }
1024
1025    for (idx=0; idx < (alloc->numCrnti) && 
1026          (schdTbSz >= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN); idx++)
1027    {
1028       /* Add the tBit */
1029       hdrByte = 0x40; 
1030       /* Add the rapId */
1031       hdrByte |= (0x3F & (alloc->crntiInfo[idx].rapId));
1032
1033          /* Add the header */
1034          RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
1035          if(ret != ROK)
1036          {
1037             err->errCause = RGERR_MUX_BLD_RAPIDHDR_FAIL;
1038             DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_RAPIDHDR_FAIL");
1039             RG_FREE_MSG(datBuf);
1040             return RFAILED;
1041          }
1042
1043       /* Prepare the data */
1044       data[0]  =  0x7F & ((alloc->crntiInfo[idx].ta.val) >> 4);
1045       data[1] = 0;
1046       data[2] = 0;
1047       data[3] = 0;
1048       {    
1049          rgMUXGet20bitRarGrnt(cell->bwCfg.ulTotalBw, &(alloc->crntiInfo[idx].grnt), &data[1]);
1050       }
1051       data[1] |=  ((uint8_t)((alloc->crntiInfo[idx].ta.val) << 4));
1052       data[4]  =  (alloc->crntiInfo[idx].tmpCrnti) >> 8;
1053       data[5]  =  (uint8_t) (alloc->crntiInfo[idx].tmpCrnti);
1054
1055       DU_LOG("\nDEBUG  -->  MAC : Rar,Rapid=%d, Temp CRNTI:%d", 
1056                 alloc->crntiInfo[idx].rapId,
1057                 alloc->crntiInfo[idx].tmpCrnti);
1058      MS_BUF_ADD_ALLOC_CALLER();
1059       if(SAddPstMsgMult(&data[0], RG_RAR_ELEM_LEN, datBuf) != ROK)
1060       {
1061          err->errCause = RGERR_MUX_BLD_RAPID_FAIL;
1062          DU_LOG("\nERROR  -->  MAC : RGERR_MUX_BLD_RAPID_FAIL");
1063          RG_FREE_MSG(datBuf);
1064          return RFAILED;
1065       }
1066       schdTbSz -= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN;
1067    }
1068
1069    if(rgMUXAddPadd(inst,&schdTbSz, datBuf, TRUE, err) != ROK)
1070    {
1071       RG_FREE_MSG(datBuf);
1072       DU_LOG("\nERROR  -->  MAC : FAILED to mux add padding");
1073       return RFAILED;
1074    }
1075
1076    *txPdu = datBuf;
1077
1078    return ROK;
1079 } /* rgMUXBldRarPdu */
1080
1081 /***********************************************************
1082  *
1083  *     Func : rgMUXGet20bitRarGrnt
1084  *
1085  *     Desc : This function fills up the 20-bit grant
1086  *            for RA response.
1087  *
1088  *     Ret  : None.
1089  *
1090  *     Notes: None.
1091  *
1092  *     File : rg_mux.c
1093  *
1094  **********************************************************/
1095 static Void rgMUXGet20bitRarGrnt
1096 (
1097 uint8_t             ulBw,
1098 RgInfRarUlGrnt *msg3Grnt,
1099 uint8_t             *grnt
1100 )
1101 {
1102    uint16_t       riv = rgMUXCalcRiv(ulBw, msg3Grnt->rbStart, msg3Grnt->numRb);
1103
1104    grnt[2]  = msg3Grnt->cqiBit;   /* cqi bit is 0, output from sched */
1105    grnt[2] |= (msg3Grnt->delayBit << 1);
1106    grnt[2] |= (msg3Grnt->tpc << 2);
1107    grnt[2] |= (msg3Grnt->iMcsCrnt << 5);
1108
1109    grnt[1]  = (msg3Grnt->iMcsCrnt >> 3);
1110    /* Forcing right shift to insert 0 as the LSB: 
1111     * since this is assumed in the computation */
1112    grnt[1] |= (uint8_t)((riv << 1) & 0xFE);
1113
1114    grnt[0]  = (uint8_t)((riv >> 7) & 0x07);
1115    grnt[0] |= ((msg3Grnt->hop & 0x01) << 3);
1116
1117    return;
1118 } /* rgMUXGet20bitRarGrnt */
1119
1120 /***********************************************************
1121  *
1122  *     Func : rgMUXCalcRiv
1123  *
1124  *     Desc : This function calculates RIV.
1125  *
1126  *     Ret  : None.
1127  *
1128  *     Notes: None.
1129  *
1130  *     File : rg_mux.c
1131  *
1132  **********************************************************/
1133 uint16_t rgMUXCalcRiv
1134 (
1135 uint8_t           bw,
1136 uint8_t           rbStart,
1137 uint8_t           numRb
1138 )
1139 {
1140    uint8_t           numRbMinus1 = numRb - 1;
1141    uint16_t          riv;
1142
1143    if (numRbMinus1 <= bw/2)
1144    {
1145       riv = bw * numRbMinus1 + rbStart;
1146    }
1147    else
1148    {
1149       riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
1150    }
1151    return (riv);
1152 } /* rgMUXCalcRiv */
1153
1154
1155
1156 /**********************************************************************
1157  
1158          End of file
1159 **********************************************************************/