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"
44 #include "sch_utils.h"
50 /*******************************************************************
52 * @brief Function to handle Cell configuration request
56 * Function : schFcfsCellCfgReq
58 * Functionality: This function configures cell paremeters
59 * required for FCFS scheduling
61 * @params[in] SchCellCb *cellCb, Cell control block
65 * ****************************************************************/
66 uint8_t schFcfsCellCfgReq(SchCellCb *cellCb)
68 SchFcfsCellCb *fcfsCellCb = NULLP;
70 SCH_ALLOC(fcfsCellCb, sizeof(SchFcfsCellCb));
73 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsCellCfgReq");
76 cmLListInit(&fcfsCellCb->ueToBeScheduled);
77 cellCb->schSpcCell = (void *)fcfsCellCb;
81 /*******************************************************************
83 * @brief Function to handle Cell configuration request
87 * Function : schFcfsCellDelReq
89 * Functionality: This function deletes/frees cell params
90 * specific to FCFS scheduling
92 * @params[in] Pointer to Cell control block
95 * ****************************************************************/
96 void schFcfsCellDelReq(SchCellCb *cellCb)
98 SchFcfsCellCb *fcfsCellCb = NULLP;
99 CmLList *node=NULL, *next=NULL;
101 fcfsCellCb = (SchFcfsCellCb *)cellCb->schSpcCell;
102 /* Remove all UE from ueToBeScheduled list and deallocate */
103 node = fcfsCellCb->ueToBeScheduled.first;
107 SCH_FREE(node->node, sizeof(uint8_t));
108 cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
109 SCH_FREE(node, sizeof(CmLList));
112 SCH_FREE(fcfsCellCb, sizeof(SchFcfsCellCb));
113 cellCb->schSpcCell = NULLP;
116 /*******************************************************************
118 * @brief Function to handle UE configuration request
122 * Function : SchFcfsAddUeConfigReq
124 * Functionality: Adds/Configures UE parameters required for
127 * @params[in] Pointer to UE control block
131 * ****************************************************************/
132 uint8_t SchFcfsAddUeConfigReq(SchUeCb *ueCb)
134 SchFcfsUeCb *ueFcfsCb;
136 SCH_ALLOC(ueFcfsCb, sizeof(SchFcfsHqCb));
139 DU_LOG("\nERROR --> SCH: Memory allocation failed in SchFcfsAddUeConfigReq");
143 cmLListInit(&ueFcfsCb->hqRetxCb.ulRetxHqList);
144 cmLListInit(&ueFcfsCb->hqRetxCb.dlRetxHqList);
145 ueCb->schSpcUeCb = (void *)ueFcfsCb;
150 /*******************************************************************
152 * @brief Handles UE reconfiguration request
156 * Function : SchFcfsModUeConfigReq
160 * @params[in] Pointer to UE control block
163 * ****************************************************************/
164 void SchFcfsModUeConfigReq(SchUeCb *ueCb)
166 /*TBD: No action required for FCFS*/
170 /*******************************************************************
172 * @brief Handles UE Delete Request
176 * Function : SchFcfsUeDeleteReq
178 * Functionality: Deletes/Frees UE parameters specific to
181 * @params[in] Pointer to UE control block
184 * ****************************************************************/
185 void SchFcfsUeDeleteReq(SchUeCb *ueCb)
187 SchFcfsCellCb *fcfsCellCb = NULLP;
188 SchFcfsUeCb *ueFcfsCb = NULLP;
189 CmLList *node=NULL, *next=NULL;
192 fcfsCellCb = (SchFcfsCellCb *)ueCb->cellCb->schSpcCell;
193 /* Remove all UE from ueToBeScheduled list and deallocate */
194 node = fcfsCellCb->ueToBeScheduled.first;
198 ueId = *(uint8_t *)node->node;
199 if(ueId == ueCb->ueId)
201 SCH_FREE(node->node, sizeof(uint8_t));
202 cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
203 SCH_FREE(node, sizeof(CmLList));
209 ueFcfsCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
210 cmLListDeleteLList(&ueFcfsCb->hqRetxCb.ulRetxHqList);
211 cmLListDeleteLList(&ueFcfsCb->hqRetxCb.dlRetxHqList);
213 SCH_FREE(ueFcfsCb, sizeof(SchFcfsUeCb));
214 ueCb->schSpcUeCb = NULLP;
218 /*******************************************************************
220 * @brief Intializes HARQ Process control block
224 * Function : schFcfsInitDlHqProcCb
226 * Functionality: Intitialized parameters of HARQ process control
227 * block specific to FCFS scheduling in Downlink
229 * @params[in] Pointer to Downlink HARQ Process control block
233 * ****************************************************************/
234 uint8_t schFcfsInitDlHqProcCb(SchDlHqProcCb *hqP)
236 SchFcfsHqProcCb *fcfsHqP;
238 SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
241 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsInitDlHqProcCb");
245 cmLListInit(&fcfsHqP->lcCb.dedLcList);
246 cmLListInit(&fcfsHqP->lcCb.defLcList);
247 hqP->schSpcDlHqProcCb = (void *)fcfsHqP;
252 /*******************************************************************
254 * @brief Handles HARQ Process delete request
258 * Function : schFcfsDeleteDlHqProcCb
260 * Functionality: Deletes HARQ Process parameters specific to
261 * FCFS scheduling in Downlink
263 * @params[in] Pointer to Downlink HARQ Process control block
266 * ****************************************************************/
267 void schFcfsDeleteDlHqProcCb(SchDlHqProcCb *hqP)
269 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcDlHqProcCb;
270 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
271 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
272 SCH_FREE(fcfsHqP, sizeof(SchFcfsHqProcCb));
273 hqP->schSpcDlHqProcCb = NULLP;
276 /*******************************************************************
278 * @brief Intializes HARQ Process control block
282 * Function : schFcfsInitUlHqProcCb
284 * Functionality: Intitialized parameters of HARQ process control
285 * block specific to FCFS scheduling in Uplink
287 * @params[in] Pointer to Uplink HARQ Process control block
291 * ****************************************************************/
292 uint8_t schFcfsInitUlHqProcCb(SchUlHqProcCb *hqP)
294 SchFcfsHqProcCb *fcfsHqP;
296 SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
299 DU_LOG("\nERROR --> SCH: Memory allocation failed in schFcfsInitUlHqProcCb");
302 cmLListInit(&fcfsHqP->lcCb.dedLcList);
303 cmLListInit(&fcfsHqP->lcCb.defLcList);
304 hqP->schSpcUlHqProcCb = (void *)fcfsHqP;
309 /*******************************************************************
311 * @brief Handled Deletion of HARQ Process control block
315 * Function : schFcfsDeleteUlHqProcCb
317 * Functionality: Deletes HARQ Process parameters specific to
318 * FCFS scheduling in Uplink
320 * @params[in] Pointer to Uplink HARQ Process Control block
323 * ****************************************************************/
324 void schFcfsDeleteUlHqProcCb(SchUlHqProcCb *hqP)
326 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcUlHqProcCb;
327 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
328 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
329 SCH_FREE(fcfsHqP, sizeof(SchFcfsHqProcCb));
330 hqP->schSpcUlHqProcCb = NULLP;
333 /*******************************************************************
335 * @brief Handles freeing of HARQ Process
339 * Function : schFcfsFreeDlHqProcCb
341 * Functionality: Frees HARQ Process parameters specific to
342 * FCFS scheduling in Downlink when HARQ process becomes free
344 * @params[in] Pointer to HARQ process control block
347 * ****************************************************************/
348 void schFcfsFreeDlHqProcCb(SchDlHqProcCb *hqP)
350 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcDlHqProcCb;
352 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
353 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
356 /*******************************************************************
358 * @brief Handles freeing of HARQ Process
362 * Function : schFcfsFreeUlHqProcCb
364 * Functionality: Frees HARQ Process parameters specific to
365 * FCFS scheduling in Uplink when HARQ process becomes free
367 * @params[in] Pointer to HARQ process control block
370 * ****************************************************************/
371 void schFcfsFreeUlHqProcCb(SchUlHqProcCb *hqP)
373 SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcUlHqProcCb;
375 cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
376 cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
379 /*******************************************************************
381 * @brief Adds HARQ process to retransmission list
385 * Function : schFcfsAddToDlHqRetxList
387 * Functionality: Adds HARQ process to retransmission list
389 * @params[in] Pointer to Downlink HARQ Process
392 * ****************************************************************/
393 void schFcfsAddToDlHqRetxList(SchDlHqProcCb *hqP)
395 SchFcfsUeCb *fcfsUeCb;
397 fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
398 cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);
400 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
402 schDrxStrtDlHqRttTmr(hqP);
407 schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
411 /*******************************************************************
413 * @brief Adds HARQ process to retransmission list
417 * Function : schFcfsAddToUlHqRetxList
419 * Functionality: Adds HARQ process to retransmission list
421 * @params[in] Pointer to Uplink HARQ Process
424 * ****************************************************************/
425 void schFcfsAddToUlHqRetxList(SchUlHqProcCb *hqP)
427 SchFcfsUeCb *fcfsUeCb;
429 fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
430 cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);
432 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
434 schDrxStrtUlHqRttTmr(hqP);
439 schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
443 /*******************************************************************
445 * @brief Add UE to ueToBeScheduled List
449 * Function : schFcfsAddUeToSchedule
452 * Search if UE entry present in the list
454 * If no, add UE to the list
456 * @params[in] Cell control block
459 * @return ROK - success
462 * ****************************************************************/
463 uint8_t schFcfsAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
465 SchFcfsCellCb *fcfsCellCb = NULLP;
469 fcfsCellCb = (SchFcfsCellCb *)cellCb->schSpcCell;
470 /* Search if UE entry is already present in ueToBeScheduled list.
471 * If yes, another entry for same UE not needed. Hence, return */
472 node = fcfsCellCb->ueToBeScheduled.first;
475 ueId = (uint8_t *)node->node;
476 if(*ueId == ueIdToAdd)
481 /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
482 SCH_ALLOC(ueId, sizeof(uint8_t));
485 DU_LOG("\nERROR --> SCH : Memory allocation failure in schFcfsAddUeToSchedule");
489 if(addNodeToLList(&fcfsCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
491 DU_LOG("\nERROR --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
497 /*******************************************************************
499 * @brief Handled CRC Indication
503 * Function : schFcfsProcessCrcInd
505 * Functionality: Processes CRC Indication as required for FCFS
508 * @params[in] Pointer to Cell control block
512 * ****************************************************************/
513 void schFcfsProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
515 schFcfsAddUeToSchedule(cellCb, ueId);
518 /*******************************************************************
520 * @brief Processes Buffer Occupancy report from RLC
524 * Function : schFcfsDlRlcBoInfo
526 * Functionality: Process buffer occupany report
531 * ****************************************************************/
532 void schFcfsDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
534 schFcfsAddUeToSchedule(cellCb, ueId);
537 /*******************************************************************
539 * @brief Processes BSR request
543 * Function : schFcfsBsr
545 * Functionality: Processes BSR as per FCFS scheduling
547 * @params[in] Pointer to Cell
551 * ****************************************************************/
552 void schFcfsBsr(SchCellCb *cellCb, uint16_t ueId)
554 schFcfsAddUeToSchedule(cellCb, ueId);
557 /*******************************************************************
559 * @brief Processed UCI Indication
563 * Function : schFcfsSrUciInd
565 * Functionality: Processing of UCI indication specific to
568 * @params[in] Pointer to Cell
572 * ****************************************************************/
573 void schFcfsSrUciInd(SchCellCb *cellCb, uint16_t ueId)
575 schFcfsAddUeToSchedule(cellCb, ueId);
578 /*******************************************************************
580 * @brief Processing of RACH Indication
584 * Function : schFcfsProcessRachInd
586 * Functionality: Processing of RACH Indication specific to
589 * @params[in] Pointer to Cell Cb
593 * ****************************************************************/
594 void schFcfsProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
596 schFcfsAddUeToSchedule(cellCb, ueId);
599 /*******************************************************************
601 * @brief Processing of DL HARQ Indication
605 * Function : SchFcfsDlHarqInd
612 * ****************************************************************/
613 void SchFcfsDlHarqInd()
618 /*******************************************************************
620 * @brief Processing of Paging indication
624 * Function : schFcfsPagingInd
631 * ****************************************************************/
632 void schFcfsPagingInd()
637 /*******************************************************************
639 * @brief Processing of RACH Resource Request
643 * Function : schFcfsRachRsrcReq
650 * ****************************************************************/
651 void schFcfsRachRsrcReq()
656 /*******************************************************************
658 * @brief Processing of RACH Resource Release
662 * Function : schFcfsRachRsrcRel
669 * ****************************************************************/
670 void schFcfsRachRsrcRel()
675 /*******************************************************************
677 * @brief Remove entry from HARQ retransmission list
681 * Function : schFcfsRemoveFrmDlHqRetxList
683 * Functionality: Remove entry from HARQ retransmission list
685 * @params[in] Pointer to UE
689 * ****************************************************************/
690 void schFcfsRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
692 SchFcfsUeCb *fcfsUeCb;
694 fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
695 cmLListDelFrm(&fcfsUeCb->hqRetxCb.dlRetxHqList, node);
698 /*******************************************************************
700 * @brief Remove entry from HARQ retransmission list
704 * Function : schFcfsRemoveFrmUlHqRetxList
706 * Functionality: Remove entry from HARQ retransmission list
708 * @params[in] Pointer to UE
712 * ****************************************************************/
713 void schFcfsRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
715 SchFcfsUeCb *fcfsUeCb;
717 fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
718 cmLListDelFrm(&fcfsUeCb->hqRetxCb.ulRetxHqList, node);
721 /*******************************************************************
723 * @brief Remove UE from Scheduling List
727 * Function : schFcfsRemoveUeFrmScheduleLst
729 * Functionality: Remove UE from Scheduling List
731 * @params[in] Pointer to Cell
735 * ****************************************************************/
736 void schFcfsRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
738 SchFcfsCellCb *fcfsCell;
740 fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
741 SCH_FREE(node->node, sizeof(uint8_t));
742 deleteNodeFromLList(&fcfsCell->ueToBeScheduled, node);
745 /*******************************************************************
747 * @brief Handler to calculate TBS size for BSR requested
751 * Function : schFcfsCalculateUlTbs
753 * Functionality: Function will note the required TBS for each LCGIDX and use
754 * the Priority LCG List and RRM policy to allocate the TBS size
756 * @params [in] ueCb (Pointer to UE CB)
757 * [in] puschTime (Time slot where PUSCH will be sent)
758 * [in] symbLen (No of Symbols used for PUSCH transmission)
759 * [out] startPrb(Pointer to startPRB which will be calculated while
760 * finding the best Free Block)
761 * [out] totTBS(Pointer to total TBS size)
762 * [in] isRetx (to indicate retransmission)
763 * [in] hqP (UL Harq process pointer)
765 * @return uint8_t : ROK > Scheduling of UL grant is successful
766 * RFAILED > vice versa
768 * ****************************************************************/
769 uint8_t schFcfsCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
770 uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchFcfsHqProcCb *fcfsHqP)
773 CmLListCp *lcLL = NULLP;
774 uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
775 uint16_t rsvdDedicatedPRB;
780 for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
782 if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
787 /*TODO: lcgIdx and LCID has been implemented as one to one mapping.
788 * Need to check the mapping to figure out the LCID and lcgIdx once L2
789 * spec specifies any logic*/
791 if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
793 lcLL = &(fcfsHqP->lcCb.dedLcList);
794 rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
798 lcLL = &(fcfsHqP->lcCb.defLcList);
801 /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
802 if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
804 DU_LOG("\nERROR --> SCH: LcgId:%d updation failed",lcId);
809 if ((fcfsHqP->lcCb.defLcList.count == 0) && (fcfsHqP->lcCb.dedLcList.count == 0))
811 if( (ueCb->srRcvd) || (isRetx) )
813 *startPrb = MAX_NUM_RB;
814 *totTBS = schCalcTbSize(UL_GRANT_SIZE);
816 /*Returning true when NO Grant is there for UE as this is not scheduling
821 maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
823 /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
824 * the list based on RRM policy*/
826 /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or
827 * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
830 mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
831 if((fcfsHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
833 fcfsHqP->lcCb.sharedNumPrb = maxFreePRB;
834 DU_LOG("\nDEBUG --> SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
835 fcfsHqP->lcCb.sharedNumPrb);
837 /*PRB Alloc for Default LCs*/
838 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
839 &(fcfsHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
843 fcfsHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
845 /*PRB Alloc for Dedicated LCs*/
846 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
847 &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
848 NULLP, &(ueCb->srRcvd));
850 /*PRB Alloc for Default LCs*/
851 prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
852 &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
853 NULLP,&(ueCb->srRcvd));
856 /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
857 * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/
858 if(fcfsHqP->lcCb.dedLcList.count != 0)
859 updateGrantSizeForBoRpt(&(fcfsHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
861 updateGrantSizeForBoRpt(&(fcfsHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
863 /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
868 DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
872 /*Schedule the LC for next slot*/
873 DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
880 /*******************************************************************
882 * @brief Grants resources to LC in uplink
886 * Function : schProcessSrOrBsrReq
889 * Grants resources to LC in uplink
891 * @params[in] PDCCH Time
900 *******************************************************************/
901 uint8_t schFcfsScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
904 SchFcfsHqProcCb *fcfsHqProcCb;
905 uint8_t ret = RFAILED;
906 uint16_t startPrb = 0;
907 uint32_t totDataReq = 0; /* in bytes */
909 SchPuschInfo *puschInfo;
910 DciInfo *dciInfo = NULLP;
912 cell = (*hqP)->hqEnt->cell;
913 ueCb = (*hqP)->hqEnt->ue;
914 fcfsHqProcCb = (SchFcfsHqProcCb *)(*hqP)->schSpcUlHqProcCb;
915 ret = schFcfsCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, fcfsHqProcCb);
917 if(totDataReq > 0 && ret == ROK)
919 SCH_ALLOC(dciInfo, sizeof(DciInfo));
922 DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc");
925 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
926 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
928 updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
932 cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
933 memset(dciInfo,0,sizeof(DciInfo));
935 /* Update PUSCH allocation */
936 if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
938 if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo)
940 puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo;
941 if(puschInfo != NULLP)
943 /* Fill DCI for UL grant */
944 schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
945 ueCb->srRcvd = false;
946 ueCb->bsrRcvd = false;
947 cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
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, bool isRetx, SchDlHqProcCb **hqP)
981 SchFcfsHqProcCb *fcfsHqProcCb;
984 uint16_t startPrb = 0, maxFreePRB = 0;
986 uint32_t accumalatedSize = 0;
987 CmLListCp *lcLL = NULLP;
988 uint16_t rsvdDedicatedPRB = 0;
989 DlMsgSchInfo *dciSlotAlloc;
991 /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
992 * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
993 * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
994 * else if only Default list is present then first node in this List will add this overhead len*/
995 bool isTxPayloadLenAdded = FALSE;
997 ueCb = (*hqP)->hqEnt->ue;
998 dciSlotAlloc = (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1];
999 fcfsHqProcCb = (SchFcfsHqProcCb *)((*hqP)->schSpcDlHqProcCb);
1001 if (isRetx == FALSE)
1003 /*Re-Initalization per UE*/
1004 /* scheduled LC data fill */
1005 dciSlotAlloc->transportBlock[0].numLc = 0;
1006 isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
1007 accumalatedSize = 0;
1009 for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
1011 if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
1013 /*Check the LC is Dedicated or default and accordingly LCList will
1015 if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
1017 lcLL = &(fcfsHqProcCb->lcCb.dedLcList);
1018 rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1022 lcLL = &(fcfsHqProcCb->lcCb.defLcList);
1025 /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
1026 if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
1027 (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
1029 DU_LOG("\nERROR --> SCH : Updation in LC List Failed");
1030 /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1031 if(!dciSlotAlloc->dlMsgPdschCfg)
1033 SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1034 (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1036 return accumalatedSize;
1041 if ((fcfsHqProcCb->lcCb.defLcList.count == 0) && (fcfsHqProcCb->lcCb.dedLcList.count == 0))
1043 DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n");
1044 UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1046 /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1047 if(!dciSlotAlloc->dlMsgPdschCfg)
1049 SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1050 (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1052 /*TRUE because this UE has nothing to be scheduled*/
1053 return accumalatedSize;
1057 /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1058 maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, &startPrb, DIR_DL);
1060 /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1061 * the list based on RRM policy*/
1063 /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or
1064 * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1069 mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1071 if((fcfsHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1073 fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1074 DU_LOG("\nDEBUG --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1075 fcfsHqProcCb->lcCb.sharedNumPrb);
1077 /*PRB Alloc for Default LCs*/
1078 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1079 &(fcfsHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1083 fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1084 /*PRB Alloc for Dedicated LCs*/
1085 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1086 &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1088 /*PRB Alloc for Default LCs*/
1089 prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1090 &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1095 /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1096 * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1097 if (isRetx == FALSE)
1099 if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
1100 updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1102 updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1106 accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1109 /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1110 if (!accumalatedSize)
1114 DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
1118 /*Schedule the LC for next slot*/
1119 DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
1121 /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1122 * Allocation can be done in next slot*/
1123 accumalatedSize = 0;
1126 return accumalatedSize;
1129 /*******************************************************************
1131 * @brief Scheduling of Slots in UL And DL
1135 * Function : schFcfsScheduleSlot
1137 * Functionality: Scheduling of slots in UL and DL specific to
1140 * @params[in] Pointer to Cell
1142 * Scheduler instance
1145 * ****************************************************************/
1146 void schFcfsScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1148 SchFcfsCellCb *fcfsCell;
1149 SchFcfsUeCb *fcfsUeCb;
1150 SchDlHqProcCb *hqP = NULLP;
1151 SchUlHqProcCb *ulHqP = NULLP;
1152 CmLList *pendingUeNode;
1155 bool isRarPending = false, isRarScheduled = false;
1156 bool isMsg4Pending = false, isMsg4Scheduled = false;
1157 bool isDlMsgPending = false, isDlMsgScheduled = false;
1158 bool isUlGrantPending = false, isUlGrantScheduled = false;
1160 fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
1162 /* Select first UE in the linked list to be scheduled next */
1163 pendingUeNode = fcfsCell->ueToBeScheduled.first;
1166 if(pendingUeNode->node)
1168 ueId = *(uint8_t *)(pendingUeNode->node);
1169 fcfsUeCb = (SchFcfsUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1171 /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and
1172 * PUSCH to receive MSG3 as per k0-k2 configuration*/
1173 if(cell->raReq[ueId-1] != NULLP)
1175 isRarPending = true;
1176 isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1179 /*MSG3 retransmisson*/
1180 if(cell->raCb[ueId-1].retxMsg3HqProc)
1182 schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1185 /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1186 * PUCCH to receive UL msg as per k0-k1 configuration */
1187 if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1189 /* Retransmission of MSG4 */
1190 isMsg4Pending = true;
1191 if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1192 isMsg4Scheduled = true;
1196 /* First transmission of MSG4 */
1197 if(cell->raCb[ueId-1].msg4recvd)
1199 isMsg4Pending = true;
1200 if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1201 isMsg4Scheduled = true;
1203 /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1204 if(!isMsg4Scheduled)
1205 schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1209 if(isRarPending || isMsg4Pending)
1211 /* If RAR or MSG is successfully scheduled then
1212 * remove UE from linked list since no pending msgs for this UE */
1213 if(isRarScheduled || isMsg4Scheduled)
1215 schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1217 /* If RAR/MSG4 is pending but couldnt be scheduled then,
1218 * put this UE at the end of linked list to be scheduled later */
1221 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1226 if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1228 if(pendingUeNode->node)
1230 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1240 node = fcfsUeCb->hqRetxCb.dlRetxHqList.first;
1243 /* DL Data ReTransmisson */
1244 isDlMsgPending = true;
1245 isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1246 if(isDlMsgScheduled)
1249 schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1251 schFcfsRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1256 /* DL Data new transmission */
1257 if((cell->boIndBitMap) & (1<<ueId))
1259 isDlMsgPending = true;
1260 isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1262 /* If DL scheduling failed, free the newly assigned HARQ process */
1263 if(!isDlMsgScheduled)
1264 schDlReleaseHqProcess(hqP);
1268 schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
1274 /* Scheduling of UL grant */
1277 node = fcfsUeCb->hqRetxCb.ulRetxHqList.first;
1280 /* UL Data ReTransmisson */
1281 isUlGrantPending = true;
1282 isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1283 if(isUlGrantScheduled)
1286 schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1288 schFcfsRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1293 /* UL Data new transmission */
1294 if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1296 isUlGrantPending = true;
1297 isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1298 if(!isUlGrantScheduled)
1299 schUlReleaseHqProcess(ulHqP, FALSE);
1303 schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
1309 if(!isUlGrantPending && !isDlMsgPending)
1311 /* No action required */
1313 else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1315 cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1319 schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1326 /*******************************************************************
1328 * @brief Initializes all function pointers to FCFS function handler
1332 * Function : schFcfsAllApisInit
1334 * Functionality: Initializes all function pointers to FCFS
1337 * @params[in] Function pointer array
1340 * ****************************************************************/
1341 void schFcfsAllApisInit(SchAllApis *allFcfsApi)
1343 /* Interface API function pointers */
1344 allFcfsApi->SchCellCfgReq = schFcfsCellCfgReq;
1345 allFcfsApi->SchCellDeleteReq = schFcfsCellDelReq;
1346 allFcfsApi->SchAddUeConfigReq = SchFcfsAddUeConfigReq;
1347 allFcfsApi->SchModUeConfigReq = SchFcfsModUeConfigReq;
1348 allFcfsApi->SchUeDeleteReq = SchFcfsUeDeleteReq;
1349 allFcfsApi->SchDlHarqInd = SchFcfsDlHarqInd;
1350 allFcfsApi->SchCrcInd = schFcfsProcessCrcInd;
1351 allFcfsApi->SchRachInd = schFcfsProcessRachInd;
1352 allFcfsApi->SchPagingInd = schFcfsPagingInd;
1353 allFcfsApi->SchRachRsrcReq = schFcfsRachRsrcReq;
1354 allFcfsApi->SchRachRsrcRel = schFcfsRachRsrcRel;
1355 allFcfsApi->SchDlRlcBoInfo = schFcfsDlRlcBoInfo;
1356 allFcfsApi->SchSrUciInd = schFcfsSrUciInd;
1357 allFcfsApi->SchBsr = schFcfsBsr;
1359 /* Internal API function pointers */
1360 allFcfsApi->SchAddToDlHqRetxList = schFcfsAddToDlHqRetxList;
1361 allFcfsApi->SchAddToUlHqRetxList = schFcfsAddToUlHqRetxList;
1362 allFcfsApi->SchRemoveFrmDlHqRetxList = schFcfsRemoveFrmDlHqRetxList;
1363 allFcfsApi->SchRemoveFrmUlHqRetxList = schFcfsRemoveFrmUlHqRetxList;
1364 allFcfsApi->SchAddUeToSchedule = schFcfsAddUeToSchedule;
1365 allFcfsApi->SchRemoveUeFrmScheduleLst = schFcfsRemoveUeFrmScheduleLst;
1366 allFcfsApi->SchInitDlHqProcCb = schFcfsInitDlHqProcCb;
1367 allFcfsApi->SchInitUlHqProcCb = schFcfsInitUlHqProcCb;
1368 allFcfsApi->SchFreeDlHqProcCb = schFcfsFreeDlHqProcCb;
1369 allFcfsApi->SchFreeUlHqProcCb = schFcfsFreeUlHqProcCb;
1370 allFcfsApi->SchDeleteDlHqProcCb = schFcfsDeleteDlHqProcCb;
1371 allFcfsApi->SchDeleteUlHqProcCb = schFcfsDeleteUlHqProcCb;
1372 allFcfsApi->SchScheduleSlot = schFcfsScheduleSlot;
1373 allFcfsApi->SchScheduleDlLc = schFcfsScheduleDlLc;
1374 allFcfsApi->SchScheduleUlLc = schFcfsScheduleUlLc;
1376 /**********************************************************************
1378 **********************************************************************/