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