1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
32 @brief MAC Multiplexing API.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=229;
37 static int RLOG_MODULE_ID=4096;
39 /* header include files -- defines (.h) */
40 #include "envopt.h" /* environment options */
41 #include "envdep.h" /* environment dependent */
42 #include "envind.h" /* environment independent */
44 #include "gen.h" /* general */
45 #include "ssi.h" /* system services */
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 */
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 */
60 #include "rg_err.h" /* MAC error defines */
61 #include "rg.h" /* MAC defines */
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 */
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 */
82 #include "du_app_mac_inf.h"
83 #include "rg.x" /* MAC includes */
87 #include "ss_msg.x" /* MAC includes */
89 #ifndef T2K_MEM_LEAK_DBG
90 EXTERN S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
92 char* file = __FILE__;
98 /* global variables */
103 PRIVATE Void rgMUXGet20bitRarGrnt ARGS((U8 ulBw,
104 RgInfRarUlGrnt *msg3Grnt,
106 EXTERN U16 rgMUXCalcRiv ARGS((U8 bw,
110 #ifndef MS_MBUF_CORRUPTION
111 #define MS_BUF_ADD_ALLOC_CALLER()
113 /* forward references */
115 #define RG_PACK_SHDR_FIXD_SZ(_subHdr, _lcId, _mBuf, _ret) {\
116 _subHdr.shLen = RG_FIXDSZ_CE_SHDR_LEN;\
117 _subHdr.shData[0] = (0x3F & _lcId);\
118 MS_BUF_ADD_ALLOC_CALLER(); \
119 _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
122 #define RG_PACK_CE(_ce, _len, _ceBuf, _ret) {\
123 MS_BUF_ADD_ALLOC_CALLER(); \
124 _ret = SAddPstMsgMult((U8 *)(&(_ce)), _len, _ceBuf);\
127 #define RG_MUX_CALC_LEN(_len,_lenBytes,_elmTotLen) {\
129 _lenBytes = (_len <= 255) ? 1 : 2;\
130 _hdrLen = _lenBytes + RG_SDU_SHDR_LEN;\
131 _elmTotLen = _hdrLen + _len;\
134 #define RG_PACK_VAR_SZ_CE_SDU_SHDR(_subHdr, _lcId, _len,_mBuf, _ret) {\
138 _subHdr.shData[0] = (0x3F & _lcId);\
140 _subHdr.shData[1] = (0xFF & _len);\
141 _subHdr.shData[2] = 0;\
145 _subHdr.shData[0] = (0x7F & ((0x40) | _lcId));\
147 _subHdr.shData[1] = (0xFF & (_len >> 8));\
148 _subHdr.shData[2] = (0xFF & _len);\
150 MS_BUF_ADD_ALLOC_CALLER(); \
151 _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
154 #define RG_PACK_PAD_SHDR(_mBuf, _ret) {\
155 _ret = SAddPreMsg(0x3F, _mBuf);\
158 #define RG_PACK_RAR_SHDR(_byte, _mBuf, _ret) {\
159 _ret = SAddPstMsg(_byte, _mBuf);\
164 * @brief Function to add ces along with subhdrs.
165 * This function packs first CE sub-hdr and then CE in ceBuf pointer
169 * Function : rgMUXAddCes
171 * @param[in] Inst inst
172 * @param[in] RgBldPduInfo *pdu
173 * @param[in] Buffer *ceBuf
174 * @param[in] RgErrInfo *err
180 PRIVATE S16 rgMUXAddCes
188 PRIVATE S16 rgMUXAddCes(inst,pdu, ceShdrBuf, ceBuf, err)
200 if (NULLP != pdu->contResId)
202 if(pdu->schdTbSz >= RG_CRES_ELM_LEN)
204 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_CRES_LCID_IDX, ceBuf, ret);
208 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
209 RLOG0(L_ERROR, "Muxing of Contention Resolution CE sub-header is failed");
213 RG_PACK_CE(pdu->contResId->resId[0], RG_CRES_LEN, ceBuf, ret);
217 err->errCause = RGERR_MUX_BLD_CE_FAIL;
218 RLOG0(L_ERROR, "Muxing of Contention Resolution CE is failed")
221 pdu->schdTbSz -= RG_CRES_ELM_LEN;
224 if (TRUE == pdu->ta.pres)
226 if(pdu->schdTbSz >= RG_TA_ELM_LEN)
228 U8 taVal; /* Moving from outer scope to available scope */
229 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_TA_LCID_IDX, ceBuf, ret);
233 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
234 RLOG0(L_ERROR, "Muxing of TA CE sub-hdr is failed")
239 RG_PACK_CE(taVal, RG_TA_LEN, ceBuf, ret);
243 err->errCause = RGERR_MUX_BLD_CE_FAIL;
244 RLOG0(L_ERROR, "Muxing of TA CE is failed")
247 pdu->schdTbSz -= RG_TA_ELM_LEN;
248 RLOG1(L_DEBUG,"TA muxed by MAC: %u", pdu->ta.val);
252 if(TRUE == pdu->sCellActCe.pres)
254 if(pdu->schdTbSz >= RG_SCELL_CE_ELM_LEN)
256 /* Adding the subheader for ACT CE */
257 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_SCELL_LCID_IDX, ceBuf, ret);
261 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
262 RLOG0(L_ERROR, "Muxing of SCELL Activation CE sub-hdr is failed")
266 /* Adding the ACT CE */
267 RG_PACK_CE(pdu->sCellActCe.val, RG_SCELL_ACT_CE_LEN, ceBuf, ret);
271 err->errCause = RGERR_MUX_BLD_CE_FAIL;
272 RLOG0(L_ERROR, "Muxing of SCELL Activation CE is failed")
275 pdu->schdTbSz -= RG_SCELL_CE_ELM_LEN;
281 /*LcId is not yet decided in 5G-NR spec for MAC CEs Hence, not writing code
288 * @brief Function to insert SDU along with sub headers.
292 * Function : rgMUXInsSdu
294 * @param[in] Inst inst
295 * @param[in] MsgLen *schdTbSz
297 * @param[in] Buffer *sdu
298 * @param[out] Buffer *sduBuf
299 * @param[out] RgErrInfo *err
305 PRIVATE S16 rgMUXInsSdu
315 PRIVATE S16 rgMUXInsSdu(inst,schdTbSz, lcId, sdu, sduBuf, err)
330 SFndLenMsg(sdu, &msgLen);
332 RG_MUX_CALC_LEN(msgLen,lenBytes,elmTotLen);
336 rgDlrate_rgu += msgLen;
338 if (*schdTbSz >= elmTotLen)
341 RG_PACK_VAR_SZ_CE_SDU_SHDR(subHdr, lcId, msgLen,sduBuf, ret);
344 err->errCause = RGERR_MUX_BLD_SDUHDR_FAIL;
345 RLOG1(L_ERROR, "RGERR_MUX_BLD_SDUHDR_FAIL for LCID:%d",lcId);
349 #ifndef L2_OPTMZ /* no need to pack as passing not muxing all LCs PDUs to 1*/
350 RG_PACK_SDU(sduBuf, sdu, ret);
359 err->errCause = RGERR_MUX_BLD_SDU_FAIL;
360 RLOG1(L_ERROR, "RGERR_MUX_BLD_SDU_FAIL for LCID:%d",lcId);
364 *schdTbSz -= elmTotLen;
368 /* This Sub-PDU can not be accodmodated at all */
369 RLOG4(L_ERROR, "Failed lcId %u, elmTotLen %d lenBytes %d LCID:%d",
370 lcId, ((S16)elmTotLen), lenBytes,lcId);
371 RLOG3(L_ERROR, "msglen %d schdTbSz %d LCID:%d",
372 ((S16)msgLen), ((S16)*schdTbSz),lcId);
379 * @brief Function to insert SDU along with sub headers.
383 * Function : rgMUXAddPadd
385 * @param[in] Inst inst
386 * @param[in] RgBldPduInfo *pdu
387 * @param[out] Buffer *mBuf
388 * @param[out] Buffer *sduBuf
397 PUBLIC S16 rgMUXAddPadd
406 PUBLIC S16 rgMUXAddPadd(inst,schdTbSz, sduBuf, isRar, err)
415 Buffer *padBuf = NULLP;
427 if((FALSE == isRar) && (NULL != sHdrBuf))
431 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_PAD_LCID_IDX, sduBuf, ret);
435 err->errCause = RGERR_MUX_BLD_PADHDR_FAIL;
436 RLOG0(L_ERROR, "RGERR_MUX_BLD_PADHDR_FAIL");
445 if (*schdTbSz <= RG_MAX_PAD_ARR_SZ)
448 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
452 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
455 padSize += *schdTbSz;
459 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
460 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
469 if (*schdTbSz > RG_MAX_PAD_ARR_SZ)
472 RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
476 RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
479 padSize += RG_MAX_PAD_ARR_SZ;
484 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
485 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
489 *schdTbSz -= RG_MAX_PAD_ARR_SZ;
494 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
498 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
501 padSize += *schdTbSz;
506 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
507 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
523 * @brief Function to add SDU along with sub headers.
527 * Function : rgMUXAddSdus
529 * @param[in] Inst inst
530 * @param[in] RgBldPduInfo *pdu
531 * @param[out] Buffer *mBuf
532 * @param[out] Buffer *sduBuf
538 PRIVATE S16 rgMUXAddSdus
546 PRIVATE S16 rgMUXAddSdus(inst,pdu, sduBuf, err)
553 RgRguDDatReqPerUe *dDatReq;
554 RgRguCmnDatReq *cDatReq;
561 cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
562 /* Add sdu(s) to the Message Buffer */
563 if (NULLP != cDatReq)
565 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
566 RG_CCCH_LCID, cDatReq->pdu, sduBuf, err) != ROK)
570 RG_FREE_MSG(cDatReq->pdu);
575 dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
576 /* Add sdu(s) to the Message Buffer */
577 if (NULLP != dDatReq)
579 if(pdu->tbIndex == 1)
582 /* Adding this temporary variable for optimization */
583 RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
585 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
588 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
593 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
594 datReqTb->lchData[idx1].lcId,
595 datReqTb->lchData[idx1].pdu.mBuf[idx2],
598 RLOG1(L_ERROR, "FAILED for LCID:%d",datReqTb->lchData[idx1].lcId);
602 RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
606 else if(pdu->tbIndex == 2)
609 RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
610 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
613 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
618 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
619 datReqTb->lchData[idx1].lcId,
620 datReqTb->lchData[idx1].pdu.mBuf[idx2],
623 RLOG2(L_ERROR, "FAILED TB Size %d LCID:%d",
624 ((S16)pdu->schdTbSz),datReqTb->lchData[idx1].lcId);
628 RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
635 case EVENT_SLOT_IND_TO_MAC:
639 } /* End of switch(reqType) */
640 if(rgMUXAddPadd(inst,&pdu->schdTbSz, sduBuf, FALSE, err) != ROK)
642 RLOG1(L_ERROR, "FAILED for TB Size:%d",(S16)pdu->schdTbSz);
649 * @brief Function to create MAC PDU from RLC SDUs and control elements, if any.
653 * Function : rgMUXBldPdu
655 * -# This function shall be invoked by Downlink Harq Module as soon as a
656 * Data request is received from RLC for a UE along with its stored
657 * control elements to create a MAC PDU.
658 * -# It shall create subheaders for the control elements (timing advance
659 * and contention resolution ID) and pack sub-header before each CE,
660 * if given, and then shall run through all the logical channels and
661 * create subheader for each of the SDUs given on that logical channel
662 * and pack corresponding sub-header before the each SDU
663 * -# It shall invoke rgMUXPadPdu if the total length of the created
664 * buffer is less than the scheduled TB size.
667 * @param[in] Inst *inst
668 * @param[in] RgBldPduInfo *bldPdu
669 * @param[in] Buffer **txPdu
670 * @param[out] RgErrInfo *err
676 PUBLIC S16 rgMUXBldPdu
684 PUBLIC S16 rgMUXBldPdu(inst, pdu, txPdu, err)
691 Buffer *mBuf = NULLP;
696 if (rgGetMsg(inst, &mBuf) != ROK)
698 /* Buffer couldnt get allocated. Return a failure */
699 err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
700 err->errType = RGERR_MUX_BLD_PDU;
701 RLOG1(L_FATAL, "Memory allocation failed during MUXing of MAC TB: MacInst %d", inst);
705 if(rgMUXAddCes(inst, pdu, mBuf, err) != ROK)
708 err->errType = RGERR_MUX_BLD_PDU;
709 RLOG1(L_ERROR, "Failed to Multiplex MAC CEs: MacInst %d", inst);
713 if(rgMUXAddSdus(inst, pdu, mBuf, err) != ROK)
716 err->errType = RGERR_MUX_BLD_PDU;
717 RLOG1(L_ERROR, "FAILED to Multiplex MAC SDU: MacInst %d", inst);
727 #else /* else of ifndef L2_OPTMZ */
730 * @brief Function to add SDU along with sub headers.
734 * Function : rgMUXAddSdus
736 * @param[in] RgBldPduInfo *pdu
737 * @param[out] Buffer *mBuf
738 * @param[out] Buffer *sduBuf
744 PRIVATE S16 rgMUXAddSdus
749 RgTfuDatReqTbInfo *tb,
753 PRIVATE S16 rgMUXAddSdus(pdu, sHdrBuf, tb, err)
757 RgTfuDatReqTbInfo *tb;
761 RgRguDDatReqPerUe *dDatReq;
762 RgRguCmnDatReq *cDatReq;
770 cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
771 /* Add sdu(s) to the Message Buffer */
772 if (NULLP != cDatReq)
774 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
775 RG_CCCH_LCID, cDatReq->pdu,
776 sHdrBuf, NULLP, err) != ROK)
780 /* L2 Optimization for mUe/Tti: RLC pdu mbuf pointer will be passed
781 * to CL it is stored in DlHqProc->TbInfo and it will be used in
782 * case of harq retransmission. Store CCCH data at 0th index of
784 tb->lchInfo[tb->numLch].mBuf[(tb->lchInfo[tb->numLch].numPdu)]\
786 tb->lchInfo[tb->numLch].numPdu++;
788 RLOG3(L_INFO,"MSG4 is muxed numLch=%ld numPdu=%ld tbaddr =%p", tb->numLch,tb->lchInfo[tb->numLch-1].numPdu, (U32)tb);
793 dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
794 /* Add sdu(s) to the Message Buffer */
795 if (NULLP != dDatReq)
797 if(pdu->tbIndex == 1)
800 /* Adding this temporary variable for optimization */
801 RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
803 tb->numLch = lchIdx = 0;
805 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
807 tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
810 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
815 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
816 datReqTb->lchData[idx1].lcId,
817 datReqTb->lchData[idx1].pdu.mBuf[idx2],
818 sHdrBuf, NULLP, err) != ROK)
820 RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED\n"));
824 /* L2 Optimization for mUe/Tti:Increment numPdu by 1
825 * Store pdu buffer in tb to send it to CL/PHY. Increment
827 tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
830 if(datReqTb->lchData[idx1].freeBuff == FALSE)
831 {/* Not incrementing refCnt for UM Mode. */
832 tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
836 if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
839 tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
840 if(NULL == tmp->b_rptr)
842 RLOG0(L_INFO,"11111Its Null here only ");
847 RLOG0(L_INFO,"222222Its Null here only \n");
850 //tb->lchInfo[tb->numLch].numPdu++;
858 tb->lchInfo[lchIdx].numPdu = pduIdx;
859 /* If Bearer is UM then MBUF to be free by MAC layer */
860 tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
866 else if(pdu->tbIndex == 2)
869 RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
870 tb->numLch = lchIdx = 0;
871 // prc_trace_format_string(0x40,3,": AddSdus: numOfLch=%d numOfPdu=%d, schdSz=%d", datReqTb->nmbLch, datReqTb->lchData[0].pdu.numPdu, pdu->schdTbSz);
872 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
874 tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
876 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
881 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
882 datReqTb->lchData[idx1].lcId,
883 datReqTb->lchData[idx1].pdu.mBuf[idx2],
884 sHdrBuf, NULLP, err) != ROK)
886 RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED TB Size %d\n",
887 ((S16)pdu->schdTbSz)));
890 /* L2 Optimization for mUe/Tti:Increment numPdu by 1
891 * Store pdu buffer in tb to send it to CL/PHY. Increment
893 tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
895 if(datReqTb->lchData[idx1].freeBuff == FALSE)
896 {/* Not incrementing refCnt for UM Mode. */
897 tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
900 if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
903 tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
904 if(NULL == tmp->b_rptr)
906 RLOG0(L_INFO,"2212121Its Null here only \n");
911 RLOG0(L_INFO,"343343433ts Null here only \n");
914 // tb->lchInfo[tb->numLch].numPdu++;
922 tb->lchInfo[lchIdx].numPdu = pduIdx;
923 /* If Bearer is UM then MBUF to be free by MAC layer */
924 tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
934 case EVENT_SLOT_IND_TO_MAC:
938 } /* End of switch(reqType) */
941 if(rgMUXAddPadd(inst, &pdu->schdTbSz, sduBuf, NULLP, FALSE, err) != ROK)
943 //RGDBGERRNEW((rgPBuf, "FAILED"));
946 tb->padSize = padSize;
952 * @brief Function to create MAC PDU from RLC SDUs and control elements, if any.
956 * Function : rgMUXBldPdu
957 * -# This function shall be invoked by Downlink Harq Module as soon as a
958 * Data request is received from RLC for a UE along with its stored
959 * control elements to create a MAC PDU.
960 * -# It shall create subheaders for the control elements (timing advance
961 * and contention resolution ID), if given, and then shall run through
962 * all the logical channels and create subheader for each of the SDUs
963 * given on that logical channel.
964 * -# L2 Optimization for mUe/Tti: Avoiding muxing to reduce overhead of
965 * additional Mbuf allocation memory related operation.
966 -# MAC header, MAC CEs, MAC PDUs and MAC padding are stored in pre-
967 allocated mBufs. These pointers will not be freed by CL
968 * -# It shall invoke rgMUXPadPdu if the total length of the created
969 * buffer is less than the scheduled TB size.
970 * -# At successfull operation of this function tb->macHdr, will have
971 * complete MAC Header. tb->macCes will have MAC CEs if any. tb->
972 * lchInfo[idx].mBuf[idx] will have MAC SDU per LCH per TB per UE
975 * @param[in] RgBldPduInfo *bldPdu
976 * @param[out] RgTbInfo *tb
977 * @param[out] RgErrInfo *err
983 PUBLIC S16 rgMUXBldPdu
987 RgTfuDatReqTbInfo *tb,
991 PUBLIC S16 rgMUXBldPdu(inst, pdu, tb, err)
994 RgTfuDatReqTbInfo *tb;
998 Buffer *mBuf1; /* MAC hearder */
999 Buffer *mBuf2; /* MAC CEs */
1000 //U32 lchIdx, pduIdx;
1004 /* Reseting macHdr and macCes pointers */
1006 SResetMBuf(tb->macHdr);
1008 SResetMBuf(tb->macCes);
1010 mBuf1 = tb->macHdr; /* MAC hearder */
1011 mBuf2 = tb->macCes; /* MAC CEs */
1012 tb->tbSize = pdu->schdTbSz;
1014 if(rgMUXAddCes(inst, pdu, mBuf1, mBuf2, err) != ROK)
1016 /* Reset rPtr and wPtr to the base of data buffer(db_base)*/
1017 RLOG0(L_INFO,"rgMUXBldPdu: rgMUXAddCes is Failed \n");
1019 err->errType = RGERR_MUX_BLD_PDU;
1020 //RGDBGERRNEW((rgPBuf, "FAILED"));
1023 if(rgMUXAddSdus(inst, pdu, mBuf1, tb, err) != ROK)
1025 /*TODO:MP Reset rPtr and wPtr to the base of data buffer(db_base)
1026 * Reset numLch and numPdu to zero and set MAC SDU buf to NULLP */
1027 RLOG0(L_INFO, "rgMUXBldPdu: rgMUXAddSdus is Failed \n");
1030 err->errType = RGERR_MUX_BLD_PDU;
1031 //RGDBGERRNEW((rgPBuf, "FAILED"));
1035 // SPrntMsg(tb->macHdr, 0, 0);
1036 // prc_trace_format_string(0x40,3,": padSize=%ld", tb->padSize);
1043 #endif /* end of L2_OPTMZ */
1046 * @brief Function to create RAR PDU.
1050 * Function : rgMUXBldRarPdu
1051 * This function is used to build RAR PDUs and is being
1052 * invoked by the scheduler.
1054 * @param[out]RgCellCb *cellCb
1055 * @param[in] RgRaRspAlloc *bldPdu
1056 * @param[in] Buffer **txPdu
1057 * @param[out] RgErrInfo *err
1063 PUBLIC S16 rgMUXBldRarPdu
1066 RgInfRaRntiInfo *alloc,
1071 PUBLIC S16 rgMUXBldRarPdu(cell, alloc, txPdu, err)
1073 RgInfRaRntiInfo *alloc;
1078 Buffer *datBuf = NULLP;
1080 U8 data[RG_RAR_ELEM_LEN];
1084 Inst inst = cell->macInst - RG_INST_START;
1086 TRC2(rgMUXBldRarPdu)
1088 schdTbSz = alloc->schdTbSz;
1089 /* RAR PDU Requirements */
1091 1. SubHeader - R/T/RAPID. //5GNR, changed E to R
1092 2. TA ( if applicable)
1094 a. Hopping Flag - 1 Bit.
1095 b. Fixed Size RB Assignment. - 10 Bits.
1096 c. Truncated Modulation and coding scheme - 4 Bits.
1097 d. TPC command for scheduled PUSCH. - 3 Bits.
1098 e. UL Delay - 1 Bit.
1099 f. CQI Request - 1 Bit.
1103 /* Initialize the error type */
1104 err->errType = RGERR_MUX_BLD_RAR_PDU;
1106 if ((ret = rgGetMsg(inst,&datBuf)) != ROK)
1108 /* Buffer couldnt get allocated. Return a failure */
1109 err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
1110 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "FAILED to getMsg");
1114 if (TRUE == alloc->backOffInd.pres)
1116 /*Set T Bit , NO E bit Required */
1119 hdrByte |= (0x0F & (alloc->backOffInd.val));
1121 /* Add the header */
1122 RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
1125 err->errCause = RGERR_MUX_BLD_BI_FAIL;
1126 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_BI_FAIL");
1127 RG_FREE_MSG(datBuf);
1133 for (idx=0; idx < (alloc->numCrnti) &&
1134 (schdTbSz >= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN); idx++)
1139 hdrByte |= (0x3F & (alloc->crntiInfo[idx].rapId));
1141 /* Add the header */
1142 RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
1145 err->errCause = RGERR_MUX_BLD_RAPIDHDR_FAIL;
1146 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_RAPIDHDR_FAIL");
1147 RG_FREE_MSG(datBuf);
1151 /* Prepare the data */
1152 data[0] = 0x7F & ((alloc->crntiInfo[idx].ta.val) >> 4);
1157 rgMUXGet20bitRarGrnt(cell->bwCfg.ulTotalBw, &(alloc->crntiInfo[idx].grnt), &data[1]);
1159 data[1] |= ((U8)((alloc->crntiInfo[idx].ta.val) << 4));
1160 data[4] = (alloc->crntiInfo[idx].tmpCrnti) >> 8;
1161 data[5] = (U8) (alloc->crntiInfo[idx].tmpCrnti);
1163 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
1164 "Rar,Rapid=%d, Temp CRNTI:%d",
1165 alloc->crntiInfo[idx].rapId,
1166 alloc->crntiInfo[idx].tmpCrnti);
1167 MS_BUF_ADD_ALLOC_CALLER();
1168 if(SAddPstMsgMult(&data[0], RG_RAR_ELEM_LEN, datBuf) != ROK)
1170 err->errCause = RGERR_MUX_BLD_RAPID_FAIL;
1171 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_RAPID_FAIL");
1172 RG_FREE_MSG(datBuf);
1175 schdTbSz -= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN;
1178 if(rgMUXAddPadd(inst,&schdTbSz, datBuf, TRUE, err) != ROK)
1180 RG_FREE_MSG(datBuf);
1181 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"FAILED to mux add padding");
1188 } /* rgMUXBldRarPdu */
1190 /***********************************************************
1192 * Func : rgMUXGet20bitRarGrnt
1194 * Desc : This function fills up the 20-bit grant
1203 **********************************************************/
1205 PRIVATE Void rgMUXGet20bitRarGrnt
1208 RgInfRarUlGrnt *msg3Grnt,
1212 PRIVATE Void rgMUXGet20bitRarGrnt(ulBw, msg3Grnt, grnt)
1214 RgInfRarUlGrnt *msg3Grnt;
1218 U16 riv = rgMUXCalcRiv(ulBw, msg3Grnt->rbStart, msg3Grnt->numRb);
1220 TRC2(rgMUXGet20bitRarGrnt);
1222 grnt[2] = msg3Grnt->cqiBit; /* cqi bit is 0, output from sched */
1223 grnt[2] |= (msg3Grnt->delayBit << 1);
1224 grnt[2] |= (msg3Grnt->tpc << 2);
1225 grnt[2] |= (msg3Grnt->iMcsCrnt << 5);
1227 grnt[1] = (msg3Grnt->iMcsCrnt >> 3);
1228 /* Forcing right shift to insert 0 as the LSB:
1229 * since this is assumed in the computation */
1230 grnt[1] |= (U8)((riv << 1) & 0xFE);
1232 grnt[0] = (U8)((riv >> 7) & 0x07);
1233 grnt[0] |= ((msg3Grnt->hop & 0x01) << 3);
1236 } /* rgMUXGet20bitRarGrnt */
1238 /***********************************************************
1240 * Func : rgMUXCalcRiv
1242 * Desc : This function calculates RIV.
1250 **********************************************************/
1252 PUBLIC U16 rgMUXCalcRiv
1259 PUBLIC U16 rgMUXCalcRiv(bw, rbStart, numRb)
1265 U8 numRbMinus1 = numRb - 1;
1270 if (numRbMinus1 <= bw/2)
1272 riv = bw * numRbMinus1 + rbStart;
1276 riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
1279 } /* rgMUXCalcRiv */
1283 /**********************************************************************
1286 **********************************************************************/