#include "du_app_mac_inf.h"
#include "mac_sch_interface.h"
#include "sch.h"
+#include "sch_tmr.h"
#include "sch_utils.h"
-
-SchMacDlAllocFunc schMacDlAllocOpts[] =
-{
- packSchMacDlAlloc,
- MacProcDlAlloc,
- packSchMacDlAlloc
-};
-
-SchCb schCb[SCH_MAX_INST];
-int schFillRar(RarAlloc *rarAlloc, uint16_t raRnti, uint16_t pci, uint8_t
- offsetPointA);
+#ifdef NR_DRX
+#include "sch_drx.h"
+#endif
/*******************************************************************
*
memset(&pst, 0, sizeof(Pst));
FILL_PST_SCH_TO_MAC(pst, inst);
- pst.event = EVENT_DL_ALLOC;
+ pst.event = EVENT_DL_SCH_INFO;
+
+ 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;
+
+ 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->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(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;
- return(*schMacDlAllocOpts[pst.selector])(&pst, dlSchedInfo);
+ 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)) != 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.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.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;
+ }
+ }
+
+ 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;
+
+ /*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;
}
+/*******************************************************************
+ *
+ * @brief Handles sending DL Page alloc to MAC
+ *
+ * @details
+ *
+ * Function : sendDlPAgeAllocToMac
+ *
+ * Functionality:
+ * Sends DL Page Resource Allocation to MAC from SCH
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t sendDlPageAllocToMac(DlPageAlloc *dlPageAlloc, Inst inst)
+{
+ Pst pst;
+
+ memset(&pst, 0, sizeof(Pst));
+ FILL_PST_SCH_TO_MAC(pst, inst);
+ pst.event = EVENT_DL_PAGING_ALLOC;
+
+ return(MacMessageRouter(&pst, (void *)dlPageAlloc));
+}
/*******************************************************************
*
* RFAILED - failure
*
* ****************************************************************/
-void schCalcSlotValues(SlotIndInfo slotInd, SchSlotValue *schSlotValue)
+void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue, uint16_t numOfSlots)
{
/****************************************************************
* PHY_DELTA - the physical layer delta *
* on PHY_DELTA + SCHED_DELTA + BO_DELTA *
****************************************************************/
- ADD_DELTA_TO_TIME(slotInd, schSlotValue->currentTime, PHY_DELTA_DL);
- ADD_DELTA_TO_TIME(slotInd, schSlotValue->broadcastTime, PHY_DELTA_DL + SCHED_DELTA);
- ADD_DELTA_TO_TIME(slotInd, schSlotValue->rarTime, PHY_DELTA_DL + SCHED_DELTA);
- ADD_DELTA_TO_TIME(slotInd, schSlotValue->dlMsgTime, PHY_DELTA_DL + SCHED_DELTA);
+ ADD_DELTA_TO_TIME(slotInd, schSlotValue->currentTime, PHY_DELTA_DL, numOfSlots);
+ ADD_DELTA_TO_TIME(slotInd, schSlotValue->broadcastTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots);
+ ADD_DELTA_TO_TIME(slotInd, schSlotValue->rarTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots);
+ ADD_DELTA_TO_TIME(slotInd, schSlotValue->dlMsgTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots);
+ ADD_DELTA_TO_TIME(slotInd, schSlotValue->ulDciTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots);
}
/*******************************************************************
*
- * @brief
+ * @brief Checks if a slot is to be scheduled for SSB transmission
*
* @details
*
- * Function :
+ * Function : schCheckSsbOcc
*
* Functionality:
-
+ * Checks if a slot is to be scheduled for SSB transmission
*
- * @params[in]
+ * @params[in] SlotTimingInfo slotTime
+ * SchCellCb *cell
+ * @return Pdu transmission
+ *
+ * ****************************************************************/
+PduTxOccsaion schCheckSsbOcc(SchCellCb *cell, SlotTimingInfo slotTime)
+{
+ uint8_t ssb_rep;
+
+ ssb_rep = cell->cellCfg.ssbPeriod;
+
+ /* Identify SSB ocassion*/
+ if ((slotTime.sfn % SCH_MIB_TRANS == 0) && (slotTime.slot ==0))
+ {
+ return NEW_TRANSMISSION;
+ }
+ else if(cell->firstSsbTransmitted)
+ {
+ if((ssb_rep == 5) && ((slotTime.slot == 0 || slotTime.slot == 10)))
+ return REPEATITION;
+ else if((slotTime.sfn % (ssb_rep/10) == 0) && slotTime.slot == 0)
+ return REPEATITION;
+ }
+ /* not SSB occassion */
+ return NO_TRANSMISSION;
+}
+
+/*******************************************************************
+ *
+ * @brief Checks if a slot is to be scheduled for SIB1 transmission
+ *
+ * @details
+ *
+ * Function : schCheckSib1Occ
+ *
+ * Functionality:
+ * Checks if a slot is to be scheduled for SIB1 transmission
+ *
+ * @params[in] SlotTimingInfo slotTime
+ * SchCellCb *cell
+ * @return Pdu transmission
+ *
+ * ****************************************************************/
+PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime)
+{
+ /* Identify SIB1 occasions */
+ if((slotTime.sfn % SCH_SIB1_TRANS == 0) && (slotTime.slot ==0))
+ {
+ return NEW_TRANSMISSION;
+ }
+ else if(cell->firstSib1Transmitted)
+ {
+ if((slotTime.sfn % (SIB1_REPETITION_PERIOD/10) == 0) &&
+ (slotTime.slot == 0))
+ {
+ return REPEATITION;
+ }
+ }
+ /* not SIB1 occassion */
+ return NO_TRANSMISSION;
+}
+
+/*******************************************************************
+ *
+ * @brief find correct combination of k0-k1 value
+ *
+ * @details
+ *
+ * Function : findValidK0K1Value
+ *
+ * Functionality:
+ * find correct combination of k0-k1 value
+ *
+ * @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
*
- * ****************************************************************/
-uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlMsgAlloc *dlMsgAlloc)
+ *******************************************************************/
+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 ueIdx, lcIdx;
- uint16_t slot;
- uint16_t crnti = 0;
- uint32_t accumalatedSize = 0;
+ uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ;
+ uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0;
SchUeCb *ueCb = NULLP;
+ SchK0K1TimingInfoTbl *k0K1InfoTbl;
- while(cell->boIndBitMap)
+ ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdcchTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
{
- slot = dlSchedInfo->schSlotValue.dlMsgTime.slot;
+ /* If it is not a DL slot, cannot schedule PDCCH. Return from here. */
+ return false;
+ }
+#endif
- GET_RIGHT_MOST_SET_BIT(cell->boIndBitMap, ueIdx);
- GET_CRNTI(crnti,ueIdx);
- ueCb = &cell->ueCb[ueIdx-1];
+ if(cell->schDlSlotInfo[pdcchTime->slot]->pdcchUe != 0)
+ {
+ return false;
+ }
- /* allocate PDCCH and PDSCH resources for the ue */
- SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgAlloc));
- if(!dlMsgAlloc)
+ if(dedMsg == true)
+ {
+ ueCb = &cell->ueCb[ueId-1];
+ k0K1InfoTbl = &ueCb->k0K1InfoTbl;
+ }
+ else
+ {
+ k0K1InfoTbl = &cell->k0K1InfoTbl;
+ }
+
+ numK0 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].numK0;
+ for(k0TblIdx = 0; k0TblIdx < numK0; k0TblIdx++)
+ {
+ k0Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k0Index;
+ if(dedMsg != true)
{
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for ded DL msg alloc");
- return RFAILED;
+ 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
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0 != NULLP)
+ {
+ k0Val = *(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0);
+ *pdschStartSymbol = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].startSymbol;
+ *pdschSymblLen = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].symbolLength;
+ }
}
- memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
- dlSchedInfo->dlMsgAlloc = dlMsgAlloc;
- dlMsgAlloc->crnti = crnti;
- /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
- memcpy(&dlMsgAlloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
- sizeof(DlMsgInfo));
+ ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdschTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+ {
+ continue;
+ }
+#endif
+ if(cell->schDlSlotInfo[pdschTime->slot]->pdschUe != 0)
+ {
+ continue;
+ }
- /* scheduled LC data fill */
- dlMsgAlloc->numLc = 0;
- for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+ numK1 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.numK1;
+ for(k1TblIdx = 0; k1TblIdx < numK1; k1TblIdx++)
{
- if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
+ k1Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.k1Indexes[k1TblIdx];
+ if(dedMsg != true)
{
- dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].lcId = lcIdx;
-
- /* calculation for BO includse RLC and MAC header size */
- dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes = \
- ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE;
- accumalatedSize += dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes;
- dlMsgAlloc->numLc++;
+ k1Val = defaultUlAckTbl[k1Index];
+ }
+ else
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck)
+ {
+ k1Val = ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index];
+ }
+ }
+ ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pucchTime->slot, cell->slotFrmtBitMap) == DL_SLOT)
+ {
+ continue;
+ }
+#endif
+ if(cell->schUlSlotInfo[pucchTime->slot]->pucchUe != 0)
+ {
+ continue;
}
- ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+ if(hqP)
+ {
+ ADD_DELTA_TO_TIME((*pucchTime), hqP->pucchTime, 0, cell->numSlots);
+ }
+ pdcchTime->cellId = cell->cellId;
+ pdschTime->cellId = cell->cellId;
+
+ 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;
+}
- /* pdcch and pdsch data is filled */
- schDlRsrcAllocDlMsg(dlMsgAlloc, cell, crnti, &accumalatedSize, slot);
- /* Calculated TB size could be less than the total size requested.
- * Hence, updated the scheduled bytes report. Following is valid only for
- * one LC.
- * TODO : Update the scheduling byte report for multiple LC based on QCI
- * and Priority */
- dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc -1].schBytes = accumalatedSize;
+/*******************************************************************
+*
+* @brief Process DL Resource allocation for Page
+*
+* @details
+*
+* Function : schProcDlPageAlloc
+*
+* Functionality: Process DL Resource allocation for Page
+*
+* @params[in] SchCellCb *cell, SlotTimingInfo currTime, Inst schInst
+*
+* @return pointer to return Value(ROK, RFAILED)
+*
+* ****************************************************************/
+uint8_t schProcDlPageAlloc(SchCellCb *cell, SlotTimingInfo currTime, Inst schInst)
+{
+ DlPageAlloc dlPageAlloc;
+ CmLList *pageInfoNode = NULLP;
+ SchPageInfo *pageInfo = NULLP;
+ SlotTimingInfo pdschTime;
+ uint32_t tbSize = 0;
+ uint16_t startPrb = 0, maxFreePRB = 0, nPRB = 0;
+ uint8_t ret = RFAILED;
- /* PUCCH resource */
- schAllocPucchResource(cell, dlMsgAlloc->crnti, slot);
+ pageInfoNode = schPageInfoSearchFromPageList(currTime, &(cell->pageCb.pageIndInfoRecord[currTime.sfn]));
- /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo->schSlotValue.dlMsgTime.slot]->dlMsgInfo, \
- sizeof(DlMsgInfo));
- cell->schDlSlotInfo[dlSchedInfo->schSlotValue.dlMsgTime.slot]->dlMsgInfo = NULL;
+ if(pageInfoNode == NULLP)
+ {
+ return ROK;
+ }
+ pageInfo = (SchPageInfo *)pageInfoNode->node;
+
+ while(true)
+ {
+ dlPageAlloc.cellId = currTime.cellId;
+
+ ADD_DELTA_TO_TIME(currTime, dlPageAlloc.dlPageTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
+ dlPageAlloc.shortMsgInd = FALSE;
+ pdschTime = dlPageAlloc.dlPageTime;
- /* after allocation is done, unset the bo bit for that ue */
- UNSET_ONE_BIT(ueIdx, cell->boIndBitMap);
+ /*Calculate Best FREE BLOCK with MAX PRB count*/
+ maxFreePRB = searchLargestFreeBlock(cell, pdschTime, &startPrb, DIR_DL);
+
+ if(maxFreePRB != 0)
+ {
+ tbSize = calculateEstimateTBSize(pageInfo->msgLen, pageInfo->mcs, NUM_PDSCH_SYMBOL, maxFreePRB, &nPRB);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> SCH: Unable to get any free block for Paging at SFN:%d, SLOT:%d",\
+ pdschTime.sfn, pdschTime.slot);
+ break;
+ }
+ /*Fill PDCCH: PDCCH Cfg is same as SIB1 as Paging will be a broadcast message*/
+ 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.cceIndex;
+ dlPageAlloc.pageDlDci.aggregLevel = cell->sib1SchCfg.sib1PdcchCfg.dci.aggregLevel;
+ dlPageAlloc.pageDlDci.precoderGranularity = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.precoderGranularity;
+ dlPageAlloc.pageDlDci.coreSetSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.coreSetSize;
+ /*Fill BWP*/
+ memcpy(&dlPageAlloc.bwp, &cell->sib1SchCfg.bwp, sizeof(BwpCfg));
+
+ /*Fill PDSCH*/
+ 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;
+ }
+
+ /*Fill Page PDU information*/
+ dlPageAlloc.pageDlSch.dlPagePduLen = pageInfo->msgLen;
+
+ SCH_ALLOC(dlPageAlloc.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
+
+ if(dlPageAlloc.pageDlSch.dlPagePdu == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: Memory Allocation Failed during Page Resource allocation");
+ break;
+ }
+ 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.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
+ break;
+ }
+ ret = ROK;
+ break;
}
- return ROK;
+ /*Remove the Page Node*/
+ SCH_FREE(pageInfo->pagePdu, pageInfo->msgLen);
+ schDeleteFromPageInfoList(&(cell->pageCb.pageIndInfoRecord[currTime.sfn]), pageInfoNode);
+
+ return(ret);
+
}
/*******************************************************************
*
* @details
*
- * Function : schProcessSlotInd
+ * Function : SchProcSlotInd
*
* Functionality:
* Handles TTI indication received from PHY
* RFAILED - failure
*
* ****************************************************************/
-uint8_t schProcessSlotInd(SlotIndInfo *slotInd, Inst schInst)
+uint8_t SchProcSlotInd(Pst *pst, SlotTimingInfo *slotInd)
{
- uint8_t ssb_rep, ueIdx, lcgIdx, ret = ROK;
- uint16_t slot;
- DlSchedInfo dlSchedInfo;
- DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
- RarAlloc *rarAlloc = NULLP;
- DlMsgAlloc *msg4Alloc = NULLP;
- DlMsgAlloc *dlMsgAlloc = NULLP;
- SchCellCb *cell = NULLP;
-
-
- memset(&dlSchedInfo,0,sizeof(DlSchedInfo));
- dlSchedInfo.dlMsgAlloc = NULLP;
- schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue);
- dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
- dlBrdcstAlloc->ssbTrans = NO_SSB;
- dlBrdcstAlloc->sib1Trans = NO_SIB1;
+ uint8_t ueIdx, ret = ROK;
+ uint16_t slot;
+ DlSchedInfo dlSchedInfo;
+ DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
+ SchCellCb *cell = NULLP;
+ Inst schInst = pst->dstInst-SCH_INST_START;
+ CmLList *node = NULLP;
+ TotalPrbUsage *dlTotalPrbUsage = NULLP;
cell = schCb[schInst].cells[schInst];
- ssb_rep = cell->cellCfg.ssbSchCfg.ssbPeriod;
- memcpy(&cell->slotInfo, slotInd, sizeof(SlotIndInfo));
- dlBrdcstAlloc->ssbIdxSupported = 1;
+ if(cell == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH : Cell Does not exist");
+ return RFAILED;
+ }
+ memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
+ schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue, cell->numSlots);
+ dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
- slot = dlSchedInfo.schSlotValue.currentTime.slot;
+ memcpy(&cell->slotInfo, slotInd, sizeof(SlotTimingInfo));
+ dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED;
dlSchedInfo.cellId = cell->cellId;
+ slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
- /* Identify SSB ocassion*/
- if ((dlSchedInfo.schSlotValue.broadcastTime.sfn % SCH_MIB_TRANS == 0) && (dlSchedInfo.schSlotValue.broadcastTime.slot ==0))
- {
- dlBrdcstAlloc->ssbTrans = SSB_TRANSMISSION;
- if(!cell->firstSsbTransmitted)
- cell->firstSsbTransmitted = true;
- }
- else if (cell->firstSsbTransmitted)
- {
- if((ssb_rep == 5) && ((dlSchedInfo.schSlotValue.broadcastTime.slot == 0 || dlSchedInfo.schSlotValue.broadcastTime.slot == 10)))
- dlBrdcstAlloc->ssbTrans = SSB_REPEAT;
- else if((dlSchedInfo.schSlotValue.broadcastTime.sfn % (ssb_rep/10) == 0) && dlSchedInfo.schSlotValue.broadcastTime.slot == 0)
- dlBrdcstAlloc->ssbTrans = SSB_REPEAT;
- }
- else
- {
- /* not SSB occassion */
- }
-
- /* Identify SIB1 occasions */
- if((dlSchedInfo.schSlotValue.broadcastTime.sfn % SCH_SIB1_TRANS == 0) && (dlSchedInfo.schSlotValue.broadcastTime.slot ==0))
- {
- dlBrdcstAlloc->sib1Trans = SIB1_TRANSMISSION;
- if(!cell->firstSib1Transmitted)
- cell->firstSib1Transmitted = true;
- }
- else if (cell->firstSib1Transmitted)
+#ifdef NR_DRX
+ schHandleStartDrxTimer(cell);
+#endif
+
+ /* Check for SSB occassion */
+ dlBrdcstAlloc->ssbTransmissionMode = schCheckSsbOcc(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->ssbTransmissionMode)
{
- if((dlSchedInfo.schSlotValue.broadcastTime.sfn % (cell->cellCfg.sib1SchCfg.sib1RepetitionPeriod/10) == 0) &&
- (dlSchedInfo.schSlotValue.broadcastTime.slot == 0))
+ if(schBroadcastSsbAlloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
{
- dlBrdcstAlloc->sib1Trans = SIB1_REPITITION;
+ DU_LOG("\nERROR --> SCH : schBroadcastSsbAlloc failed");
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
}
- }
- else
- {
- /* not SIB1 occassion */
- }
-
-
- if(dlBrdcstAlloc->ssbTrans || dlBrdcstAlloc->sib1Trans)
- {
- dlSchedInfo.isBroadcastPres = true;
- slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
- ret = schBroadcastAlloc(cell,dlBrdcstAlloc,slot);
- if(ret != ROK)
+ else
{
- DU_LOG("\nERROR --> SCH : schBroadcastAlloc failed");
- return ret;
+ dlSchedInfo.isBroadcastPres = true;
+ if((dlBrdcstAlloc->ssbTransmissionMode == NEW_TRANSMISSION) && (!cell->firstSsbTransmitted))
+ cell->firstSsbTransmitted = true;
}
}
- /* check for RAR */
- if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarInfo != NULLP)
+ /* Check for SIB1 occassion */
+ dlBrdcstAlloc->sib1TransmissionMode = schCheckSib1Occ(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->sib1TransmissionMode)
{
- slot = dlSchedInfo.schSlotValue.rarTime.slot;
- SCH_ALLOC(rarAlloc, sizeof(RarAlloc));
- if(!rarAlloc)
+ if(schBroadcastSib1Alloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
{
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for RAR alloc");
- return RFAILED;
+ DU_LOG("\nERROR --> SCH : schBroadcastSib1Alloc failed");
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
}
-
- dlSchedInfo.rarAlloc = rarAlloc;
-
- /* RAR info is copied, this was earlier filled in schProcessRachInd */
- memcpy(&rarAlloc->rarInfo,cell->schDlSlotInfo[slot]->rarInfo, sizeof(RarInfo));
-
- /* pdcch and pdsch data is filled */
- schFillRar(rarAlloc,
- cell->schDlSlotInfo[slot]->rarInfo->raRnti,
- cell->cellCfg.phyCellId,
- cell->cellCfg.ssbSchCfg.ssbOffsetPointA);
-
- SCH_FREE(cell->schDlSlotInfo[slot]->rarInfo,sizeof(RarAlloc));
- cell->schDlSlotInfo[slot]->rarInfo = NULLP;
- }
-
- /* check for MSG4 */
- if((cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo != NULLP) &&
- (cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo->isMsg4Pdu))
- {
- slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
-
- SCH_ALLOC(msg4Alloc, sizeof(DlMsgAlloc));
- if(!msg4Alloc)
+ else
{
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for msg4 alloc");
- return RFAILED;
+ dlSchedInfo.isBroadcastPres = true;
+ if((dlBrdcstAlloc->sib1TransmissionMode == NEW_TRANSMISSION) && (!cell->firstSib1Transmitted))
+ cell->firstSib1Transmitted = true;
}
+ }
- dlSchedInfo.dlMsgAlloc = msg4Alloc;
-
- /* Msg4 info is copied, this was earlier filled in macSchDlRlcBoInfo */
- memcpy(&msg4Alloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
- sizeof(DlMsgInfo));
-
- /* pdcch and pdsch data is filled */
- schDlRsrcAllocMsg4(msg4Alloc, cell, dlSchedInfo.schSlotValue.dlMsgTime.slot);
+ /*Process Paging Msg*/
+ schProcDlPageAlloc(cell, *slotInd, schInst);
- /* PUCCH resource */
- schAllocPucchResource(cell, msg4Alloc->dlMsgInfo.crnti, dlSchedInfo.schSlotValue.dlMsgTime.slot);
+ cell->api->SchScheduleSlot(cell, slotInd, schInst);
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
- cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo = NULL;
- }
- /* check if UL grant must be sent in this slot for a SR/BSR that had been received */
- for(ueIdx=0; ueIdx<cell->numActvUe; ueIdx++)
+ /* Check if any PDU is scheduled at this slot for any UE */
+ for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
{
- uint32_t totDataReq = 0; /* in bytes */
- DciInfo *dciInfo = NULLP;
- SchUeCb *ueCb = NULLP;
-
- ueCb = &cell->ueCb[ueIdx];
- /* check for SR */
- if(ueCb->srRcvd)
- {
- totDataReq = UL_GRANT_SIZE; /*fixing so that all control msgs can be handled in SR */
- ueCb->srRcvd = false;
- }
- /* check for BSR */
- for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
+ /* If RAR PDCCH/PDSCH is scheduled for a UE at this slot, fill RAR specific interface
+ * structure to send to MAC */
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarAlloc[ueIdx] != NULLP)
{
- totDataReq+= ueCb->bsrInfo[lcgIdx].dataVol;
- ueCb->bsrInfo[lcgIdx].dataVol = 0;
+ slot = dlSchedInfo.schSlotValue.rarTime.slot;
+ dlSchedInfo.rarAlloc[ueIdx] = cell->schDlSlotInfo[slot]->rarAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->rarAlloc[ueIdx] = NULLP;
}
- if(totDataReq > 0) /* UL grant must be provided for this UE in this slot */
- {
- SchPuschInfo schPuschInfo;
- memset(&schPuschInfo, 0, sizeof(SchPuschInfo));
- SCH_ALLOC(dciInfo, sizeof(DciInfo));
- if(!dciInfo)
- {
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc");
- return RFAILED;
- }
- memset(dciInfo,0,sizeof(DciInfo));
- /* update the SFN and SLOT */
- memcpy(&dlSchedInfo.schSlotValue.ulDciTime, slotInd, sizeof(SlotIndInfo));
- slot = dlSchedInfo.schSlotValue.ulDciTime.slot;
- /* Update PUSCH allocation */
- schFillPuschAlloc(ueCb, slot, totDataReq, &schPuschInfo);
- /* Fill DCI for UL grant */
- schFillUlDci(ueCb, schPuschInfo, dciInfo);
- memcpy(&dciInfo->slotIndInfo, &dlSchedInfo.schSlotValue.ulDciTime, sizeof(SlotIndInfo));
- dlSchedInfo.ulGrant = dciInfo;
+ /* If DL-Msg PDCCH/PDSCH is scheduled for a UE at this slot, fill
+ * specific interface structure to send to MAC */
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgAlloc[ueIdx] != NULLP)
+ {
+ slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
+ dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx] = NULLP;
}
}
- /* Check for pending BO grant for LC */
- if((cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo != NULLP) &&
- (!cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo->isMsg4Pdu))
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.ulDciTime.slot]->ulGrant != NULLP)
{
- schFillBoGrantDlSchedInfo(cell, &dlSchedInfo, dlMsgAlloc);
+ slot = dlSchedInfo.schSlotValue.ulDciTime.slot;
+ dlSchedInfo.ulGrant = cell->schDlSlotInfo[slot]->ulGrant;
+ cell->schDlSlotInfo[slot]->ulGrant = NULLP;
}
- /* send msg to MAC */
+ /* Send msg to MAC */
ret = sendDlAllocToMac(&dlSchedInfo, schInst);
if(ret != ROK)
{
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;
+ 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;
}