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