From: barveankit Date: Sat, 30 Apr 2022 18:27:16 +0000 (+0530) Subject: [Epic-ID: ODUHIGH-402][Task-ID: ODUHIGH-418] Harq feature changes X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F34%2F8134%2F10;p=o-du%2Fl2.git [Epic-ID: ODUHIGH-402][Task-ID: ODUHIGH-418] Harq feature changes Signed-off-by: barveankit Change-Id: I38674060ab7dcb876cd9b0d39723a6d887215d77 Signed-off-by: barveankit --- diff --git a/src/5gnrmac/mac.h b/src/5gnrmac/mac.h index fb78f8073..6115c67dc 100644 --- a/src/5gnrmac/mac.h +++ b/src/5gnrmac/mac.h @@ -90,6 +90,21 @@ typedef enum MAC_LC_STATE_ACTIVE }MacLcState; +typedef struct dlTbInfo +{ + SlotTimingInfo txTime; + uint16_t tbSize; + uint8_t *tb; +}DlTbInfo; + +/* DL HARQ Process Info */ +typedef struct dlHarqProcCb +{ + uint8_t procId; /* HARQ Process Id */ + uint8_t numTb; /* Number of TB */ + DlTbInfo tbInfo[MAX_NUM_TB_PER_UE]; /* TB information */ +}DlHarqProcCb; + typedef struct macDlSlot { DlSchedInfo dlInfo; @@ -108,8 +123,7 @@ typedef struct macCbInfo uint8_t msg3Pdu[6]; /* used as CRI value during muxing */ uint8_t *msg4Pdu; /* storing DL-CCCH Ind Pdu */ uint16_t msg4PduLen; /* storing DL-CCCH Ind Pdu Len */ - uint8_t *msg4TxPdu; /* muxed Pdu used for re-transmission */ - uint16_t msg4TbSize; /* size required for msg4TxPdu */ + DlHarqProcCb msg4HqInfo; /* HARQ process info for msg 4 */ }MacRaCbInfo; typedef struct macCe @@ -138,12 +152,6 @@ typedef struct macDlData MacDlInfo pduInfo[MAX_MAC_DL_PDU]; }MacDlData; -/* HARQ Process Info */ -typedef struct dlHarqProcCb -{ - uint8_t procId; /* HARQ Process Id */ -}DlHarqProcCb; - /* DL HARQ entity */ typedef struct dlHarqEnt { diff --git a/src/5gnrmac/mac_demux.c b/src/5gnrmac/mac_demux.c index d244d5792..1989a3be5 100644 --- a/src/5gnrmac/mac_demux.c +++ b/src/5gnrmac/mac_demux.c @@ -143,16 +143,6 @@ uint8_t unpackRxData(uint16_t cellId, SlotTimingInfo slotInfo, RxDataIndPdu *rxD pduLen -= length; rxPduIdx = rxPduIdx + length; - /* Delete RA cb once RRC setup complete received */ - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == rxDataIndPdu->rnti) - { - MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, \ - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen); - MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \ - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN); - memset(&macCb.macCell[cellIdx]->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo)); - } - /* Send UL Data to RLC */ ret = macProcUlData(cellId, rxDataIndPdu->rnti, slotInfo, lcId, length, pdu); diff --git a/src/5gnrmac/mac_harq_dl.c b/src/5gnrmac/mac_harq_dl.c new file mode 100644 index 000000000..8b3499fd3 --- /dev/null +++ b/src/5gnrmac/mac_harq_dl.c @@ -0,0 +1,245 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +/* header include files (.h) */ +#include "common_def.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "lwr_mac_upr_inf.h" +#include "mac.h" +#include "mac_utils.h" +#include "mac_harq_dl.h" + +/** + * @brief Add HARQ process to UE's DL HARQ Entity + * + * @details + * + * Function : addDlHqProcInUe + * + * This functions adds HARQ process to UE's DL HARQ entity + * + * @param[in] Time of transmission on this HARQ process + * @param[in] UE Cb + * @param[in] DL Scheduling Information + * @return + * -# Void + **/ +void addDlHqProcInUe(SlotTimingInfo dlMsgTime, MacUeCb *ueCb, DlMsgSchInfo schedInfo) +{ + uint8_t hqProcId = 0, tbIdx = 0, cwIdx = 0; + DlHarqEnt *dlHqEnt = NULLP; + DlHarqProcCb *hqProcCb = NULLP; + + dlHqEnt = &ueCb->dlInfo.dlHarqEnt; + hqProcId = schedInfo.dlMsgInfo.harqProcNum; + hqProcCb = &dlHqEnt->harqProcCb[hqProcId]; + + /* Check if harqProcId is already present in UE's DL HARQ Entity */ + if(hqProcCb->procId == schedInfo.dlMsgInfo.harqProcNum) + { + /* Expected Behaviour: + * If a HARQ proc is already present in DL HARQ entity, it means this HARQ proc + * is not free and SCH must not schedule on this process. + * + * Corner Case (occured if this line is hit): + * HARQ proc is present in DL HARQ entity but SCH has scheduled a new data transmission on it. + * + * Action: + * Free the process and schedule new data on it + */ + for(tbIdx = 0; tbIdx < hqProcCb->numTb; tbIdx++) + { + MAC_FREE(hqProcCb->tbInfo[tbIdx].tb, hqProcCb->tbInfo[tbIdx].tbSize); + } + memset(hqProcCb, 0, sizeof(DlHarqProcCb)); + } + + /* Fill HARQ Proc Cb */ + hqProcCb->procId = hqProcId; + for(cwIdx = 0; cwIdx < schedInfo.dlMsgPdschCfg.numCodewords; cwIdx++) + { + memcpy(&hqProcCb->tbInfo[hqProcCb->numTb].txTime, &dlMsgTime, sizeof(SlotTimingInfo)); + hqProcCb->tbInfo[hqProcCb->numTb].tbSize = schedInfo.dlMsgPdschCfg.codeword[cwIdx].tbSize; + hqProcCb->numTb++; + } + return; +} + +/** + * @brief Adds multiplexes TB to DL HARQ Process Info + * + * @details + * + * Function : updateNewTbInDlHqProcCb + * + * This function adds multiplxed TB to DL HARQ process. + * It will be used in case retransmission is required. + * + * @param[in] Time on which TB will be transmitted + * @param[in] UE CB + * @param[in] Transport Block + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t updateNewTbInDlHqProcCb(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint32_t tbSize, uint8_t *txPdu) +{ + uint8_t hqProcIdx = 0, tbIdx = 0; + DlHarqEnt *dlHqEnt = NULLP; + DlTbInfo *tbInfo = NULLP; + + dlHqEnt = &ueCb->dlInfo.dlHarqEnt; + + /* Search HARQ Proc Cb in DL HARQ Ent */ + for(hqProcIdx = 0; hqProcIdx < MAX_NUM_HARQ_PROC; hqProcIdx++) + { + /* Search TB Info in a HARQ Proc Cb */ + for(tbIdx =0; tbIdx < dlHqEnt->harqProcCb[hqProcIdx].numTb; tbIdx++) + { + /* Store MAC PDU if a harqProcCb->tbInfo is found with + * a. same SFN/Slot on which incoming RLC DL Data is to be scheduled + * b. same TB size as MAC PDU size + */ + if((dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].txTime.sfn == slotInfo.sfn) && + (dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].txTime.slot == slotInfo.slot) && + (dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].tbSize == tbSize)) + { + tbInfo = &dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx]; + MAC_ALLOC(tbInfo->tb, tbSize); + if(!tbInfo->tb) + { + DU_LOG("\nERROR --> MAC : Failed to allocate memory for TB in updateTbInDlHqProcCb"); + return RFAILED; + } + memcpy(tbInfo->tb, txPdu, tbSize); + + return ROK; + } + } + } + return RFAILED; +} + +/** + * @brief Returns a transmission block from HARQ process Cb + * + * @details + * + * Function : fetchTbfromDlHarqProc + * + * Returns a transmission block from HARQ process Cb + * + * @param[in] Time of retransmission + * @param[in] UE CB + * @param[in] HARQ process Id + * @param[in] TB size + * @return + * -# Pointer to TB + * -# NULL + **/ +uint8_t* fetchTbfromDlHarqProc(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint8_t hqProcId, uint32_t tbSize) +{ + uint8_t tbIdx = 0; + DlHarqEnt *dlHqEnt = NULLP; + DlHarqProcCb *hqProcCb = NULLP; + + dlHqEnt = &ueCb->dlInfo.dlHarqEnt; + hqProcCb = &dlHqEnt->harqProcCb[hqProcId]; + + /* Search HARQ Proc Cb in DL HARQ Ent */ + if(hqProcCb->procId == hqProcId) + { + /* Search TB Info in a HARQ Proc Cb */ + for(tbIdx =0; tbIdx < hqProcCb->numTb; tbIdx++) + { + if(hqProcCb->tbInfo[tbIdx].tbSize == tbSize) + { + /* Update transmission time in TB Info */ + memset(&hqProcCb->tbInfo[tbIdx].txTime, 0, sizeof(SlotTimingInfo)); + memcpy(&hqProcCb->tbInfo[tbIdx].txTime, &slotInfo, sizeof(SlotTimingInfo)); + + return hqProcCb->tbInfo[tbIdx].tb; + } + } + } + return NULLP; +} +/** + * @brief Release Dl Harq process + * + * @details + * + * Function : fetchTbfromDlHarqProc + * + * Release Dl Harq process + * + * @param[in] Pst *pst, the post structure + * @param[in] SchRlsHqInfo *hqIndo, release hq info structure + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t MacSchReleaseDlHarqProc(Pst *pst, SchRlsHqInfo *hqInfo) +{ + uint8_t hqProcId, tbIdx = 0; + uint16_t cellIdx = 0, hqInfoIdx = 0, ueId = 0; + MacCellCb *cellCb = NULLP; + MacUeCb *ueCb = NULLP; + DlHarqEnt *dlHqEnt = NULLP; + DlHarqProcCb *hqProcCb = NULLP; + + GET_CELL_IDX(hqInfo->cellId, cellIdx); + cellCb = macCb.macCell[cellIdx]; + + for(hqInfoIdx = 0; hqInfoIdx < hqInfo->numUes; hqInfoIdx++) + { + GET_UE_ID(hqInfo->ueHqInfo[hqInfoIdx].crnti, ueId) + ueCb = &cellCb->ueCb[ueId -1]; + dlHqEnt = &ueCb->dlInfo.dlHarqEnt; + hqProcId = hqInfo->ueHqInfo[hqInfoIdx].hqProcId; + + /* First check if the HARQ process to be released belong to msg 4 */ + if ((ueCb->raCb) && (ueCb->raCb->msg4HqInfo.procId == hqProcId)) + { + deleteMacRaCb(cellIdx, ueCb); + } + else + { + /* Search harqProcId in UE's DL HARQ Entity */ + hqProcCb = &dlHqEnt->harqProcCb[hqProcId]; + if(hqProcCb->procId == hqProcId) + { + /* Free HARQ process */ + for(tbIdx = 0; tbIdx < hqProcCb->numTb; tbIdx++) + { + MAC_FREE(hqProcCb->tbInfo[tbIdx].tb, hqProcCb->tbInfo[tbIdx].tbSize); + } + memset(hqProcCb, 0, sizeof(DlHarqProcCb)); + hqProcCb->procId = MAX_NUM_HARQ_PROC; + } + } + } + + MAC_FREE(hqInfo->ueHqInfo, (sizeof(SchUeHqInfo) * hqInfo->numUes)); + MAC_FREE(hqInfo, sizeof(SchRlsHqInfo)); + return ROK; +} + +/********************************************************************** + End of file + **********************************************************************/ diff --git a/src/5gnrmac/mac_harq_dl.h b/src/5gnrmac/mac_harq_dl.h new file mode 100644 index 000000000..721d8ef94 --- /dev/null +++ b/src/5gnrmac/mac_harq_dl.h @@ -0,0 +1,26 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ + +void addDlHqProcInUe(SlotTimingInfo dlMsgTime, MacUeCb *ueCb, DlMsgSchInfo schedInfo); +uint8_t updateNewTbInDlHqProcCb(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint32_t tbSize, uint8_t *txPdu); +uint8_t* fetchTbfromDlHarqProc(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint8_t hqProcId, uint32_t tbSize); + +/********************************************************************** + End of file + **********************************************************************/ + diff --git a/src/5gnrmac/mac_msg_hdl.c b/src/5gnrmac/mac_msg_hdl.c index 16ade7180..f16751314 100644 --- a/src/5gnrmac/mac_msg_hdl.c +++ b/src/5gnrmac/mac_msg_hdl.c @@ -32,6 +32,7 @@ #include "lwr_mac_upr_inf.h" #include "mac.h" #include "mac_utils.h" +#include "mac_harq_dl.h" /* This file contains message handling functionality for MAC */ @@ -69,6 +70,14 @@ MacSchSrUciIndFunc macSchSrUciIndOpts[]= packMacSchSrUciInd }; +/* Function pointer for sending HARQ Uci ind from MAC to SCH */ +MacSchHarqUciIndFunc macSchHarqUciIndOpts[]= +{ + packMacSchHarqUciInd, + MacSchHarqUciInd, + packMacSchHarqUciInd +}; + /* Function pointer for sending Slice cfg ind from MAC to SCH */ MacSchSliceCfgReqFunc macSchSliceCfgReqOpts[]= { @@ -194,7 +203,7 @@ uint8_t fapiMacRxDataInd(Pst *pst, RxDataInd *rxDataInd) for(pduIdx = 0; pduIdx < rxDataInd->numPdus; pduIdx++) { - + GET_CELL_IDX(rxDataInd->cellId, cellIdx); GET_UE_ID(rxDataInd->pdus[pduIdx].rnti, ueId); @@ -287,6 +296,10 @@ uint8_t MacProcRlcDlData(Pst* pstInfo, RlcData *dlData) currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPduLen = txPduLen; currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPdu = txPdu; + /* Add muxed TB to DL HARQ Proc CB. This will be used if retranmission of + * TB is requested in future. */ + updateNewTbInDlHqProcCb(dlData->slotInfo, &macCb.macCell[cellIdx]->ueCb[ueId -1], \ + currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[0].tbSize, txPdu); } for(lcIdx = 0; lcIdx < dlData->numLc; lcIdx++) @@ -726,6 +739,51 @@ uint8_t macProcLongBsr(uint16_t cellId, uint16_t crnti,uint8_t numLcg,\ return(*macSchBsrOpts[pst.selector])(&pst, &bsrInd); } +/******************************************************************* + * + * @brief Builds and send HARQ UCI Indication to SCH + * + * @details + * + * Function : buildAndSendHarqInd + * + * Functionality: + * Builds and send HARQ UCI Indication to SCH + * + * @params[in] harqInfo Pointer + * crnti value + * cell Index value + * slot Ind Pointer + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t buildAndSendHarqInd(HarqInfoF0F1 *harqInfo, uint8_t crnti, uint16_t cellIdx, SlotTimingInfo *slotInd) +{ + uint16_t harqCounter=0; + Pst pst; + HarqUciIndInfo harqUciInd; + memset(&pst, 0, sizeof(Pst)); + memset(&harqUciInd, 0, sizeof(HarqUciIndInfo)); + + harqUciInd.cellId = macCb.macCell[cellIdx]->cellId; + harqUciInd.crnti = crnti; + harqUciInd.slotInd.sfn = slotInd->sfn; + harqUciInd.slotInd.slot = slotInd->slot; + harqUciInd.numHarq = harqInfo->numHarq; + memset(harqUciInd.harqPayload, 0, MAX_SR_BITS_IN_BYTES); + for(harqCounter = 0; harqCounter < harqInfo->numHarq; harqCounter++) + { + harqUciInd.harqPayload[harqCounter] = harqInfo->harqValue[harqCounter]; + } + + /* Fill Pst */ + FILL_PST_MAC_TO_SCH(pst, EVENT_UCI_IND_TO_SCH); + + return(*macSchHarqUciIndOpts[pst.selector])(&pst, &harqUciInd); +} + + /******************************************************************* * * @brief Builds and send SR UCI Indication to SCH @@ -785,7 +843,7 @@ uint8_t buildAndSendSrInd(UciInd *macUciInd, uint8_t crnti) uint8_t FapiMacUciInd(Pst *pst, UciInd *macUciInd) { uint8_t pduIdx = 0, ret = ROK; - uint16_t nPdus = 0, crnti = 0; + uint16_t nPdus = 0, crnti = 0, cellIdx = 0; if(macUciInd) { @@ -797,12 +855,19 @@ uint8_t FapiMacUciInd(Pst *pst, UciInd *macUciInd) case UCI_IND_PUSCH: break; case UCI_IND_PUCCH_F0F1: + { + { + DU_LOG("\nDEBUG --> MAC : Received HARQ UCI Indication\n"); + GET_CELL_IDX(macUciInd->cellId, cellIdx); + buildAndSendHarqInd(&macUciInd->pdus[pduIdx].uci.uciPucchF0F1.harqInfo, macUciInd->pdus[pduIdx].uci.uciPucchF0F1.crnti, cellIdx, &macUciInd->slotInd); + } if(macUciInd->pdus[pduIdx].uci.uciPucchF0F1.srInfo.srIndPres) { DU_LOG("\nDEBUG --> MAC : Received SR UCI indication"); crnti = macUciInd->pdus[pduIdx].uci.uciPucchF0F1.crnti; ret = buildAndSendSrInd(macUciInd, crnti); } + } break; case UCI_IND_PUCCH_F2F3F4: break; diff --git a/src/5gnrmac/mac_rach.c b/src/5gnrmac/mac_rach.c index 010063100..cc59d5c93 100644 --- a/src/5gnrmac/mac_rach.c +++ b/src/5gnrmac/mac_rach.c @@ -146,8 +146,13 @@ uint8_t createMacRaCb(MacCellCb *cellCb, RachIndInfo *rachIndInfo) GET_CRNTI(crnti, ueIdx+1); /* Store in raCb */ + memset(&cellCb->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo)); cellCb->macRaCb[ueIdx].cellId = rachIndInfo->cellId; cellCb->macRaCb[ueIdx].crnti = crnti; + + /* Initialize MSG4 HARQ PROC CB */ + cellCb->macRaCb[ueIdx].msg4HqInfo.procId = MAX_NUM_HARQ_PROC; + } /* Store in Rach Indication message to be sent to SCH */ diff --git a/src/5gnrmac/mac_slot_ind.c b/src/5gnrmac/mac_slot_ind.c index 321e3500b..fc32cc140 100644 --- a/src/5gnrmac/mac_slot_ind.c +++ b/src/5gnrmac/mac_slot_ind.c @@ -28,6 +28,7 @@ #include "lwr_mac.h" #include "lwr_mac_fsm.h" #include "mac_utils.h" +#include "mac_harq_dl.h" /* function pointers for packing slot ind from mac to sch */ MacSchSlotIndFunc macSchSlotIndOpts[] = @@ -54,10 +55,14 @@ MacSchSlotIndFunc macSchSlotIndOpts[] = **/ uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo) { - uint8_t schInfoIdx = 0; + uint8_t schInfoIdx = 0, cwIdx = 0; uint8_t ueId = 0, ueIdx = 0; uint16_t cellIdx = 0; - MacDlSlot *currDlSlot = NULLP; + uint8_t *retxTb = NULLP, *txPdu = NULLP; + uint16_t txPduLen = 0; + MacDlSlot *currDlSlot = NULLP; + DlMsgSchInfo schedInfo; + DlHarqProcCb *hqProcCb = NULLP; #ifdef CALL_FLOW_DEBUG_LOG DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_SCH_INFO\n"); @@ -100,16 +105,78 @@ uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo) { GET_UE_ID(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.crnti, ueId); ueIdx = ueId -1; - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize = \ - dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[0].tbSize; + schedInfo = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]; + hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo; + + if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx) + { + /* First transmission of MSG4 */ + hqProcCb->procId = schedInfo.dlMsgInfo.harqProcNum; + for(cwIdx = 0; cwIdx < schedInfo.dlMsgPdschCfg.numCodewords; cwIdx++) + { + memcpy(&hqProcCb->tbInfo[hqProcCb->numTb].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \ + sizeof(SlotTimingInfo)); + hqProcCb->tbInfo[hqProcCb->numTb].tbSize = schedInfo.dlMsgPdschCfg.codeword[cwIdx].tbSize; + hqProcCb->numTb++; + } + } + else + { + /* MSG4 retransmission */ + if(hqProcCb->procId == schedInfo.dlMsgInfo.harqProcNum) + { + memcpy(&hqProcCb->tbInfo[0].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \ + sizeof(SlotTimingInfo)); + } + } } else { memcpy(&currDlSlot->dlInfo.schSlotValue, &dlSchedInfo->schSlotValue, sizeof(SchSlotValue)); - /* Send LC schedule result to RLC */ - if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) || - (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH)) - sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx); + + if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx) + { + /* If new data transmission is scheduled, send schedule results to RLC */ + if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) || + (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH)) + { + sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx); + + /* Add HARQ Proc to DL HARQ Proc Entity in UE */ + addDlHqProcInUe(currDlSlot->dlInfo.schSlotValue.dlMsgTime, &macCb.macCell[cellIdx]->ueCb[ueIdx], \ + dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]); + } + } + else + { + /* For retransmission, fetch PDU to be retransmitted from DL HARQ entity and schedule on corresponding slot */ + + /* As of now this loop will run only once for one TB. + * TODO : update handling of fetched TB appropriately when support for two TB is added + */ + for(cwIdx = 0; \ + cwIdx < dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.numCodewords;\ + cwIdx++) + { + /* Fetch TB to be retransmitted */ + txPduLen = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[cwIdx].tbSize; + retxTb = fetchTbfromDlHarqProc(currDlSlot->dlInfo.schSlotValue.dlMsgTime, \ + &macCb.macCell[cellIdx]->ueCb[ueIdx], \ + dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.harqProcNum, txPduLen); + + /* Store PDU in corresponding DL slot */ + MAC_ALLOC(txPdu, txPduLen); + if(!txPdu) + { + DU_LOG("\nERROR --> MAC : Memory allocation failed in MacProcRlcDlData"); + return RFAILED; + } + memcpy(txPdu, retxTb, txPduLen); + + currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPduLen = txPduLen; + currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPdu = txPdu; + } + } } } } @@ -117,8 +184,7 @@ uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo) if(dlSchedInfo->ulGrant != NULLP) { - currDlSlot = &macCb.macCell[cellIdx]->\ - dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot]; + currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot]; currDlSlot->dlInfo.ulGrant = dlSchedInfo->ulGrant; } } @@ -189,6 +255,7 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo) uint16_t msg4TxPduLen; MacDlData msg4DlData; MacCeInfo macCeData; + DlHarqProcCb *hqProcCb; GET_CELL_IDX(cellId, cellIdx); @@ -204,23 +271,25 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo) return; } + hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo; + msg4TxPduLen = hqProcCb->tbInfo[0].tbSize - TX_PAYLOAD_HDR_LEN; + if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu != NULLP) { MAC_ALLOC(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen); if(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu != NULLP) { - msg4TxPduLen = macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN; - fillMsg4DlData(&msg4DlData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen, \ macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu); fillMacCe(&macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg3Pdu); + /* Forming Mux Pdu */ - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu = NULLP; - MAC_ALLOC(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen); - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu != NULLP) + hqProcCb->tbInfo[0].tb = NULLP; + MAC_ALLOC(hqProcCb->tbInfo[0].tb, msg4TxPduLen); + if(hqProcCb->tbInfo[0].tb != NULLP) { - memset(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, 0, msg4TxPduLen); - macMuxPdu(&msg4DlData, &macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen); + memset(hqProcCb->tbInfo[0].tb, 0, msg4TxPduLen); + macMuxPdu(&msg4DlData, &macCeData, hqProcCb->tbInfo[0].tb, msg4TxPduLen); } else { @@ -228,18 +297,22 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo) } /* Free memory allocated */ MAC_FREE(msg4DlData.pduInfo[msg4DlData.numPdu-1].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen); + MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen); + macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu = NULLP; + macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen = 0; msg4DlData.numPdu--; + } } /* storing msg4 Pdu in macDlSlot */ - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu) + if(hqProcCb->tbInfo[0].tb) { msg4SchInfo->dlMsgInfo.dlMsgPduLen = msg4TxPduLen; MAC_ALLOC(msg4SchInfo->dlMsgInfo.dlMsgPdu, msg4SchInfo->dlMsgInfo.dlMsgPduLen); if(msg4SchInfo->dlMsgInfo.dlMsgPdu != NULLP) { - memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \ + memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, hqProcCb->tbInfo[0].tb, \ msg4SchInfo->dlMsgInfo.dlMsgPduLen); } } diff --git a/src/5gnrmac/mac_ue_mgr.c b/src/5gnrmac/mac_ue_mgr.c index 4206acd38..06953b45d 100644 --- a/src/5gnrmac/mac_ue_mgr.c +++ b/src/5gnrmac/mac_ue_mgr.c @@ -2008,6 +2008,7 @@ uint8_t fillMacUeCb(MacUeCb *ueCb, MacUeCfg *ueCfg, uint8_t cellIdx) DU_LOG("\nERROR --> MAC: Failed while filing MAC LC List at fillMacUeCb()"); } ueCb->transmissionAction = ueCfg->transmissionAction; + return ret; } @@ -2059,27 +2060,21 @@ uint8_t updateMacRaCb(uint16_t cellIdx, MacUeCb *ueCb) void deleteMacRaCb(uint16_t cellIdx, MacUeCb *ueCb) { - uint8_t ueIdx; + uint8_t tbIdx; + MacRaCbInfo *raCb = ueCb->raCb; + DlHarqProcCb *hqProcCb; - for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) + if(raCb && (raCb->crnti == ueCb->crnti)) { - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == ueCb->crnti) + hqProcCb = &raCb->msg4HqInfo; + MAC_FREE(raCb->msg4Pdu, raCb->msg4PduLen); + for(tbIdx = 0; tbIdx < raCb->msg4HqInfo.numTb; tbIdx++) { - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu) - { - MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, \ - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen); - } - if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu) - { - MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \ - macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize); - } - memset(&macCb.macCell[cellIdx]->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo)); - break; + MAC_FREE(raCb->msg4HqInfo.tbInfo[tbIdx].tb, \ + raCb->msg4HqInfo.tbInfo[tbIdx].tbSize); } + memset(raCb, 0, sizeof(MacRaCbInfo)); } - } /******************************************************************* @@ -2099,7 +2094,8 @@ void deleteMacRaCb(uint16_t cellIdx, MacUeCb *ueCb) * ****************************************************************/ uint8_t createUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg) { - uint8_t ret =ROK; + uint8_t ret = ROK; + uint8_t hqProcIdx = 0; if((ueCb->ueId == ueCfg->ueId) && (ueCb->crnti == ueCfg->crnti)\ &&(ueCb->state == UE_STATE_ACTIVE)) @@ -2118,6 +2114,12 @@ uint8_t createUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg) } else { + /* Initialize all DL HARQ PROC ID to MAX NUM OF HARQ PROC */ + for(hqProcIdx = 0; hqProcIdx < MAX_NUM_HARQ_PROC; hqProcIdx++) + { + ueCb->dlInfo.dlHarqEnt.harqProcCb[hqProcIdx].procId = MAX_NUM_HARQ_PROC; + } + /* If UE has not requested for RACH yet, it means UE context is created for a * UE in handover */ if(macCb.macCell[cellIdx]->macRaCb[ueCb->ueId-1].crnti == ueCb->crnti) @@ -2166,7 +2168,6 @@ uint8_t modifyUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg) } else { - deleteMacRaCb(cellIdx, ueCb); return ROK; } } diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index c3be113a3..3e485c4a5 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -335,22 +335,12 @@ uint8_t MacSchRachInd(Pst *pst, RachIndInfo *rachInd) * ****************************************************************/ uint8_t MacSchCrcInd(Pst *pst, CrcIndInfo *crcInd) { + Inst inst = pst->dstInst-SCH_INST_START; #ifdef CALL_FLOW_DEBUG_LOG DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_CRC_IND_TO_SCH\n"); #endif - switch(crcInd->crcInd[0]) - { - case CRC_FAILED: - DU_LOG("\nDEBUG --> SCH : Received CRC indication. CRC Status [FAILURE]"); - break; - case CRC_PASSED: - DU_LOG("\nDEBUG --> SCH : Received CRC indication. CRC Status [PASS]"); - break; - default: - DU_LOG("\nDEBUG --> SCH : Invalid CRC state %d", crcInd->crcInd[0]); - return RFAILED; - } + schProcessCrcInd(crcInd, inst); return ROK; } @@ -909,6 +899,11 @@ uint8_t SchHdlCellCfgReq(Pst *pst, SchCellCfg *schCellCfg) cellCb->actvUeBitMap = 0; cellCb->boIndBitMap = 0; + cellCb->cellCfg.schHqCfg.maxDlDataHqTx = SCH_MAX_NUM_DL_HQ_TX; + cellCb->cellCfg.schHqCfg.maxMsg4HqTx = SCH_MAX_NUM_MSG4_TX; + cellCb->cellCfg.schHqCfg.maxUlDataHqTx = SCH_MAX_NUM_UL_HQ_TX; + cellCb->cellCfg.schRachCfg.maxMsg3Tx = SCH_MAX_NUM_MSG3_TX; + /* Fill and send Cell config confirm */ memset(&rspPst, 0, sizeof(Pst)); FILL_PST_SCH_TO_MAC(rspPst, pst->dstInst); @@ -945,13 +940,11 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) bool isLcIdValid = false; SchUeCb *ueCb = NULLP; SchCellCb *cell = NULLP; - Inst inst = pst->dstInst-SCH_INST_START; - CmLListCp *lcLL = NULLP; + Inst inst = pst->dstInst-SCH_INST_START; #ifdef CALL_FLOW_DEBUG_LOG DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_DL_RLC_BO_INFO_TO_SCH\n"); -#endif - +#endif DU_LOG("\nDEBUG --> SCH : Received RLC BO Status indication LCId [%d] BO [%d]", dlBoInfo->lcId, dlBoInfo->dataVolume); cell = schCb[inst].cells[inst]; @@ -982,28 +975,20 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) *Thus clearing out the LC from the Lc priority list*/ if(dlBoInfo->dataVolume == 0) { - /*Check the LC is Dedicated or default and accordingly LCList will - * be used*/ - if(ueCb->dlInfo.dlLcCtxt[lcId].isDedicated) - { - lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); - } - else - { - lcLL = &(ueCb->dlLcPrbEst.defLcList); - } - handleLcLList(lcLL, lcId, DELETE); + /* TODO : Check the LC is Dedicated or default and accordingly LCList + * will be used*/ return ROK; } if(lcId == SRB0_LCID) { cell->raCb[ueId -1].msg4recvd = true; - cell->raCb[ueId -1].dlMsgPduLen = dlBoInfo->dataVolume; - + cell->raCb[ueId -1].dlMsgPduLen = dlBoInfo->dataVolume; } else { + /* TODO : These part of changes will be corrected during DL scheduling as + * per K0 - K1 -K2 */ SET_ONE_BIT(ueId, cell->boIndBitMap); if(ueCb->dlInfo.dlLcCtxt[lcId].lcId == lcId) { @@ -1015,7 +1000,6 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) return RFAILED; } } - /* Adding UE Id to list of pending UEs to be scheduled */ addUeToBeScheduled(cell, ueId); return ROK; @@ -1132,14 +1116,55 @@ uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd) } if(uciInd->numSrBits) { - ueCb->srRcvd = true; - + ueCb->srRcvd = true; /* Adding UE Id to list of pending UEs to be scheduled */ addUeToBeScheduled(cellCb, ueCb->ueId); } return ROK; } +/******************************************************************* + * + * @brief Processes HARQ UCI indication from MAC + * + * @details + * + * Function : MacSchHarqUciInd + * + * Functionality: + * Processes HARQ UCI indication from MAC + * + * @params[in] Post structure + * UCI Indication + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t MacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd) +{ + Inst inst = pst->dstInst-SCH_INST_START; + SchUeCb *ueCb; + SchCellCb *cellCb = schCb[inst].cells[inst]; + +#ifdef CALL_FLOW_DEBUG_LOG + DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_UCI_IND_TO_SCH\n"); +#endif + + DU_LOG("\nDEBUG --> SCH : Received HARQ"); + + ueCb = schGetUeCb(cellCb, uciInd->crnti); + + if(ueCb->state == SCH_UE_STATE_INACTIVE) + { + DU_LOG("\nERROR --> SCH : Crnti %d is inactive", uciInd->crnti); + return ROK; + } + + schUpdateHarqFdbk(ueCb, uciInd->numHarq, uciInd->harqPayload, &uciInd->slotInd); + + return ROK; +} + /******************************************************************* * * @brief Allocates requested PRBs for DL diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 3793761f5..4281ef808 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -59,6 +59,20 @@ #define PRB_BITMAP_IDX_LEN 64 #define PRB_BITMAP_MAX_IDX ((MAX_NUM_RB + PRB_BITMAP_IDX_LEN-1) / PRB_BITMAP_IDX_LEN) +#define SCH_MAX_NUM_UL_HQ_PROC 16 +#define SCH_MAX_NUM_DL_HQ_PROC 16 +#define SCH_MAX_NUM_MSG3_TX 2 +#define SCH_MAX_NUM_DL_HQ_TX 3 +#define SCH_MAX_NUM_UL_HQ_TX 3 +#define SCH_MAX_NUM_MSG4_TX 2 +#define HQ_ACK 0 +#define HQ_NACK 1 +#define HQ_DTX 2 + +typedef struct schDlHqProcCb SchDlHqProcCb; +typedef struct schUlHqEnt SchUlHqEnt; +typedef struct schRaReq SchRaReq; +typedef struct schDlHqEnt SchDlHqEnt; typedef struct schCellCb SchCellCb; typedef struct schUeCb SchUeCb; @@ -78,6 +92,14 @@ typedef enum SCH_UE_HANDIN_IN_PROGRESS }SchUeState; +typedef enum +{ + SCH_RA_STATE_MSG2_HANDLE, + SCH_RA_STATE_MSG3_PENDING, + SCH_RA_STATE_MSG4_PENDING, + SCH_RA_STATE_MSG4_DONE +}SchRaState; + typedef enum { SCH_LC_STATE_INACTIVE, @@ -91,6 +113,124 @@ typedef enum WINDOW_EXPIRED }RaRspWindowStatus; +typedef enum +{ + HQ_TB_ACKED=0, + HQ_TB_NACKED, + HQ_TB_WAITING +}SchHqTbState; + +/*Following structures to keep record and estimations of PRB allocated for each + * LC taking into consideration the RRM policies*/ +typedef struct lcInfo +{ + uint8_t lcId; /*LCID for which BO are getting recorded*/ + uint32_t reqBO; /*Size of the BO requested/to be allocated for this LC*/ + uint32_t allocBO; /*TBS/BO Size which is actually allocated*/ + uint8_t allocPRB; /*PRB count which is allocated based on RRM policy/FreePRB*/ +}LcInfo; + +typedef struct schLcPrbEstimate +{ + /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer + * and have separate DedLCInfo for each RRMPolcyMemberList*/ + /* Dedicated LC List will be allocated, if any available*/ + CmLListCp dedLcList; /*Contain LCInfo per RRMPolicy*/ + CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/ + /* SharedPRB number can be used by any LC. + * Need to calculate in every Slot based on PRB availability*/ + uint16_t sharedNumPrb; +}SchLcPrbEstimate; +typedef struct schUlHqTbCb +{ + uint32_t tbSzReq; + uint32_t tbSzAllc; + uint8_t ndi; + uint8_t rv; + uint8_t rvIdx; + uint8_t qamOrder; + SchMcsTable mcsTable; + uint8_t iMcs; + uint8_t iMcsInDci; + uint8_t numLyrs; + uint8_t txCntr; + SchHqTbState state; + uint8_t cntrRetxAllocFail; + uint8_t statsBitmap; +}SchUlHqTbCb; + +typedef struct schDlHqTbCb +{ + uint8_t tbIdx; + Bool isEnabled; + uint32_t tbSzReq; + uint8_t txCntr; + uint8_t ndi; + uint8_t rv; + uint8_t rvIdx; + uint8_t iMcs; + uint8_t iMcsInDci; + uint8_t numLyrs; + SchHqTbState state; + uint8_t isAckNackDtx; + uint8_t cntrRetxAllocFail; + //InfUeTbInfo tbCompInfo; + uint8_t statsBitmap; +}SchDlHqTbCb; + +typedef struct schUlHqProcCb +{ + uint8_t procId; /*!< HARQ Process ID */ + SchUlHqEnt *hqEnt; + uint8_t maxHqTxPerHqP; + SchUlHqTbCb tbInfo; + CmLList ulHqEntLnk; + CmLList ulSlotLnk; + uint8_t strtSymbl; + uint8_t numSymbl; + SchLcPrbEstimate ulLcPrbEst; /*UL PRB Alloc Estimate among different LC*/ + CmLList ulHqProcLink; + uint8_t puschResType; /* Resource allocation type */ + uint16_t puschStartPrb; + uint16_t puschNumPrb; + uint8_t dmrsMappingType; + uint8_t nrOfDmrsSymbols; + uint8_t dmrsAddPos; +}SchUlHqProcCb; + +struct schDlHqProcCb +{ + uint8_t procId; /*!< HARQ Process ID */ + SchDlHqEnt *hqEnt; + uint8_t maxHqTxPerHqP; + CmLList dlHqEntLnk; + CmLList ulSlotLnk; + SchDlHqTbCb tbInfo[2]; + uint8_t k1; + SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/ + CmLList dlHqProcLink; +}; +struct schUlHqEnt +{ + SchCellCb *cell; /*!< Contains the pointer to cell*/ + SchUeCb *ue; /*!< Contains the pointer to ue*/ + CmLListCp free; /*!< List of free HARQ processes */ + CmLListCp inUse; /*!< List of in-use HARQ processes */ + uint8_t maxHqTx; /*!< Maximum number of harq re-transmissions */ + uint8_t numHqPrcs; /*!< Number of HARQ Processes */ + SchUlHqProcCb procs[SCH_MAX_NUM_UL_HQ_PROC]; /*!< Uplink harq process info */ +}; +struct schDlHqEnt +{ + SchCellCb *cell; /*!< Contains the pointer to cell */ + SchUeCb *ue; /*!< Contains the pointer to UE */ + CmLListCp free; /*!< List of free HARQ processes */ + CmLListCp inUse; /*!< List of in-use HARQ processes */ + uint8_t maxHqTx; /*!< Maximum number of harq transmissions */ + uint8_t numHqPrcs; /*!< Number of HARQ Processes */ + SchDlHqProcCb procs[SCH_MAX_NUM_DL_HQ_PROC];/*!< Downlink harq processes */ +}; + /** * @brief * Structure holding LTE MAC's General Configuration information. @@ -144,9 +284,15 @@ typedef struct schDlSlotInfo typedef struct schRaCb { + uint8_t ueId; bool msg4recvd; uint16_t tcrnti; uint16_t dlMsgPduLen; + SchUlHqProcCb msg3HqProc; + SchUlHqProcCb *retxMsg3HqProc; + SchRaState raState; + SchCellCb *cell; + SchRaReq *raReq; }SchRaCb; /** @@ -184,6 +330,7 @@ typedef struct schLcCtxt uint16_t pduSessionId; /*Pdu Session Id*/ Snssai *snssai; /*S-NSSAI assoc with LCID*/ bool isDedicated; /*Flag containing Dedicated S-NSSAI or not*/ + uint16_t rsvdDedicatedPRB; }SchDlLcCtxt; typedef struct schDlCb @@ -194,7 +341,7 @@ typedef struct schDlCb typedef struct schUlLcCtxt { SchLcState lcState; - uint8_t lcId; + uint8_t lcId; uint8_t priority; uint8_t lcGroup; uint8_t schReqId; @@ -203,6 +350,7 @@ typedef struct schUlLcCtxt uint16_t pduSessionId; /*Pdu Session Id*/ Snssai *snssai; /*S-NSSAI assoc with LCID*/ bool isDedicated; /*Flag containing Dedicated S-NSSAI or not*/ + uint16_t rsvdDedicatedPRB; }SchUlLcCtxt; typedef struct schUlCb @@ -227,35 +375,15 @@ typedef struct schUeCfgCb SchDataTransmission dataTransmissionAction; }SchUeCfgCb; -/*Following structures to keep record and estimations of PRB allocated for each - * LC taking into consideration the RRM policies*/ -typedef struct lcInfo +typedef struct schHqDlMap { - uint8_t lcId; /*LCID for which BO are getting recorded*/ - uint32_t reqBO; /*Size of the BO requested/to be allocated for this LC*/ - uint32_t allocBO; /*TBS/BO Size which is actually allocated*/ - uint8_t allocPRB; /*PRB count which is allocated based on RRM policy/FreePRB*/ -}LcInfo; + CmLListCp hqList; +}SchHqDlMap; -typedef struct dedicatedLCInfo +typedef struct schHqUlMap { - CmLListCp dedLcList; /*Linklist of LC assoc with RRMPolicyMemberList*/ - uint16_t rsvdDedicatedPRB; /*Number of PRB reserved for this Dedicated S-NSSAI*/ -}DedicatedLCInfo; - -typedef struct schLcPrbEstimate -{ - /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer - * and have separate DedLCInfo for each RRMPolcyMemberList*/ - /* Dedicated LC List will be allocated, if any available*/ - DedicatedLCInfo *dedLcInfo; /*Contain LCInfo per RRMPolicy*/ - - CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/ - - /* SharedPRB number can be used by any LC. - * Need to calculate in every Slot based on PRB availability*/ - uint16_t sharedNumPrb; -}SchLcPrbEstimate; + CmLListCp hqList; +}SchHqUlMap; /** * @brief @@ -274,8 +402,14 @@ typedef struct schUeCb BsrInfo bsrInfo[MAX_NUM_LOGICAL_CHANNEL_GROUPS]; SchUlCb ulInfo; SchDlCb dlInfo; - SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/ - SchLcPrbEstimate ulLcPrbEst; /*UL PRB Alloc Estimate among different LC*/ + SchUlHqEnt ulHqEnt; + SchDlHqEnt dlHqEnt; + SchDlHqProcCb *msg4Proc; + SchDlHqProcCb *retxMsg4HqProc; + SchHqDlMap **hqDlmap; + SchHqUlMap **hqUlmap; + CmLListCp ulRetxHqList; + CmLListCp dlRetxHqList; }SchUeCb; /** @@ -364,7 +498,7 @@ typedef struct schCb SchGenCb genCfg; /*!< General Config info */ CmTqCp tmrTqCp; /*!< Timer Task Queue Cntrl Point */ CmTqType tmrTq[SCH_TQ_SIZE]; /*!< Timer Task Queue */ - SchCellCb *cells[MAX_NUM_CELL]; /* Array to store cellCb ptr */ + SchCellCb *cells[MAX_NUM_CELL]; /* Array to store cellCb ptr */ SchSliceCfg sliceCfg; }SchCb; @@ -388,6 +522,7 @@ uint8_t addUeToBeScheduled(SchCellCb *cell, uint8_t ueId); /* Incoming message handler function declarations */ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst inst); uint8_t schProcessRachInd(RachIndInfo *rachInd, Inst schInst); +uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst); /* DL scheduling related function declarations */ PduTxOccsaion schCheckSsbOcc(SchCellCb *cell, SlotTimingInfo slotTime); @@ -395,32 +530,32 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime); uint8_t schBroadcastSsbAlloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc); uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc); bool schProcessRaReq(Inst schInst, SchCellCb *cellCb, SlotTimingInfo currTime, uint8_t ueId); -bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId); +uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId,bool isRetxMsg4, SchDlHqProcCb **hqP); uint8_t schFillRar(SchCellCb *cell, SlotTimingInfo rarTime, uint16_t ueId, RarAlloc *rarAlloc, uint8_t k0Index); uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti, -uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols); +uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols,bool isRetx, SchDlHqProcCb* hqP); uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueId, DlMsgAlloc *msg4Alloc,\ -uint8_t pdschStartSymbol, uint8_t pdschNumSymbols); +uint8_t pdschStartSymbol, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP); uint8_t allocatePrbDl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \ uint16_t *startPrb, uint16_t numPrb); -void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti); +void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti, bool isRetx, SchDlHqProcCb* hqP); bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, uint8_t *pdschStartSymbol,\ -uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime); - +uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP); +RaRspWindowStatus isInRaRspWindow(SchRaReq *raReq, SlotTimingInfo frameToCheck, uint16_t numSlotsPerSystemFrame); /* UL scheduling related function declarations */ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst); bool schCheckPrachOcc(SchCellCb *cell, SlotTimingInfo prachOccasionTimingInfo); uint8_t schCalcPrachNumRb(SchCellCb *cell); void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo prachOccasionTimingInfo); -uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti); -uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo); -uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbsSize, \ - uint8_t startSymb, uint8_t symbLen, uint16_t startPrb); +uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti,SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP); +uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP); +uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize, + uint8_t startSymb, uint8_t symbLen, uint16_t startPrb, bool isRetx, SchUlHqProcCb *hqP); uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \ uint16_t *startPrb, uint16_t numPrb); -bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId); -bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\ - uint16_t *startPrb, uint32_t *totTBS); +bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchUlHqProcCb **hqP); +uint8_t schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\ + uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP); /*Generic Functions*/ void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc, BsrInfo *bsrInfo, uint32_t *accumalatedBOSize); @@ -436,7 +571,28 @@ void schCfgPdcchMonOccOfPO(SchCellCb *cell); void schIncrSlot(SlotTimingInfo *timingInfo, uint8_t incr, uint16_t numSlotsPerRF); uint8_t schFillPagePdschCfg(SchCellCb *cell, PdschCfg *pagePdschCfg, SlotTimingInfo slotTime, \ uint16_t tbSize, uint8_t mcs, uint16_t startPrb); - +/*DL HARQ Functions*/ +void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb); +void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk); +void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2); +uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP); +void schDlReleaseHqProcess(SchDlHqProcCb *hqP); + +/*UL HARQ Functions*/ +void schUlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb); +uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb); +void schUlHqProcessNack(SchUlHqProcCb *hqP); +void schUlHqProcessAck(SchUlHqProcCb *hqP); +uint8_t schUlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqProcCb **hqP); +void schUlReleaseHqProcess(SchUlHqProcCb *hqP, Bool togNdi); + +/* UE Manager HARQ Fun*/ +void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload,SlotTimingInfo *slotInd); + +/* Round Robbin Scheduler funtions*/ +uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo); +bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx); +void schMsg4Complete(SchUeCb *ueCb); /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index 23b648bd6..a16cda542 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -389,6 +389,7 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\ ulSchedPucch->srFlag = true; ulSchedPucch->uciFlag = true; } + ulSchedPucch->harqFlag = true;//check how to enable? } return ret; } @@ -451,10 +452,6 @@ uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTiming schPucchInfo->uciFlag = true; } } - /* set HARQ flag to true */ - schPucchInfo->harqFlag = true; - schPucchInfo->numHarqBits = 1; /* 1 bit for HARQ */ - return ROK; } @@ -535,13 +532,16 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) * Functionality: * Fills pdcch and pdsch info for msg4 * - * @params[in] + * @params[in] SchCellCb *cell, SlotTimingInfo msg4Time + * @params[in] uint8_t ueId, DlMsgAlloc *dlMsgAlloc + * @params[in] uint8_t pdschStartSymbol, uint8_t pdschNumSymbols + * @params[in] bool isRetx, SchDlHqProcCb *hqP * @return ROK - success * RFAILED - failure * * ****************************************************************/ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueId, DlMsgAlloc *dlMsgAlloc,\ -uint8_t pdschStartSymbol, uint8_t pdschNumSymbols) + uint8_t pdschStartSymbol, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP) { uint8_t coreset0Idx = 0; uint8_t firstSymbol = 0; @@ -575,7 +575,7 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols) bwp = &msg4Alloc->bwp; coreset0Idx = initialBwp->pdcchCommon.commonSearchSpace.coresetId; - fillDlMsgInfo(&msg4Alloc->dlMsgInfo, cell->raCb[ueId-1].tcrnti); + fillDlMsgInfo(&msg4Alloc->dlMsgInfo, cell->raCb[ueId-1].tcrnti, isRetx, hqP); msg4Alloc->dlMsgInfo.dlMsgPduLen = cell->raCb[ueId-1].dlMsgPduLen; /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */ @@ -638,8 +638,17 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols) pdsch->codeword[cwCount].qamModOrder = 2; pdsch->codeword[cwCount].mcsIndex = mcs; /* mcs configured to 4 */ pdsch->codeword[cwCount].mcsTable = 0; /* notqam256 */ - pdsch->codeword[cwCount].rvIndex = 0; - tbSize = schCalcTbSize(msg4Alloc->dlMsgInfo.dlMsgPduLen + TX_PAYLOAD_HDR_LEN); /* MSG4 size + FAPI header size*/ + if(isRetx != TRUE) + { + tbSize = schCalcTbSize(msg4Alloc->dlMsgInfo.dlMsgPduLen + TX_PAYLOAD_HDR_LEN); /* MSG4 size + FAPI header size*/ + hqP->tbInfo[cwCount].tbSzReq = tbSize; + pdsch->codeword[cwCount].rvIndex = 0; + } + else + { + pdsch->codeword[cwCount].rvIndex = (pdsch->codeword[cwCount].rvIndex +1) & 0x03; + tbSize = hqP->tbInfo[cwCount].tbSzReq; + } pdsch->codeword[cwCount].tbSize = tbSize; } pdsch->dataScramblingId = cell->cellCfg.phyCellId; @@ -712,23 +721,32 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols) * Scheduling for Pucch Resource * * @params[in] SchCellCb *cell, SlotTimingInfo pucchTime, crnti + * @params[in] SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP * @return ROK - success * RFAILED - failure * *******************************************************************/ -uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti) +uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti, + SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP) { uint16_t pucchSlot = 0; SchUlSlotInfo *schUlSlotInfo = NULLP; - + pucchSlot = pucchTime.slot; schUlSlotInfo = cell->schUlSlotInfo[pucchSlot]; memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo)); schUlSlotInfo->pucchPres = true; schUlSlotInfo->schPucchInfo.rnti = crnti; - + if(ueCb != NULLP) + { + /* set HARQ flag to true */ + schUlSlotInfo->schPucchInfo.harqFlag = true; + schUlSlotInfo->schPucchInfo.numHarqBits = 1; /* 1 bit for HARQ */ + ADD_DELTA_TO_TIME(pucchTime, pucchTime, 3); /* SLOT_DELAY=3 */ + cmLListAdd2Tail(&(ueCb->hqDlmap[pucchTime.slot]->hqList), &hqP->ulSlotLnk); + } return ROK; } @@ -743,13 +761,18 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16 * Functionality: * Fills pdcch and pdsch info for dl msg * - * @params[in] + * @params[in] SchCellCb *cell, SlotTimingInfo slotTime + * @params[in] uint16_t crnti, uint32_t tbSize + * @params[in] DlMsgAlloc *dlMsgAlloc, uint16_t startPRB + * @params[in] uint8_t pdschStartSymbol, uint8_t pdschNumSymbols + * @params[in] bool isRetx, SchDlHqProcCb *hqP * @return ROK - success * RFAILED - failure * * ****************************************************************/ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti, - uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols) + uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, + uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP) { uint8_t ueId=0; PdcchCfg *pdcch = NULLP; @@ -816,7 +839,11 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c pdsch->codeword[cwCount].mcsTable = ueCb.ueCfg.dlModInfo.mcsTable; pdsch->codeword[cwCount].rvIndex = 0; - tbSize +=TX_PAYLOAD_HDR_LEN; + if (isRetx != TRUE) + { + tbSize +=TX_PAYLOAD_HDR_LEN; + hqP->tbInfo[cwCount].tbSzReq = tbSize; + } pdsch->codeword[cwCount].tbSize = tbSize; } pdsch->dataScramblingId = cell->cellCfg.phyCellId; @@ -1628,18 +1655,25 @@ void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc,\ * fill DL message information for MSG4 and Dedicated DL Msg * * @params[in] DlMsgInfo *dlMsgInfo, uint8_t crnti +* @params[in] bool isRetx, SchDlHqProcCb *hqP * @return void * *******************************************************************/ -void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti) +void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti, bool isRetx, SchDlHqProcCb *hqP) { + hqP->tbInfo[0].isEnabled = TRUE; + hqP->tbInfo[0].state = HQ_TB_WAITING; + hqP->tbInfo[0].txCntr++; + hqP->tbInfo[1].isEnabled = TRUE; + hqP->tbInfo[1].state = HQ_TB_WAITING; + hqP->tbInfo[1].txCntr++; dlMsgInfo->crnti = crnti; - dlMsgInfo->ndi = 1; - dlMsgInfo->harqProcNum = 0; + dlMsgInfo->ndi = hqP->tbInfo[0].ndi; /*How to handle two tb case?TBD*/ + dlMsgInfo->harqProcNum = hqP->procId; dlMsgInfo->dlAssignIdx = 0; dlMsgInfo->pucchTpc = 0; dlMsgInfo->pucchResInd = 0; - dlMsgInfo->harqFeedbackInd = 0; + dlMsgInfo->harqFeedbackInd = hqP->k1; dlMsgInfo->dciFormatId = 1; } @@ -1654,13 +1688,17 @@ void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti) * Functionality: * sch Process pending Msg4 Req * - * @params[in] SchCellCb *cell, SlotTimingInfo currTime + * @params[in] SchCellCb *cell, cell cb struct pointer + * @params[in] SlotTimingInfo currTime, current timing info + * @params[in] uint8_t ueId, ue ID + * @params[in] bool isRetxMsg4, indicator to MSG4 retransmission + * @params[in] SchDlHqProcCb **msg4HqProc, address of MSG4 HARQ proc pointer * @return ROK - success * RFAILED - failure * *******************************************************************/ -bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) +uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetxMsg4, SchDlHqProcCb **msg4HqProc) { uint8_t pdschStartSymbol = 0, pdschNumSymbols = 0; SlotTimingInfo pdcchTime, pdschTime, pucchTime; @@ -1670,13 +1708,23 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) if(cell == NULL) { DU_LOG("\nERROR --> SCH: schDlRsrcAllocMsg4() : Cell is NULL"); - return false; + return RFAILED; } - + + if (isRetxMsg4 == FALSE) + { + if (RFAILED == schDlGetAvlHqProcess(cell, &cell->ueCb[ueId - 1], msg4HqProc)) + { + DU_LOG("\nERROR --> SCH: schDlRsrcAllocMsg4() : No process"); + return RFAILED; + } + } + if(findValidK0K1Value(cell, currTime, ueId, false, &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime,\ - &pucchTime) != true ) + &pucchTime, isRetxMsg4, *msg4HqProc) != true ) { - return false; + DU_LOG("\nERROR --> SCH: schDlRsrcAllocMsg4() : k0 k1 not found"); + return RFAILED; } if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL) @@ -1685,7 +1733,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) if(dciSlotAlloc == NULLP) { DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciSlotAlloc"); - return false; + return RFAILED; } cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = dciSlotAlloc; memset(dciSlotAlloc, 0, sizeof(DlMsgAlloc)); @@ -1695,7 +1743,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1]; /* Fill PDCCH and PDSCH scheduling information for Msg4 */ - if((schDlRsrcAllocMsg4(cell, pdschTime, ueId, dciSlotAlloc, pdschStartSymbol, pdschNumSymbols)) != ROK) + if((schDlRsrcAllocMsg4(cell, pdschTime, ueId, dciSlotAlloc, pdschStartSymbol, pdschNumSymbols, isRetxMsg4, *msg4HqProc)) != ROK) { DU_LOG("\nERROR --> SCH: Scheduling of Msg4 failed in slot [%d]", pdschTime.slot); if(dciSlotAlloc->numSchedInfo == 0) @@ -1705,7 +1753,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) } else memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); - return false; + return RFAILED; } /* Check if both DCI and RAR are sent in the same slot. @@ -1732,7 +1780,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) } else memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); - return false; + return RFAILED; } cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = msg4SlotAlloc; memset(msg4SlotAlloc, 0, sizeof(DlMsgAlloc)); @@ -1757,13 +1805,17 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) } /* PUCCH resource */ - schAllocPucchResource(cell, pucchTime, cell->raCb[ueId-1].tcrnti); + schAllocPucchResource(cell, pucchTime, cell->raCb[ueId-1].tcrnti, &cell->ueCb[ueId-1], isRetxMsg4, *msg4HqProc); cell->schDlSlotInfo[pdcchTime.slot]->pdcchUe = ueId; cell->schDlSlotInfo[pdschTime.slot]->pdschUe = ueId; cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId; cell->raCb[ueId-1].msg4recvd = FALSE; - return true; + if(isRetxMsg4) + { + cell->ueCb[ueId-1].retxMsg4HqProc= NULLP; + } + return ROK; } /******************************************************************* @@ -1783,18 +1835,20 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) * [out] startPrb(Pointer to startPRB which will be calculated while * finding the best Free Block) * [out] totTBS(Pointer to total TBS size) + * [in] isRetx (to indicate retransmission) + * [in] hqP (UL Harq process pointer) * - * @return bool : true > Scheduling of UL grant is successful - * false > vice versa + * @return uint8_t : ROK > Scheduling of UL grant is successful + * RFAILED > vice versa * * ****************************************************************/ -bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\ - uint16_t *startPrb, uint32_t *totTBS) +uint8_t schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\ + uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP) { uint16_t mcsIdx = 0; CmLListCp *lcLL = NULLP; uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0; - + uint16_t rsvdDedicatedPRB; *startPrb = 0; *totTBS = 0; @@ -1812,33 +1866,32 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen, lcId = lcgIdx; if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated) { - lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList); + lcLL = &(hqP->ulLcPrbEst.dedLcList); + rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB; } else { - lcLL = &(ueCb->ulLcPrbEst.defLcList); + lcLL = &(hqP->ulLcPrbEst.defLcList); } /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/ if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK) { - DU_LOG("\nERROR --> SCH: LcgId:%d updation failed",lcId); - return false; + DU_LOG("\nERROR --> SCH: LcgId:%d updation failed",lcId); + return RFAILED; } } - if ((ueCb->ulLcPrbEst.defLcList.count == 0) && \ - ((ueCb->ulLcPrbEst.dedLcInfo == NULL) || (ueCb->ulLcPrbEst.dedLcInfo->dedLcList.count == 0))) + if ((hqP->ulLcPrbEst.defLcList.count == 0) && (hqP->ulLcPrbEst.dedLcList.count == 0)) { - if(ueCb->srRcvd) + if( (ueCb->srRcvd) || (isRetx) ) { *startPrb = MAX_NUM_RB; *totTBS = schCalcTbSize(UL_GRANT_SIZE); } - /*Returning true when NO Grant is there for UE as this is not scheduling - * error*/ - return (true); + * error*/ + return ROK; } maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL); @@ -1851,38 +1904,37 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen, if(maxFreePRB != 0) { mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex; - if((ueCb->ulLcPrbEst.dedLcInfo == NULLP) - || ((maxFreePRB < ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB))) - { - ueCb->ulLcPrbEst.sharedNumPrb = maxFreePRB; + if((hqP->ulLcPrbEst.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB))) + { + hqP->ulLcPrbEst.sharedNumPrb = maxFreePRB; DU_LOG("\nDEBUG --> SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\ - ueCb->ulLcPrbEst.sharedNumPrb); + hqP->ulLcPrbEst.sharedNumPrb); /*PRB Alloc for Default LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen,\ - &(ueCb->ulLcPrbEst.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd)); + prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen,\ + &(hqP->ulLcPrbEst.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd)); } else { - ueCb->ulLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB; + hqP->ulLcPrbEst.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB; /*PRB Alloc for Dedicated LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, symbLen,\ - &(ueCb->ulLcPrbEst.sharedNumPrb), &(ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB),\ + prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.dedLcList), TRUE, mcsIdx, symbLen,\ + &(hqP->ulLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB),\ NULLP,&(ueCb->srRcvd)); /*PRB Alloc for Default LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen, \ - &(ueCb->ulLcPrbEst.sharedNumPrb), &(ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB),\ + prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen, \ + &(hqP->ulLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB),\ NULLP,&(ueCb->srRcvd)); } } /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - updateGrantSizeForBoRpt(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), NULLP, ueCb->bsrInfo, totTBS); + if(hqP->ulLcPrbEst.dedLcList.count != 0) + updateGrantSizeForBoRpt(&(hqP->ulLcPrbEst.dedLcList), NULLP, ueCb->bsrInfo, totTBS); - updateGrantSizeForBoRpt(&(ueCb->ulLcPrbEst.defLcList), NULLP, ueCb->bsrInfo, totTBS); + updateGrantSizeForBoRpt(&(hqP->ulLcPrbEst.defLcList), NULLP, ueCb->bsrInfo, totTBS); /*Below case will hit if NO LC(s) are allocated due to resource crunch*/ if (*totTBS == 0) @@ -1895,10 +1947,10 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen, { /*Schedule the LC for next slot*/ DU_LOG("\nDEBUG --> SCH : No LC has been scheduled"); - } - return (false); - } - return (true); + } + return RFAILED; + } + return ROK; } /******************************************************************* @@ -1912,14 +1964,15 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen, * Functionality: * sch Process pending Sr or Bsr Req * - * @params[in] SchCellCb *cell, SlotTimingInfo currTime - * @return ROK - success - * RFAILED - failure + * @params[in] SchCellCb *cell, SlotTimingInfo currTime + * @params[in] uint8_t ueId, Bool isRetx, SchUlHqProcCb **hqP + * @return true - success + * false - failure * *******************************************************************/ -bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) +bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchUlHqProcCb **hqP) { - bool k2Found = FALSE, ret = FALSE; + bool k2Found = FALSE, ret = RFAILED; uint8_t startSymb = 0, symbLen = 0; uint8_t k2TblIdx = 0, k2Index = 0, k2Val = 0; uint16_t startPrb = 0; @@ -1929,10 +1982,10 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId DciInfo *dciInfo = NULLP; SchK2TimingInfoTbl *k2InfoTbl=NULLP; SlotTimingInfo dciTime, puschTime; - + if(cell == NULLP) { - DU_LOG("\nERROR --> SCH: schDlRsrcAllocMsg4() : Cell is NULL"); + DU_LOG("\nERROR --> SCH: schProcessSrOrBsrReq() : Cell is NULL"); return false; } @@ -1940,9 +1993,18 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId if(ueCb == NULLP) { - DU_LOG("\nERROR --> SCH: schDlRsrcAllocMsg4() : UE is NULL"); + DU_LOG("\nERROR --> SCH: schProcessSrOrBsrReq() : UE is NULL"); return false; } + + if (isRetx == FALSE) + { + if (schUlGetAvlHqProcess(cell, ueCb, hqP) != ROK) + { + return RFAILED; + } + } + /* Calculating time frame to send DCI for SR */ ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA); #ifdef NR_TDD @@ -1970,7 +2032,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId startSymb = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[k2Index].startSymbol; symbLen = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[k2Index].symbolLength; } - + /* Check for number of Symbol of PUSCH should be same as original in case of transmisson*/ /* Calculating time frame to send PUSCH for SR */ ADD_DELTA_TO_TIME(dciTime, puschTime, k2Val); #ifdef NR_TDD @@ -1988,25 +2050,28 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId if(k2Found == true) { - ret = schCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq); - if(totDataReq > 0 && ret == TRUE) + ret = schCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP); + + if(totDataReq > 0 && ret == ROK) { SCH_ALLOC(dciInfo, sizeof(DciInfo)); if(!dciInfo) { DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc"); + if(isRetx != TRUE) + { + if((*hqP)->ulLcPrbEst.dedLcList.count != 0) + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, RFAILED); - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, RFAILED); - - updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED); + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED); + } return false; } cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo; memset(dciInfo,0,sizeof(DciInfo)); /* Update PUSCH allocation */ - if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb) == ROK) + if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK) { if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo) { @@ -2014,24 +2079,22 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId if(puschInfo != NULLP) { /* Fill DCI for UL grant */ - schFillUlDci(ueCb, puschInfo, dciInfo); + schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP); memcpy(&dciInfo->slotIndInfo, &dciTime, sizeof(SlotTimingInfo)); ueCb->srRcvd = false; ueCb->bsrRcvd = false; cell->schUlSlotInfo[puschTime.slot]->puschUe = ueId; - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, ROK); - - updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, ROK); + if((*hqP)->ulLcPrbEst.dedLcList.count != 0) + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, ROK); + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, ROK); + cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk); return true; } } } - - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, RFAILED); - - updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED); + if((*hqP)->ulLcPrbEst.dedLcList.count != 0) + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, RFAILED); + updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED); } } return (ret); diff --git a/src/5gnrsch/sch_crc.c b/src/5gnrsch/sch_crc.c new file mode 100644 index 000000000..4aa9f81c1 --- /dev/null +++ b/src/5gnrsch/sch_crc.c @@ -0,0 +1,115 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +#include "common_def.h" +#include "tfu.h" +#include "lrg.h" +#include "tfu.x" +#include "lrg.x" +#include "du_log.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "sch.h" +#include "sch_utils.h" + +/** + * @brief Process CRC indication + * + * @details + * + * Function : schProcessCrcInd + * + * This function process CRC indication + * + * @param[in] CrcIndInfo *crcInd, recvd crc indication + * @param[in] Inst schInst, scheduler inst + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst) +{ + SchCellCb *cell = schCb[schInst].cells[schInst]; + uint16_t count=0; + uint8_t ueId=0; + SchUlHqProcCb *hqP = NULLP; + + while(count numCrcInd) + { + GET_UE_ID(crcInd->crnti, ueId); + if (cell->raCb[ueId-1].raState == SCH_RA_STATE_MSG3_PENDING) + { + if (crcInd->crcInd[count]) + { + /* failure case*/ + if (cell->raCb[ueId-1].msg3HqProc.tbInfo.txCntr < cell->cellCfg.schRachCfg.maxMsg3Tx) + { + addUeToBeScheduled(cell, ueId); + cell->raCb[ueId - 1].retxMsg3HqProc = &cell->raCb[ueId - 1].msg3HqProc; + } + else + { + /*Release all contexts of the UE RA*/ + } + } + else + { + /* pass case*/ + /*Dedicated preamble case need to be added*/ + cell->raCb[ueId-1].raState = SCH_RA_STATE_MSG4_PENDING; + /*HARQ init part is in ADD UE CONFIG now, could be moved here*/ + } + } + else + { + if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.count == 0) + { + DU_LOG("\n ERROR no harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId); + continue; + } + if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first == 0) + { + DU_LOG("\n ERROR NULL harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId); + continue; + } + hqP = (SchUlHqProcCb*) cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first->node; + if(hqP == NULLP) + { + continue; + } + else + { + if (crcInd->crcInd[count]) + { + /* failure case*/ + schUlHqProcessNack(hqP); + } + else + { + /* pass case*/ + schUlHqProcessAck(hqP); + } + } + cmLListDelFrm(&(cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList), &hqP->ulSlotLnk); + } + count++; + } + return ROK; +} +/********************************************************************** + End of file + **********************************************************************/ \ No newline at end of file diff --git a/src/5gnrsch/sch_harq_dl.c b/src/5gnrsch/sch_harq_dl.c new file mode 100644 index 000000000..c5cebed36 --- /dev/null +++ b/src/5gnrsch/sch_harq_dl.c @@ -0,0 +1,403 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +#include "common_def.h" +#include "tfu.h" +#include "lrg.h" +#include "tfu.x" +#include "lrg.x" +#include "du_log.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "sch.h" +#include "sch_utils.h" +#include "cm_llist.h" + +SchMacDlReleaseHarqFunc schMacDlReleaseHarqOpts[] = +{ + packSchMacDlReleaseHarq, + MacSchReleaseDlHarqProc, + packSchMacDlReleaseHarq +}; + +typedef struct schCellCb SchCellCb; +typedef struct schUeCb SchUeCb; +void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE); +void schDlHqAddToFreeList(SchDlHqProcCb *hqP); + +/** + * @brief DL Harq entity intialization + * + * @details + * + * Function : schDlHqEntInit + * + * This function intialize DL Harq entity + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @return + * -# void + **/ +void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb) +{ + ueCb->dlHqEnt.numHqPrcs = SCH_MAX_NUM_DL_HQ_PROC; + ueCb->dlHqEnt.maxHqTx = cellCb->cellCfg.schHqCfg.maxDlDataHqTx; + ueCb->dlHqEnt.cell = cellCb; + ueCb->dlHqEnt.ue =ueCb; + schDlHqEntReset(cellCb, ueCb, &ueCb->dlHqEnt); +} +/** + * @brief DL Harq entity Reset + * + * @details + * + * Function : schDlHqEntReset + * + * This function Reset DL Harq entity + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @param[in] SchDlHqEnt *hqE, Dl Harq entity pointer + * @return + * -# void + **/ +void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE) +{ + uint8_t count = 0; + SchDlHqProcCb *hqP = NULL; + cmLListInit(&hqE->free); + cmLListInit(&hqE->inUse); + + for(count=0; count < hqE->numHqPrcs; count++) + { + hqP = &(hqE->procs[count]); + hqP->procId = count; + hqP->hqEnt = hqE; + hqP->maxHqTxPerHqP = hqE->maxHqTx; + hqP->dlHqEntLnk.node = (PTR)hqP; + hqP->dlHqProcLink.node = (PTR)hqP; + hqP->ulSlotLnk.node = (PTR)hqP; + schDlHqAddToFreeList(hqP); + } +} +/** + * @brief Add hq process to free list of DL Harq entity + * + * @details + * + * Function : schDlHqAddToFreeList + * + * This function adds hq process to free list of DL Harq entity + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @return + * -# void + **/ +void schDlHqAddToFreeList(SchDlHqProcCb *hqP) +{ + cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->dlHqEntLnk); +} +/** + * @brief Delete hq process from free list of DL Harq entity + * + * @details + * + * Function : schDlHqDeleteFromFreeList + * + * This function deletes hq process to free list of DL Harq entity + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @return + * -# void + **/ +void schDlHqDeleteFromFreeList(SchDlHqProcCb *hqP) +{ + cmLListDelFrm(&(hqP->hqEnt->free), &hqP->dlHqEntLnk); +} +/** + * @brief Add hq process to in use list of DL Harq entity + * + * @details + * + * Function : schDlHqAddToInUseList + * + * This function adds hq process to in use list of DL Harq entity + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @return + * -# void + **/ +void schDlHqAddToInUseList(SchDlHqProcCb *hqP) +{ + cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk); +} +/** + * @brief Delete hq process from in use list of DL Harq entity + * + * @details + * + * Function : schDlHqDeleteFromInUseList + * + * This function deletes hq process to in use list of DL Harq entity + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @return + * -# void + **/ +void schDlHqDeleteFromInUseList(SchDlHqProcCb *hqP) +{ + cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk); +} +/** + * @brief Get available Harq process from Harq entity + * + * @details + * + * Function : schDlGetAvlHqProcess + * + * This function fetches hq process from free list and puts in in use list + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @param[in] SchDlHqProcCb **hqP, Address of DL harq process pointer + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP) +{ + SchDlHqProcCb *tmp; + if (ueCb->dlHqEnt.free.count == 0) + { + return RFAILED; + } + tmp = (SchDlHqProcCb*)(cmLListFirst(&(ueCb->dlHqEnt.free))->node); + if (NULLP == tmp) + { + return RFAILED; + } + schDlHqDeleteFromFreeList(tmp); + schDlHqAddToInUseList(tmp); + *hqP = tmp; + (*hqP)->maxHqTxPerHqP = ueCb->dlHqEnt.maxHqTx; + return ROK; +} +/** + * @brief Release Harq process from the DL Harq entity + * + * @details + * + * Function : schDlReleaseHqProcess + * + * This function releases Harq process from DL Harq entity + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @return + * -# void + **/ +void schDlReleaseHqProcess(SchDlHqProcCb *hqP) +{ + cmLListDeleteLList(&hqP->dlLcPrbEst.dedLcList); + cmLListDeleteLList(&hqP->dlLcPrbEst.defLcList); + schDlHqDeleteFromInUseList(hqP); + schDlHqAddToFreeList(hqP); +} + +/******************************************************************* + * + * @brief Handles sending DL HARQ process release to MAC + * + * @details + * + * Function : sendDlHarqProcReleaseToMac + * + * Functionality: + * Sends DL DL HARQ process release to MAC from SCH + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t sendDlHarqProcReleaseToMac(SchDlHqProcCb *hqP, Inst inst) +{ + Pst pst; + SchRlsHqInfo *rlsHqInfo; + memset(&pst, 0, sizeof(Pst)); + FILL_PST_SCH_TO_MAC(pst, inst); + pst.event = EVENT_DL_REL_HQ_PROC; + + SCH_ALLOC(rlsHqInfo, sizeof(SchRlsHqInfo)); + rlsHqInfo->cellId = hqP->hqEnt->cell->cellId; + rlsHqInfo->numUes = 1; + + SCH_ALLOC(rlsHqInfo->ueHqInfo, sizeof(SchUeHqInfo)*rlsHqInfo->numUes); + rlsHqInfo->ueHqInfo[0].crnti = hqP->hqEnt->ue->crnti; + rlsHqInfo->ueHqInfo[0].hqProcId = hqP->procId; + + return(*schMacDlReleaseHarqOpts[pst.selector])(&pst, rlsHqInfo); +} +/** + * @brief Release Harq process TB from the DL Harq process + * + * @details + * + * Function : schDlReleaseHqPTb + * + * This function releases Harq process TB from DL Harq proces + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @param[in] uint8_t tbIdx, TB index + * @param[in] bool togNdi, indication to toggle NDI bit + * @return + * -# void + **/ +void schDlReleaseHqPTb(SchDlHqProcCb *hqP, uint8_t tbIdx, bool togNdi) +{ + if (TRUE == togNdi) + { + hqP->tbInfo[tbIdx].ndi ^= 1; + } + + { + hqP->tbInfo[tbIdx].isAckNackDtx = HQ_ACK; + hqP->tbInfo[tbIdx].isEnabled = FALSE; + hqP->tbInfo[tbIdx].state = HQ_TB_ACKED; + hqP->tbInfo[tbIdx].txCntr = 0; + if (HQ_TB_ACKED == hqP->tbInfo[tbIdx^1].state) + { + schDlReleaseHqProcess(hqP); + sendDlHarqProcReleaseToMac(hqP, hqP->hqEnt->cell->instIdx); + } + } +} +/** + * @brief Handles failure of HARQ process TB + * + * @details + * + * Function : schDlHqTbFail + * + * This function handles failure of HARQ process TB + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @param[in] uint8_t tbIdx, TB index + * @param[in] bool isMaxRetx, indicates max retransmission + * @return + * -# void + **/ +void schDlHqTbFail(SchDlHqProcCb *hqP, uint8_t tbIdx, bool isMaxRetx) +{ + if (isMaxRetx) + { + schDlReleaseHqPTb(hqP, tbIdx, TRUE); + } + else + { + hqP->tbInfo[tbIdx].state = HQ_TB_NACKED; + if (HQ_TB_WAITING == hqP->tbInfo[tbIdx^1].state) + { + cmLListAdd2Tail( &(hqP->hqEnt->ue->dlRetxHqList), &hqP->dlHqProcLink); + } + } +} +/** + * @brief Handles Harq feedback for MSG4 + * + * @details + * + * Function : schMsg4FeedbackUpdate + * + * This function handles Harq feedback for MSG4 + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @param[in] uint8_t fdbk, Received feedback + * @return + * -# void + **/ +void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk) +{ + hqP->tbInfo[0].isAckNackDtx = fdbk; + hqP->tbInfo[1].isAckNackDtx = HQ_TB_ACKED; + if (HQ_TB_ACKED == hqP->tbInfo[0].isAckNackDtx) + { + schDlReleaseHqPTb(hqP, 0, TRUE); + schDlReleaseHqPTb(hqP, 1, TRUE); + schMsg4Complete(hqP->hqEnt->ue); + } + else + { + if( hqP->tbInfo[0].txCntr >= hqP->hqEnt->cell->cellCfg.schHqCfg.maxMsg4HqTx) + { + schDlReleaseHqProcess(hqP); + hqP->hqEnt->ue->msg4Proc = NULLP; + hqP->hqEnt->ue->retxMsg4HqProc = NULLP; + /* Delete UE and RA context */ + } + addUeToBeScheduled(hqP->hqEnt->cell,hqP->hqEnt->ue->ueId); + hqP->hqEnt->ue->retxMsg4HqProc = hqP; + } +} +/** + * @brief Handles Harq feedback for DL Data + * + * @details + * + * Function : schDlHqFeedbackUpdate + * + * This function handles Harq feedback for DL data + * + * @param[in] SchDlHqProcCb *hqP, DL harq process pointer + * @param[in] uint8_t fdbk1, Received feedback for TB -0 + * @param[in] uint8_t fdbk2, Received feedback for TB -1 + * @return + * -# void + **/ +void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2) +{ + uint8_t tbIdx; + for (tbIdx = 0; tbIdx <2; tbIdx++) + { + if (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state) + { + hqP->tbInfo[tbIdx].isAckNackDtx = (0 == tbIdx)?fdbk1:fdbk2; + } + if (TRUE == hqP->tbInfo[tbIdx].isEnabled) + { + if (HQ_TB_ACKED == hqP->tbInfo[tbIdx].isAckNackDtx) + { + schDlReleaseHqPTb(hqP, tbIdx, TRUE); + } + else + { + if(hqP->tbInfo[tbIdx].txCntr >= hqP->maxHqTxPerHqP) + { + schDlHqTbFail(hqP, tbIdx, TRUE); + } + else + { + schDlHqTbFail(hqP, tbIdx, FALSE); + addUeToBeScheduled(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId); + } + } + } + } +} +/********************************************************************** + End of file + **********************************************************************/ diff --git a/src/5gnrsch/sch_harq_ul.c b/src/5gnrsch/sch_harq_ul.c new file mode 100644 index 000000000..fdd5ffa5a --- /dev/null +++ b/src/5gnrsch/sch_harq_ul.c @@ -0,0 +1,266 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +#include "common_def.h" +#include "tfu.h" +#include "lrg.h" +#include "tfu.x" +#include "lrg.x" +#include "du_log.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "sch.h" +#include "sch_utils.h" +typedef struct schCellCb SchCellCb; +typedef struct schUeCb SchUeCb; +void schUlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqEnt *hqE); +void schUlHqAddToFreeList(SchUlHqProcCb *hqP); +/** + * @brief UL Harq entity intialization + * + * @details + * + * Function : schUlHqEntInit + * + * This function intialize UL Harq entity + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @return + * -# void + **/ +void schUlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb) +{ + ueCb->ulHqEnt.numHqPrcs = SCH_MAX_NUM_UL_HQ_PROC; + ueCb->ulHqEnt.maxHqTx = cellCb->cellCfg.schHqCfg.maxUlDataHqTx; + ueCb->ulHqEnt.cell = cellCb; + ueCb->ulHqEnt.ue =ueCb; + schUlHqEntReset(cellCb, ueCb, &ueCb->ulHqEnt); +} +/** + * @brief UL Harq entity Reset + * + * @details + * + * Function : schUlHqEntReset + * + * This function Reset UL Harq entity + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @param[in] SchUlHqEnt *hqE, Ul Harq entity pointer + * @return + * -# void + **/ +void schUlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqEnt *hqE) +{ + uint8_t count = 0; + SchUlHqProcCb *hqP = NULL; + cmLListInit(&hqE->free); + cmLListInit(&hqE->inUse); + for(count=0; count < hqE->numHqPrcs; count++) + { + hqP = &(hqE->procs[count]); + hqP->procId = count; + hqP->hqEnt = hqE; + hqP->maxHqTxPerHqP = hqE->maxHqTx; + hqP->ulHqEntLnk.node = (PTR)hqP; + hqP->ulHqProcLink.node = (PTR)hqP; + hqP->ulSlotLnk.node = (PTR)hqP; + schUlHqAddToFreeList(hqP); + } +} +/** + * @brief Add hq process to free list of UL Harq entity + * + * @details + * + * Function : schUlHqAddToFreeList + * + * This function adds hq process to free list of UL Harq entity + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqAddToFreeList(SchUlHqProcCb *hqP) +{ + cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->ulHqEntLnk); +} +/** + * @brief Delete hq process from free list of UL Harq entity + * + * @details + * + * Function : schUlHqDeleteFromFreeList + * + * This function deletes hq process to free list of UL Harq entity + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqDeleteFromFreeList(SchUlHqProcCb *hqP) +{ + if(hqP->hqEnt->free.count == 0) + { + DU_LOG("\n ERROR schUlHqDeleteFromInUseList no proc in in free\n"); + } + cmLListDelFrm(&(hqP->hqEnt->free), &hqP->ulHqEntLnk); +} +/** + * @brief Add hq process to in use list of UL Harq entity + * + * @details + * + * Function : schUlHqAddToInUseList + * + * This function adds hq process to in use list of UL Harq entity + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqAddToInUseList(SchUlHqProcCb *hqP) +{ + cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->ulHqEntLnk); +} +/** + * @brief Delete hq process from in use list of UL Harq entity + * + * @details + * + * Function : schUlHqDeleteFromInUseList + * + * This function deletes hq process to in use list of UL Harq entity + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqDeleteFromInUseList(SchUlHqProcCb *hqP) +{ + if(hqP->hqEnt->inUse.count == 0) + { + DU_LOG("\n ERROR schUlHqDeleteFromInUseList no proc in in use\n"); + } + cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->ulHqEntLnk); +} +/** + * @brief Get available Harq process from Harq entity + * + * @details + * + * Function : schUlGetAvlHqProcess + * + * This function fetches hq process from free list and puts in in use list + * + * @param[in] SchCellCb *cellCb, cell cb pointer + * @param[in] SchUeCb *ueCb, ue cb pointer + * @param[in] SchUlHqProcCb **hqP, Address of UL harq process pointer + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t schUlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqProcCb **hqP) +{ + SchUlHqProcCb *tmp; + if (ueCb->ulHqEnt.free.count == 0) + { + return RFAILED; + } + tmp = (SchUlHqProcCb*)(cmLListFirst(&(ueCb->ulHqEnt.free))->node); + if (NULLP == tmp) + { + return RFAILED; + } + schUlHqDeleteFromFreeList(tmp); + schUlHqAddToInUseList(tmp); + *hqP = tmp; + (*hqP)->maxHqTxPerHqP = ueCb->ulHqEnt.maxHqTx; + return ROK; +} +/** + * @brief Release Harq process from the UL Harq entity + * + * @details + * + * Function : schUlReleaseHqProcess + * + * This function releases Harq process from UL Harq entity + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @param[in] Bool togNdi, indication to togle NDI bit + * @return + * -# void + **/ +void schUlReleaseHqProcess(SchUlHqProcCb *hqP, Bool togNdi) +{ + if (togNdi == TRUE) + { + hqP->tbInfo.ndi ^= 1; + } + cmLListDeleteLList(&hqP->ulLcPrbEst.dedLcList); + cmLListDeleteLList(&hqP->ulLcPrbEst.defLcList); + schUlHqDeleteFromInUseList(hqP); + schUlHqAddToFreeList(hqP); +} +/** + * @brief Handles NACK for UL Harq process + * + * @details + * + * Function : schUlHqProcessNack + * + * This function handle NACK for UL Harq process + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqProcessNack(SchUlHqProcCb *hqP) +{ + if (hqP->tbInfo.txCntr < hqP->maxHqTxPerHqP) + { + cmLListAdd2Tail(&(hqP->hqEnt->ue->ulRetxHqList), &hqP->ulHqProcLink); + addUeToBeScheduled(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId); + } + else + { + schUlReleaseHqProcess(hqP, TRUE); + } +} +/** + * @brief Handles ACK for UL Harq process + * + * @details + * + * Function : schUlHqProcessAck + * + * This function handles ACK for UL Harq process + * + * @param[in] SchUlHqProcCb *hqP, UL harq process pointer + * @return + * -# void + **/ +void schUlHqProcessAck(SchUlHqProcCb *hqP) +{ + schUlReleaseHqProcess(hqP, TRUE); +} +/********************************************************************** + End of file + **********************************************************************/ \ No newline at end of file diff --git a/src/5gnrsch/sch_rach.c b/src/5gnrsch/sch_rach.c index 2f3f4f953..162ed15f6 100644 --- a/src/5gnrsch/sch_rach.c +++ b/src/5gnrsch/sch_rach.c @@ -388,6 +388,7 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst) schCb[schInst].cells[schInst]->numActvUe++; SET_ONE_BIT(raReq->ueCb->ueId, schCb[schInst].cells[schInst]->actvUeBitMap); raReq->ueCb->state = SCH_UE_STATE_ACTIVE; + schCb[schInst].cells[schInst]->raCb[ueId -1].raState = SCH_RA_STATE_MSG4_DONE; } } else @@ -396,7 +397,9 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst) GET_UE_ID(raReq->rachInd->crnti, ueId); schCb[schInst].cells[schInst]->raCb[ueId -1].tcrnti = raReq->rachInd->crnti; schCb[schInst].cells[schInst]->raCb[ueId -1].msg4recvd = FALSE; + schCb[schInst].cells[schInst]->raCb[ueId -1].raState = SCH_RA_STATE_MSG3_PENDING; } + schCb[schInst].cells[schInst]->raCb[ueId -1].cell = schCb[schInst].cells[schInst]; } /** @@ -414,7 +417,7 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst) * @param[out] msg3NumRb * @return void **/ -SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, SlotTimingInfo msg3SlotTime) +SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, SlotTimingInfo msg3SlotTime, SchUlHqProcCb* msg3HqProc, bool isRetx) { SchCellCb *cell = NULLP; SchUlSlotInfo *schUlSlotInfo = NULLP; @@ -456,7 +459,7 @@ SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, S tbSize = tbSize / 8 ; /*bits to byte conversion*/ schUlSlotInfo->schPuschInfo->crnti = crnti; - schUlSlotInfo->schPuschInfo->harqProcId = SCH_HARQ_PROC_ID; + schUlSlotInfo->schPuschInfo->harqProcId = msg3HqProc->procId; schUlSlotInfo->schPuschInfo->resAllocType = SCH_ALLOC_TYPE_1; schUlSlotInfo->schPuschInfo->fdAlloc.startPrb = startRb; schUlSlotInfo->schPuschInfo->fdAlloc.numPrb = numRb; @@ -471,7 +474,23 @@ SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, S schUlSlotInfo->schPuschInfo->dmrsMappingType = DMRS_MAP_TYPE_A; /* Setting Type-A */ schUlSlotInfo->schPuschInfo->nrOfDmrsSymbols = NUM_DMRS_SYMBOLS; schUlSlotInfo->schPuschInfo->dmrsAddPos = DMRS_ADDITIONAL_POS; - + if(!isRetx) + { + msg3HqProc->strtSymbl = startSymb; + msg3HqProc->numSymbl = symbLen; + msg3HqProc->puschResType = schUlSlotInfo->schPuschInfo->resAllocType; + msg3HqProc->puschStartPrb = schUlSlotInfo->schPuschInfo->fdAlloc.startPrb; + msg3HqProc->puschNumPrb = schUlSlotInfo->schPuschInfo->fdAlloc.numPrb; + msg3HqProc->tbInfo.qamOrder = schUlSlotInfo->schPuschInfo->tbInfo.qamOrder; + msg3HqProc->tbInfo.iMcs = schUlSlotInfo->schPuschInfo->tbInfo.mcs; + msg3HqProc->tbInfo.mcsTable = schUlSlotInfo->schPuschInfo->tbInfo.mcsTable; + msg3HqProc->tbInfo.ndi = schUlSlotInfo->schPuschInfo->tbInfo.ndi; + msg3HqProc->tbInfo.rv = schUlSlotInfo->schPuschInfo->tbInfo.rv; + msg3HqProc->tbInfo.tbSzReq = schUlSlotInfo->schPuschInfo->tbInfo.tbSize; + msg3HqProc->dmrsMappingType = schUlSlotInfo->schPuschInfo->dmrsMappingType; + msg3HqProc->nrOfDmrsSymbols = schUlSlotInfo->schPuschInfo->nrOfDmrsSymbols; + msg3HqProc->dmrsAddPos = schUlSlotInfo->schPuschInfo->dmrsAddPos; + } return schUlSlotInfo->schPuschInfo; } @@ -539,7 +558,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin SchK0K1TimingInfoTbl *k0K1InfoTbl=NULLP; SchK2TimingInfoTbl *msg3K2InfoTbl=NULLP; RaRspWindowStatus windowStatus=0; - + #ifdef NR_TDD totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod); #endif @@ -683,12 +702,12 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin if(cell->raReq[ueId-1]->isCFRA) { /* Allocate resources for PUCCH */ - schAllocPucchResource(cell, pucchTime, cell->raReq[ueId-1]->rachInd->crnti); + schAllocPucchResource(cell, pucchTime, cell->raReq[ueId-1]->rachInd->crnti,NULLP, FALSE, NULLP); } else { /* Allocate resources for msg3 */ - msg3PuschInfo = schAllocMsg3Pusch(schInst, cell->raReq[ueId-1]->rachInd->crnti, k2Index, msg3Time); + msg3PuschInfo = schAllocMsg3Pusch(schInst, cell->raReq[ueId-1]->rachInd->crnti, k2Index, msg3Time, &(cell->raCb[ueId-1].msg3HqProc), FALSE); if(msg3PuschInfo) { dciSlotAlloc->rarInfo.ulGrant.bwpSize = cell->cellCfg.schInitialUlBwp.bwp.freqAlloc.numPrb; @@ -1055,7 +1074,23 @@ uint8_t MacSchRachRsrcRel(Pst *pst, SchRachRsrcRel *schRachRsrcRel) SCH_FREE(schRachRsrcRel, sizeof(SchRachRsrcRel)); return ret; } - + /* @brief process MSG4 completion + * + * @details + * + * Function : schMsg4Complete + * + * This function updates ra state and msg4 Hqrq + * proc upon MSG4 completion + * @param[in] SchUeCb *ueCb, UE cb pointer + * @return VOID + */ +void schMsg4Complete(SchUeCb *ueCb) +{ + DU_LOG("\nINFO --> SCH: State change for ueId[%2d] to SCH_RA_STATE_MSG4_DONE\n",ueCb->ueId); + ueCb->cellCb->raCb[ueCb->ueId-1].raState = SCH_RA_STATE_MSG4_DONE; + ueCb->msg4Proc = ueCb->retxMsg4HqProc = NULLP; +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_rr.c b/src/5gnrsch/sch_rr.c new file mode 100644 index 000000000..a6c52e2ec --- /dev/null +++ b/src/5gnrsch/sch_rr.c @@ -0,0 +1,180 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +#include "common_def.h" +#include "tfu.h" +#include "lrg.h" +#include "tfu.x" +#include "lrg.x" +#include "du_log.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "sch.h" +#include "sch_utils.h" +/** + * @brief Handles retransmission for MSG3 + * + * @details + * + * Function : schMsg3RetxSchedulingForUe + * + * This function handles retransmission for MSG3 + * + * @param[in] SchRaCb *raCb, RA cb pointer + * @return + * -# ROK + * -# RFAILED + **/ +uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) +{ + bool k2Found = false; +#ifdef NR_TDD + uint8_t totalCfgSlot = 0; +#endif + uint16_t dciSlot = 0; + SlotTimingInfo dciTime, msg3Time; + SchCellCb *cell = NULLP; + SlotTimingInfo currTime; + DciInfo *dciInfo = NULLP; + cell = raCb->cell; + currTime = cell->slotInfo; + + /* Calculating time frame to send DCI for MSG3 Retx*/ + ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA); +#ifdef NR_TDD + /* Consider this slot for sending DCI, only if it is a DL slot */ + if(schGetSlotSymbFrmt(dciSlot, raCb->cell->slotFrmtBitMap) == DL_SLOT) +#endif + { + /* If PDCCH is already scheduled on this slot, cannot schedule PDSCH for another UE here. */ + if(cell->schDlSlotInfo[dciSlot]->pdcchUe != 0) + return false; + + k2Found = schGetMsg3K2(cell, &raCb->msg3HqProc, dciTime.slot, &msg3Time, TRUE); + + if (!k2Found) + { + return RFAILED; + } + SCH_ALLOC(dciInfo, sizeof(DciInfo)); + if(!dciInfo) + { + DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc"); + return RFAILED; + } + cell->schDlSlotInfo[msg3Time.slot]->ulGrant = dciInfo; + SCH_ALLOC(cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, sizeof(SchPuschInfo)); + memset(dciInfo,0,sizeof(DciInfo)); + schFillUlDciForMsg3Retx(raCb, cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, dciInfo); + } + raCb->retxMsg3HqProc = NULLP; + return ROK; +} +/** + * @brief Get K2 value for MSG3 + * + * @details + * + * Function : schGetMsg3K2 + * + * This function gets K2 for MSG3 + * + * @param[in] SchCellCb *cell, Cell cb struc pointer + * @param[in] SchUlHqProcCb* msg3HqProc, msg3 harq proc pointer + * @param[in] uint16_t dlTime, DL time of scheduling + * @param[in] SlotTimingInfo *msg3Time, MSG3 timing info + * @param[in] bool isRetx, indicates MSG3 retransmission + * @return + * -# true + * -# false + **/ +bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx) +{ + bool k2Found = false; + uint8_t k2TblIdx = 0; + uint8_t k2Index = 0; + uint8_t k2 = 0; + uint8_t numK2 = 0; + uint8_t puschMu = 0; + uint8_t msg3Delta = 0, msg3MinSchTime = 0; +#ifdef NR_TDD + uint8_t totalCfgSlot = 0; +#endif + SchK2TimingInfoTbl *msg3K2InfoTbl=NULLP; + SlotTimingInfo currTime, msg3TempTime; + currTime = cell->slotInfo; + puschMu = cell->cellCfg.numerology; + + if (isRetx) + { + if(!msg3HqProc) + return false; + + numK2 = cell->cellCfg.schInitialUlBwp.k2InfoTbl.k2TimingInfo[dlTime].numK2; + msg3K2InfoTbl = &cell->cellCfg.schInitialUlBwp.msg3K2InfoTbl; + msg3MinSchTime = 0; + msg3Delta = 0; + } + else + { + numK2 = cell->cellCfg.schInitialUlBwp.msg3K2InfoTbl.k2TimingInfo[dlTime].numK2; + msg3K2InfoTbl = &cell->cellCfg.schInitialUlBwp.k2InfoTbl; + msg3MinSchTime = minMsg3SchTime[cell->cellCfg.numerology]; + msg3Delta = puschDeltaTable[puschMu]; + } + + for(k2TblIdx = 0; k2TblIdx < numK2; k2TblIdx++) + { + k2Index = msg3K2InfoTbl->k2TimingInfo[dlTime].k2Indexes[k2TblIdx]; + + k2 = cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].k2; + if (isRetx) + { + if ((msg3HqProc->strtSymbl != cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].startSymbol) || + (msg3HqProc->numSymbl != cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].symbolLength)) + { + continue; + } + } + /* Delta is added to the slot allocation for msg3 based on 38.214 section 6.1.2.1 */ + k2 = k2 + msg3Delta; + if(k2 >= msg3MinSchTime) + { + ADD_DELTA_TO_TIME(currTime, msg3TempTime, k2); +#ifdef NR_TDD + if(schGetSlotSymbFrmt(msg3TempTime.slot % totalCfgSlot, cell->slotFrmtBitMap) == DL_SLOT) + continue; +#endif + /* If PUSCH is already scheduled on this slot, another PUSCH + * pdu cannot be scheduled here */ + if(cell->schUlSlotInfo[msg3TempTime.slot]->puschUe != 0) + continue; + k2Found = true; + break; + } + } + if (k2Found == true) + { + msg3Time->slot = msg3TempTime.slot; + msg3Time->sfn = msg3TempTime.sfn; + msg3Time->slot = msg3TempTime.slot; + } + return k2Found; +} +/********************************************************************** + End of file + **********************************************************************/ \ No newline at end of file diff --git a/src/5gnrsch/sch_slot_ind.c b/src/5gnrsch/sch_slot_ind.c index dcebee162..7c08cf38a 100644 --- a/src/5gnrsch/sch_slot_ind.c +++ b/src/5gnrsch/sch_slot_ind.c @@ -234,12 +234,18 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime) * Functionality: * find correct combination of k0-k1 value * - * @params[in] + * @params[in] SchCellCb *cell, SlotTimingInfo currTime + * @params[in] uint8_t ueId, bool dedMsg + * @params[in] uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen + * @params[in] SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime + * @params[in] SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP * @return ROK - success * RFAILED - failure * *******************************************************************/ -bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime) +bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, + uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime, + SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP) { uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ; uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0; @@ -331,6 +337,10 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, return true; } } + /* + * Number of symbols in case of retransmisson should be same as it was in + * original transmisson. Symbol availablity checks need to be added. + */ return false; } @@ -345,12 +355,13 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, * Functionality: * - * @params[in] + * @params[in] SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId + * @params[in] bool isRetx, SchDlHqProcCb **hqP * @return ROK - success * RFAILED - failure * * ****************************************************************/ -bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId) +bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchDlHqProcCb **hqP) { uint8_t lcIdx = 0; uint8_t pdschNumSymbols = 0, pdschStartSymbol = 0; @@ -361,24 +372,32 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t CmLListCp *lcLL = NULLP; DlMsgAlloc *dciSlotAlloc, *dlMsgAlloc; SlotTimingInfo pdcchTime, pdschTime, pucchTime; + uint16_t rsvdDedicatedPRB = 0; /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated. * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead * else if only Default list is present then first node in this List will add this overhead len*/ bool isTxPayloadLenAdded = FALSE; - GET_CRNTI(crnti,ueId); ueCb = &cell->ueCb[ueId-1]; + if (isRetx == FALSE) + { + if(schDlGetAvlHqProcess(cell, ueCb, hqP) != ROK) + { + return false; + } + } + if(findValidK0K1Value(cell, currTime, ueId, ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1TblPrsnt,\ - &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime) != true ) + &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime, isRetx, *hqP) != true ) { /* If a valid combination of slots to scheduled PDCCH, PDSCH and PUCCH is * not found, do not perform resource allocation. Return from here. */ return false; } - + /* allocate PDCCH and PDSCH resources for the ue */ if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL) { @@ -398,66 +417,69 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1]; } /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */ - fillDlMsgInfo(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].dlMsgInfo, dciSlotAlloc->crnti); + fillDlMsgInfo(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].dlMsgInfo, dciSlotAlloc->crnti, isRetx, *hqP); + dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].isRetx = isRetx; - /*Re-Initalization per UE*/ - /* scheduled LC data fill */ - dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0; - isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/ - accumalatedSize = 0; - for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++) + if (isRetx == FALSE) { - if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo) - { - /*Check the LC is Dedicated or default and accordingly LCList will - * be used*/ - if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated) - { - lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); - } - else - { - lcLL = &(ueCb->dlLcPrbEst.defLcList); - } + /*Re-Initalization per UE*/ + /* scheduled LC data fill */ + dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0; + isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/ + accumalatedSize = 0; - /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/ - if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\ - (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK) + for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++) + { + if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo) { - DU_LOG("\nERROR --> SCH : Updation in LC List Failed"); - /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ - if(dciSlotAlloc->numSchedInfo == 0) + /*Check the LC is Dedicated or default and accordingly LCList will + * be used*/ + if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated) { - SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc)); - cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL; + lcLL = &((*hqP)->dlLcPrbEst.dedLcList); + rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB; } else - memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); - return false; - } - } - ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0; - }//End of for loop + { + lcLL = &((*hqP)->dlLcPrbEst.defLcList); + } + /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/ + if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\ + (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK) + { + DU_LOG("\nERROR --> SCH : Updation in LC List Failed"); + /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ + if(dciSlotAlloc->numSchedInfo == 0) + { + SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc)); + cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL; + } + else + memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); + return false; + } + } + ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0; + }//End of for loop + if (((*hqP)->dlLcPrbEst.defLcList.count == 0) && ( ((*hqP)->dlLcPrbEst.dedLcList.count == 0))) + { + DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n"); + UNSET_ONE_BIT(ueId, cell->boIndBitMap); - if ((ueCb->dlLcPrbEst.defLcList.count == 0) && \ - ((ueCb->dlLcPrbEst.dedLcInfo == NULL) || (ueCb->dlLcPrbEst.dedLcInfo->dedLcList.count == 0))) - { - DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n"); - UNSET_ONE_BIT(ueId, cell->boIndBitMap); + /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ + if(dciSlotAlloc->numSchedInfo == 0) + { + SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc)); + cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL; + } + else + memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); - /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ - if(dciSlotAlloc->numSchedInfo == 0) - { - SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc)); - cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL; + /*TRUE because this UE has nothing to be scheduled*/ + return true; } - else - memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); - - /*TRUE because this UE has nothing to be scheduled*/ - return true; } /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/ @@ -468,40 +490,50 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or * Num of Free PRB available is not enough to reserve Dedicated PRBs*/ - if(maxFreePRB != 0) + if(isRetx == FALSE) { - mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex; - if((ueCb->dlLcPrbEst.dedLcInfo == NULLP) - || ((maxFreePRB < ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB))) - { - ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB; - DU_LOG("\nDEBUG --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\ - ueCb->dlLcPrbEst.sharedNumPrb); - - /*PRB Alloc for Default LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols,\ - &(ueCb->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP); - } - else + if(maxFreePRB != 0) { - ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB; - - /*PRB Alloc for Dedicated LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, pdschNumSymbols,\ - &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP); - - /*PRB Alloc for Default LCs*/ - prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols, \ - &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP); + mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex; + + if(((*hqP)->dlLcPrbEst.dedLcList.count == NULLP) + || ((maxFreePRB < rsvdDedicatedPRB))) + { + (*hqP)->dlLcPrbEst.sharedNumPrb = maxFreePRB; + DU_LOG("\nDEBUG --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\ + (*hqP)->dlLcPrbEst.sharedNumPrb); + + /*PRB Alloc for Default LCs*/ + prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols,\ + &((*hqP)->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP); + } + else + { + (*hqP)->dlLcPrbEst.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB; + /*PRB Alloc for Dedicated LCs*/ + prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\ + &((*hqP)->dlLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP); + + /*PRB Alloc for Default LCs*/ + prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols, \ + &((*hqP)->dlLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP); + } } } /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes - * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ - if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) - updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize)); + * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ + if (isRetx == FALSE) + { + if((*hqP)->dlLcPrbEst.dedLcList.count != 0) + updateGrantSizeForBoRpt(&((*hqP)->dlLcPrbEst.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize)); - updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize)); + updateGrantSizeForBoRpt(&((*hqP)->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize)); + } + else + { + accumalatedSize = (*hqP)->tbInfo[0].tbSzReq; + } /*Below case will hit if NO LC(s) are allocated due to resource crunch*/ if (!accumalatedSize) @@ -521,7 +553,7 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t } /*[Step6]: pdcch and pdsch data is filled */ - if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols)) != ROK) + if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols, isRetx, *hqP)) != ROK) { DU_LOG("\nERROR --> SCH : Scheduling of DL dedicated message failed"); @@ -532,7 +564,9 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL; } else + { memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo)); + } return false; } @@ -596,14 +630,14 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t dlMsgAlloc->numSchedInfo++; } - schAllocPucchResource(cell, pucchTime, crnti); + schAllocPucchResource(cell, pucchTime, crnti, ueCb, isRetx, *hqP); + cell->schDlSlotInfo[pdcchTime.slot]->pdcchUe = ueId; cell->schDlSlotInfo[pdschTime.slot]->pdschUe = ueId; cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId; /* after allocation is done, unset the bo bit for that ue */ UNSET_ONE_BIT(ueId, cell->boIndBitMap); - return true; } @@ -732,10 +766,13 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) bool isMsg4Pending = false, isMsg4Scheduled = false; bool isUlGrantPending = false, isUlGrantScheduled = false; bool isDlMsgPending = false, isDlMsgScheduled = false; - CmLList *pendingUeNode; - DlSchedInfo dlSchedInfo; - DlBrdcstAlloc *dlBrdcstAlloc = NULLP; - SchCellCb *cell = NULLP; + CmLList *pendingUeNode; + DlSchedInfo dlSchedInfo; + DlBrdcstAlloc *dlBrdcstAlloc = NULLP; + SchCellCb *cell = NULLP; + CmLList *node; + uint8_t* ueNode; + SchDlHqProcCb *hqP = NULLP, *ulHqP = NULLP; memset(&dlSchedInfo, 0, sizeof(DlSchedInfo)); schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue); @@ -798,8 +835,8 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) { if(pendingUeNode->node) { + ueNode = (uint8_t *)pendingUeNode->node; ueId = *(uint8_t *)(pendingUeNode->node); - /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and * PUSCH to receive MSG3 as per k0-k2 configuration*/ if(cell->raReq[ueId-1] != NULLP) @@ -808,12 +845,34 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId); } + /*MSG3 retransmisson*/ + if(cell->raCb[ueId-1].retxMsg3HqProc) + { + schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1])); + } + /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and * PUCCH to receive UL msg as per k0-k1 configuration */ - if(cell->raCb[ueId-1].msg4recvd) + if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd { + /* Retransmission of MSG4 */ isMsg4Pending = true; - isMsg4Scheduled = schProcessMsg4Req(cell, *slotInd, ueId); + if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK) + isMsg4Scheduled = true; + } + else + { + /* First transmission of MSG4 */ + if(cell->raCb[ueId-1].msg4recvd) + { + isMsg4Pending = true; + if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4Proc) == ROK) + isMsg4Scheduled = true; + + /* If MSG4 scheduling failed, free the newly assigned HARQ process */ + if(!isMsg4Scheduled) + schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4Proc); + } } if(isRarPending || isMsg4Pending) @@ -827,23 +886,56 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) } /* If RAR/MSG4 is pending but couldnt be scheduled then, * put this UE at the end of linked list to be scheduled later */ - else + else { cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode)); } } - if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd) + /* DL Data */ + node = cell->ueCb[ueId-1].dlRetxHqList.first; + if(node != NULLP) { - isUlGrantPending = true; - isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId); + /* DL Data ReTransmisson */ + isDlMsgPending = true; + isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node))); + cmLListDelFrm(&cell->ueCb[ueId-1].dlRetxHqList, node); } + else + { + /* DL Data new transmission */ + if((cell->boIndBitMap) & (1<boIndBitMap) & (1<ueCb[ueId-1].ulRetxHqList.first; + if(node != NULLP) { - isDlMsgPending = true; - isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId); + /* UL Data ReTransmisson */ + isUlGrantPending = true; + isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node)); + cmLListDelFrm(&cell->ueCb[ueId-1].ulRetxHqList, node); + } + else + { + /* UL Data new transmission */ + if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd) + { + isUlGrantPending = true; + isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP); + if(!isUlGrantScheduled) + schUlReleaseHqProcess(ulHqP, FALSE); + } } + if(!isUlGrantPending && !isDlMsgPending) { /* No action required */ @@ -854,7 +946,7 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) } else { - SCH_FREE(pendingUeNode->node, sizeof(uint8_t)); + SCH_FREE(ueNode, sizeof(uint8_t)); deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode); } } @@ -880,7 +972,6 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx]; cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx] = NULLP; } - } if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.ulDciTime.slot]->ulGrant != NULLP) diff --git a/src/5gnrsch/sch_ue_mgr.c b/src/5gnrsch/sch_ue_mgr.c index 3db4b1c0e..8ca3bac28 100644 --- a/src/5gnrsch/sch_ue_mgr.c +++ b/src/5gnrsch/sch_ue_mgr.c @@ -192,7 +192,7 @@ void fillSchUlLcCtxt(SchUlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg) * * ****************************************************************/ -uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, bool *isDedicated) +uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, uint16_t *rsvdDedicatedPRB, bool *isDedicated) { uint8_t sliceCfgIdx =0; SchSliceCfg sliceCfg = schCb[inst].sliceCfg; @@ -203,22 +203,13 @@ uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, b { if(memcmp(snssai, &(sliceCfg.listOfConfirguration[sliceCfgIdx]->snssai), sizeof(Snssai)) == 0) { - if(lcPrbEst->dedLcInfo == NULLP) - { - SCH_ALLOC(lcPrbEst->dedLcInfo, sizeof(DedicatedLCInfo)); - if(lcPrbEst->dedLcInfo == NULLP) - { - DU_LOG("\nINFO --> SCH : Memory Allocation Failed"); - return RFAILED; - } - } if(sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo) { /*Updating latest RrmPolicy*/ - lcPrbEst->dedLcInfo->rsvdDedicatedPRB = \ + *rsvdDedicatedPRB = \ (uint16_t)(((sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo->policyDedicatedRatio)*(MAX_NUM_RB))/100); *isDedicated = TRUE; - DU_LOG("\nINFO --> SCH : Updated RRM policy, reservedPOOL:%d",lcPrbEst->dedLcInfo->rsvdDedicatedPRB); + DU_LOG("\nINFO --> SCH : Updated RRM policy, reservedPOOL:%d",*rsvdDedicatedPRB); } } } @@ -250,11 +241,10 @@ uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, b uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) { - uint8_t lcIdx, ueLcIdx; + uint8_t lcIdx, ueLcIdx, idx; uint8_t freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0}; SchPdschCfgCmn pdschCfg; SchPucchDlDataToUlAck *dlDataToUlAck; - CmLListCp *lcLL = NULLP; uint8_t retDL = ROK, retUL = ROK; bool isLcIdValid = FALSE; @@ -280,7 +270,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) { if(ueCb->ueCfg.spCellCfgPres && ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true) { - for(uint8_t idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++) + for(idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++) { if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0 && ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0) { @@ -321,7 +311,6 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) } memcpy(&ueCb->ueCfg.dlModInfo, &ueCfg->dlModInfo , sizeof(SchModulationInfo)); memcpy(&ueCb->ueCfg.ulModInfo, &ueCfg->ulModInfo , sizeof(SchModulationInfo)); - //Updating SchUlCb and SchDlCb DB in SchUeCb for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++) { @@ -343,12 +332,12 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) * and Create the Dedicated LC List & Update the Reserve PRB number*/ if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP) { - retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst),\ + retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB),\ &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)); } if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP) { - retUL = updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\ + retUL = updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\ &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)); } @@ -368,7 +357,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) /*Updating the RRM reserved pool PRB count*/ if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP) { - retUL = updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\ + retUL = updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\ &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)); } if(retUL == RFAILED) @@ -382,21 +371,11 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) /*Delete the LC node from the UL LC List*/ if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated) { - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - { - lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList); - handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); - if(lcLL->count == 0)/*IF No Node in DedicateLCList to be deleted*/ - { - /*Free the Dedicated LC Info structure*/ - SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); - } - } + /*Remove from HARQ Transmission or retransmission*/ } else/*Default LC list*/ { - lcLL = &(ueCb->ulLcPrbEst.defLcList); - handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); + } SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt)); @@ -411,7 +390,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) /*Updating the RRM policy*/ if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP) { - retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst), \ + retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB), \ &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)); } if(retDL == RFAILED) @@ -425,21 +404,10 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) /*Delete the LC node from the DL LC List*/ if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated) { - if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) - { - lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); - handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); - if(lcLL->count == 0)/*Last Node in DedicateLCList to be deleted*/ - { - /*Free the Dedicated LC Info structure*/ - SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); - } - } + /*Remove from HARQ Transmission or retransmission*/ } else { - lcLL = &(ueCb->dlLcPrbEst.defLcList); - handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); } SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt)); @@ -519,7 +487,7 @@ SchCellCb *getSchCellCb(uint16_t srcEvent, Inst inst, SchUeCfg *ueCfg) * ****************************************************************/ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg) { - uint8_t lcIdx = 0, ret = ROK; + uint8_t lcIdx = 0, ret = ROK, idx = 0; SchCellCb *cellCb = NULLP; SchUeCb *ueCb = NULLP; SchUeCfgRsp cfgRsp; @@ -550,10 +518,35 @@ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg) /* Fill received Ue Configuration in UeCb */ memset(ueCb, 0, sizeof(SchUeCb)); + ueCb->ueId = ueCfg->ueId; ueCb->crnti = ueCfg->crnti; + ueCb->cellCb = cellCb; + schUlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]); + schDlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]); + SCH_ALLOC(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots)); + SCH_ALLOC(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots)); + if ( (ueCb->hqDlmap == NULLP) || (ueCb->hqUlmap == NULLP) ) + { + DU_LOG("\nINFO --> SCH : Memory Allocation Failed"); + return RFAILED; + } + for (idx = 0; idxcellCb->numSlots; idx++) + { + SCH_ALLOC(ueCb->hqDlmap[idx], sizeof(SchHqDlMap)); + SCH_ALLOC(ueCb->hqUlmap[idx], sizeof(SchHqUlMap)); + + if ( (ueCb->hqDlmap[idx] == NULLP) || (ueCb->hqUlmap[idx] == NULLP) ) + { + DU_LOG("\nINFO --> SCH : Memory Allocation Failed"); + return RFAILED; + } + cmLListInit(&ueCb->hqDlmap[idx]->hqList); + cmLListInit(&ueCb->hqUlmap[idx]->hqList); + } ret = fillSchUeCb(inst, ueCb, ueCfg); + if(ret == ROK) { /* If UE has initiated RACH and then UE context is created, it means UE is @@ -571,7 +564,6 @@ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg) ueCb->state = SCH_UE_HANDIN_IN_PROGRESS; } - ueCb->cellCb = cellCb; ueCb->srRcvd = false; ueCb->bsrRcvd = false; for(lcIdx=0; lcIdxueCfg.ulModInfo.mcsIndex, symbLen); allocatePrbUl(cellCb, puschTime, startSymb, symbLen, &startPrb, numRb); - puschInfo.crnti = ueCb->crnti; - puschInfo.harqProcId = SCH_HARQ_PROC_ID; - puschInfo.resAllocType = SCH_ALLOC_TYPE_1; - puschInfo.fdAlloc.startPrb = startPrb; - puschInfo.fdAlloc.numPrb = numRb; - puschInfo.tdAlloc.startSymb = startSymb; - puschInfo.tdAlloc.numSymb = symbLen; - puschInfo.tbInfo.qamOrder = ueCb->ueCfg.ulModInfo.modOrder; - puschInfo.tbInfo.mcs = ueCb->ueCfg.ulModInfo.mcsIndex; - puschInfo.tbInfo.mcsTable = ueCb->ueCfg.ulModInfo.mcsTable; - puschInfo.tbInfo.ndi = 1; /* new transmission */ - puschInfo.tbInfo.rv = 0; - puschInfo.tbInfo.tbSize = tbSize; - puschInfo.dmrsMappingType = DMRS_MAP_TYPE_A; /* Setting Type-A */ - puschInfo.nrOfDmrsSymbols = NUM_DMRS_SYMBOLS; - puschInfo.dmrsAddPos = DMRS_ADDITIONAL_POS; - + if (isRetx == FALSE) + { + puschInfo.crnti = ueCb->crnti; + puschInfo.harqProcId = SCH_HARQ_PROC_ID; + puschInfo.resAllocType = SCH_ALLOC_TYPE_1; + puschInfo.fdAlloc.startPrb = startPrb; + puschInfo.fdAlloc.numPrb = numRb; + puschInfo.tdAlloc.startSymb = startSymb; + puschInfo.tdAlloc.numSymb = symbLen; + puschInfo.tbInfo.qamOrder = ueCb->ueCfg.ulModInfo.modOrder; + puschInfo.tbInfo.mcs = ueCb->ueCfg.ulModInfo.mcsIndex; + puschInfo.tbInfo.mcsTable = ueCb->ueCfg.ulModInfo.mcsTable; + puschInfo.tbInfo.ndi = 1; /* new transmission */ + puschInfo.tbInfo.rv = 0; + puschInfo.tbInfo.tbSize = tbSize; + puschInfo.dmrsMappingType = DMRS_MAP_TYPE_A; /* Setting Type-A */ + puschInfo.nrOfDmrsSymbols = NUM_DMRS_SYMBOLS; + puschInfo.dmrsAddPos = DMRS_ADDITIONAL_POS; + hqP->puschResType = puschInfo.resAllocType; + hqP->puschStartPrb = puschInfo.fdAlloc.startPrb; + hqP->puschNumPrb = puschInfo.fdAlloc.numPrb; + hqP->strtSymbl = puschInfo.tdAlloc.startSymb; + hqP->numSymbl = puschInfo.tdAlloc.numSymb; + hqP->tbInfo.qamOrder = puschInfo.tbInfo.qamOrder; + hqP->tbInfo.iMcs = puschInfo.tbInfo.mcs; + hqP->tbInfo.mcsTable = puschInfo.tbInfo.mcsTable; + hqP->tbInfo.ndi = puschInfo.tbInfo.ndi; + hqP->tbInfo.rv = puschInfo.tbInfo.rv; + hqP->tbInfo.rvIdx = 0; + hqP->tbInfo.tbSzReq = puschInfo.tbInfo.tbSize; + hqP->dmrsMappingType = puschInfo.dmrsMappingType; + hqP->nrOfDmrsSymbols = puschInfo.nrOfDmrsSymbols; + hqP->dmrsAddPos = puschInfo.dmrsAddPos; + } + else + { + puschInfo.crnti = ueCb->crnti; + puschInfo.harqProcId = hqP->procId; + puschInfo.resAllocType = hqP->puschResType; + puschInfo.fdAlloc.startPrb = hqP->puschStartPrb; + puschInfo.fdAlloc.numPrb = hqP->puschNumPrb; + puschInfo.tdAlloc.startSymb = hqP->strtSymbl; + puschInfo.tdAlloc.numSymb = hqP->numSymbl; + puschInfo.tbInfo.qamOrder = hqP->tbInfo.qamOrder; + puschInfo.tbInfo.mcs = hqP->tbInfo.iMcs; + puschInfo.tbInfo.mcsTable = hqP->tbInfo.mcsTable; + puschInfo.tbInfo.ndi = hqP->tbInfo.ndi; /* retransmission */ + hqP->tbInfo.rvIdx = (hqP->tbInfo.rvIdx +1) & 0x3; + puschInfo.tbInfo.rv = schCmnDlRvTbl[hqP->tbInfo.rvIdx]; + puschInfo.tbInfo.tbSize = hqP->tbInfo.tbSzReq; + puschInfo.dmrsMappingType = hqP->dmrsMappingType; /* Setting Type-A */ + puschInfo.nrOfDmrsSymbols = hqP->nrOfDmrsSymbols; + puschInfo.dmrsAddPos = hqP->dmrsAddPos; + } schUlSlotInfo = cellCb->schUlSlotInfo[puschTime.slot]; SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo)); if(!schUlSlotInfo->schPuschInfo) @@ -650,6 +681,110 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSi return ROK; } +/******************************************************************* +* +* @brief Fills UL DCI information for MSG3 retransmission +* +* @details +* +* Function : schFillUlDciForMsg3Retx +* +* Functionality: fills UL DCI information for MSG3 retransmission +* +* @params[in] +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo) +{ + SchCellCb *cellCb = raCb->cell; + dciInfo->cellId = cellCb->cellId; + dciInfo->crnti = raCb->tcrnti; + SchUlHqProcCb *msg3HqProc = &raCb->msg3HqProc; + if (msg3HqProc == NULLP) + { + return RFAILED; + } + + /* fill bwp cfg */ + dciInfo->bwpCfg.subcarrierSpacing = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing; + dciInfo->bwpCfg.cyclicPrefix = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix; + dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb; + dciInfo->bwpCfg.freqAlloc.numPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; + + /*fill coreset cfg */ + //Considering number of RBs in coreset1 is same as coreset0 + dciInfo->coresetCfg.coreSetSize = coresetIdxTable[0][1]; + //Considering coreset1 also starts from same symbol as coreset0 + dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3]; + dciInfo->coresetCfg.durationSymbols = coresetIdxTable[0][2]; + memcpy(dciInfo->coresetCfg.freqDomainResource, cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc, FREQ_DOM_RSRC_SIZE); + + dciInfo->coresetCfg.cceRegMappingType = 1; /* coreset0 is always interleaved */ + dciInfo->coresetCfg.regBundleSize = 6; /* spec-38.211 sec 7.3.2.2 */ + dciInfo->coresetCfg.interleaverSize = 2; /* spec-38.211 sec 7.3.2.2 */ + dciInfo->coresetCfg.coreSetType = 0; + dciInfo->coresetCfg.coreSetSize = coresetIdxTable[0][1]; + dciInfo->coresetCfg.shiftIndex = cellCb->cellCfg.phyCellId; + dciInfo->coresetCfg.precoderGranularity = 0; + dciInfo->coresetCfg.cceIndex = 0; /* 0-3 for UL and 4-7 for DL */ + dciInfo->coresetCfg.aggregationLevel = 4; /* same as for sib1 */ + + dciInfo->formatType = FORMAT0_0; + msg3HqProc->tbInfo.rvIdx++; + msg3HqProc->tbInfo.rv = schCmnDlRvTbl[msg3HqProc->tbInfo.rvIdx & 0x03]; + /* fill UL grant */ + dciInfo->format.format0_0.resourceAllocType = msg3HqProc->puschResType; + dciInfo->format.format0_0.freqAlloc.startPrb = msg3HqProc->puschStartPrb; + dciInfo->format.format0_0.freqAlloc.numPrb = msg3HqProc->puschNumPrb; + dciInfo->format.format0_0.timeAlloc.startSymb = msg3HqProc->strtSymbl; + dciInfo->format.format0_0.timeAlloc.numSymb = msg3HqProc->numSymbl; + dciInfo->format.format0_0.rowIndex = 0; /* row Index */ + dciInfo->format.format0_0.mcs = msg3HqProc->tbInfo.iMcs; + dciInfo->format.format0_0.harqProcId = msg3HqProc->procId; + dciInfo->format.format0_0.puschHopFlag = FALSE; /* disabled */ + dciInfo->format.format0_0.freqHopFlag = FALSE; /* disabled */ + dciInfo->format.format0_0.ndi = msg3HqProc->tbInfo.ndi; /* new transmission */ + dciInfo->format.format0_0.rv = msg3HqProc->tbInfo.rv; + dciInfo->format.format0_0.tpcCmd = 0; //Sphoorthi TODO: check + dciInfo->format.format0_0.sUlCfgd = FALSE; /* SUL not configured */ + + /* Fill DCI Structure */ + dciInfo->dciInfo.rnti = raCb->tcrnti; + dciInfo->dciInfo.scramblingId = cellCb->cellCfg.phyCellId; + dciInfo->dciInfo.scramblingRnti = 0; + dciInfo->dciInfo.cceIndex = 0; /* 0-3 for UL and 4-7 for DL */ + dciInfo->dciInfo.aggregLevel = 4; + dciInfo->dciInfo.beamPdcchInfo.numPrgs = 1; + dciInfo->dciInfo.beamPdcchInfo.prgSize = 1; + dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces = 0; + dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx = 0; + dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0] = 0; + dciInfo->dciInfo.txPdcchPower.powerValue = 0; + dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0; + dciInfo->dciInfo.pdschCfg = NULL; /* No DL data being sent */ + msg3HqProc->tbInfo.txCntr++; + + puschInfo->crnti = raCb->tcrnti; + puschInfo->harqProcId = msg3HqProc->procId; + puschInfo->resAllocType = msg3HqProc->puschResType; + puschInfo->fdAlloc.startPrb = msg3HqProc->puschStartPrb; + puschInfo->fdAlloc.numPrb = msg3HqProc->puschNumPrb; + puschInfo->tdAlloc.startSymb = msg3HqProc->strtSymbl; + puschInfo->tdAlloc.numSymb = msg3HqProc->numSymbl; + puschInfo->tbInfo.qamOrder = msg3HqProc->tbInfo.qamOrder; + puschInfo->tbInfo.mcs = msg3HqProc->tbInfo.iMcs; + puschInfo->tbInfo.mcsTable = msg3HqProc->tbInfo.mcsTable; + puschInfo->tbInfo.ndi = msg3HqProc->tbInfo.ndi; /* retransmission */ + puschInfo->tbInfo.rv = msg3HqProc->tbInfo.rvIdx; + puschInfo->tbInfo.tbSize = msg3HqProc->tbInfo.tbSzReq; + puschInfo->dmrsMappingType = msg3HqProc->dmrsMappingType; /* Setting Type-A */ + puschInfo->nrOfDmrsSymbols = msg3HqProc->nrOfDmrsSymbols; + puschInfo->dmrsAddPos = msg3HqProc->dmrsAddPos; + + return ROK; +} /******************************************************************* * @@ -661,12 +796,13 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSi * * Functionality: fills DCI for UL grant in response to BSR * - * @params[in] + * @params[in] SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, + * @params[in] bool isRetx, SchUlHqProcCb *hqP * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo) +uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP) { SchCellCb *cellCb = ueCb->cellCb; SchControlRsrcSet coreset1 ; @@ -936,7 +1072,6 @@ void deleteSchUeCb(SchUeCb *ueCb) uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0; SchPucchCfg *pucchCfg = NULLP; SchPdschConfig *pdschCfg = NULLP; - CmLListCp *lcLL = NULLP; if(ueCb) { @@ -979,26 +1114,6 @@ void deleteSchUeCb(SchUeCb *ueCb) SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); } - /*Clearing out Dedicated LC list*/ - if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) - { - lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); - deleteLcLL(lcLL); - SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); - } - if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) - { - lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList); - deleteLcLL(lcLL); - SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); - } - /*Deleteing the Default LC list*/ - lcLL = &(ueCb->dlLcPrbEst.defLcList); - deleteLcLL(lcLL); - - lcLL = &(ueCb->ulLcPrbEst.defLcList); - deleteLcLL(lcLL); - memset(ueCb, 0, sizeof(SchUeCb)); } } @@ -1287,11 +1402,63 @@ uint8_t MacSchCellDeleteReq(Pst *pst, SchCellDelete *cellDelete) DU_LOG("\nERROR --> SCH : MacSchCellDeleteReq(): failed to send Cell Delete response"); ret = RFAILED; } - } return ret; } +/******************************************************************* + * + * @brief Function updates DL HARQ Feedback + * + * @details + * + * Function : schUpdateHarqFdbk + * + * Functionality: Function updates DL HARQ feedback + * + * @params[in] SchUeCb *ueCb, UE cb struct pointer + * @params[in] uint8_t numHarq, number of HARQ processes in feedback + * @params[in] uint8_t *harqPayload, harq feedback payload received + * @params[in] SlotTimingInfo *slotInd, slot timing information + * @return void + * + * ****************************************************************/ +void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd) +{ + SchDlHqProcCb *hqP; + SchHqDlMap *hqDlMap; + CmLList *node; + uint8_t fdbkPos = 0; + + hqDlMap = ueCb->hqDlmap[slotInd->slot]; + if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE) + { + return; + } + if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING) + { + node = hqDlMap->hqList.first; + while(node) + { + hqP = (SchDlHqProcCb*)node->node; + node = node->next; + cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk); + /* + Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg. + case 1 semi static harq Ack/Nack codebook //Supported + case 2 dynamic harq ACK/NACK codebook //Not supported + */ + schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used + } + } + else + { + node = hqDlMap->hqList.first; + hqP = (SchDlHqProcCb*)node->node; + cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk); + schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]); + } +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_utils.c b/src/5gnrsch/sch_utils.c index 140efc8b9..d77ec860b 100644 --- a/src/5gnrsch/sch_utils.c +++ b/src/5gnrsch/sch_utils.c @@ -773,6 +773,7 @@ uint8_t minMsg3SchTime[MAX_NUM_MU] = {6, 6, 6, 6}; uint8_t defaultUlAckTbl[DEFAULT_UL_ACK_LIST_COUNT]= {1, 2, 3 , 4, 5, 6, 7, 8}; +uint8_t schCmnDlRvTbl[4] = {0, 2, 3, 1}; /** * @brief Function to find first DMRS symbol in PDSCH * @@ -1465,7 +1466,6 @@ LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLL action) uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize) { LcInfo *lcNode = NULLP; - lcNode = handleLcLList(lcLL, lcId, CREATE); if(lcNode == NULLP) @@ -1473,8 +1473,9 @@ uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize) DU_LOG("\nERROR --> SCH : LC is neither present nor able to create in List lcId:%d",lcId); return RFAILED; } + lcNode->reqBO = payloadSize; - lcNode->allocBO = 0; + lcNode->allocBO = 0; lcNode->allocPRB = 0; /*Re-Initializing the AllocPRB*/ return ROK; } diff --git a/src/5gnrsch/sch_utils.h b/src/5gnrsch/sch_utils.h index 273164263..5d3d41e5d 100644 --- a/src/5gnrsch/sch_utils.h +++ b/src/5gnrsch/sch_utils.h @@ -107,7 +107,7 @@ uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4]; uint8_t puschDeltaTable[MAX_MU_PUSCH]; uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8]; uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5]; - +uint8_t schCmnDlRvTbl[4]; /* Functions declarations : Linked list handler */ uint8_t addNodeToLList(CmLListCp *llist, void *blockToAdd, CmLList *currNode); uint8_t deleteNodeFromLList(CmLListCp *llist, CmLList *node); diff --git a/src/cm/cm_llist.c b/src/cm/cm_llist.c index 1cc4092aa..e8c02510c 100644 --- a/src/cm/cm_llist.c +++ b/src/cm/cm_llist.c @@ -370,6 +370,32 @@ CmLListCp *list2 /*-- node to be added --*/ return; } /*-- end of cmLListCatLList --*/ + +/*-- + * + * Fun: cmLListDeleteLList + * + * Desc: delete a linked list + * + * Ret: None + * + * Notes: None + * + * File: cm_llist.c + * + --*/ +Void cmLListDeleteLList +( +CmLListCp *list /*-- list control point --*/ +) +{ + while(list->count) + { + cmLListDelFrm(list, list->first); + } + return; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/cm_llist.x b/src/cm/cm_llist.x index acafe771c..40e414838 100755 --- a/src/cm/cm_llist.x +++ b/src/cm/cm_llist.x @@ -64,7 +64,7 @@ Void cmLListInsCrnt ARGS ((CmLListCp *lList, CmLList *node)); Void cmLListInsAfterCrnt ARGS ((CmLListCp *lList, CmLList *node)); CmLList *cmLListDelFrm ARGS ((CmLListCp *lList, CmLList *node)); Void cmLListCatLList ARGS (( CmLListCp *list1, CmLListCp *list2)); - +Void cmLListDeleteLList ARGS ((CmLListCp *lList)); #ifdef __cplusplus } #endif diff --git a/src/cm/common_def.h b/src/cm/common_def.h index 1678c8f61..0ed59eed5 100644 --- a/src/cm/common_def.h +++ b/src/cm/common_def.h @@ -63,6 +63,8 @@ #define MAX_NUM_SRB 3 /* Max. no of Srbs */ #define MAX_NUM_DRB 29 /* spec 38.331, maxDRB */ #define MAX_NUM_SSB 64 /* spec 28.331, maxNrofSSBs */ +#define MAX_NUM_HARQ_PROC 16 /* spec 38.331, nrofHARQ-ProcessesForPDSCH */ +#define MAX_NUM_TB_PER_UE 2 /* spec 38.331, maxNrofCodeWordsScheduledByDCI */ /* 5G ORAN phy delay */ #define PHY_DELTA_DL 1 diff --git a/src/cm/mac_sch_interface.c b/src/cm/mac_sch_interface.c index ec64f2978..9d1cd0e3f 100644 --- a/src/cm/mac_sch_interface.c +++ b/src/cm/mac_sch_interface.c @@ -326,6 +326,36 @@ uint8_t packMacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd) return ROK; } +/******************************************************************* + * + * @brief Pack and Send HARQ UCI Ind from MAC to SCH + * + * @details + * + * Function : packMacHarqSchUciInd + * + * Functionality: + * Pack and Send HARQ UCI Ind from MAC to SCH + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t packMacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd) +{ + if((pst->selector == ODU_SELECTOR_LC) || (pst->selector == ODU_SELECTOR_LWLC)) + { + /* TODO */ + } + else + { + return RFAILED; + } + return ROK; +} + + /******************************************************************* * * @brief Pack and Send Modify UE Config Request from MAC to SCH @@ -685,6 +715,26 @@ uint8_t packSchMacDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc) { return ROK; } + +/** + * @brief function to pack Harq process release message + * from SCH to MAC + * + * @details + * + * Function : packSchMacDlReleaseHarq + * + * + * @param[in] Pst *pst, the post structure + * @param[in] SchRlsHqInfo *rlsHqInfo + * @return S16 + * -# ROK + **/ +uint8_t packSchMacDlReleaseHarq(Pst *pst, SchRlsHqInfo *rlsHqInfo) +{ + return ROK; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/mac_sch_interface.h b/src/cm/mac_sch_interface.h index ddc0410ed..1ab00fb56 100644 --- a/src/cm/mac_sch_interface.h +++ b/src/cm/mac_sch_interface.h @@ -46,7 +46,7 @@ #define EVENT_RACH_RESOURCE_RELEASE_TO_SCH 27 #define EVENT_PAGING_IND_TO_SCH 28 #define EVENT_DL_PAGING_ALLOC 29 - +#define EVENT_DL_REL_HQ_PROC 30 /*macros*/ #define MAX_SSB_IDX 1 /* forcing it as 1 for now. Right value is 64 */ #define SCH_SSB_MASK_SIZE 1 @@ -67,6 +67,7 @@ #define MAX_NUMBER_OF_CRC_IND_BITS 1 #define MAX_NUMBER_OF_UCI_IND_BITS 1 #define MAX_SR_BITS_IN_BYTES 1 +#define MAX_HARQ_BITS_IN_BYTES 1 #define MAX_NUM_LOGICAL_CHANNEL_GROUPS 8 #define MAX_NUM_SR_CFG_PER_CELL_GRP 8 /* Max number of scheduling request config per cell group */ #define MAX_NUM_TAGS 4 /* Max number of timing advance groups */ @@ -633,6 +634,7 @@ typedef struct schRachCfg uint8_t raContResTmr; /* RA Contention Resoultion Timer */ uint8_t rsrpThreshSsb; /* RSRP Threshold SSB */ uint8_t raRspWindow; /* RA Response Window */ + uint8_t maxMsg3Tx; /* MAximum num of msg3 tx*/ }SchRachCfg; typedef struct schBwpParams @@ -763,6 +765,13 @@ typedef struct schPlmnInfoList Snssai **snssai; /* List of supporting snssai*/ }SchPlmnInfoList; +typedef struct schHqCfgParam +{ + uint8_t maxDlDataHqTx; + uint8_t maxMsg4HqTx; + uint8_t maxUlDataHqTx; +}SchHqCfg; + typedef struct schCellCfg { uint16_t cellId; /* Cell Id */ @@ -778,6 +787,7 @@ typedef struct schCellCfg SchBwpDlCfg schInitialDlBwp; /* Initial DL BWP */ SchBwpUlCfg schInitialUlBwp; /* Initial UL BWP */ SchPlmnInfoList plmnInfoList; /* Consits of PlmnId and Snssai list */ + SchHqCfg schHqCfg; #ifdef NR_TDD TDDCfg tddCfg; /* TDD Cfg */ #endif @@ -884,6 +894,7 @@ typedef struct lcSchInfo typedef struct dlMsgSchedInfo { + bool isRetx; uint8_t numLc; LcSchInfo lcSchInfo[MAX_NUM_LC]; /* Scheduled LC info */ BwpCfg bwp; @@ -1696,6 +1707,15 @@ typedef struct srUciIndInfo uint8_t srPayload[MAX_SR_BITS_IN_BYTES]; }SrUciIndInfo; +typedef struct harqUciIndInfo +{ + uint16_t cellId; + uint16_t crnti; + SlotTimingInfo slotInd; + uint8_t numHarq; + uint8_t harqPayload[MAX_HARQ_BITS_IN_BYTES]; +}HarqUciIndInfo; + typedef struct schRrmPolicyRatio { uint8_t policyMaxRatio; @@ -1737,6 +1757,19 @@ typedef struct schPageInd uint8_t *pagePdu; }SchPageInd; +typedef struct schUeHqInfo +{ + uint16_t crnti; + uint8_t hqProcId; +}SchUeHqInfo; + +typedef struct schRlsHqInfo +{ + uint16_t cellId; + uint8_t numUes; + SchUeHqInfo *ueHqInfo; +}SchRlsHqInfo; + /* function pointers */ typedef uint8_t (*SchCellCfgCfmFunc) ARGS(( Pst *pst, /* Post Structure */ @@ -1792,6 +1825,10 @@ typedef uint8_t (*MacSchBsrFunc) ARGS(( UlBufferStatusRptInd *bsrInd )); +typedef uint8_t (*MacSchHarqUciIndFunc) ARGS(( + Pst *pst, /* Post structure */ + HarqUciIndInfo *uciInd)); /* UCI IND Info */ + typedef uint8_t (*MacSchSrUciIndFunc) ARGS(( Pst *pst, /* Post structure */ SrUciIndInfo *uciInd)); /* UCI IND Info */ @@ -1854,6 +1891,10 @@ typedef uint8_t (*MacSchPagingIndFunc) ARGS(( Pst *pst, /* Post structure */ SchPageInd *schPagingInd)); /* Paging Indication */ +typedef uint8_t (*SchMacDlReleaseHarqFunc) ARGS(( + Pst *pst, /* Post structure */ + SchRlsHqInfo *rlsHqInfo)); /* Release Harq proc */ + /* function declarations */ uint8_t packMacSchSlotInd(Pst *pst, SlotTimingInfo *slotInd); uint8_t packSchMacDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo); @@ -1882,6 +1923,8 @@ uint8_t unpackMacSchSlotInd(MacSchSlotIndFunc func, Pst *pst, Buffer *mBuf); uint8_t packMacSchBsr(Pst *pst, UlBufferStatusRptInd *bsrInd); uint8_t MacSchBsr(Pst *pst, UlBufferStatusRptInd *bsrInd); uint8_t packMacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd); +uint8_t packMacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd); +uint8_t MacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd); uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd); uint8_t packMacSchModUeConfigReq(Pst *pst, SchUeCfg *ueCfgToSch); uint8_t MacSchModUeConfigReq(Pst *pst, SchUeCfg *ueCfgToSch); @@ -1913,6 +1956,8 @@ uint8_t packMacSchPagingInd(Pst *pst, SchPageInd *pageInd); uint8_t MacSchPagingInd(Pst *pst, SchPageInd *pageInd); uint8_t packSchMacDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc); uint8_t MacProcDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc); +uint8_t packSchMacDlReleaseHarq(Pst *pst, SchRlsHqInfo *rlsHqInfo); +uint8_t MacSchReleaseDlHarqProc(Pst *pst, SchRlsHqInfo *rlsHqInfo); /********************************************************************** End of file **********************************************************************/ diff --git a/src/phy_stub/phy_stub_msg_hdl.c b/src/phy_stub/phy_stub_msg_hdl.c index c3d33ae8a..830333350 100644 --- a/src/phy_stub/phy_stub_msg_hdl.c +++ b/src/phy_stub/phy_stub_msg_hdl.c @@ -285,10 +285,36 @@ void l1HdlConfigReq(uint32_t msgLen, void *msg) * RFAILED - failure * * ****************************************************************/ -uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn) +uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn, fapi_ul_pusch_pdu_t puschPdu) { + uint8_t result[]={0,//MSG3 + 0,//BSR + 0,//MSG5 RRC Setup Complete + 0,//Security Mode Complete + 0,//Registraion Complete + 0,//RRC Reconfiguration Complete + 0,//UL DATA -1 + 0,//UL DATA -2 + 0,//UL DATA -3 + 0,//UL DATA -4 + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + #ifdef INTEL_FAPI uint8_t idx = 0; + static uint8_t ind=0; + uint16_t ret = ROK; fapi_crc_ind_t *crcInd; MAC_ALLOC(crcInd, sizeof(fapi_crc_ind_t)); @@ -304,12 +330,17 @@ uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn) crcInd->slot = slot; crcInd->numCrcs = 1; - crcInd->crc[idx].handle = 0; - crcInd->crc[idx].rnti = 0; - crcInd->crc[idx].harqId = 0; + crcInd->crc[idx].handle = puschPdu.handle; + crcInd->crc[idx].rnti = puschPdu.rnti; + crcInd->crc[idx].harqId = puschPdu.puschData.harqProcessId; crcInd->crc[idx].tbCrcStatus = 0; crcInd->crc[idx].numCb = 1; - crcInd->crc[idx].cbCrcStatus[0] = 0; + crcInd->crc[idx].cbCrcStatus[0] = result[ind%50]; + ret = (0== crcInd->crc[idx].cbCrcStatus[0])?ROK:RFAILED; + /*TBD: To use crc ind with random number and percentage */ + //crcInd->crc[idx].cbCrcStatus[0] = (crcPassPer >= rand()%(100))?0:1; + + ind++; crcInd->crc[idx].ul_cqi = 0; crcInd->crc[idx].timingAdvance = 0; crcInd->crc[idx].rssi = 0; @@ -317,12 +348,12 @@ uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn) fillMsgHeader(&crcInd->header, FAPI_CRC_INDICATION, \ sizeof(fapi_crc_ind_t) - sizeof(fapi_msg_t)); - /* Sending RACH indication to MAC */ + /* Sending CRC indication to MAC */ DU_LOG("\nINFO --> PHY STUB: Sending CRC Indication to MAC"); procPhyMessages(crcInd->header.msg_id, sizeof(fapi_crc_ind_t), (void *)crcInd); MAC_FREE(crcInd, sizeof(fapi_crc_ind_t)); #endif - return ROK; + return ret; } /* l1BuildAndSendCrcInd */ #ifdef INTEL_FAPI @@ -890,9 +921,35 @@ S16 l1HdlTxDataReq(uint16_t msgLen, void *msg) uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu_t pucchPdu) { uint8_t idx = 0; + static uint8_t ind=0; + uint8_t result[]={0,//msg4 + 0,//Security Mode Command + 0,//Registration Accept + 0,//RRC Reconfiguration + 0,//Data 1 + 0,//Data 2 + 0,//Data 3 + 0,//Data 4 + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0,}; pduInfo->handle = pucchPdu.handle; pduInfo->pduBitmap = 1; //hardcoded for SR + if (pucchPdu.bitLenHarq) + { + pduInfo->pduBitmap |= HARQ_PDU_BITMASK; + } pduInfo->pucchFormat = pucchPdu.formatType; pduInfo->ul_cqi = 0; pduInfo->rnti = pucchPdu.rnti; @@ -900,8 +957,11 @@ uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu pduInfo->rssi = 0; if(pduInfo->pduBitmap & SR_PDU_BITMASK) { - pduInfo->srInfo.srIndication = SR_DETECTED; - pduInfo->srInfo.srConfidenceLevel = CONFDC_LEVEL_GOOD; + if (result[ind%50] == 0) + { + pduInfo->srInfo.srIndication = SR_DETECTED; + pduInfo->srInfo.srConfidenceLevel = CONFDC_LEVEL_GOOD; + } } if(pduInfo->pduBitmap & HARQ_PDU_BITMASK) { @@ -909,7 +969,10 @@ uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu pduInfo->harqInfo.harqConfidenceLevel = CONFDC_LEVEL_GOOD; for(idx = 0; idx < pduInfo->harqInfo.numHarq; idx++) { - pduInfo->harqInfo.harqValue[idx] = HARQ_PASS; + pduInfo->harqInfo.harqValue[idx] = result[ind%50]; + ind++; + /*TBD: To use harq ind with random number and percentage*/ + //pduInfo->harqInfo.harqValue[idx] = (dlHqPassPer >= rand()%(100))?HARQ_PASS:HARQ_FAIL; } } return ROK; @@ -1062,7 +1125,10 @@ S16 l1HdlUlTtiReq(uint16_t msgLen, void *msg) if(ulTtiReq->pdus[numPdus-1].pduType == 1) { DU_LOG("\nINFO --> PHY STUB: PUSCH PDU"); - l1BuildAndSendRxDataInd(ulTtiReq->slot, ulTtiReq->sfn, ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu); + if (ROK == l1BuildAndSendCrcInd(ulTtiReq->slot, ulTtiReq->sfn,ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu)) + { + l1BuildAndSendRxDataInd(ulTtiReq->slot, ulTtiReq->sfn, ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu); + } } if(ulTtiReq->pdus[numPdus-1].pduType == 2) { @@ -1088,6 +1154,7 @@ S16 l1HdlUlTtiReq(uint16_t msgLen, void *msg) l1BuildAndSendRachInd(ulTtiReq->slot, ulTtiReq->sfn, CB_RA_PREAMBLE_IDX); phyDb.ueDb.numActvUe++; } + #if 0 /* Send RACH Ind to L2 for second UE */ if(phyDb.ueDb.ueCb[UE_IDX_1].rachIndSent == false && ulTtiReq->sfn == 304 && ulTtiReq->slot == 0)