packSchMacDlAlloc
};
-SchCb schCb[SCH_MAX_INST];
-
/*******************************************************************
*
* @brief Handles sending DL broadcast alloc to MAC
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->ulDciTime, PHY_DELTA_DL + SCHED_DELTA);
}
/*******************************************************************
return NO_TRANSMISSION;
}
+/*******************************************************************
+ *
+ * @brief find correct combination of k0-k1 value
+ *
+ * @details
+ *
+ * Function : findValidK0K1Value
+ *
+ * Functionality:
+ * find correct combination of k0-k1 value
+ *
+ * @params[in]
+ * @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)
+{
+ 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;
+
+ ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdcchTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+ {
+ /* If it is not a DL slot, cannot schedule PDCCH. Return from here. */
+ return false;
+ }
+#endif
+
+ if(cell->schDlSlotInfo[pdcchTime->slot]->pdcchUe != 0)
+ {
+ return false;
+ }
+
+ if(dedMsg == true)
+ {
+ ueCb = &cell->ueCb[ueId-1];
+ k0K1InfoTbl = &ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1InfoTbl;
+ }
+ else
+ {
+ k0K1InfoTbl = &cell->cellCfg.schInitialDlBwp.k0K1InfoTbl;
+ }
+
+ numK0 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].numK0;
+ for(k0TblIdx = 0; k0TblIdx < numK0; k0TblIdx++)
+ {
+ 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;
+ }
+ else
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0 != NULLP)
+ {
+ k0Val = *(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0);
+ *pdschStartSymbol = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].startSymbol;
+ *pdschSymblLen = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].symbolLength;
+ }
+ }
+
+ ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdschTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+ {
+ 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++)
+ {
+ k1Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.k1Indexes[k1TblIdx];
+ if(dedMsg != true)
+ {
+ k1Val = defaultUlAckTbl[k1Index];
+ }
+ else
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck)
+ {
+ k1Val = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index];
+ }
+ }
+ ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pucchTime->slot, cell->slotFrmtBitMap) == DL_SLOT)
+ {
+ continue;
+ }
+#endif
+ if(cell->schUlSlotInfo[pucchTime->slot]->pucchUe != 0)
+ {
+ continue;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
/*******************************************************************
*
* @brief
*
* @details
*
- * Function :
+ * Function : schFillBoGrantDlSchedInfo
*
* Functionality:
* RFAILED - failure
*
* ****************************************************************/
-uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlMsgAlloc *dlMsgAlloc)
+bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
{
- uint8_t ueIdx, lcIdx;
- uint16_t slot;
- uint16_t crnti = 0;
+ 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;
+
+ /* 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];
- while(cell->boIndBitMap)
+ if(findValidK0K1Value(cell, currTime, ueId, ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1TblPrsnt,\
+ &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime) != true )
{
- slot = dlSchedInfo->schSlotValue.dlMsgTime.slot;
+ /* 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;
+ }
- GET_RIGHT_MOST_SET_BIT(cell->boIndBitMap, ueIdx);
- GET_CRNTI(crnti,ueIdx);
- ueCb = &cell->ueCb[ueIdx-1];
+ /* allocate PDCCH and PDSCH resources for the ue */
+ if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL)
+ {
- /* allocate PDCCH and PDSCH resources for the ue */
- SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgAlloc));
- if(!dlMsgAlloc)
+ SCH_ALLOC(dciSlotAlloc, sizeof(DlMsgAlloc));
+ if(!dciSlotAlloc)
{
DU_LOG("\nERROR --> SCH : Memory Allocation failed for ded DL msg alloc");
- return RFAILED;
+ return false;
}
- memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
- dlSchedInfo->dlMsgAlloc = dlMsgAlloc;
- dlMsgAlloc->crnti = crnti;
+ 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);
- /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
- memcpy(&dlMsgAlloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
- sizeof(DlMsgInfo));
+ /*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;
- /* scheduled LC data fill */
- dlMsgAlloc->numLc = 0;
- for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+ for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+ {
+ if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
{
- 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
{
- dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].lcId = lcIdx;
+ lcLL = &(ueCb->dlLcPrbEst.defLcList);
+ }
- /* 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++;
+ /*[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;
}
-
- if (!dlMsgAlloc->numLc)
+ ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+ }//End of for loop
+
+
+ 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)
{
- DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n");
- /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
- SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc));
- dlSchedInfo->dlMsgAlloc = NULLP;
- return ROK;
+ 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;
+ }
- /* pdcch and pdsch data is filled */
- if((schDlRsrcAllocDlMsg(cell, dlSchedInfo->schSlotValue.dlMsgTime, crnti, &accumalatedSize, dlMsgAlloc)) != ROK)
+ /*[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(maxFreePRB != 0)
+ {
+ 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
{
- DU_LOG("\nERROR --> SCH : Scheduling of DL dedicated message failed");
- /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
- SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc));
- dlSchedInfo->dlMsgAlloc = NULLP;
- return RFAILED;
+ 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);
}
+ }
+
+ /*[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));
- /* 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
- * */
- accumalatedSize = accumalatedSize/dlMsgAlloc->numLc;
- for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++)
- dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize;
-
- /* PUCCH resource */
- schAllocPucchResource(cell, dlMsgAlloc->crnti, slot);
-
- /* after allocation is done, unset the bo bit for that ue */
- UNSET_ONE_BIT(ueIdx, cell->boIndBitMap);
+ updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+
+ /*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;
}
- return ROK;
+ /*[Step6]: pdcch and pdsch data is filled */
+ if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols)) != 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)
+ {
+ 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));
+ return false;
+ }
+ cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = dlMsgAlloc;
+ memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
+ dlMsgAlloc->crnti = dciSlotAlloc->crnti;
+ }
+ 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);
+ 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;
}
/*******************************************************************
* ****************************************************************/
uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
{
- uint8_t ueIdx, lcgIdx, ret = ROK;
- uint16_t slot;
- DlSchedInfo dlSchedInfo;
+ 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;
+ DlSchedInfo dlSchedInfo;
DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
- DlMsgAlloc *msg4Alloc = NULLP;
- DlMsgAlloc *dlMsgAlloc = NULLP;
- SchCellCb *cell = NULLP;
+ SchCellCb *cell = NULLP;
- memset(&dlSchedInfo,0,sizeof(DlSchedInfo));
- dlSchedInfo.dlMsgAlloc = NULLP;
+ memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue);
dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION;
dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED;
dlSchedInfo.cellId = cell->cellId;
-
slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
/* Check for SSB occassion */
}
}
- /* Check for Pending RA Requests */
- schProcessRaReq(*slotInd, cell);
-
- /* Check for RAR */
- if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarAlloc != NULLP)
- {
- slot = dlSchedInfo.schSlotValue.rarTime.slot;
- dlSchedInfo.rarAlloc = cell->schDlSlotInfo[slot]->rarAlloc;
- cell->schDlSlotInfo[slot]->rarAlloc = NULLP;
- }
-
- /* Check for MSG4 */
- if((cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo != NULLP) &&
- (cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo->isMsg4Pdu))
+ /* Select first UE in the linked list to be scheduled next */
+ pendingUeNode = cell->ueToBeScheduled.first;
+ if(pendingUeNode)
{
- slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
-
- SCH_ALLOC(msg4Alloc, sizeof(DlMsgAlloc));
- if(!msg4Alloc)
+ if(pendingUeNode->node)
{
- DU_LOG("\nERROR --> SCH : Memory Allocation failed for msg4 alloc");
- return RFAILED;
- }
+ ueId = *(uint8_t *)(pendingUeNode->node);
- dlSchedInfo.dlMsgAlloc = msg4Alloc;
+ /* 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);
+ }
- /* Msg4 info is copied, this was earlier filled in macSchDlRlcBoInfo */
- memcpy(&msg4Alloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
- sizeof(DlMsgInfo));
+ /* 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)
+ {
+ isMsg4Pending = true;
+ isMsg4Scheduled = schProcessMsg4Req(cell, *slotInd, ueId);
+ }
- /* pdcch and pdsch data is filled */
- if((schDlRsrcAllocMsg4(cell, dlSchedInfo.schSlotValue.dlMsgTime, msg4Alloc)) != ROK)
- {
- DU_LOG("\nERROR --> SCH : MSG4 scheduling failed");
- SCH_FREE(msg4Alloc, sizeof(DlMsgAlloc));
- dlSchedInfo.dlMsgAlloc = NULLP;
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
- return RFAILED;
- }
+ 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));
+ }
+ }
- /* PUCCH resource */
- schAllocPucchResource(cell, msg4Alloc->dlMsgInfo.crnti, dlSchedInfo.schSlotValue.dlMsgTime.slot);
+ if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
+ {
+ isUlGrantPending = true;
+ isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId);
+ }
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
+ if((cell->boIndBitMap) & (1<<ueId))
+ {
+ isDlMsgPending = true;
+ isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId);
+ }
+ if(!isUlGrantPending && !isDlMsgPending)
+ {
+ /* No action required */
+ }
+ else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
+ {
+ cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
+ }
+ else
+ {
+ SCH_FREE(pendingUeNode->node, sizeof(uint8_t));
+ deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
+ }
+ }
}
- /* 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)
+ /* 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 = UL_GRANT_SIZE; /*fixing so that all control msgs can be handled in SR */
- ueCb->srRcvd = false;
+ slot = dlSchedInfo.schSlotValue.rarTime.slot;
+ dlSchedInfo.rarAlloc[ueIdx] = cell->schDlSlotInfo[slot]->rarAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->rarAlloc[ueIdx] = NULLP;
}
- /* check for BSR */
- for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
+
+ /* 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)
{
- totDataReq+= ueCb->bsrInfo[lcgIdx].dataVol;
- ueCb->bsrInfo[lcgIdx].dataVol = 0;
+ slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
+ dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->dlMsgAlloc[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(SlotTimingInfo));
- 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(SlotTimingInfo));
- dlSchedInfo.ulGrant = dciInfo;
- }
}
- /* 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)
{
- if((schFillBoGrantDlSchedInfo(cell, &dlSchedInfo, dlMsgAlloc)) != ROK)
- {
- DU_LOG("\nERROR --> SCH : DL MSG scheduling failed");
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
- return RFAILED;
- }
-
- /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
- SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
+ slot = dlSchedInfo.schSlotValue.ulDciTime.slot;
+ dlSchedInfo.ulGrant = cell->schDlSlotInfo[slot]->ulGrant;
+ cell->schDlSlotInfo[slot]->ulGrant = NULLP;
}
/* Send msg to MAC */
schInitDlSlot(cell->schDlSlotInfo[slot]);
schUlResAlloc(cell, schInst);
-
return ret;
}