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