-/*******************************************************************
- *
- * @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;
-
- /* 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, 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)
- {
- 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, 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;
-}
-