1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for scheduling based on First Come First Serve
30 **********************************************************************/
32 /** @file sch_slot_ind.c
33 @brief This module processes slot indications
35 #include "common_def.h"
41 #include "du_app_mac_inf.h"
42 #include "mac_sch_interface.h"
45 #include "sch_utils.h"
51 /*******************************************************************
53 * @brief Function to handle Cell configuration request
57 * Function : schFcfsCellCfgReq
59 * Functionality: This function configures cell paremeters
60 * required for FCFS scheduling
62 * @params[in] SchCellCb *cellCb, Cell control block
66 * ****************************************************************/
67 uint8_t schFcfsCellCfgReq(SchCellCb *cellCb)
69 SchFcfsCellCb *fcfsCellCb = NULLP;
71 SCH_ALLOC(fcfsCellCb, sizeof(SchFcfsCellCb));
74 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsCellCfgReq");
77 cmLListInit(&fcfsCellCb->ueToBeScheduled);
78 cellCb->schSpcCell = (void *)fcfsCellCb;
82 /*******************************************************************
84 * @brief Function to handle Cell configuration request
88 * Function : schFcfsCellDelReq
90 * Functionality: This function deletes/frees cell params
91 * specific to FCFS scheduling
93 * @params[in] Pointer to Cell control block
96 * ****************************************************************/
97 void schFcfsCellDelReq(SchCellCb *cellCb)
99 SchFcfsCellCb *fcfsCellCb = NULLP;
100 CmLList *node=NULL, *next=NULL;
102 fcfsCellCb = (SchFcfsCellCb *)cellCb->schSpcCell;
103 /* Remove all UE from ueToBeScheduled list and deallocate */
104 node = fcfsCellCb->ueToBeScheduled.first;
108 SCH_FREE(node->node, sizeof(uint8_t));
109 cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
110 SCH_FREE(node, sizeof(CmLList));
113 SCH_FREE(fcfsCellCb, sizeof(SchFcfsCellCb));
114 cellCb->schSpcCell = NULLP;
117 /*******************************************************************
119 * @brief Function to handle UE configuration request
123 * Function : SchFcfsAddUeConfigReq
125 * Functionality: Adds/Configures UE parameters required for
128 * @params[in] Pointer to UE control block
132 * ****************************************************************/
133 uint8_t SchFcfsAddUeConfigReq(SchUeCb *ueCb)
135 SchFcfsUeCb *ueFcfsCb;
137 SCH_ALLOC(ueFcfsCb, sizeof(SchFcfsHqCb));
140 DU_LOG("\nERROR --> SCH: Memory allocation failed in SchFcfsAddUeConfigReq");
144 cmLListInit(&ueFcfsCb->hqRetxCb.ulRetxHqList);
145 cmLListInit(&ueFcfsCb->hqRetxCb.dlRetxHqList);
146 ueCb->schSpcUeCb = (void *)ueFcfsCb;
151 /*******************************************************************
153 * @brief Handles UE reconfiguration request
157 * Function : SchFcfsModUeConfigReq
161 * @params[in] Pointer to UE control block
164 * ****************************************************************/
165 void SchFcfsModUeConfigReq(SchUeCb *ueCb)
167 /*TBD: No action required for FCFS*/
171 /*******************************************************************
173 * @brief Handles UE Delete Request
177 * Function : SchFcfsUeDeleteReq
179 * Functionality: Deletes/Frees UE parameters specific to
182 * @params[in] Pointer to UE control block
185 * ****************************************************************/
186 void SchFcfsUeDeleteReq(SchUeCb *ueCb)
188 SchFcfsCellCb *fcfsCellCb = NULLP;
189 SchFcfsUeCb *ueFcfsCb = NULLP;
190 CmLList *node=NULL, *next=NULL;
193 fcfsCellCb = (SchFcfsCellCb *)ueCb->cellCb->schSpcCell;
194 /* Remove all UE from ueToBeScheduled list and deallocate */
195 node = fcfsCellCb->ueToBeScheduled.first;
199 ueId = *(uint8_t *)node->node;
200 if(ueId == ueCb->ueId)
202 SCH_FREE(node->node, sizeof(uint8_t));
203 cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
204 SCH_FREE(node, sizeof(CmLList));
210 ueFcfsCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
211 cmLListDeleteLList(&ueFcfsCb->hqRetxCb.ulRetxHqList);
212 cmLListDeleteLList(&ueFcfsCb->hqRetxCb.dlRetxHqList);
214 SCH_FREE(ueFcfsCb, sizeof(SchFcfsUeCb));
215 ueCb->schSpcUeCb = NULLP;
219 /*******************************************************************
221 * @brief Intializes HARQ Process control block
225 * Function : schFcfsInitDlHqProcCb
227 * Functionality: Intitialized parameters of HARQ process control
228 * block specific to FCFS scheduling in Downlink
230 * @params[in] Pointer to Downlink HARQ Process control block
234 * ****************************************************************/
235 uint8_t schFcfsInitDlHqProcCb(SchDlHqProcCb *hqP)
237 SchFcfsHqProcCb *fcfsHqP;
239 SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
242 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsInitDlHqProcCb");
246 cmLListInit(&fcfsHqP->lcCb.dedLcList);
247 cmLListInit(&fcfsHqP->lcCb.defLcList);
248 hqP->schSpcDlHqProcCb = (void *)fcfsHqP;
253 /*******************************************************************
255 * @brief Handles HARQ Process delete request
259 * Function : schFcfsDeleteDlHqProcCb
261 * Functionality: Deletes HARQ Process parameters specific to
262 * FCFS scheduling in Downlink
264 * @params[in] Pointer to Downlink HARQ Process control block
267 * ****************************************************************/
268 void schFcfsDeleteDlHqProcCb(SchDlHqProcCb *hqP)
270 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcDlHqProcCb;
271 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
272 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
273 SCH_FREE(fcfsHqP, sizeof(SchFcfsHqProcCb));
274 hqP->schSpcDlHqProcCb = NULLP;
277 /*******************************************************************
279 * @brief Intializes HARQ Process control block
283 * Function : schFcfsInitUlHqProcCb
285 * Functionality: Intitialized parameters of HARQ process control
286 * block specific to FCFS scheduling in Uplink
288 * @params[in] Pointer to Uplink HARQ Process control block
292 * ****************************************************************/
293 uint8_t schFcfsInitUlHqProcCb(SchUlHqProcCb *hqP)
295 SchFcfsHqProcCb *fcfsHqP;
297 SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
300 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsInitUlHqProcCb");
303 cmLListInit(&fcfsHqP->lcCb.dedLcList);
304 cmLListInit(&fcfsHqP->lcCb.defLcList);
305 hqP->schSpcUlHqProcCb = (void *)fcfsHqP;
310 /*******************************************************************
312 * @brief Handled Deletion of HARQ Process control block
316 * Function : schFcfsDeleteUlHqProcCb
318 * Functionality: Deletes HARQ Process parameters specific to
319 * FCFS scheduling in Uplink
321 * @params[in] Pointer to Uplink HARQ Process Control block
324 * ****************************************************************/
325 void schFcfsDeleteUlHqProcCb(SchUlHqProcCb *hqP)
327 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcUlHqProcCb;
328 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
329 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
330 SCH_FREE(fcfsHqP, sizeof(SchFcfsHqProcCb));
331 hqP->schSpcUlHqProcCb = NULLP;
334 /*******************************************************************
336 * @brief Handles freeing of HARQ Process
340 * Function : schFcfsFreeDlHqProcCb
342 * Functionality: Frees HARQ Process parameters specific to
343 * FCFS scheduling in Downlink when HARQ process becomes free
345 * @params[in] Pointer to HARQ process control block
348 * ****************************************************************/
349 void schFcfsFreeDlHqProcCb(SchDlHqProcCb *hqP)
351 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcDlHqProcCb;
353 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
354 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
357 /*******************************************************************
359 * @brief Handles freeing of HARQ Process
363 * Function : schFcfsFreeUlHqProcCb
365 * Functionality: Frees HARQ Process parameters specific to
366 * FCFS scheduling in Uplink when HARQ process becomes free
368 * @params[in] Pointer to HARQ process control block
371 * ****************************************************************/
372 void schFcfsFreeUlHqProcCb(SchUlHqProcCb *hqP)
374 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcUlHqProcCb;
376 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
377 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
380 /*******************************************************************
382 * @brief Adds HARQ process to retransmission list
386 * Function : schFcfsAddToDlHqRetxList
388 * Functionality: Adds HARQ process to retransmission list
390 * @params[in] Pointer to Downlink HARQ Process
393 * ****************************************************************/
394 void schFcfsAddToDlHqRetxList(SchDlHqProcCb *hqP)
396 SchFcfsUeCb *fcfsUeCb;
398 fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
399 cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);
401 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
403 schDrxStrtDlHqRttTmr(hqP);
408 schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
412 /*******************************************************************
414 * @brief Adds HARQ process to retransmission list
418 * Function : schFcfsAddToUlHqRetxList
420 * Functionality: Adds HARQ process to retransmission list
422 * @params[in] Pointer to Uplink HARQ Process
425 * ****************************************************************/
426 void schFcfsAddToUlHqRetxList(SchUlHqProcCb *hqP)
428 SchFcfsUeCb *fcfsUeCb;
430 fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
431 cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);
433 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
435 schDrxStrtUlHqRttTmr(hqP);
440 schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
444 /*******************************************************************
446 * @brief Add UE to ueToBeScheduled List
450 * Function : schFcfsAddUeToSchedule
453 * Search if UE entry present in the list
455 * If no, add UE to the list
457 * @params[in] Cell control block
460 * @return ROK - success
463 * ****************************************************************/
464 uint8_t schFcfsAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
466 SchFcfsCellCb *fcfsCellCb = NULLP;
470 fcfsCellCb = (SchFcfsCellCb *)cellCb->schSpcCell;
471 /* Search if UE entry is already present in ueToBeScheduled list.
472 * If yes, another entry for same UE not needed. Hence, return */
473 node = fcfsCellCb->ueToBeScheduled.first;
476 ueId = (uint8_t *)node->node;
477 if(*ueId == ueIdToAdd)
482 /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
483 SCH_ALLOC(ueId, sizeof(uint8_t));
486 DU_LOG("\nERROR --> SCH : Memory allocation failure in schFcfsAddUeToSchedule");
490 if(addNodeToLList(&fcfsCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
492 DU_LOG("\nERROR --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
498 /*******************************************************************
500 * @brief Handled CRC Indication
504 * Function : schFcfsProcessCrcInd
506 * Functionality: Processes CRC Indication as required for FCFS
509 * @params[in] Pointer to Cell control block
513 * ****************************************************************/
514 void schFcfsProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
516 schFcfsAddUeToSchedule(cellCb, ueId);
519 /*******************************************************************
521 * @brief Processes Buffer Occupancy report from RLC
525 * Function : schFcfsDlRlcBoInfo
527 * Functionality: Process buffer occupany report
532 * ****************************************************************/
533 void schFcfsDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
535 schFcfsAddUeToSchedule(cellCb, ueId);
538 /*******************************************************************
540 * @brief Processes BSR request
544 * Function : schFcfsBsr
546 * Functionality: Processes BSR as per FCFS scheduling
548 * @params[in] Pointer to Cell
552 * ****************************************************************/
553 void schFcfsBsr(SchCellCb *cellCb, uint16_t ueId)
555 schFcfsAddUeToSchedule(cellCb, ueId);
558 /*******************************************************************
560 * @brief Processed UCI Indication
564 * Function : schFcfsSrUciInd
566 * Functionality: Processing of UCI indication specific to
569 * @params[in] Pointer to Cell
573 * ****************************************************************/
574 void schFcfsSrUciInd(SchCellCb *cellCb, uint16_t ueId)
576 schFcfsAddUeToSchedule(cellCb, ueId);
579 /*******************************************************************
581 * @brief Processing of RACH Indication
585 * Function : schFcfsProcessRachInd
587 * Functionality: Processing of RACH Indication specific to
590 * @params[in] Pointer to Cell Cb
594 * ****************************************************************/
595 void schFcfsProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
597 schFcfsAddUeToSchedule(cellCb, ueId);
600 /*******************************************************************
602 * @brief Processing of DL HARQ Indication
606 * Function : SchFcfsDlHarqInd
613 * ****************************************************************/
614 void SchFcfsDlHarqInd()
619 /*******************************************************************
621 * @brief Processing of Paging indication
625 * Function : schFcfsPagingInd
632 * ****************************************************************/
633 void schFcfsPagingInd()
638 /*******************************************************************
640 * @brief Processing of RACH Resource Request
644 * Function : schFcfsRachRsrcReq
651 * ****************************************************************/
652 void schFcfsRachRsrcReq()
657 /*******************************************************************
659 * @brief Processing of RACH Resource Release
663 * Function : schFcfsRachRsrcRel
670 * ****************************************************************/
671 void schFcfsRachRsrcRel()
676 /*******************************************************************
678 * @brief Remove entry from HARQ retransmission list
682 * Function : schFcfsRemoveFrmDlHqRetxList
684 * Functionality: Remove entry from HARQ retransmission list
686 * @params[in] Pointer to UE
690 * ****************************************************************/
691 void schFcfsRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
693 SchFcfsUeCb *fcfsUeCb;
695 fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
696 cmLListDelFrm(&fcfsUeCb->hqRetxCb.dlRetxHqList, node);
699 /*******************************************************************
701 * @brief Remove entry from HARQ retransmission list
705 * Function : schFcfsRemoveFrmUlHqRetxList
707 * Functionality: Remove entry from HARQ retransmission list
709 * @params[in] Pointer to UE
713 * ****************************************************************/
714 void schFcfsRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
716 SchFcfsUeCb *fcfsUeCb;
718 fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
719 cmLListDelFrm(&fcfsUeCb->hqRetxCb.ulRetxHqList, node);
722 /*******************************************************************
724 * @brief Remove UE from Scheduling List
728 * Function : schFcfsRemoveUeFrmScheduleLst
730 * Functionality: Remove UE from Scheduling List
732 * @params[in] Pointer to Cell
736 * ****************************************************************/
737 void schFcfsRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
739 SchFcfsCellCb *fcfsCell;
741 fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
742 SCH_FREE(node->node, sizeof(uint8_t));
743 deleteNodeFromLList(&fcfsCell->ueToBeScheduled, node);
746 /*******************************************************************
748 * @brief Handler to calculate TBS size for BSR requested
752 * Function : schFcfsCalculateUlTbs
754 * Functionality: Function will note the required TBS for each LCGIDX and use
755 * the Priority LCG List and RRM policy to allocate the TBS size
757 * @params [in] ueCb (Pointer to UE CB)
758 * [in] puschTime (Time slot where PUSCH will be sent)
759 * [in] symbLen (No of Symbols used for PUSCH transmission)
760 * [out] startPrb(Pointer to startPRB which will be calculated while
761 * finding the best Free Block)
762 * [out] totTBS(Pointer to total TBS size)
763 * [in] isRetx (to indicate retransmission)
764 * [in] hqP (UL Harq process pointer)
766 * @return uint8_t : ROK > Scheduling of UL grant is successful
767 * RFAILED > vice versa
769 * ****************************************************************/
770 uint8_t schFcfsCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
771 uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchFcfsHqProcCb *fcfsHqP)
774 CmLListCp *lcLL = NULLP;
775 uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
776 uint16_t rsvdDedicatedPRB;
781 for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
783 if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
788 /*TODO: lcgIdx and LCID has been implemented as one to one mapping.
789 * Need to check the mapping to figure out the LCID and lcgIdx once L2
790 * spec specifies any logic*/
792 if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
794 lcLL = &(fcfsHqP->lcCb.dedLcList);
795 rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
799 lcLL = &(fcfsHqP->lcCb.defLcList);
802 /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
803 if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
805 DU_LOG("\nERROR --> SCH: LcgId:%d updation failed",lcId);
810 if ((fcfsHqP->lcCb.defLcList.count == 0) && (fcfsHqP->lcCb.dedLcList.count == 0))
812 if( (ueCb->srRcvd) || (isRetx) )
814 *startPrb = MAX_NUM_RB;
815 *totTBS = schCalcTbSize(UL_GRANT_SIZE);
817 /*Returning true when NO Grant is there for UE as this is not scheduling
822 maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
824 /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
825 * the list based on RRM policy*/
827 /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or
828 * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
831 mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
832 if((fcfsHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
834 fcfsHqP->lcCb.sharedNumPrb = maxFreePRB;
835 DU_LOG("\nDEBUG --> SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
836 fcfsHqP->lcCb.sharedNumPrb);
838 /*PRB Alloc for Default LCs*/
839 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
840 &(fcfsHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
844 fcfsHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
846 /*PRB Alloc for Dedicated LCs*/
847 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
848 &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
849 NULLP, &(ueCb->srRcvd));
851 /*PRB Alloc for Default LCs*/
852 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
853 &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
854 NULLP,&(ueCb->srRcvd));
857 /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
858 * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/
859 if(fcfsHqP->lcCb.dedLcList.count != 0)
860 updateGrantSizeForBoRpt(&(fcfsHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
862 updateGrantSizeForBoRpt(&(fcfsHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
864 /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
869 DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
873 /*Schedule the LC for next slot*/
874 DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
881 /*******************************************************************
883 * @brief Grants resources to LC in uplink
887 * Function : schProcessSrOrBsrReq
890 * Grants resources to LC in uplink
892 * @params[in] PDCCH Time
901 *******************************************************************/
902 uint8_t schFcfsScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
905 SchFcfsHqProcCb *fcfsHqProcCb;
906 uint8_t ret = RFAILED;
907 uint16_t startPrb = 0;
908 uint32_t totDataReq = 0; /* in bytes */
909 SchUeCb *ueCb = NULLP;
910 SchPuschInfo *puschInfo = NULLP;
911 DciInfo *dciInfo = NULLP;
913 cell = (*hqP)->hqEnt->cell;
914 ueCb = (*hqP)->hqEnt->ue;
915 fcfsHqProcCb = (SchFcfsHqProcCb *)(*hqP)->schSpcUlHqProcCb;
916 ret = schFcfsCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, fcfsHqProcCb);
918 if(totDataReq > 0 && ret == ROK)
920 SCH_ALLOC(dciInfo, sizeof(DciInfo));
923 DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc");
926 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
927 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
929 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
933 cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
934 memset(dciInfo,0,sizeof(DciInfo));
936 /* Update PUSCH allocation */
937 if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
939 if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo[ueCb->ueId])
941 puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo[ueCb->ueId];
942 if(puschInfo != NULLP)
944 /* Fill DCI for UL grant */
945 schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
946 ueCb->srRcvd = false;
947 ueCb->bsrRcvd = false;
948 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
949 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
950 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
951 cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);
956 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
957 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
958 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
963 /*******************************************************************
965 * @brief Grants resources to LC in downlink
969 * Function : schFcfsScheduleDlLc
971 * Functionality: Grants resources to LC in uplink
973 * @params[in] PDCCH Time
978 * ****************************************************************/
979 uint32_t schFcfsScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols, \
980 uint16_t *startPrb, bool isRetx, SchDlHqProcCb **hqP)
982 SchFcfsHqProcCb *fcfsHqProcCb;
985 uint16_t maxFreePRB = 0;
987 uint32_t accumalatedSize = 0;
988 CmLListCp *lcLL = NULLP;
989 uint16_t rsvdDedicatedPRB = 0;
990 DlMsgSchInfo *dciSlotAlloc;
992 /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
993 * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
994 * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
995 * else if only Default list is present then first node in this List will add this overhead len*/
996 bool isTxPayloadLenAdded = FALSE;
998 ueCb = (*hqP)->hqEnt->ue;
999 dciSlotAlloc = (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1];
1000 fcfsHqProcCb = (SchFcfsHqProcCb *)((*hqP)->schSpcDlHqProcCb);
1002 if (isRetx == FALSE)
1004 /*Re-Initalization per UE*/
1005 /* scheduled LC data fill */
1006 dciSlotAlloc->transportBlock[0].numLc = 0;
1007 isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
1008 accumalatedSize = 0;
1010 for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
1012 if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
1014 /*Check the LC is Dedicated or default and accordingly LCList will
1016 if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
1018 lcLL = &(fcfsHqProcCb->lcCb.dedLcList);
1019 rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1023 lcLL = &(fcfsHqProcCb->lcCb.defLcList);
1026 /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
1027 if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
1028 (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
1030 DU_LOG("\nERROR --> SCH : Updation in LC List Failed");
1031 /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1032 if(!dciSlotAlloc->dlMsgPdschCfg)
1034 SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1035 (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1037 return accumalatedSize;
1042 if ((fcfsHqProcCb->lcCb.defLcList.count == 0) && (fcfsHqProcCb->lcCb.dedLcList.count == 0))
1044 DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n");
1045 UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1047 /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1048 if(!dciSlotAlloc->dlMsgPdschCfg)
1050 SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1051 (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1053 /*TRUE because this UE has nothing to be scheduled*/
1054 return accumalatedSize;
1058 /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1059 maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, startPrb, DIR_DL);
1061 /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1062 * the list based on RRM policy*/
1064 /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or
1065 * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1070 mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1072 if((fcfsHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1074 fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1075 DU_LOG("\nDEBUG --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1076 fcfsHqProcCb->lcCb.sharedNumPrb);
1078 /*PRB Alloc for Default LCs*/
1079 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1080 &(fcfsHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1084 fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1085 /*PRB Alloc for Dedicated LCs*/
1086 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1087 &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1089 /*PRB Alloc for Default LCs*/
1090 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1091 &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1096 /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1097 * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1098 if (isRetx == FALSE)
1100 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
1101 updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1103 updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1107 accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1110 /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1111 if (!accumalatedSize)
1115 DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
1119 /*Schedule the LC for next slot*/
1120 DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
1122 /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1123 * Allocation can be done in next slot*/
1124 accumalatedSize = 0;
1127 return accumalatedSize;
1130 /*******************************************************************
1132 * @brief Scheduling of Slots in UL And DL
1136 * Function : schFcfsScheduleSlot
1138 * Functionality: Scheduling of slots in UL and DL specific to
1141 * @params[in] Pointer to Cell
1143 * Scheduler instance
1146 * ****************************************************************/
1147 void schFcfsScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1149 SchFcfsCellCb *fcfsCell;
1150 SchFcfsUeCb *fcfsUeCb;
1151 SchDlHqProcCb *hqP = NULLP;
1152 SchUlHqProcCb *ulHqP = NULLP;
1153 CmLList *pendingUeNode;
1155 uint8_t ueId, ueCount = 0;
1156 bool isRarPending = false, isRarScheduled = false;
1157 bool isMsg4Pending = false, isMsg4Scheduled = false;
1158 bool isDlMsgPending = false, isDlMsgScheduled = false;
1159 bool isUlGrantPending = false, isUlGrantScheduled = false;
1161 fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
1163 /* Select first UE in the linked list to be scheduled next */
1164 pendingUeNode = fcfsCell->ueToBeScheduled.first;
1165 ueCount = fcfsCell->ueToBeScheduled.count;
1167 while(pendingUeNode && ueCount > 0)
1169 /*Since Multi-UE perTTI is not supported, re-init following parameters.*/
1170 isRarPending = false; isRarScheduled = false;
1171 isMsg4Pending = false; isMsg4Scheduled = false;
1172 isDlMsgPending = false; isDlMsgScheduled = false;
1173 isUlGrantPending = false; isUlGrantScheduled = false;
1174 if(pendingUeNode->node)
1176 ueId = *(uint8_t *)(pendingUeNode->node);
1177 fcfsUeCb = (SchFcfsUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1179 /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and
1180 * PUSCH to receive MSG3 as per k0-k2 configuration*/
1181 if(cell->raReq[ueId-1] != NULLP)
1183 isRarPending = true;
1184 isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1187 /*MSG3 retransmisson*/
1188 if(cell->raCb[ueId-1].retxMsg3HqProc)
1190 schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1193 /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1194 * PUCCH to receive UL msg as per k0-k1 configuration */
1195 if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1197 /* Retransmission of MSG4 */
1198 isMsg4Pending = true;
1199 if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1200 isMsg4Scheduled = true;
1204 /* First transmission of MSG4 */
1205 if(cell->raCb[ueId-1].msg4recvd)
1207 isMsg4Pending = true;
1208 if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1209 isMsg4Scheduled = true;
1211 /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1212 if(!isMsg4Scheduled)
1213 schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1217 if(isRarPending || isMsg4Pending)
1219 /* If RAR or MSG is successfully scheduled then
1220 * remove UE from linked list since no pending msgs for this UE */
1221 if(isRarScheduled || isMsg4Scheduled)
1223 schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1225 /* If RAR/MSG4 is pending but couldnt be scheduled then,
1226 * put this UE at the end of linked list to be scheduled later */
1229 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1234 if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1236 if(pendingUeNode->node)
1238 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1248 node = fcfsUeCb->hqRetxCb.dlRetxHqList.first;
1251 /* DL Data ReTransmisson */
1252 isDlMsgPending = true;
1253 isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1254 if(isDlMsgScheduled)
1257 schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1259 schFcfsRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1264 /* DL Data new transmission */
1265 if((cell->boIndBitMap) & (1<<ueId))
1267 isDlMsgPending = true;
1268 isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1270 /* If DL scheduling failed, free the newly assigned HARQ process */
1271 if(!isDlMsgScheduled)
1272 schDlReleaseHqProcess(hqP);
1276 schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
1283 if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxUlUeActiveStatus != true))
1285 if(pendingUeNode->node)
1287 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1293 /* Scheduling of UL grant */
1296 node = fcfsUeCb->hqRetxCb.ulRetxHqList.first;
1299 /* UL Data ReTransmisson */
1300 isUlGrantPending = true;
1301 isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1302 if(isUlGrantScheduled)
1305 schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1307 schFcfsRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1312 /* UL Data new transmission */
1313 if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1315 isUlGrantPending = true;
1316 isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1317 if(!isUlGrantScheduled)
1318 schUlReleaseHqProcess(ulHqP, FALSE);
1322 schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
1328 if(isUlGrantPending || isDlMsgPending)
1330 if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1332 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1336 schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1341 if(!isUlGrantPending && !isDlMsgPending && !isRarPending && !isMsg4Pending)
1343 DU_LOG("\nERROR --> SCH: In SchFcfsScheduleSlot, UE:%d is wrongly queued\
1344 in Pending UE List without any actions, Removing the UE from the list",ueId);
1345 schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1347 if(cell->schDlSlotInfo[slotInd->slot]->prbAlloc.numPrbAlloc >= MAX_NUM_RB)
1349 DU_LOG("\nINFO --> SCH: No PRB available to proceed with next UE");
1352 pendingUeNode = fcfsCell->ueToBeScheduled.first;
1357 /*******************************************************************
1359 * @brief Initializes all function pointers to FCFS function handler
1363 * Function : schFcfsAllApisInit
1365 * Functionality: Initializes all function pointers to FCFS
1368 * @params[in] Function pointer array
1371 * ****************************************************************/
1372 void schFcfsAllApisInit(SchAllApis *allFcfsApi)
1374 /* Interface API function pointers */
1375 allFcfsApi->SchCellCfgReq = schFcfsCellCfgReq;
1376 allFcfsApi->SchCellDeleteReq = schFcfsCellDelReq;
1377 allFcfsApi->SchAddUeConfigReq = SchFcfsAddUeConfigReq;
1378 allFcfsApi->SchModUeConfigReq = SchFcfsModUeConfigReq;
1379 allFcfsApi->SchUeDeleteReq = SchFcfsUeDeleteReq;
1380 allFcfsApi->SchDlHarqInd = SchFcfsDlHarqInd;
1381 allFcfsApi->SchCrcInd = schFcfsProcessCrcInd;
1382 allFcfsApi->SchRachInd = schFcfsProcessRachInd;
1383 allFcfsApi->SchPagingInd = schFcfsPagingInd;
1384 allFcfsApi->SchRachRsrcReq = schFcfsRachRsrcReq;
1385 allFcfsApi->SchRachRsrcRel = schFcfsRachRsrcRel;
1386 allFcfsApi->SchDlRlcBoInfo = schFcfsDlRlcBoInfo;
1387 allFcfsApi->SchSrUciInd = schFcfsSrUciInd;
1388 allFcfsApi->SchBsr = schFcfsBsr;
1390 /* Internal API function pointers */
1391 allFcfsApi->SchAddToDlHqRetxList = schFcfsAddToDlHqRetxList;
1392 allFcfsApi->SchAddToUlHqRetxList = schFcfsAddToUlHqRetxList;
1393 allFcfsApi->SchRemoveFrmDlHqRetxList = schFcfsRemoveFrmDlHqRetxList;
1394 allFcfsApi->SchRemoveFrmUlHqRetxList = schFcfsRemoveFrmUlHqRetxList;
1395 allFcfsApi->SchAddUeToSchedule = schFcfsAddUeToSchedule;
1396 allFcfsApi->SchRemoveUeFrmScheduleLst = schFcfsRemoveUeFrmScheduleLst;
1397 allFcfsApi->SchInitDlHqProcCb = schFcfsInitDlHqProcCb;
1398 allFcfsApi->SchInitUlHqProcCb = schFcfsInitUlHqProcCb;
1399 allFcfsApi->SchFreeDlHqProcCb = schFcfsFreeDlHqProcCb;
1400 allFcfsApi->SchFreeUlHqProcCb = schFcfsFreeUlHqProcCb;
1401 allFcfsApi->SchDeleteDlHqProcCb = schFcfsDeleteDlHqProcCb;
1402 allFcfsApi->SchDeleteUlHqProcCb = schFcfsDeleteUlHqProcCb;
1403 allFcfsApi->SchScheduleSlot = schFcfsScheduleSlot;
1404 allFcfsApi->SchScheduleDlLc = schFcfsScheduleDlLc;
1405 allFcfsApi->SchScheduleUlLc = schFcfsScheduleUlLc;
1407 /**********************************************************************
1409 **********************************************************************/