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