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 "rg.x" /* MAC includes */
86 #include "ss_msg.x" /* MAC includes */
88 #ifndef T2K_MEM_LEAK_DBG
89 EXTERN S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
91 char* file = __FILE__;
97 /* global variables */
102 PRIVATE Void rgMUXGet20bitRarGrnt ARGS((U8 ulBw,
103 RgInfRarUlGrnt *msg3Grnt,
105 EXTERN U16 rgMUXCalcRiv ARGS((U8 bw,
109 #ifndef MS_MBUF_CORRUPTION
110 #define MS_BUF_ADD_ALLOC_CALLER()
112 /* forward references */
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);\
121 #define RG_PACK_CE(_ce, _len, _ceBuf, _ret) {\
122 MS_BUF_ADD_ALLOC_CALLER(); \
123 _ret = SAddPstMsgMult((U8 *)(&(_ce)), _len, _ceBuf);\
126 #define RG_MUX_CALC_LEN(_len,_lenBytes,_elmTotLen) {\
128 _lenBytes = (_len <= 255) ? 1 : 2;\
129 _hdrLen = _lenBytes + RG_SDU_SHDR_LEN;\
130 _elmTotLen = _hdrLen + _len;\
133 #define RG_PACK_VAR_SZ_CE_SDU_SHDR(_subHdr, _lcId, _len,_mBuf, _ret) {\
137 _subHdr.shData[0] = (0x3F & _lcId);\
139 _subHdr.shData[1] = (0xFF & _len);\
140 _subHdr.shData[2] = 0;\
144 _subHdr.shData[0] = (0x7F & ((0x40) | _lcId));\
146 _subHdr.shData[1] = (0xFF & (_len >> 8));\
147 _subHdr.shData[2] = (0xFF & _len);\
149 MS_BUF_ADD_ALLOC_CALLER(); \
150 _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
153 #define RG_PACK_PAD_SHDR(_mBuf, _ret) {\
154 _ret = SAddPreMsg(0x3F, _mBuf);\
157 #define RG_PACK_RAR_SHDR(_byte, _mBuf, _ret) {\
158 _ret = SAddPstMsg(_byte, _mBuf);\
163 * @brief Function to add ces along with subhdrs.
164 * This function packs first CE sub-hdr and then CE in ceBuf pointer
168 * Function : rgMUXAddCes
170 * @param[in] Inst inst
171 * @param[in] RgBldPduInfo *pdu
172 * @param[in] Buffer *ceBuf
173 * @param[in] RgErrInfo *err
179 PRIVATE S16 rgMUXAddCes
187 PRIVATE S16 rgMUXAddCes(inst,pdu, ceShdrBuf, ceBuf, err)
199 if (NULLP != pdu->contResId)
201 if(pdu->schdTbSz >= RG_CRES_ELM_LEN)
203 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_CRES_LCID_IDX, ceBuf, ret);
207 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
208 RLOG0(L_ERROR, "Muxing of Contention Resolution CE sub-header is failed");
212 RG_PACK_CE(pdu->contResId->resId[0], RG_CRES_LEN, ceBuf, ret);
216 err->errCause = RGERR_MUX_BLD_CE_FAIL;
217 RLOG0(L_ERROR, "Muxing of Contention Resolution CE is failed")
220 pdu->schdTbSz -= RG_CRES_ELM_LEN;
223 if (TRUE == pdu->ta.pres)
225 if(pdu->schdTbSz >= RG_TA_ELM_LEN)
227 U8 taVal; /* Moving from outer scope to available scope */
228 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_TA_LCID_IDX, ceBuf, ret);
232 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
233 RLOG0(L_ERROR, "Muxing of TA CE sub-hdr is failed")
238 RG_PACK_CE(taVal, RG_TA_LEN, ceBuf, ret);
242 err->errCause = RGERR_MUX_BLD_CE_FAIL;
243 RLOG0(L_ERROR, "Muxing of TA CE is failed")
246 pdu->schdTbSz -= RG_TA_ELM_LEN;
247 RLOG1(L_DEBUG,"TA muxed by MAC: %u", pdu->ta.val);
251 if(TRUE == pdu->sCellActCe.pres)
253 if(pdu->schdTbSz >= RG_SCELL_CE_ELM_LEN)
255 /* Adding the subheader for ACT CE */
256 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_SCELL_LCID_IDX, ceBuf, ret);
260 err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
261 RLOG0(L_ERROR, "Muxing of SCELL Activation CE sub-hdr is failed")
265 /* Adding the ACT CE */
266 RG_PACK_CE(pdu->sCellActCe.val, RG_SCELL_ACT_CE_LEN, ceBuf, ret);
270 err->errCause = RGERR_MUX_BLD_CE_FAIL;
271 RLOG0(L_ERROR, "Muxing of SCELL Activation CE is failed")
274 pdu->schdTbSz -= RG_SCELL_CE_ELM_LEN;
280 /*LcId is not yet decided in 5G-NR spec for MAC CEs Hence, not writing code
287 * @brief Function to insert SDU along with sub headers.
291 * Function : rgMUXInsSdu
293 * @param[in] Inst inst
294 * @param[in] MsgLen *schdTbSz
296 * @param[in] Buffer *sdu
297 * @param[out] Buffer *sduBuf
298 * @param[out] RgErrInfo *err
304 PRIVATE S16 rgMUXInsSdu
314 PRIVATE S16 rgMUXInsSdu(inst,schdTbSz, lcId, sdu, sduBuf, err)
329 SFndLenMsg(sdu, &msgLen);
331 RG_MUX_CALC_LEN(msgLen,lenBytes,elmTotLen);
335 rgDlrate_rgu += msgLen;
337 if (*schdTbSz >= elmTotLen)
340 RG_PACK_VAR_SZ_CE_SDU_SHDR(subHdr, lcId, msgLen,sduBuf, ret);
343 err->errCause = RGERR_MUX_BLD_SDUHDR_FAIL;
344 RLOG1(L_ERROR, "RGERR_MUX_BLD_SDUHDR_FAIL for LCID:%d",lcId);
348 #ifndef L2_OPTMZ /* no need to pack as passing not muxing all LCs PDUs to 1*/
349 RG_PACK_SDU(sduBuf, sdu, ret);
358 err->errCause = RGERR_MUX_BLD_SDU_FAIL;
359 RLOG1(L_ERROR, "RGERR_MUX_BLD_SDU_FAIL for LCID:%d",lcId);
363 *schdTbSz -= elmTotLen;
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);
378 * @brief Function to insert SDU along with sub headers.
382 * Function : rgMUXAddPadd
384 * @param[in] Inst inst
385 * @param[in] RgBldPduInfo *pdu
386 * @param[out] Buffer *mBuf
387 * @param[out] Buffer *sduBuf
396 PUBLIC S16 rgMUXAddPadd
405 PUBLIC S16 rgMUXAddPadd(inst,schdTbSz, sduBuf, isRar, err)
414 Buffer *padBuf = NULLP;
426 if((FALSE == isRar) && (NULL != sHdrBuf))
430 RG_PACK_SHDR_FIXD_SZ(subHdr, RG_PAD_LCID_IDX, sduBuf, ret);
434 err->errCause = RGERR_MUX_BLD_PADHDR_FAIL;
435 RLOG0(L_ERROR, "RGERR_MUX_BLD_PADHDR_FAIL");
444 if (*schdTbSz <= RG_MAX_PAD_ARR_SZ)
447 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
451 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
454 padSize += *schdTbSz;
458 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
459 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
468 if (*schdTbSz > RG_MAX_PAD_ARR_SZ)
471 RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
475 RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
478 padSize += RG_MAX_PAD_ARR_SZ;
483 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
484 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
488 *schdTbSz -= RG_MAX_PAD_ARR_SZ;
493 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
497 RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
500 padSize += *schdTbSz;
505 err->errCause = RGERR_MUX_BLD_PAD_FAIL;
506 RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
522 * @brief Function to add SDU along with sub headers.
526 * Function : rgMUXAddSdus
528 * @param[in] Inst inst
529 * @param[in] RgBldPduInfo *pdu
530 * @param[out] Buffer *mBuf
531 * @param[out] Buffer *sduBuf
537 PRIVATE S16 rgMUXAddSdus
545 PRIVATE S16 rgMUXAddSdus(inst,pdu, sduBuf, err)
552 RgRguDDatReqPerUe *dDatReq;
553 RgRguCmnDatReq *cDatReq;
560 cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
561 /* Add sdu(s) to the Message Buffer */
562 if (NULLP != cDatReq)
564 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
565 RG_CCCH_LCID, cDatReq->pdu, sduBuf, err) != ROK)
569 RG_FREE_MSG(cDatReq->pdu);
574 dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
575 /* Add sdu(s) to the Message Buffer */
576 if (NULLP != dDatReq)
578 if(pdu->tbIndex == 1)
581 /* Adding this temporary variable for optimization */
582 RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
584 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
587 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
592 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
593 datReqTb->lchData[idx1].lcId,
594 datReqTb->lchData[idx1].pdu.mBuf[idx2],
597 RLOG1(L_ERROR, "FAILED for LCID:%d",datReqTb->lchData[idx1].lcId);
601 RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
605 else if(pdu->tbIndex == 2)
608 RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
609 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
612 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
617 if(rgMUXInsSdu(inst,&pdu->schdTbSz,
618 datReqTb->lchData[idx1].lcId,
619 datReqTb->lchData[idx1].pdu.mBuf[idx2],
622 RLOG2(L_ERROR, "FAILED TB Size %d LCID:%d",
623 ((S16)pdu->schdTbSz),datReqTb->lchData[idx1].lcId);
627 RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
638 } /* End of switch(reqType) */
639 if(rgMUXAddPadd(inst,&pdu->schdTbSz, sduBuf, FALSE, err) != ROK)
641 RLOG1(L_ERROR, "FAILED for TB Size:%d",(S16)pdu->schdTbSz);
648 * @brief Function to create MAC PDU from RLC SDUs and control elements, if any.
652 * Function : rgMUXBldPdu
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.
666 * @param[in] Inst *inst
667 * @param[in] RgBldPduInfo *bldPdu
668 * @param[in] Buffer **txPdu
669 * @param[out] RgErrInfo *err
675 PUBLIC S16 rgMUXBldPdu
683 PUBLIC S16 rgMUXBldPdu(inst, pdu, txPdu, err)
690 Buffer *mBuf = NULLP;
695 if (rgGetMsg(inst, &mBuf) != ROK)
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);
704 if(rgMUXAddCes(inst, pdu, mBuf, err) != ROK)
707 err->errType = RGERR_MUX_BLD_PDU;
708 RLOG1(L_ERROR, "Failed to Multiplex MAC CEs: MacInst %d", inst);
712 if(rgMUXAddSdus(inst, pdu, mBuf, err) != ROK)
715 err->errType = RGERR_MUX_BLD_PDU;
716 RLOG1(L_ERROR, "FAILED to Multiplex MAC SDU: MacInst %d", inst);
726 #else /* else of ifndef L2_OPTMZ */
729 * @brief Function to add SDU along with sub headers.
733 * Function : rgMUXAddSdus
735 * @param[in] RgBldPduInfo *pdu
736 * @param[out] Buffer *mBuf
737 * @param[out] Buffer *sduBuf
743 PRIVATE S16 rgMUXAddSdus
748 RgTfuDatReqTbInfo *tb,
752 PRIVATE S16 rgMUXAddSdus(pdu, sHdrBuf, tb, err)
756 RgTfuDatReqTbInfo *tb;
760 RgRguDDatReqPerUe *dDatReq;
761 RgRguCmnDatReq *cDatReq;
769 cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
770 /* Add sdu(s) to the Message Buffer */
771 if (NULLP != cDatReq)
773 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
774 RG_CCCH_LCID, cDatReq->pdu,
775 sHdrBuf, NULLP, err) != ROK)
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
783 tb->lchInfo[tb->numLch].mBuf[(tb->lchInfo[tb->numLch].numPdu)]\
785 tb->lchInfo[tb->numLch].numPdu++;
787 RLOG3(L_INFO,"MSG4 is muxed numLch=%ld numPdu=%ld tbaddr =%p", tb->numLch,tb->lchInfo[tb->numLch-1].numPdu, (U32)tb);
792 dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
793 /* Add sdu(s) to the Message Buffer */
794 if (NULLP != dDatReq)
796 if(pdu->tbIndex == 1)
799 /* Adding this temporary variable for optimization */
800 RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
802 tb->numLch = lchIdx = 0;
804 for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
806 tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
809 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
814 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
815 datReqTb->lchData[idx1].lcId,
816 datReqTb->lchData[idx1].pdu.mBuf[idx2],
817 sHdrBuf, NULLP, err) != ROK)
819 RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED\n"));
823 /* L2 Optimization for mUe/Tti:Increment numPdu by 1
824 * Store pdu buffer in tb to send it to CL/PHY. Increment
826 tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
829 if(datReqTb->lchData[idx1].freeBuff == FALSE)
830 {/* Not incrementing refCnt for UM Mode. */
831 tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
835 if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
838 tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
839 if(NULL == tmp->b_rptr)
841 RLOG0(L_INFO,"11111Its Null here only ");
846 RLOG0(L_INFO,"222222Its Null here only \n");
849 //tb->lchInfo[tb->numLch].numPdu++;
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;
865 else if(pdu->tbIndex == 2)
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++)
873 tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
875 (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
880 if(rgMUXInsSdu(inst, &pdu->schdTbSz,
881 datReqTb->lchData[idx1].lcId,
882 datReqTb->lchData[idx1].pdu.mBuf[idx2],
883 sHdrBuf, NULLP, err) != ROK)
885 RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED TB Size %d\n",
886 ((S16)pdu->schdTbSz)));
889 /* L2 Optimization for mUe/Tti:Increment numPdu by 1
890 * Store pdu buffer in tb to send it to CL/PHY. Increment
892 tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
894 if(datReqTb->lchData[idx1].freeBuff == FALSE)
895 {/* Not incrementing refCnt for UM Mode. */
896 tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
899 if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
902 tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
903 if(NULL == tmp->b_rptr)
905 RLOG0(L_INFO,"2212121Its Null here only \n");
910 RLOG0(L_INFO,"343343433ts Null here only \n");
913 // tb->lchInfo[tb->numLch].numPdu++;
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;
937 } /* End of switch(reqType) */
940 if(rgMUXAddPadd(inst, &pdu->schdTbSz, sduBuf, NULLP, FALSE, err) != ROK)
942 //RGDBGERRNEW((rgPBuf, "FAILED"));
945 tb->padSize = padSize;
951 * @brief Function to create MAC PDU from RLC SDUs and control elements, if any.
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
974 * @param[in] RgBldPduInfo *bldPdu
975 * @param[out] RgTbInfo *tb
976 * @param[out] RgErrInfo *err
982 PUBLIC S16 rgMUXBldPdu
986 RgTfuDatReqTbInfo *tb,
990 PUBLIC S16 rgMUXBldPdu(inst, pdu, tb, err)
993 RgTfuDatReqTbInfo *tb;
997 Buffer *mBuf1; /* MAC hearder */
998 Buffer *mBuf2; /* MAC CEs */
999 //U32 lchIdx, pduIdx;
1003 /* Reseting macHdr and macCes pointers */
1005 SResetMBuf(tb->macHdr);
1007 SResetMBuf(tb->macCes);
1009 mBuf1 = tb->macHdr; /* MAC hearder */
1010 mBuf2 = tb->macCes; /* MAC CEs */
1011 tb->tbSize = pdu->schdTbSz;
1013 if(rgMUXAddCes(inst, pdu, mBuf1, mBuf2, err) != ROK)
1015 /* Reset rPtr and wPtr to the base of data buffer(db_base)*/
1016 RLOG0(L_INFO,"rgMUXBldPdu: rgMUXAddCes is Failed \n");
1018 err->errType = RGERR_MUX_BLD_PDU;
1019 //RGDBGERRNEW((rgPBuf, "FAILED"));
1022 if(rgMUXAddSdus(inst, pdu, mBuf1, tb, err) != ROK)
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");
1029 err->errType = RGERR_MUX_BLD_PDU;
1030 //RGDBGERRNEW((rgPBuf, "FAILED"));
1034 // SPrntMsg(tb->macHdr, 0, 0);
1035 // prc_trace_format_string(0x40,3,": padSize=%ld", tb->padSize);
1042 #endif /* end of L2_OPTMZ */
1045 * @brief Function to create RAR PDU.
1049 * Function : rgMUXBldRarPdu
1050 * This function is used to build RAR PDUs and is being
1051 * invoked by the scheduler.
1053 * @param[out]RgCellCb *cellCb
1054 * @param[in] RgRaRspAlloc *bldPdu
1055 * @param[in] Buffer **txPdu
1056 * @param[out] RgErrInfo *err
1062 PUBLIC S16 rgMUXBldRarPdu
1065 RgInfRaRntiInfo *alloc,
1070 PUBLIC S16 rgMUXBldRarPdu(cell, alloc, txPdu, err)
1072 RgInfRaRntiInfo *alloc;
1077 Buffer *datBuf = NULLP;
1079 U8 data[RG_RAR_ELEM_LEN];
1083 Inst inst = cell->macInst - RG_INST_START;
1085 TRC2(rgMUXBldRarPdu)
1087 schdTbSz = alloc->schdTbSz;
1088 /* RAR PDU Requirements */
1090 1. SubHeader - R/T/RAPID. //5GNR, changed E to R
1091 2. TA ( if applicable)
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.
1102 /* Initialize the error type */
1103 err->errType = RGERR_MUX_BLD_RAR_PDU;
1105 if ((ret = rgGetMsg(inst,&datBuf)) != ROK)
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");
1113 if (TRUE == alloc->backOffInd.pres)
1115 /*Set T Bit , NO E bit Required */
1118 hdrByte |= (0x0F & (alloc->backOffInd.val));
1120 /* Add the header */
1121 RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
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);
1132 for (idx=0; idx < (alloc->numCrnti) &&
1133 (schdTbSz >= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN); idx++)
1138 hdrByte |= (0x3F & (alloc->crntiInfo[idx].rapId));
1140 /* Add the header */
1141 RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
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);
1150 /* Prepare the data */
1151 data[0] = 0x7F & ((alloc->crntiInfo[idx].ta.val) >> 4);
1156 rgMUXGet20bitRarGrnt(cell->bwCfg.ulTotalBw, &(alloc->crntiInfo[idx].grnt), &data[1]);
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);
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)
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);
1174 schdTbSz -= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN;
1177 if(rgMUXAddPadd(inst,&schdTbSz, datBuf, TRUE, err) != ROK)
1179 RG_FREE_MSG(datBuf);
1180 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"FAILED to mux add padding");
1187 } /* rgMUXBldRarPdu */
1189 /***********************************************************
1191 * Func : rgMUXGet20bitRarGrnt
1193 * Desc : This function fills up the 20-bit grant
1202 **********************************************************/
1204 PRIVATE Void rgMUXGet20bitRarGrnt
1207 RgInfRarUlGrnt *msg3Grnt,
1211 PRIVATE Void rgMUXGet20bitRarGrnt(ulBw, msg3Grnt, grnt)
1213 RgInfRarUlGrnt *msg3Grnt;
1217 U16 riv = rgMUXCalcRiv(ulBw, msg3Grnt->rbStart, msg3Grnt->numRb);
1219 TRC2(rgMUXGet20bitRarGrnt);
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);
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);
1231 grnt[0] = (U8)((riv >> 7) & 0x07);
1232 grnt[0] |= ((msg3Grnt->hop & 0x01) << 3);
1235 } /* rgMUXGet20bitRarGrnt */
1237 /***********************************************************
1239 * Func : rgMUXCalcRiv
1241 * Desc : This function calculates RIV.
1249 **********************************************************/
1251 PUBLIC U16 rgMUXCalcRiv
1258 PUBLIC U16 rgMUXCalcRiv(bw, rbStart, numRb)
1264 U8 numRbMinus1 = numRb - 1;
1269 if (numRbMinus1 <= bw/2)
1271 riv = bw * numRbMinus1 + rbStart;
1275 riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
1278 } /* rgMUXCalcRiv */
1282 /**********************************************************************
1285 **********************************************************************/