#include "du_app_mac_inf.h"
#include "mac_sch_interface.h"
#include "sch.h"
+#include "sch_tmr.h"
#include "sch_utils.h"
#ifdef NR_DRX
#include "sch_drx.h"
#endif
-SchMacDlAllocFunc schMacDlAllocOpts[] =
-{
- packSchMacDlAlloc,
- MacProcDlAlloc,
- packSchMacDlAlloc
-};
-
-SchMacDlPageAllocFunc schMacDlPageAllocOpts[] =
-{
- packSchMacDlPageAlloc,
- MacProcDlPageAlloc,
- packSchMacDlPageAlloc
-};
-
/*******************************************************************
*
* @brief Handles sending DL broadcast alloc to MAC
FILL_PST_SCH_TO_MAC(pst, inst);
pst.event = EVENT_DL_SCH_INFO;
- return(*schMacDlAllocOpts[pst.selector])(&pst, dlSchedInfo);
+ return(MacMessageRouter(&pst, (void *)dlSchedInfo));
+}
+
+/*******************************************************************
+ *
+ * @brief
+ *
+ * @details
+ *
+ * Function : schFillBoGrantDlSchedInfo
+ *
+ * Functionality:
+
+ *
+ * @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 isRetx, SchDlHqProcCb **hqP)
+{
+ uint8_t pdschNumSymbols = 0, pdschStartSymbol = 0;
+ uint8_t lcIdx = 0;
+ uint16_t startPrb = 0;
+ uint16_t crnti = 0;
+ uint32_t accumalatedSize = 0;
+ SchUeCb *ueCb = NULLP;
+ DlMsgSchInfo *dciSlotAlloc, *dlMsgAlloc;
+ SlotTimingInfo pdcchTime, pdschTime, pucchTime;
+ SchPdcchAllocInfo pdcchAllocInfo;
+
+ GET_CRNTI(crnti,ueId);
+ ueCb = &cell->ueCb[ueId-1];
+
+ if (isRetx == FALSE)
+ {
+ if(schDlGetAvlHqProcess(cell, ueCb, hqP) != ROK)
+ {
+ return false;
+ }
+ }
+
+ memset(&pdcchAllocInfo,0,sizeof(SchPdcchAllocInfo));
+ if(findValidK0K1Value(cell, currTime, ueId, ueCb->k0K1TblPrsnt,\
+ &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, \
+ &pucchTime, isRetx, *hqP, &pdcchAllocInfo) != 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)
+ {
+
+ SCH_ALLOC(dciSlotAlloc, sizeof(DlMsgSchInfo));
+ if(!dciSlotAlloc)
+ {
+ DU_LOG("\nERROR --> SCH : Memory Allocation failed for ded DL msg alloc");
+ return false;
+ }
+ cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = dciSlotAlloc;
+ memset(dciSlotAlloc, 0, sizeof(DlMsgSchInfo));
+ }
+ else
+ {
+ dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1];
+ }
+ /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
+ fillDlMsgInfo(dciSlotAlloc, crnti, isRetx, *hqP);
+ dciSlotAlloc->transportBlock[0].ndi = isRetx;
+
+ accumalatedSize = cell->api->SchScheduleDlLc(pdcchTime, pdschTime, pdschNumSymbols, &startPrb, isRetx, hqP);
+ /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
+ if (!accumalatedSize)
+ return false;
+
+ /*[Step6]: pdcch and pdsch data is filled */
+ if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb,\
+ pdschStartSymbol, pdschNumSymbols, isRetx, *hqP, pdcchAllocInfo)) != ROK)
+ {
+ DU_LOG("\nERROR --> SCH : Scheduling of DL dedicated message failed");
+
+ /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+ if(!dciSlotAlloc->dlMsgPdschCfg)
+ {
+ SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
+ cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+ }
+ return false;
+ }
+
+ /* TODO : Update the scheduling byte report for multiple LC based on QCI
+ * and Priority */
+ /* As of now, the total number of bytes scheduled for a slot is divided
+ * equally amongst all LC with pending data. This is avoid starving of any
+ * LC
+ * */
+#if 0
+ accumalatedSize = accumalatedSize/dlMsgAlloc->numLc;
+ for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++)
+ dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize;
+#endif
+
+ /* Check if both DCI and DL_MSG are sent in the same slot.
+ * If not, allocate memory for DL_MSG PDSCH slot to store PDSCH info */
+
+ if(pdcchTime.slot == pdschTime.slot)
+ {
+ SCH_ALLOC(dciSlotAlloc->dlMsgPdschCfg, sizeof(PdschCfg));
+ if(!dciSlotAlloc->dlMsgPdschCfg)
+ {
+ DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciSlotAlloc->dlMsgPdschCfg");
+ SCH_FREE(dciSlotAlloc->dlMsgPdcchCfg, sizeof(PdcchCfg));
+ SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
+ cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
+ return false;
+ }
+ memcpy(dciSlotAlloc->dlMsgPdschCfg,\
+ &dciSlotAlloc->dlMsgPdcchCfg->dci[dciSlotAlloc->dlMsgPdcchCfg->numDlDci - 1].pdschCfg, sizeof(PdschCfg));
+ }
+ else
+ {
+ /* Allocate memory to schedule dlMsgAlloc to send DL_Msg, pointer will be checked at schProcessSlotInd() */
+ if(cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] == NULLP)
+ {
+ SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgSchInfo));
+ if(dlMsgAlloc == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH : Memory Allocation failed for dlMsgAlloc");
+ SCH_FREE(dciSlotAlloc->dlMsgPdcchCfg, sizeof(PdcchCfg));
+ if(dciSlotAlloc->dlMsgPdschCfg == NULLP)
+ {
+ SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
+ cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
+ }
+ return false;
+ }
+ cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = dlMsgAlloc;
+ memset(dlMsgAlloc, 0, sizeof(DlMsgSchInfo));
+ }
+ else
+ dlMsgAlloc = cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1];
+
+ /* Copy all DL_MSG info */
+ dlMsgAlloc->crnti =crnti;
+ dlMsgAlloc->bwp = dciSlotAlloc->bwp;
+ SCH_ALLOC(dlMsgAlloc->dlMsgPdschCfg, sizeof(PdschCfg));
+ if(dlMsgAlloc->dlMsgPdschCfg)
+ {
+ memcpy(dlMsgAlloc->dlMsgPdschCfg,\
+ &dciSlotAlloc->dlMsgPdcchCfg->dci[dciSlotAlloc->dlMsgPdcchCfg->numDlDci - 1].pdschCfg, sizeof(PdschCfg));
+ }
+ else
+ {
+ SCH_FREE(dciSlotAlloc->dlMsgPdcchCfg, sizeof(PdcchCfg));
+ if(dciSlotAlloc->dlMsgPdschCfg == NULLP)
+ {
+ SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
+ cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
+
+ }
+ SCH_FREE(dlMsgAlloc, sizeof(DlMsgSchInfo));
+ cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
+ DU_LOG("\nERROR --> SCH : Memory Allocation failed for dlMsgAlloc->dlMsgPdschCfg");
+ return false;
+ }
+ }
+
+ cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId;
+
+ /*Re-setting the BO's of all DL LCs in this UE*/
+ for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+ {
+ ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+ }
+
+ /* after allocation is done, unset the bo bit for that ue */
+ UNSET_ONE_BIT(ueId, cell->boIndBitMap);
+ return true;
}
/*******************************************************************
FILL_PST_SCH_TO_MAC(pst, inst);
pst.event = EVENT_DL_PAGING_ALLOC;
- return(*schMacDlPageAllocOpts[pst.selector])(&pst, dlPageAlloc);
-
+ return(MacMessageRouter(&pst, (void *)dlPageAlloc));
}
/*******************************************************************
{
uint8_t ssb_rep;
- ssb_rep = cell->cellCfg.ssbSchCfg.ssbPeriod;
+ ssb_rep = cell->cellCfg.ssbPeriod;
/* Identify SSB ocassion*/
if ((slotTime.sfn % SCH_MIB_TRANS == 0) && (slotTime.slot ==0))
}
else if(cell->firstSib1Transmitted)
{
- if((slotTime.sfn % (cell->cellCfg.sib1SchCfg.sib1RepetitionPeriod/10) == 0) &&
+ if((slotTime.sfn % (SIB1_REPETITION_PERIOD/10) == 0) &&
(slotTime.slot == 0))
{
return REPEATITION;
*******************************************************************/
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)
+ SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP,
+ SchPdcchAllocInfo *pdcchAllocInfo)
{
uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ;
uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0;
+ uint8_t ret = RFAILED;
SchUeCb *ueCb = NULLP;
SchK0K1TimingInfoTbl *k0K1InfoTbl;
}
#endif
- if(cell->schDlSlotInfo[pdcchTime->slot]->pdcchUe != 0)
- {
- return false;
- }
-
+ ueCb = &cell->ueCb[ueId-1];
if(dedMsg == true)
{
- ueCb = &cell->ueCb[ueId-1];
- k0K1InfoTbl = &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1InfoTbl;
+ k0K1InfoTbl = &ueCb->k0K1InfoTbl;
+ if(schDlCandidateSelection(ueCb, *pdcchTime, pdcchAllocInfo) == false)
+ {
+ DU_LOG("\nDEBUG --> SCH: DL candidate Selection failed bcz PDCCH is unavailable for this slot");
+ return false;
+ }
}
else
{
- k0K1InfoTbl = &cell->cellCfg.schInitialDlBwp.k0K1InfoTbl;
+ k0K1InfoTbl = &cell->k0K1InfoTbl;
}
numK0 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].numK0;
k0Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k0Index;
if(dedMsg != true)
{
- k0Val = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0;
- *pdschStartSymbol = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].startSymbol;
- *pdschSymblLen = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].lengthSymbol;
+ k0Val = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0;
+ *pdschStartSymbol = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].startSymbol;
+ *pdschSymblLen = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].lengthSymbol;
}
else
{
*pdschStartSymbol = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].startSymbol;
*pdschSymblLen = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].symbolLength;
}
+ else
+ {
+ k0Val = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0;
+ *pdschStartSymbol = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].startSymbol;
+ *pdschSymblLen = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].lengthSymbol;
+ }
}
ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val, cell->numSlots);
continue;
}
#endif
- if(cell->schDlSlotInfo[pdschTime->slot]->pdschUe != 0)
- {
- continue;
- }
numK1 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.numK1;
for(k1TblIdx = 0; k1TblIdx < numK1; k1TblIdx++)
{
k1Val = ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index];
}
+ else
+ {
+ k1Val = defaultUlAckTbl[k1Index];
+ }
}
ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val, cell->numSlots);
#ifdef NR_TDD
{
ADD_DELTA_TO_TIME((*pucchTime), hqP->pucchTime, 0, cell->numSlots);
}
- 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;
-}
-
-/*******************************************************************
- *
- * @brief
- *
- * @details
- *
- * Function : schFillBoGrantDlSchedInfo
- *
- * Functionality:
-
- *
- * @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 isRetx, SchDlHqProcCb **hqP)
-{
- uint8_t lcIdx = 0;
- uint8_t pdschNumSymbols = 0, pdschStartSymbol = 0;
- uint16_t startPrb = 0, maxFreePRB = 0;
- uint16_t crnti = 0, mcsIdx = 0;
- uint32_t accumalatedSize = 0;
- SchUeCb *ueCb = NULLP;
- CmLListCp *lcLL = NULLP;
- DlMsgAlloc *dciSlotAlloc, *dlMsgAlloc;
- SlotTimingInfo pdcchTime, pdschTime, pucchTime;
- uint16_t rsvdDedicatedPRB = 0;
+ pdcchTime->cellId = cell->cellId;
+ pdschTime->cellId = cell->cellId;
- /* 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];
+ cell->schUlSlotInfo[pucchTime->slot]->pucchUe = ueId;
- if (isRetx == FALSE)
- {
- if(schDlGetAvlHqProcess(cell, ueCb, hqP) != ROK)
- {
- return false;
- }
- }
-
- if(findValidK0K1Value(cell, currTime, ueId, ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1TblPrsnt,\
- &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)
- {
-
- SCH_ALLOC(dciSlotAlloc, sizeof(DlMsgAlloc));
- if(!dciSlotAlloc)
- {
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for ded DL msg alloc");
- return false;
- }
- cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = dciSlotAlloc;
- memset(dciSlotAlloc, 0, sizeof(DlMsgAlloc));
- dciSlotAlloc->crnti = crnti;
- }
- else
- {
- 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, isRetx, *hqP);
- dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].isRetx = isRetx;
-
-
- if (isRetx == FALSE)
- {
- /*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(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 = &((*hqP)->dlLcPrbEst.dedLcList);
- rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
- }
- else
- {
- 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);
-
- /* 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));
-
- /*TRUE because this UE has nothing to be scheduled*/
- return true;
- }
- }
-
- /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
- maxFreePRB = searchLargestFreeBlock(cell, pdschTime, &startPrb, DIR_DL);
-
- /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
- * the list based on RRM policy*/
-
- /*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(isRetx == FALSE)
- {
- if(maxFreePRB != 0)
- {
- 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 (isRetx == FALSE)
- {
- if((*hqP)->dlLcPrbEst.dedLcList.count != 0)
- updateGrantSizeForBoRpt(&((*hqP)->dlLcPrbEst.dedLcList), 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)
- {
- if(maxFreePRB == 0)
- {
- DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
- }
- else
- {
- /*Schedule the LC for next slot*/
- DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
- }
- /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
- * Allocation can be done in next slot*/
- return false;
- }
-
- /*[Step6]: pdcch and pdsch data is filled */
- if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols, isRetx, *hqP)) != ROK)
- {
- DU_LOG("\nERROR --> SCH : Scheduling of DL dedicated message 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;
- }
-
- /* TODO : Update the scheduling byte report for multiple LC based on QCI
- * and Priority */
- /* As of now, the total number of bytes scheduled for a slot is divided
- * equally amongst all LC with pending data. This is avoid starving of any
- * LC
- * */
-#if 0
- accumalatedSize = accumalatedSize/dlMsgAlloc->numLc;
- for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++)
- dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize;
-#endif
-
- /* Check if both DCI and DL_MSG are sent in the same slot.
- * If not, allocate memory for DL_MSG PDSCH slot to store PDSCH info */
-
- if(pdcchTime.slot == pdschTime.slot)
- {
- dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pduPres = BOTH;
- dciSlotAlloc->numSchedInfo++;
- }
- else
- {
- /* Allocate memory to schedule dlMsgAlloc to send DL_Msg, pointer will be checked at schProcessSlotInd() */
- if(cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] == NULLP)
- {
- SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgAlloc));
- if(dlMsgAlloc == NULLP)
+ /*Availability of PUCCH for HARQ resources*/
+ ret = schAllocPucchResource(cell, *pucchTime, ueCb, hqP, pdcchAllocInfo);
+ if(ret == RFAILED)
{
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for dlMsgAlloc");
- if(dciSlotAlloc->numSchedInfo == 0)
- {
- SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
- cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
- }
- else
- memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+ /*DL allocation can't go through as PUCCH is unavailable*/
return false;
}
- cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = dlMsgAlloc;
- memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
- dlMsgAlloc->crnti = dciSlotAlloc->crnti;
+ return true;
}
- else
- dlMsgAlloc = cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1];
-
- /* Copy all DL_MSG info */
- memcpy(&dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo], \
- &dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], sizeof(DlMsgSchInfo));
- dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].dlMsgPdcchCfg.dci.pdschCfg = \
- &dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].dlMsgPdschCfg;
-
- /* Assign correct PDU types in corresponding slots */
- dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].pduPres = PDSCH_PDU;
- dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pduPres = PDCCH_PDU;
- dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pdschSlot = pdschTime.slot;
-
- dciSlotAlloc->numSchedInfo++;
- dlMsgAlloc->numSchedInfo++;
}
- 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;
+ /*
+ * 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;
}
/*******************************************************************
break;
}
/*Fill PDCCH: PDCCH Cfg is same as SIB1 as Paging will be a broadcast message*/
- memcpy(&dlPageAlloc.pagePdcchCfg, &cell->cellCfg.sib1SchCfg.sib1PdcchCfg, sizeof(PdcchCfg));
- dlPageAlloc.pagePdcchCfg.dci.rnti = P_RNTI;
-
+ memcpy(dlPageAlloc.pageDlDci.freqDomainResource, cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.freqDomainResource, 6 * sizeof(uint8_t));
+ dlPageAlloc.pageDlDci.durationSymbols = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.durationSymbols;
+ dlPageAlloc.pageDlDci.cceRegMappingType = INTERLEAVED_CCE_REG_MAPPING;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.regBundleSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.regBundleSize;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.interleaverSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.interleaverSize;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.shiftIndex = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.shiftIndex;
+ dlPageAlloc.pageDlDci.ssStartSymbolIndex = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.startSymbolIndex;
+ dlPageAlloc.pageDlDci.cceIndex = cell->sib1SchCfg.sib1PdcchCfg.dci[0].cceIndex;
+ dlPageAlloc.pageDlDci.aggregLevel = cell->sib1SchCfg.sib1PdcchCfg.dci[0].aggregLevel;
+ dlPageAlloc.pageDlDci.precoderGranularity = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.precoderGranularity;
+ dlPageAlloc.pageDlDci.coreSetSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.coreSetSize;
/*Fill BWP*/
- memcpy(&dlPageAlloc.bwp, &cell->cellCfg.sib1SchCfg.bwp, sizeof(BwpCfg));
+ memcpy(&dlPageAlloc.bwp, &cell->sib1SchCfg.bwp, sizeof(BwpCfg));
/*Fill PDSCH*/
- if(schFillPagePdschCfg(cell, &dlPageAlloc.pagePdschCfg, pdschTime, tbSize, pageInfo->mcs, startPrb) != ROK)
+ if(schFillPagePdschCfg(cell, &dlPageAlloc.pageDlSch, pdschTime, tbSize, pageInfo->mcs, startPrb) != ROK)
{
DU_LOG("\nERROR --> SCH: Issue in PDSCH Allocation for Paging at SFN:%d, SLOT:%d",\
pdschTime.sfn, pdschTime.slot);
break;
}
- dlPageAlloc.pagePdcchCfg.dci.pdschCfg = &dlPageAlloc.pagePdschCfg;
/*Fill Page PDU information*/
- dlPageAlloc.dlPagePduLen = pageInfo->msgLen;
+ dlPageAlloc.pageDlSch.dlPagePduLen = pageInfo->msgLen;
- SCH_ALLOC(dlPageAlloc.dlPagePdu, sizeof(dlPageAlloc.dlPagePduLen));
+ SCH_ALLOC(dlPageAlloc.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
- if(dlPageAlloc.dlPagePdu == NULLP)
+ if(dlPageAlloc.pageDlSch.dlPagePdu == NULLP)
{
DU_LOG("\nERROR --> SCH: Memory Allocation Failed during Page Resource allocation");
break;
}
- memcpy(dlPageAlloc.dlPagePdu, pageInfo->pagePdu, dlPageAlloc.dlPagePduLen);
+ memcpy(dlPageAlloc.pageDlSch.dlPagePdu, pageInfo->pagePdu, dlPageAlloc.pageDlSch.dlPagePduLen);
/* Send msg to MAC */
if(sendDlPageAllocToMac(&dlPageAlloc, schInst) != ROK)
{
DU_LOG("\nERROR --> SCH : Sending DL Paging allocation from SCH to MAC failed");
- SCH_FREE(dlPageAlloc.dlPagePdu, sizeof(dlPageAlloc.dlPagePduLen));
+ SCH_FREE(dlPageAlloc.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
break;
}
ret = ROK;
*
* @details
*
- * Function : schProcessSlotInd
+ * Function : SchProcSlotInd
*
* Functionality:
* Handles TTI indication received from PHY
* RFAILED - failure
*
* ****************************************************************/
-uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
+uint8_t SchProcSlotInd(Pst *pst, SlotTimingInfo *slotInd)
{
- uint8_t ueId, ueIdx, ret = ROK;
- uint16_t slot;
- bool isRarPending = false, isRarScheduled = false;
- bool isMsg4Pending = false, isMsg4Scheduled = false;
- bool isUlGrantPending = false, isUlGrantScheduled = false;
- bool isDlMsgPending = false, isDlMsgScheduled = false;
- CmLList *pendingUeNode;
+ uint8_t ueIdx, ret = ROK;
+ uint16_t slot;
DlSchedInfo dlSchedInfo;
DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
SchCellCb *cell = NULLP;
- CmLList *node;
- uint8_t* ueNode;
- SchDlHqProcCb *hqP = NULLP;
- SchUlHqProcCb *ulHqP = NULLP;
+ Inst schInst = pst->dstInst-SCH_INST_START;
+ CmLList *node = NULLP;
+ TotalPrbUsage *dlTotalPrbUsage = NULLP;
cell = schCb[schInst].cells[schInst];
if(cell == NULLP)
memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue, cell->numSlots);
dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
- dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION;
- dlBrdcstAlloc->sib1Trans = NO_TRANSMISSION;
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
memcpy(&cell->slotInfo, slotInd, sizeof(SlotTimingInfo));
dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED;
#endif
/* Check for SSB occassion */
- dlBrdcstAlloc->ssbTrans = schCheckSsbOcc(cell, dlSchedInfo.schSlotValue.broadcastTime);
- if(dlBrdcstAlloc->ssbTrans)
+ dlBrdcstAlloc->ssbTransmissionMode = schCheckSsbOcc(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->ssbTransmissionMode)
{
if(schBroadcastSsbAlloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
{
DU_LOG("\nERROR --> SCH : schBroadcastSsbAlloc failed");
- dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION;
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
}
else
{
dlSchedInfo.isBroadcastPres = true;
- if((dlBrdcstAlloc->ssbTrans == NEW_TRANSMISSION) && (!cell->firstSsbTransmitted))
+ if((dlBrdcstAlloc->ssbTransmissionMode == NEW_TRANSMISSION) && (!cell->firstSsbTransmitted))
cell->firstSsbTransmitted = true;
}
}
/* Check for SIB1 occassion */
- dlBrdcstAlloc->sib1Trans = schCheckSib1Occ(cell, dlSchedInfo.schSlotValue.broadcastTime);
- if(dlBrdcstAlloc->sib1Trans)
+ dlBrdcstAlloc->sib1TransmissionMode = schCheckSib1Occ(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->sib1TransmissionMode)
{
if(schBroadcastSib1Alloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
{
DU_LOG("\nERROR --> SCH : schBroadcastSib1Alloc failed");
- dlBrdcstAlloc->sib1Trans = NO_TRANSMISSION;
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
}
else
{
dlSchedInfo.isBroadcastPres = true;
- if((dlBrdcstAlloc->sib1Trans == NEW_TRANSMISSION) && (!cell->firstSib1Transmitted))
+ if((dlBrdcstAlloc->sib1TransmissionMode == NEW_TRANSMISSION) && (!cell->firstSib1Transmitted))
cell->firstSib1Transmitted = true;
}
}
/*Process Paging Msg*/
schProcDlPageAlloc(cell, *slotInd, schInst);
- /* Select first UE in the linked list to be scheduled next */
- pendingUeNode = cell->ueToBeScheduled.first;
- if(pendingUeNode)
- {
- 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)
- {
- isRarPending = true;
- 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->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
- {
- /* Retransmission of MSG4 */
- isMsg4Pending = true;
- 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)
- {
- /* If RAR or MSG is successfully scheduled then
- * remove UE from linked list since no pending msgs for this UE */
- if(isRarScheduled || isMsg4Scheduled)
- {
- SCH_FREE(pendingUeNode->node, sizeof(uint8_t));
- deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
- }
- /* If RAR/MSG4 is pending but couldnt be scheduled then,
- * put this UE at the end of linked list to be scheduled later */
- else
- {
- cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
- }
- }
-
-#ifdef NR_DRX
- if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
- {
- if(pendingUeNode->node)
- {
- cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
- }
- }
- else
-#endif
- {
-
- /* DL Data */
- node = cell->ueCb[ueId-1].dlRetxHqList.first;
- if(node != NULLP)
- {
- /* DL Data ReTransmisson */
- isDlMsgPending = true;
- isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
- if(isDlMsgScheduled)
- {
-#ifdef NR_DRX
- schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
-#endif
- cmLListDelFrm(&cell->ueCb[ueId-1].dlRetxHqList, node);
- }
- }
- else
- {
- /* DL Data new transmission */
- if((cell->boIndBitMap) & (1<<ueId))
- {
- isDlMsgPending = true;
- isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
-
- /* If DL scheduling failed, free the newly assigned HARQ process */
- if(!isDlMsgScheduled)
- schDlReleaseHqProcess(hqP);
- else
- {
-#ifdef NR_DRX
- schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
-#endif
- }
- }
- }
-
- /* Scheduling of UL grant */
- node = cell->ueCb[ueId-1].ulRetxHqList.first;
- if(node != NULLP)
- {
- /* UL Data ReTransmisson */
- isUlGrantPending = true;
- isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
- if(isUlGrantScheduled)
- {
-#ifdef NR_DRX
- schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
-#endif
- 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);
- else
- {
-#ifdef NR_DRX
- schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
-#endif
- }
- }
- }
-
- if(!isUlGrantPending && !isDlMsgPending)
- {
- /* No action required */
- }
- else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
- {
- cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
- }
- else
- {
- SCH_FREE(ueNode, sizeof(uint8_t));
- deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
- }
- }
- }
- }
+ cell->api->SchScheduleSlot(cell, slotInd, schInst);
/* Check if any PDU is scheduled at this slot for any UE */
for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
return (ret);
}
+ /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
+ node = cmLListFirst(&schCb[schInst].statistics.activeKpiList.dlTotPrbUseList);
+ while(node)
+ {
+ dlTotalPrbUsage = (TotalPrbUsage *)node->node;
+ if(dlTotalPrbUsage)
+ {
+ dlTotalPrbUsage->numPrbUsedForTx += cell->schDlSlotInfo[slot]->prbAlloc.numPrbAlloc;
+ dlTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB;
+ }
+ node = node->next;
+ }
+
+ /* Re-initialize DL slot */
schInitDlSlot(cell->schDlSlotInfo[slot]);
+
+ /* Send UL Resource allocation to MAC */
schUlResAlloc(cell, schInst);
+
#ifdef NR_DRX
schHandleExpiryDrxTimer(cell);
#endif
+
return ret;
}