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 Slice based scheduling algorithm
27 File: sch_slice_based.c
29 **********************************************************************/
31 /** @file sch_slot_ind.c
32 @brief This module processes slot indications
34 #include "common_def.h"
40 #include "du_app_mac_inf.h"
41 #include "mac_sch_interface.h"
43 #include "sch_utils.h"
44 #include "sch_slice_based.h"
49 /*******************************************************************
51 * @brief Function to handle Cell configuration request
55 * Function : schSliceBasedCellCfgReq
57 * Functionality: This function configures cell paremeters
58 * required for Slice Based scheduling
60 * @params[in] SchCellCb *cellCb, Cell control block
64 * ****************************************************************/
65 uint8_t schSliceBasedCellCfgReq(SchCellCb *cellCb)
67 SchSliceBasedCellCb *schSpcCellCb = NULLP;
69 SCH_ALLOC(schSpcCellCb, sizeof(SchSliceBasedCellCb));
72 DU_LOG("\nERROR --> SCH: Memory allocation failed in schSliceBasedCellCfgReq");
75 cmLListInit(&schSpcCellCb->ueToBeScheduled);
76 cellCb->schSpcCell = (void *)schSpcCellCb;
80 /*******************************************************************
82 * @brief Function to handle Cell configuration request
86 * Function : schSliceBasedCellDelReq
88 * Functionality: This function deletes/frees cell params
89 * specific to Slice Based scheduling
91 * @params[in] Pointer to Cell control block
94 * ****************************************************************/
95 void schSliceBasedCellDelReq(SchCellCb *cellCb)
97 SchSliceBasedCellCb *schSpcCellCb = NULLP;
98 CmLList *node=NULL, *next=NULL;
100 schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
101 /* Remove all UE from ueToBeScheduled list and deallocate */
102 node = schSpcCellCb->ueToBeScheduled.first;
106 SCH_FREE(node->node, sizeof(uint8_t));
107 cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
108 SCH_FREE(node, sizeof(CmLList));
111 SCH_FREE(schSpcCellCb, sizeof(SchSliceBasedCellCb));
112 cellCb->schSpcCell = NULLP;
115 /*******************************************************************
117 * @brief Function to handle UE configuration request
121 * Function : SchSliceBasedAddUeConfigReq
123 * Functionality: Adds/Configures UE parameters required for
124 * Slice Based scheduling
126 * @params[in] Pointer to UE control block
130 * ****************************************************************/
131 uint8_t SchSliceBasedAddUeConfigReq(SchUeCb *ueCb)
133 SchSliceBasedUeCb *ueSliceBasedCb;
135 SCH_ALLOC(ueSliceBasedCb, sizeof(SchSliceBasedHqCb));
138 DU_LOG("\nERROR --> SCH: Memory allocation failed in SchSliceBasedAddUeConfigReq");
142 cmLListInit(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
143 cmLListInit(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
144 ueCb->schSpcUeCb = (void *)ueSliceBasedCb;
149 /*******************************************************************
151 * @brief Handles UE reconfiguration request
155 * Function : SchSliceBasedModUeConfigReq
159 * @params[in] Pointer to UE control block
162 * ****************************************************************/
163 void SchSliceBasedModUeConfigReq(SchUeCb *ueCb)
165 /*TBD: No action required for Slice Based*/
169 /*******************************************************************
171 * @brief Handles UE Delete Request
175 * Function : SchSliceBasedUeDeleteReq
177 * Functionality: Deletes/Frees UE parameters specific to
178 * Slice Based scheduling
180 * @params[in] Pointer to UE control block
183 * ****************************************************************/
184 void SchSliceBasedUeDeleteReq(SchUeCb *ueCb)
186 SchSliceBasedCellCb *schSpcCellCb = NULLP;
187 SchSliceBasedUeCb *ueSliceBasedCb = NULLP;
188 CmLList *node=NULL, *next=NULL;
191 schSpcCellCb = (SchSliceBasedCellCb *)ueCb->cellCb->schSpcCell;
192 /* Remove all UE from ueToBeScheduled list and deallocate */
193 node = schSpcCellCb->ueToBeScheduled.first;
197 ueId = *(uint8_t *)node->node;
198 if(ueId == ueCb->ueId)
200 SCH_FREE(node->node, sizeof(uint8_t));
201 cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
202 SCH_FREE(node, sizeof(CmLList));
208 ueSliceBasedCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
209 cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
210 cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
212 SCH_FREE(ueSliceBasedCb, sizeof(SchSliceBasedUeCb));
213 ueCb->schSpcUeCb = NULLP;
217 /*******************************************************************
219 * @brief Intializes HARQ Process control block
223 * Function : schSliceBasedInitDlHqProcCb
225 * Functionality: Intitialized parameters of HARQ process control
226 * block specific to Slice Based scheduling in Downlink
228 * @params[in] Pointer to Downlink HARQ Process control block
232 * ****************************************************************/
233 uint8_t schSliceBasedInitDlHqProcCb(SchDlHqProcCb *hqP)
235 SchSliceBasedHqProcCb *schSpcHqP;
237 SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
240 DU_LOG("\nERROR --> SCH: Memory allocation failed in schSliceBasedInitDlHqProcCb");
244 cmLListInit(&schSpcHqP->lcCb.dedLcList);
245 cmLListInit(&schSpcHqP->lcCb.defLcList);
246 hqP->schSpcDlHqProcCb = (void *)schSpcHqP;
251 /*******************************************************************
253 * @brief Handles HARQ Process delete request
257 * Function : schSliceBasedDeleteDlHqProcCb
259 * Functionality: Deletes HARQ Process parameters specific to
260 * Slice Based scheduling in Downlink
262 * @params[in] Pointer to Downlink HARQ Process control block
265 * ****************************************************************/
266 void schSliceBasedDeleteDlHqProcCb(SchDlHqProcCb *hqP)
268 SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
269 cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
270 cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
271 SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
272 hqP->schSpcDlHqProcCb = NULLP;
275 /*******************************************************************
277 * @brief Intializes HARQ Process control block
281 * Function : schSliceBasedInitUlHqProcCb
283 * Functionality: Intitialized parameters of HARQ process control
284 * block specific to Slice Based scheduling in Uplink
286 * @params[in] Pointer to Uplink HARQ Process control block
290 * ****************************************************************/
291 uint8_t schSliceBasedInitUlHqProcCb(SchUlHqProcCb *hqP)
293 SchSliceBasedHqProcCb *schSpcHqP;
295 SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
298 DU_LOG("\nERROR --> SCH: Memory allocation failed in schSliceBasedInitUlHqProcCb");
301 cmLListInit(&schSpcHqP->lcCb.dedLcList);
302 cmLListInit(&schSpcHqP->lcCb.defLcList);
303 hqP->schSpcUlHqProcCb = (void *)schSpcHqP;
308 /*******************************************************************
310 * @brief Handled Deletion of HARQ Process control block
314 * Function : schSliceBasedDeleteUlHqProcCb
316 * Functionality: Deletes HARQ Process parameters specific to
317 * Slice Based scheduling in Uplink
319 * @params[in] Pointer to Uplink HARQ Process Control block
322 * ****************************************************************/
323 void schSliceBasedDeleteUlHqProcCb(SchUlHqProcCb *hqP)
325 SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
326 cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
327 cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
328 SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
329 hqP->schSpcUlHqProcCb = NULLP;
332 /*******************************************************************
334 * @brief Handles freeing of HARQ Process
338 * Function : schSliceBasedFreeDlHqProcCb
340 * Functionality: Frees HARQ Process parameters specific to
341 * Slice Based scheduling in Downlink when HARQ process becomes free
343 * @params[in] Pointer to HARQ process control block
346 * ****************************************************************/
347 void schSliceBasedFreeDlHqProcCb(SchDlHqProcCb *hqP)
349 SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
351 cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
352 cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
355 /*******************************************************************
357 * @brief Handles freeing of HARQ Process
361 * Function : schSliceBasedFreeUlHqProcCb
363 * Functionality: Frees HARQ Process parameters specific to
364 * Slice Based scheduling in Uplink when HARQ process becomes free
366 * @params[in] Pointer to HARQ process control block
369 * ****************************************************************/
370 void schSliceBasedFreeUlHqProcCb(SchUlHqProcCb *hqP)
372 SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
374 cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
375 cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
378 /*******************************************************************
380 * @brief Adds HARQ process to retransmission list
384 * Function : schSliceBasedAddToDlHqRetxList
386 * Functionality: Adds HARQ process to retransmission list
388 * @params[in] Pointer to Downlink HARQ Process
391 * ****************************************************************/
392 void schSliceBasedAddToDlHqRetxList(SchDlHqProcCb *hqP)
394 SchSliceBasedUeCb *schSpcUeCb;
396 schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
397 cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);
399 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
401 schDrxStrtDlHqRttTmr(hqP);
406 schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
410 /*******************************************************************
412 * @brief Adds HARQ process to retransmission list
416 * Function : schSliceBasedAddToUlHqRetxList
418 * Functionality: Adds HARQ process to retransmission list
420 * @params[in] Pointer to Uplink HARQ Process
423 * ****************************************************************/
424 void schSliceBasedAddToUlHqRetxList(SchUlHqProcCb *hqP)
426 SchSliceBasedUeCb *schSpcUeCb;
428 schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
429 cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);
431 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
433 schDrxStrtUlHqRttTmr(hqP);
438 schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
442 /*******************************************************************
444 * @brief Add UE to ueToBeScheduled List
448 * Function : schSliceBasedAddUeToSchedule
451 * Search if UE entry present in the list
453 * If no, add UE to the list
455 * @params[in] Cell control block
458 * @return ROK - success
461 * ****************************************************************/
462 uint8_t schSliceBasedAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
464 SchSliceBasedCellCb *schSpcCellCb = NULLP;
468 schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
469 /* Search if UE entry is already present in ueToBeScheduled list.
470 * If yes, another entry for same UE not needed. Hence, return */
471 node = schSpcCellCb->ueToBeScheduled.first;
474 ueId = (uint8_t *)node->node;
475 if(*ueId == ueIdToAdd)
480 /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
481 SCH_ALLOC(ueId, sizeof(uint8_t));
484 DU_LOG("\nERROR --> SCH : Memory allocation failure in schSliceBasedAddUeToSchedule");
488 if(addNodeToLList(&schSpcCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
490 DU_LOG("\nERROR --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
496 /*******************************************************************
498 * @brief Handled CRC Indication
502 * Function : schSliceBasedProcessCrcInd
504 * Functionality: Processes CRC Indication as required for Slice Based
507 * @params[in] Pointer to Cell control block
511 * ****************************************************************/
512 void schSliceBasedProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
514 schSliceBasedAddUeToSchedule(cellCb, ueId);
517 /*******************************************************************
519 * @brief Processes Buffer Occupancy report from RLC
523 * Function : schSliceBasedDlRlcBoInfo
525 * Functionality: Process buffer occupany report
530 * ****************************************************************/
531 void schSliceBasedDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
533 schSliceBasedAddUeToSchedule(cellCb, ueId);
536 /*******************************************************************
538 * @brief Processes BSR request
542 * Function : schSliceBasedBsr
544 * Functionality: Processes BSR as per Slice Based scheduling
546 * @params[in] Pointer to Cell
550 * ****************************************************************/
551 void schSliceBasedBsr(SchCellCb *cellCb, uint16_t ueId)
553 schSliceBasedAddUeToSchedule(cellCb, ueId);
556 /*******************************************************************
558 * @brief Processed UCI Indication
562 * Function : schSliceBasedSrUciInd
564 * Functionality: Processing of UCI indication specific to
565 * Slice Based scheduling
567 * @params[in] Pointer to Cell
571 * ****************************************************************/
572 void schSliceBasedSrUciInd(SchCellCb *cellCb, uint16_t ueId)
574 schSliceBasedAddUeToSchedule(cellCb, ueId);
577 /*******************************************************************
579 * @brief Processing of RACH Indication
583 * Function : schSliceBasedProcessRachInd
585 * Functionality: Processing of RACH Indication specific to
586 * Slice Based scheduling
588 * @params[in] Pointer to Cell Cb
592 * ****************************************************************/
593 void schSliceBasedProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
595 schSliceBasedAddUeToSchedule(cellCb, ueId);
598 /*******************************************************************
600 * @brief Processing of DL HARQ Indication
604 * Function : SchSliceBasedDlHarqInd
611 * ****************************************************************/
612 void SchSliceBasedDlHarqInd()
617 /*******************************************************************
619 * @brief Processing of Paging indication
623 * Function : schSliceBasedPagingInd
630 * ****************************************************************/
631 void schSliceBasedPagingInd()
636 /*******************************************************************
638 * @brief Processing of RACH Resource Request
642 * Function : schSliceBasedRachRsrcReq
649 * ****************************************************************/
650 void schSliceBasedRachRsrcReq()
655 /*******************************************************************
657 * @brief Processing of RACH Resource Release
661 * Function : schSliceBasedRachRsrcRel
668 * ****************************************************************/
669 void schSliceBasedRachRsrcRel()
674 /*******************************************************************
676 * @brief Remove entry from HARQ retransmission list
680 * Function : schSliceBasedRemoveFrmDlHqRetxList
682 * Functionality: Remove entry from HARQ retransmission list
684 * @params[in] Pointer to UE
688 * ****************************************************************/
689 void schSliceBasedRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
691 SchSliceBasedUeCb *schSpcUeCb;
693 schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
694 cmLListDelFrm(&schSpcUeCb->hqRetxCb.dlRetxHqList, node);
697 /*******************************************************************
699 * @brief Remove entry from HARQ retransmission list
703 * Function : schSliceBasedRemoveFrmUlHqRetxList
705 * Functionality: Remove entry from HARQ retransmission list
707 * @params[in] Pointer to UE
711 * ****************************************************************/
712 void schSliceBasedRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
714 SchSliceBasedUeCb *schSpcUeCb;
716 schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
717 cmLListDelFrm(&schSpcUeCb->hqRetxCb.ulRetxHqList, node);
720 /*******************************************************************
722 * @brief Remove UE from Scheduling List
726 * Function : schSliceBasedRemoveUeFrmScheduleLst
728 * Functionality: Remove UE from Scheduling List
730 * @params[in] Pointer to Cell
734 * ****************************************************************/
735 void schSliceBasedRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
737 SchSliceBasedCellCb *schSpcCell;
739 schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
740 SCH_FREE(node->node, sizeof(uint8_t));
741 deleteNodeFromLList(&schSpcCell->ueToBeScheduled, node);
744 /*******************************************************************
746 * @brief Handler to calculate TBS size for BSR requested
750 * Function : schSliceBasedCalculateUlTbs
752 * Functionality: Function will note the required TBS for each LCGIDX and use
753 * the Priority LCG List and RRM policy to allocate the TBS size
755 * @params [in] ueCb (Pointer to UE CB)
756 * [in] puschTime (Time slot where PUSCH will be sent)
757 * [in] symbLen (No of Symbols used for PUSCH transmission)
758 * [out] startPrb(Pointer to startPRB which will be calculated while
759 * finding the best Free Block)
760 * [out] totTBS(Pointer to total TBS size)
761 * [in] isRetx (to indicate retransmission)
762 * [in] hqP (UL Harq process pointer)
764 * @return uint8_t : ROK > Scheduling of UL grant is successful
765 * RFAILED > vice versa
767 * ****************************************************************/
768 uint8_t schSliceBasedCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
769 uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchSliceBasedHqProcCb *schSpcHqP)
772 CmLListCp *lcLL = NULLP;
773 uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
774 uint16_t rsvdDedicatedPRB;
779 for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
781 if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
786 /*TODO: lcgIdx and LCID has been implemented as one to one mapping.
787 * Need to check the mapping to figure out the LCID and lcgIdx once L2
788 * spec specifies any logic*/
790 if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
792 lcLL = &(schSpcHqP->lcCb.dedLcList);
793 rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
797 lcLL = &(schSpcHqP->lcCb.defLcList);
800 /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
801 if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
803 DU_LOG("\nERROR --> SCH: LcgId:%d updation failed",lcId);
808 if ((schSpcHqP->lcCb.defLcList.count == 0) && (schSpcHqP->lcCb.dedLcList.count == 0))
810 if( (ueCb->srRcvd) || (isRetx) )
812 *startPrb = MAX_NUM_RB;
813 *totTBS = schCalcTbSize(UL_GRANT_SIZE);
815 /*Returning true when NO Grant is there for UE as this is not scheduling
820 maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
822 /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
823 * the list based on RRM policy*/
825 /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or
826 * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
829 mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
830 if((schSpcHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
832 schSpcHqP->lcCb.sharedNumPrb = maxFreePRB;
833 DU_LOG("\nDEBUG --> SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
834 schSpcHqP->lcCb.sharedNumPrb);
836 /*PRB Alloc for Default LCs*/
837 prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
838 &(schSpcHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
842 schSpcHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
844 /*PRB Alloc for Dedicated LCs*/
845 prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
846 &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
847 NULLP, &(ueCb->srRcvd));
849 /*PRB Alloc for Default LCs*/
850 prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
851 &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
852 NULLP,&(ueCb->srRcvd));
855 /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
856 * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/
857 if(schSpcHqP->lcCb.dedLcList.count != 0)
858 updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
860 updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
862 /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
867 DU_LOG("\nERROR --> SCH : NO FREE PRB!!");
871 /*Schedule the LC for next slot*/
872 DU_LOG("\nDEBUG --> SCH : No LC has been scheduled");
879 /*******************************************************************
881 * @brief Grants resources to LC in uplink
885 * Function : schProcessSrOrBsrReq
888 * Grants resources to LC in uplink
890 * @params[in] PDCCH Time
899 *******************************************************************/
900 uint8_t schSliceBasedScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
903 SchSliceBasedHqProcCb *schSpcHqProcCb;
904 uint8_t ret = RFAILED;
905 uint16_t startPrb = 0;
906 uint32_t totDataReq = 0; /* in bytes */
908 SchPuschInfo *puschInfo;
909 DciInfo *dciInfo = NULLP;
911 cell = (*hqP)->hqEnt->cell;
912 ueCb = (*hqP)->hqEnt->ue;
913 schSpcHqProcCb = (SchSliceBasedHqProcCb *)(*hqP)->schSpcUlHqProcCb;
914 ret = schSliceBasedCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, schSpcHqProcCb);
916 if(totDataReq > 0 && ret == ROK)
918 SCH_ALLOC(dciInfo, sizeof(DciInfo));
921 DU_LOG("\nERROR --> SCH : Memory Allocation failed for dciInfo alloc");
924 if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
925 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
927 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
931 cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
932 memset(dciInfo,0,sizeof(DciInfo));
934 /* Update PUSCH allocation */
935 if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
937 if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo)
939 puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo;
940 if(puschInfo != NULLP)
942 /* Fill DCI for UL grant */
943 schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
944 ueCb->srRcvd = false;
945 ueCb->bsrRcvd = false;
946 cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
947 if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
948 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
949 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
950 cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);
955 if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
956 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
957 updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
962 /*******************************************************************
964 * @brief Grants resources to LC in downlink
968 * Function : schSliceBasedScheduleDlLc
970 * Functionality: Grants resources to LC in uplink
972 * @params[in] PDCCH Time
977 * ****************************************************************/
978 uint32_t schSliceBasedScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols,\
979 uint16_t *startPrb, bool isRetx, SchDlHqProcCb **hqP)
981 SchSliceBasedHqProcCb *schSpcHqProcCb;
984 uint16_t 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 schSpcHqProcCb = (SchSliceBasedHqProcCb *)((*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 = &(schSpcHqProcCb->lcCb.dedLcList);
1018 rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1022 lcLL = &(schSpcHqProcCb->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 ((schSpcHqProcCb->lcCb.defLcList.count == 0) && (schSpcHqProcCb->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((schSpcHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1073 schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1074 DU_LOG("\nDEBUG --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1075 schSpcHqProcCb->lcCb.sharedNumPrb);
1077 /*PRB Alloc for Default LCs*/
1078 prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1079 &(schSpcHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1083 schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1084 /*PRB Alloc for Dedicated LCs*/
1085 prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1086 &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1088 /*PRB Alloc for Default LCs*/
1089 prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1090 &(schSpcHqProcCb->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(schSpcHqProcCb->lcCb.dedLcList.count != 0)
1100 updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1102 updateGrantSizeForBoRpt(&(schSpcHqProcCb->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 : schSliceBasedScheduleSlot
1137 * Functionality: Scheduling of slots in UL and DL specific to
1138 * Slice Based scheduling
1140 * @params[in] Pointer to Cell
1142 * Scheduler instance
1145 * ****************************************************************/
1146 void schSliceBasedScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1148 SchSliceBasedCellCb *schSpcCell;
1149 SchSliceBasedUeCb *schSpcUeCb;
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 schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
1162 /* Select first UE in the linked list to be scheduled next */
1163 pendingUeNode = schSpcCell->ueToBeScheduled.first;
1166 if(pendingUeNode->node)
1168 ueId = *(uint8_t *)(pendingUeNode->node);
1169 schSpcUeCb = (SchSliceBasedUeCb *)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 schSliceBasedRemoveUeFrmScheduleLst(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(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1226 if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1228 if(pendingUeNode->node)
1230 cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1240 node = schSpcUeCb->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 schSliceBasedRemoveFrmDlHqRetxList(&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 = schSpcUeCb->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 schSliceBasedRemoveFrmUlHqRetxList(&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(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1319 schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1326 /*******************************************************************
1328 * @brief Initializes all function pointers to Slice Based function handler
1332 * Function : schSliceBasedAllApisInit
1334 * Functionality: Initializes all function pointers to Slice Based
1337 * @params[in] Function pointer array
1340 * ****************************************************************/
1341 void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi)
1343 /* Interface API function pointers */
1344 allSliceBasedApi->SchCellCfgReq = schSliceBasedCellCfgReq;
1345 allSliceBasedApi->SchCellDeleteReq = schSliceBasedCellDelReq;
1346 allSliceBasedApi->SchAddUeConfigReq = SchSliceBasedAddUeConfigReq;
1347 allSliceBasedApi->SchModUeConfigReq = SchSliceBasedModUeConfigReq;
1348 allSliceBasedApi->SchUeDeleteReq = SchSliceBasedUeDeleteReq;
1349 allSliceBasedApi->SchDlHarqInd = SchSliceBasedDlHarqInd;
1350 allSliceBasedApi->SchCrcInd = schSliceBasedProcessCrcInd;
1351 allSliceBasedApi->SchRachInd = schSliceBasedProcessRachInd;
1352 allSliceBasedApi->SchPagingInd = schSliceBasedPagingInd;
1353 allSliceBasedApi->SchRachRsrcReq = schSliceBasedRachRsrcReq;
1354 allSliceBasedApi->SchRachRsrcRel = schSliceBasedRachRsrcRel;
1355 allSliceBasedApi->SchDlRlcBoInfo = schSliceBasedDlRlcBoInfo;
1356 allSliceBasedApi->SchSrUciInd = schSliceBasedSrUciInd;
1357 allSliceBasedApi->SchBsr = schSliceBasedBsr;
1359 /* Internal API function pointers */
1360 allSliceBasedApi->SchAddToDlHqRetxList = schSliceBasedAddToDlHqRetxList;
1361 allSliceBasedApi->SchAddToUlHqRetxList = schSliceBasedAddToUlHqRetxList;
1362 allSliceBasedApi->SchRemoveFrmDlHqRetxList = schSliceBasedRemoveFrmDlHqRetxList;
1363 allSliceBasedApi->SchRemoveFrmUlHqRetxList = schSliceBasedRemoveFrmUlHqRetxList;
1364 allSliceBasedApi->SchAddUeToSchedule = schSliceBasedAddUeToSchedule;
1365 allSliceBasedApi->SchRemoveUeFrmScheduleLst = schSliceBasedRemoveUeFrmScheduleLst;
1366 allSliceBasedApi->SchInitDlHqProcCb = schSliceBasedInitDlHqProcCb;
1367 allSliceBasedApi->SchInitUlHqProcCb = schSliceBasedInitUlHqProcCb;
1368 allSliceBasedApi->SchFreeDlHqProcCb = schSliceBasedFreeDlHqProcCb;
1369 allSliceBasedApi->SchFreeUlHqProcCb = schSliceBasedFreeUlHqProcCb;
1370 allSliceBasedApi->SchDeleteDlHqProcCb = schSliceBasedDeleteDlHqProcCb;
1371 allSliceBasedApi->SchDeleteUlHqProcCb = schSliceBasedDeleteUlHqProcCb;
1372 allSliceBasedApi->SchScheduleSlot = schSliceBasedScheduleSlot;
1373 allSliceBasedApi->SchScheduleDlLc = schSliceBasedScheduleDlLc;
1374 allSliceBasedApi->SchScheduleUlLc = schSliceBasedScheduleUlLc;
1376 /**********************************************************************
1378 **********************************************************************/