[BUG-ID: ODUHIGH-574] Fix for Inconsistent behavious in ML
[o-du/l2.git] / src / 5gnrsch / sch_fcfs.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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  *******************************************************************************/
18
19 /************************************************************************
20
21 Name:     5G NR SCH layer
22
23 Type:     C source file
24
25 Desc:     C source code for scheduling based on First Come First Serve
26           algorithm
27
28 File:     sch_fcfs.c
29
30  **********************************************************************/
31
32 /** @file sch_slot_ind.c
33   @brief This module processes slot indications
34  */
35 #include "common_def.h"
36 #include "tfu.h"
37 #include "lrg.h"
38 #include "tfu.x"
39 #include "lrg.x"
40 #include "du_log.h"
41 #include "du_app_mac_inf.h"
42 #include "mac_sch_interface.h"
43 #include "sch.h"
44 #include "sch_tmr.h"
45 #include "sch_utils.h"
46 #include "sch_fcfs.h"
47 #ifdef NR_DRX 
48 #include "sch_drx.h"
49 #endif
50
51 /*******************************************************************
52  *
53  * @brief Function to handle Cell configuration request
54  *
55  * @details
56  *
57  *    Function : schFcfsCellCfgReq
58  *
59  *    Functionality: This function configures cell paremeters
60  *       required for FCFS scheduling
61  *
62  * @params[in] SchCellCb *cellCb, Cell control block
63  * @return ROK
64  *         RFAILED
65  *
66  * ****************************************************************/
67 uint8_t schFcfsCellCfgReq(SchCellCb *cellCb)
68 {
69    SchFcfsCellCb *fcfsCellCb = NULLP;
70    
71    SCH_ALLOC(fcfsCellCb, sizeof(SchFcfsCellCb));
72    if(!fcfsCellCb)
73    {
74       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schFcfsCellCfgReq");
75       return RFAILED;
76    }
77    cmLListInit(&fcfsCellCb->ueToBeScheduled);
78    cellCb->schSpcCell = (void *)fcfsCellCb;
79    return ROK;
80 }
81
82 /*******************************************************************
83  *
84  * @brief Function to handle Cell configuration request
85  *
86  * @details
87  *
88  *    Function : schFcfsCellDelReq
89  *
90  *    Functionality: This function deletes/frees cell params
91  *       specific to FCFS scheduling
92  *
93  * @params[in] Pointer to Cell control block
94  * @return void
95  *
96  * ****************************************************************/
97 void schFcfsCellDelReq(SchCellCb *cellCb)
98 {
99    SchFcfsCellCb *fcfsCellCb = NULLP;
100    CmLList *node=NULL, *next=NULL;
101
102    fcfsCellCb = (SchFcfsCellCb *)cellCb->schSpcCell;
103    /* Remove all UE from ueToBeScheduled list and deallocate */
104    node = fcfsCellCb->ueToBeScheduled.first;
105    while(node)
106    {
107       next = node->next;
108       SCH_FREE(node->node, sizeof(uint8_t));
109       cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
110       SCH_FREE(node, sizeof(CmLList));
111       node = next;
112    }
113    SCH_FREE(fcfsCellCb, sizeof(SchFcfsCellCb));
114    cellCb->schSpcCell = NULLP;
115 }
116
117 /*******************************************************************
118  *
119  * @brief Function to handle UE configuration request
120  *
121  * @details
122  *
123  *    Function : SchFcfsAddUeConfigReq
124  *
125  *    Functionality: Adds/Configures UE parameters required for
126  *       FCFS scheduling
127  *
128  * @params[in] Pointer to UE control block
129  * @return ROK
130  *         RFAILED
131  *
132  * ****************************************************************/
133 uint8_t SchFcfsAddUeConfigReq(SchUeCb *ueCb)
134 {
135    SchFcfsUeCb *ueFcfsCb;
136
137    SCH_ALLOC(ueFcfsCb, sizeof(SchFcfsHqCb));
138    if(!ueFcfsCb)
139    {
140       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in SchFcfsAddUeConfigReq");
141       return RFAILED;
142    }
143    
144    cmLListInit(&ueFcfsCb->hqRetxCb.ulRetxHqList);
145    cmLListInit(&ueFcfsCb->hqRetxCb.dlRetxHqList);
146    ueCb->schSpcUeCb = (void *)ueFcfsCb;
147    
148    return ROK;
149 }
150
151 /*******************************************************************
152  *
153  * @brief Handles UE reconfiguration request
154  *
155  * @details
156  *
157  *    Function : SchFcfsModUeConfigReq
158  *
159  *    Functionality: 
160  *
161  * @params[in] Pointer to UE control block
162  * @return void
163  *
164  * ****************************************************************/
165 void SchFcfsModUeConfigReq(SchUeCb *ueCb)
166 {
167    /*TBD: No action required for FCFS*/
168    return;
169 }
170
171 /*******************************************************************
172  *
173  * @brief Handles UE Delete Request
174  *
175  * @details
176  *
177  *    Function : SchFcfsUeDeleteReq 
178  *
179  *    Functionality: Deletes/Frees UE parameters specific to 
180  *       FCFS scheduling
181  *
182  * @params[in] Pointer to UE control block
183  * @return void
184  *
185  * ****************************************************************/
186 void SchFcfsUeDeleteReq(SchUeCb *ueCb)
187 {
188    SchFcfsCellCb *fcfsCellCb = NULLP;
189    SchFcfsUeCb *ueFcfsCb = NULLP;
190    CmLList *node=NULL, *next=NULL;
191    uint8_t ueId = 0;
192
193    fcfsCellCb = (SchFcfsCellCb *)ueCb->cellCb->schSpcCell;
194    /* Remove all UE from ueToBeScheduled list and deallocate */
195    node = fcfsCellCb->ueToBeScheduled.first;
196    while(node)
197    {
198       next = node->next;
199       ueId = *(uint8_t *)node->node;
200       if(ueId == ueCb->ueId)
201       {
202         SCH_FREE(node->node, sizeof(uint8_t));
203         cmLListDelFrm(&fcfsCellCb->ueToBeScheduled, node);
204         SCH_FREE(node, sizeof(CmLList));
205         break;
206       }
207       node = next;
208    }
209    
210    ueFcfsCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
211    cmLListDeleteLList(&ueFcfsCb->hqRetxCb.ulRetxHqList);
212    cmLListDeleteLList(&ueFcfsCb->hqRetxCb.dlRetxHqList);
213
214    SCH_FREE(ueFcfsCb, sizeof(SchFcfsUeCb));
215    ueCb->schSpcUeCb = NULLP;
216    return;
217 }
218
219 /*******************************************************************
220  *
221  * @brief Intializes HARQ Process control block
222  *
223  * @details
224  *
225  *    Function : schFcfsInitDlHqProcCb
226  *
227  *    Functionality: Intitialized parameters of HARQ process control
228  *       block specific to FCFS scheduling in Downlink
229  *
230  * @params[in] Pointer to Downlink HARQ Process control block
231  * @return ROK
232  *         RFAILED
233  *
234  * ****************************************************************/
235 uint8_t schFcfsInitDlHqProcCb(SchDlHqProcCb *hqP)
236 {
237    SchFcfsHqProcCb *fcfsHqP;
238
239    SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
240    if(!fcfsHqP)
241    {
242       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schFcfsInitDlHqProcCb");
243       return RFAILED;
244    }
245
246    cmLListInit(&fcfsHqP->lcCb.dedLcList);
247    cmLListInit(&fcfsHqP->lcCb.defLcList);
248    hqP->schSpcDlHqProcCb = (void *)fcfsHqP;
249
250    return ROK;
251 }
252
253 /*******************************************************************
254  *
255  * @brief Handles HARQ Process delete request
256  *
257  * @details 
258  *
259  *    Function : schFcfsDeleteDlHqProcCb
260  *
261  *    Functionality: Deletes HARQ Process parameters specific to 
262  *       FCFS scheduling in Downlink
263  *
264  * @params[in] Pointer to Downlink HARQ Process control block
265  * @return void
266  *
267  * ****************************************************************/
268 void schFcfsDeleteDlHqProcCb(SchDlHqProcCb *hqP)
269 {
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;
275 }
276
277 /*******************************************************************
278  *
279  * @brief Intializes HARQ Process control block
280  *
281  * @details
282  *
283  *    Function : schFcfsInitUlHqProcCb
284  *
285  *    Functionality: Intitialized parameters of HARQ process control
286  *       block specific to FCFS scheduling in Uplink
287  *
288  * @params[in] Pointer to Uplink HARQ Process control block
289  * @return ROK
290  *         RFAILED
291  *
292  * ****************************************************************/
293 uint8_t schFcfsInitUlHqProcCb(SchUlHqProcCb *hqP)
294 {
295    SchFcfsHqProcCb *fcfsHqP;
296
297    SCH_ALLOC(fcfsHqP, sizeof(SchFcfsHqProcCb));
298    if(!fcfsHqP)
299    {
300       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schFcfsInitUlHqProcCb");
301       return RFAILED;
302    }
303    cmLListInit(&fcfsHqP->lcCb.dedLcList);
304    cmLListInit(&fcfsHqP->lcCb.defLcList);
305    hqP->schSpcUlHqProcCb = (void *)fcfsHqP;
306  
307    return ROK;
308 }
309
310 /*******************************************************************
311  *
312  * @brief Handled Deletion of HARQ Process control block
313  *
314  * @details
315  *
316  *    Function : schFcfsDeleteUlHqProcCb
317  *
318  *    Functionality: Deletes HARQ Process parameters specific to 
319  *       FCFS scheduling in Uplink
320  *
321  * @params[in] Pointer to Uplink HARQ Process Control block
322  * @return void
323  *
324  * ****************************************************************/
325 void schFcfsDeleteUlHqProcCb(SchUlHqProcCb *hqP)
326 {
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;
332 }
333
334 /*******************************************************************
335  *
336  * @brief Handles freeing of HARQ Process
337  *
338  * @details
339  *
340  *    Function : schFcfsFreeDlHqProcCb
341  *
342  *    Functionality: Frees HARQ Process parameters specific to 
343  *       FCFS scheduling in Downlink when HARQ process becomes free
344  *
345  * @params[in] Pointer to HARQ process control block
346  * @return void
347  *
348  * ****************************************************************/
349 void schFcfsFreeDlHqProcCb(SchDlHqProcCb *hqP)
350 {
351    SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcDlHqProcCb;
352
353    cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
354    cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
355 }
356
357 /*******************************************************************
358  *
359  * @brief Handles freeing of HARQ Process
360  *
361  * @details
362  *
363  *    Function : schFcfsFreeUlHqProcCb
364  *
365  *    Functionality: Frees HARQ Process parameters specific to 
366  *       FCFS scheduling in Uplink when HARQ process becomes free
367  *
368  * @params[in] Pointer to HARQ process control block
369  * @return void
370  *
371  * ****************************************************************/
372 void schFcfsFreeUlHqProcCb(SchUlHqProcCb *hqP)
373 {
374    SchFcfsHqProcCb *fcfsHqP = (SchFcfsHqProcCb *)hqP->schSpcUlHqProcCb;
375
376    cmLListDeleteLList(&fcfsHqP->lcCb.dedLcList);
377    cmLListDeleteLList(&fcfsHqP->lcCb.defLcList);
378 }
379
380 /*******************************************************************
381  *
382  * @brief Adds HARQ process to retransmission list
383  *
384  * @details
385  *
386  *    Function : schFcfsAddToDlHqRetxList
387  *
388  *    Functionality: Adds HARQ process to retransmission list
389  *
390  * @params[in] Pointer to Downlink HARQ Process 
391  * @return void
392  *
393  * ****************************************************************/
394 void schFcfsAddToDlHqRetxList(SchDlHqProcCb *hqP)
395 {
396    SchFcfsUeCb *fcfsUeCb;
397
398    fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
399    cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);  
400 #ifdef NR_DRX
401    if(hqP->hqEnt->ue->ueDrxInfoPres == true)
402    {
403       schDrxStrtDlHqRttTmr(hqP);
404    }
405    else
406 #endif
407    {
408       schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
409    }
410 }
411
412 /*******************************************************************
413  *
414  * @brief Adds HARQ process to retransmission list
415  *
416  * @details
417  *
418  *    Function : schFcfsAddToUlHqRetxList
419  *
420  *    Functionality: Adds HARQ process to retransmission list
421  *
422  * @params[in] Pointer to Uplink HARQ Process 
423  * @return void
424  *
425  * ****************************************************************/
426 void schFcfsAddToUlHqRetxList(SchUlHqProcCb *hqP)
427 {
428    SchFcfsUeCb *fcfsUeCb;
429
430    fcfsUeCb = (SchFcfsUeCb *)hqP->hqEnt->ue->schSpcUeCb;
431    cmLListAdd2Tail(&(fcfsUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);  
432 #ifdef NR_DRX
433    if(hqP->hqEnt->ue->ueDrxInfoPres == true)
434    {
435       schDrxStrtUlHqRttTmr(hqP);
436    }
437    else
438 #endif
439    {
440       schFcfsAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
441    }   
442 }
443
444 /*******************************************************************
445  *
446  * @brief Add UE to ueToBeScheduled List
447  *
448  * @details
449  *
450  *    Function : schFcfsAddUeToSchedule
451  *
452  *    Functionality:
453  *      Search if UE entry present in the list
454  *      If yes, return.
455  *      If no, add UE to the list
456  *
457  * @params[in] Cell control block
458  *             Ue Id to be added
459  *
460  * @return ROK     - success
461  *         RFAILED - failure
462  *
463  * ****************************************************************/
464 uint8_t schFcfsAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
465 {
466    SchFcfsCellCb *fcfsCellCb = NULLP;
467    uint8_t *ueId;
468    CmLList *node;
469
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;
474    while(node)
475    {
476       ueId = (uint8_t *)node->node;
477       if(*ueId == ueIdToAdd)
478          return ROK;
479       node = node->next;
480    }
481
482    /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
483    SCH_ALLOC(ueId, sizeof(uint8_t));
484    if(!ueId)
485    {
486       DU_LOG("\nERROR  -->  SCH : Memory allocation failure in schFcfsAddUeToSchedule");
487       return RFAILED;
488    }
489    *ueId = ueIdToAdd;
490    if(addNodeToLList(&fcfsCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
491    {
492       DU_LOG("\nERROR  --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
493       return RFAILED;
494    }
495    return ROK;
496 }
497
498 /*******************************************************************
499  *
500  * @brief Handled CRC Indication
501  *
502  * @details
503  *
504  *    Function : schFcfsProcessCrcInd
505  *
506  *    Functionality: Processes CRC Indication as required for FCFS
507  *       scheduling
508  *
509  * @params[in] Pointer to Cell control block
510  *             UE Id
511  * @return void
512  *
513  * ****************************************************************/
514 void schFcfsProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
515 {
516    schFcfsAddUeToSchedule(cellCb, ueId);   
517 }
518
519 /*******************************************************************
520  *
521  * @brief Processes Buffer Occupancy report from RLC
522  *
523  * @details
524  *
525  *    Function : schFcfsDlRlcBoInfo
526  *
527  *    Functionality: Process buffer occupany report 
528  *
529  * @params[in]
530  * @return
531  *
532  * ****************************************************************/
533 void schFcfsDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
534 {
535    schFcfsAddUeToSchedule(cellCb, ueId);   
536 }
537
538 /*******************************************************************
539  *
540  * @brief Processes BSR request
541  *
542  * @details
543  *
544  *    Function : schFcfsBsr
545  *
546  *    Functionality: Processes BSR as per FCFS scheduling
547  *
548  * @params[in] Pointer to Cell 
549  *             UE ID
550  * @return void
551  *
552  * ****************************************************************/
553 void schFcfsBsr(SchCellCb *cellCb, uint16_t ueId)
554 {
555    schFcfsAddUeToSchedule(cellCb, ueId);   
556 }
557
558 /*******************************************************************
559  *
560  * @brief Processed UCI Indication
561  *
562  * @details
563  *
564  *    Function : schFcfsSrUciInd
565  *
566  *    Functionality: Processing of UCI indication specific to 
567  *       FCFS scheduling
568  *
569  * @params[in] Pointer to Cell
570  *             UE Id
571  * @return void
572  *
573  * ****************************************************************/
574 void schFcfsSrUciInd(SchCellCb *cellCb, uint16_t ueId)
575 {
576    schFcfsAddUeToSchedule(cellCb, ueId);   
577 }
578
579 /*******************************************************************
580  *
581  * @brief Processing of RACH Indication
582  *
583  * @details
584  *
585  *    Function : schFcfsProcessRachInd
586  *
587  *    Functionality: Processing of RACH Indication specific to 
588  *       FCFS scheduling
589  *
590  * @params[in] Pointer to Cell Cb
591  *             UE Id
592  * @return void
593  *
594  * ****************************************************************/
595 void schFcfsProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
596 {
597    schFcfsAddUeToSchedule(cellCb, ueId);   
598 }
599
600 /*******************************************************************
601  *
602  * @brief Processing of DL HARQ Indication
603  *
604  * @details
605  *
606  *    Function : SchFcfsDlHarqInd
607  *
608  *    Functionality:
609  *
610  * @params[in] 
611  * @return void
612  *
613  * ****************************************************************/
614 void SchFcfsDlHarqInd()
615 {
616    return;
617 }
618
619 /*******************************************************************
620  *
621  * @brief Processing of Paging indication
622  *
623  * @details
624  *
625  *    Function : schFcfsPagingInd
626  *
627  *    Functionality:
628  *
629  * @params[in]
630  * @return void
631  *
632  * ****************************************************************/
633 void schFcfsPagingInd()
634 {
635    return;
636 }
637
638 /*******************************************************************
639  *
640  * @brief Processing of RACH Resource Request
641  *
642  * @details
643  *
644  *    Function : schFcfsRachRsrcReq
645  *
646  *    Functionality:
647  *
648  * @params[in]
649  * @return void
650  *
651  * ****************************************************************/
652 void schFcfsRachRsrcReq()
653 {
654    return;
655 }
656
657 /*******************************************************************
658  *
659  * @brief Processing of RACH Resource Release
660  *
661  * @details
662  *
663  *    Function : schFcfsRachRsrcRel
664  *
665  *    Functionality:
666  *
667  * @params[in]
668  * @return void
669  *
670  * ****************************************************************/
671 void schFcfsRachRsrcRel()
672 {
673    return;
674 }
675
676 /*******************************************************************
677  *
678  * @brief Remove entry from HARQ retransmission list
679  *
680  * @details
681  *
682  *    Function : schFcfsRemoveFrmDlHqRetxList
683  *
684  *    Functionality: Remove entry from HARQ retransmission list
685  *
686  * @params[in] Pointer to UE
687  *             Node to be deleted
688  * @return void
689  *
690  * ****************************************************************/
691 void schFcfsRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
692 {
693    SchFcfsUeCb *fcfsUeCb;
694
695    fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
696    cmLListDelFrm(&fcfsUeCb->hqRetxCb.dlRetxHqList, node);
697 }
698
699 /*******************************************************************
700  *
701  * @brief Remove entry from HARQ retransmission list
702  *
703  * @details
704  *
705  *    Function : schFcfsRemoveFrmUlHqRetxList
706  *
707  *    Functionality: Remove entry from HARQ retransmission list
708  *
709  * @params[in] Pointer to UE
710  *             Node to be deleted
711  * @return void
712  *
713  * ****************************************************************/
714 void schFcfsRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
715 {
716    SchFcfsUeCb *fcfsUeCb;
717
718    fcfsUeCb = (SchFcfsUeCb *)ueCb->schSpcUeCb;
719    cmLListDelFrm(&fcfsUeCb->hqRetxCb.ulRetxHqList, node);
720 }
721
722 /*******************************************************************
723  *
724  * @brief Remove UE from Scheduling List
725  *
726  * @details
727  *
728  *    Function : schFcfsRemoveUeFrmScheduleLst
729  *
730  *    Functionality: Remove UE from Scheduling List
731  *
732  * @params[in] Pointer to Cell
733  *             Node to be removed
734  * @return void
735  *
736  * ****************************************************************/
737 void schFcfsRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
738 {
739    SchFcfsCellCb *fcfsCell;
740
741    fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
742    SCH_FREE(node->node, sizeof(uint8_t));
743    deleteNodeFromLList(&fcfsCell->ueToBeScheduled, node);
744 }
745
746 /*******************************************************************
747  *
748  * @brief  Handler to calculate TBS size for BSR requested
749  *
750  * @details
751  *
752  *    Function :  schFcfsCalculateUlTbs
753  *
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
756  *
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)
765  *
766  * @return uint8_t : ROK > Scheduling of UL grant is successful
767  *                   RFAILED > vice versa
768  *
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)
772 {
773    uint16_t mcsIdx = 0;
774    CmLListCp *lcLL = NULLP;
775    uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
776    uint16_t rsvdDedicatedPRB;
777    *startPrb = 0;
778    *totTBS = 0;
779
780    /* check for BSR */
781    for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
782    {
783       if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
784       {
785          continue;
786       }
787
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*/
791       lcId = lcgIdx;
792       if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
793       {
794          lcLL = &(fcfsHqP->lcCb.dedLcList);
795          rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
796       }
797       else
798       {
799          lcLL = &(fcfsHqP->lcCb.defLcList);
800       }
801
802       /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
803       if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
804       {
805          DU_LOG("\nERROR  --> SCH: LcgId:%d updation failed",lcId);         
806          return RFAILED;
807       }
808    }
809
810    if ((fcfsHqP->lcCb.defLcList.count == 0) && (fcfsHqP->lcCb.dedLcList.count == 0))
811    {
812       if( (ueCb->srRcvd) || (isRetx) )
813       {
814          *startPrb = MAX_NUM_RB;
815          *totTBS = schCalcTbSize(UL_GRANT_SIZE);
816       }
817       /*Returning true when NO Grant is there for UE as this is not scheduling
818        * error*/      
819       return ROK;
820    }
821
822    maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
823
824    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
825     * the list based on RRM policy*/
826
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*/
829    if(maxFreePRB != 0)
830    {
831       mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
832       if((fcfsHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
833       {
834          fcfsHqP->lcCb.sharedNumPrb = maxFreePRB;
835          DU_LOG("\nDEBUG  -->  SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
836                fcfsHqP->lcCb.sharedNumPrb);
837
838          /*PRB Alloc for Default LCs*/
839          prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
840                &(fcfsHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
841       }
842       else
843       {
844          fcfsHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
845
846          /*PRB Alloc for Dedicated LCs*/
847          prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
848                &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
849                NULLP, &(ueCb->srRcvd));
850
851          /*PRB Alloc for Default LCs*/
852          prbAllocUsingRRMPolicy(&(fcfsHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
853                &(fcfsHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
854                NULLP,&(ueCb->srRcvd));
855       }
856    }
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);
861
862    updateGrantSizeForBoRpt(&(fcfsHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
863
864    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
865    if (*totTBS == 0)
866    {
867       if(maxFreePRB == 0)
868       {
869          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
870       }
871       else
872       {
873          /*Schedule the LC for next slot*/
874          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
875       }      
876       return RFAILED;
877    }   
878    return ROK;
879 }
880
881 /*******************************************************************
882  *
883  * @brief Grants resources to LC in uplink
884  *
885  * @details
886  *
887  *    Function : schProcessSrOrBsrReq
888  *
889  *    Functionality:
890  *       Grants resources to LC in uplink
891  *
892  * @params[in] PDCCH Time
893  *             PUSCH Time
894  *             Start Symbol
895  *             Number of symbols
896  *             Is retransmission
897  *             HARQ process
898  * @return ROK
899  *         RFAILED
900  *
901  *******************************************************************/
902 uint8_t schFcfsScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
903 {
904    SchCellCb *cell;
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;
912
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);
917
918    if(totDataReq > 0 && ret == ROK)
919    {
920       SCH_ALLOC(dciInfo, sizeof(DciInfo));
921       if(!dciInfo)
922       {
923          DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
924          if(isRetx != TRUE)
925          {
926             if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
927                updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
928
929             updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
930          }
931          return RFAILED;
932       }
933       cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
934       memset(dciInfo,0,sizeof(DciInfo));
935
936       /* Update PUSCH allocation */
937       if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
938       {
939          puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo[ueCb->ueId - 1];
940          if(puschInfo != NULLP)
941          {
942             /* Fill DCI for UL grant */
943             schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
944             ueCb->srRcvd = false;
945             ueCb->bsrRcvd = false;
946             if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
947                updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
948             updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
949             cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk); 
950             return ROK;
951          }
952       }
953       if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
954          updateBsrAndLcList(&(fcfsHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
955       updateBsrAndLcList(&(fcfsHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
956    }
957    return ROK;
958 }
959
960 /*******************************************************************
961  *
962  * @brief Grants resources to LC in downlink 
963  *
964  * @details
965  *
966  *    Function : schFcfsScheduleDlLc 
967  *
968  *    Functionality: Grants resources to LC in uplink
969  *
970  * @params[in] PDCCH Time
971  *
972  * @return ROK
973  *         RFAILED
974  *
975  * ****************************************************************/
976 uint32_t schFcfsScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols, \
977                                uint16_t *startPrb, bool isRetx, SchDlHqProcCb **hqP)
978 {
979    SchFcfsHqProcCb *fcfsHqProcCb;
980    SchUeCb *ueCb;
981    uint8_t lcIdx = 0;
982    uint16_t maxFreePRB = 0;
983    uint16_t mcsIdx = 0;
984    uint32_t accumalatedSize = 0;
985    CmLListCp *lcLL = NULLP;
986    uint16_t rsvdDedicatedPRB = 0;
987    DlMsgSchInfo *dciSlotAlloc;
988
989    /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
990     * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
991     * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
992     * else if only Default list is present then first node in this List will add this overhead len*/
993    bool isTxPayloadLenAdded = FALSE;
994
995    ueCb = (*hqP)->hqEnt->ue;
996    dciSlotAlloc = (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1];
997    fcfsHqProcCb = (SchFcfsHqProcCb *)((*hqP)->schSpcDlHqProcCb);
998
999    if (isRetx == FALSE)
1000    {
1001       /*Re-Initalization per UE*/
1002       /* scheduled LC data fill */
1003       dciSlotAlloc->transportBlock[0].numLc = 0;
1004       isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
1005       accumalatedSize = 0;
1006
1007       for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
1008       {
1009          if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
1010          {
1011             /*Check the LC is Dedicated or default and accordingly LCList will
1012             * be used*/
1013             if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
1014             {
1015                lcLL = &(fcfsHqProcCb->lcCb.dedLcList);
1016                rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1017             }
1018             else
1019             {
1020                lcLL = &(fcfsHqProcCb->lcCb.defLcList);
1021             }
1022
1023             /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
1024             if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
1025                      (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
1026             {
1027                DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
1028                /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1029                if(!dciSlotAlloc->dlMsgPdschCfg)
1030                {
1031                   SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1032                   (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1033                }
1034                return accumalatedSize;
1035             }
1036          }
1037       }//End of for loop
1038
1039       if ((fcfsHqProcCb->lcCb.defLcList.count == 0) && (fcfsHqProcCb->lcCb.dedLcList.count == 0))
1040       {
1041          DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
1042          UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1043
1044          /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1045          if(!dciSlotAlloc->dlMsgPdschCfg)
1046          {
1047             SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1048             (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1049          }
1050          /*TRUE because this UE has nothing to be scheduled*/
1051          return accumalatedSize;
1052       }
1053    }
1054
1055    /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1056    maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, startPrb, DIR_DL);
1057
1058    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1059     * the list based on RRM policy*/
1060
1061    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
1062     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1063    if(isRetx == FALSE)
1064    {
1065       if(maxFreePRB != 0)
1066       {
1067          mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1068
1069          if((fcfsHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1070          { 
1071             fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1072             DU_LOG("\nDEBUG  -->  SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1073                   fcfsHqProcCb->lcCb.sharedNumPrb);
1074
1075             /*PRB Alloc for Default LCs*/
1076             prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1077                   &(fcfsHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1078          }
1079          else
1080          {
1081             fcfsHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1082             /*PRB Alloc for Dedicated LCs*/
1083             prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1084                   &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1085
1086             /*PRB Alloc for Default LCs*/
1087             prbAllocUsingRRMPolicy(&(fcfsHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1088                   &(fcfsHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1089          }
1090       }
1091    }
1092
1093    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1094     * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1095    if (isRetx == FALSE)
1096    {
1097       if(fcfsHqProcCb->lcCb.dedLcList.count != 0)
1098          updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1099
1100       updateGrantSizeForBoRpt(&(fcfsHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1101    }
1102    else
1103    {
1104       accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1105    }
1106
1107    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1108    if (!accumalatedSize)
1109    {
1110       if(maxFreePRB == 0)
1111       {
1112          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
1113       }
1114       else
1115       {
1116          /*Schedule the LC for next slot*/
1117          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
1118       }
1119       /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1120        * Allocation can be done in next slot*/
1121       accumalatedSize = 0;
1122    }
1123
1124    return accumalatedSize;
1125 }
1126
1127 /*******************************************************************
1128  *
1129  * @brief Scheduling of Slots in UL And DL 
1130  *
1131  * @details
1132  *
1133  *    Function : schFcfsScheduleSlot
1134  *
1135  *    Functionality: Scheduling of slots in UL and DL specific to 
1136  *       FCFS scheduling
1137  *
1138  * @params[in] Pointer to Cell
1139  *             Slot timing info
1140  *             Scheduler instance
1141  * @return void
1142  *
1143  * ****************************************************************/
1144 void schFcfsScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1145 {
1146    SchFcfsCellCb  *fcfsCell;
1147    SchFcfsUeCb    *fcfsUeCb;
1148    SchDlHqProcCb  *hqP = NULLP;
1149    SchUlHqProcCb  *ulHqP = NULLP;
1150    CmLList        *pendingUeNode;
1151    CmLList        *node;
1152    uint8_t        ueId, ueCount = 0;
1153    bool           isRarPending = false, isRarScheduled = false;
1154    bool           isMsg4Pending = false, isMsg4Scheduled = false;
1155    bool           isDlMsgPending = false, isDlMsgScheduled = false;
1156    bool           isUlGrantPending = false, isUlGrantScheduled = false;
1157
1158    fcfsCell = (SchFcfsCellCb *)cell->schSpcCell;
1159
1160    /* Select first UE in the linked list to be scheduled next */
1161    pendingUeNode = fcfsCell->ueToBeScheduled.first;
1162    ueCount = fcfsCell->ueToBeScheduled.count;
1163
1164    while(pendingUeNode && ueCount > 0)
1165    {
1166       /*Since Multi-UE perTTI is not supported, re-init following parameters.*/
1167       isRarPending = false; isRarScheduled = false;
1168       isMsg4Pending = false; isMsg4Scheduled = false;
1169       isDlMsgPending = false; isDlMsgScheduled = false;
1170       isUlGrantPending = false; isUlGrantScheduled = false;
1171       if(pendingUeNode->node)
1172       {
1173          ueId = *(uint8_t *)(pendingUeNode->node);
1174          fcfsUeCb = (SchFcfsUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1175
1176          /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
1177           * PUSCH to receive MSG3 as per k0-k2 configuration*/
1178          if(cell->raReq[ueId-1] != NULLP)
1179          {
1180             isRarPending = true;
1181             isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1182          }
1183
1184          /*MSG3 retransmisson*/
1185          if(cell->raCb[ueId-1].retxMsg3HqProc)
1186          {            
1187             schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1188          }
1189
1190          /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1191           * PUCCH to receive UL msg as per k0-k1 configuration  */
1192          if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1193          {
1194             /* Retransmission of MSG4 */
1195             isMsg4Pending = true;
1196             if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1197                isMsg4Scheduled = true;
1198          }
1199          else
1200          {
1201             /* First transmission of MSG4 */
1202             if(cell->raCb[ueId-1].msg4recvd)
1203             {
1204                isMsg4Pending = true;
1205                if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1206                   isMsg4Scheduled = true;
1207
1208                /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1209                if(!isMsg4Scheduled)
1210                   schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1211             }
1212          }
1213
1214          if(isRarPending || isMsg4Pending)
1215          {
1216             /* If RAR or MSG is successfully scheduled then
1217              * remove UE from linked list since no pending msgs for this UE */
1218             if(isRarScheduled || isMsg4Scheduled)
1219             {
1220                schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1221             }
1222             /* If RAR/MSG4 is pending but couldnt be scheduled then,
1223              * put this UE at the end of linked list to be scheduled later */
1224             else
1225             {
1226                cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1227             }
1228          }
1229
1230 #ifdef NR_DRX 
1231          if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1232          {
1233             if(pendingUeNode->node)
1234             {
1235                cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1236             }
1237          }
1238          else 
1239 #endif
1240          {
1241
1242             /* DL Data */
1243             node = NULLP;
1244             if(fcfsUeCb)
1245                node = fcfsUeCb->hqRetxCb.dlRetxHqList.first;
1246             if(node != NULLP)
1247             {
1248                /* DL Data ReTransmisson */
1249                isDlMsgPending = true;
1250                isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1251                if(isDlMsgScheduled)
1252                {
1253 #ifdef NR_DRX 
1254                   schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1255 #endif
1256                   schFcfsRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1257                }
1258             }
1259             else
1260             {
1261                /* DL Data new transmission */
1262                if((cell->boIndBitMap) & (1<<ueId))
1263                {
1264                   isDlMsgPending = true;               
1265                   isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1266
1267                   /* If DL scheduling failed, free the newly assigned HARQ process */
1268                   if(!isDlMsgScheduled)
1269                      schDlReleaseHqProcess(hqP);
1270                   else
1271                   {
1272 #ifdef NR_DRX
1273                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], gConfigInfo.gPhyDeltaDl + SCHED_DELTA);
1274 #endif
1275                   }
1276                }
1277             }
1278          }
1279 #ifdef NR_DRX 
1280          if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxUlUeActiveStatus != true))
1281          {
1282             if(pendingUeNode->node)
1283             {
1284                cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1285             }
1286          }
1287          else 
1288 #endif
1289          {
1290             /* Scheduling of UL grant */
1291             node = NULLP;
1292             if(fcfsUeCb)
1293                node = fcfsUeCb->hqRetxCb.ulRetxHqList.first;
1294             if(node != NULLP)
1295             {
1296                /* UL Data ReTransmisson */
1297                isUlGrantPending = true;
1298                isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1299                if(isUlGrantScheduled)
1300                {
1301 #ifdef NR_DRX 
1302                   schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1303 #endif
1304                   schFcfsRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1305                }
1306             }
1307             else
1308             {
1309                /* UL Data new transmission */
1310                if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1311                {
1312                   isUlGrantPending = true;
1313                   isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1314                   if(!isUlGrantScheduled)
1315                      schUlReleaseHqProcess(ulHqP, FALSE);
1316                   else
1317                   {
1318 #ifdef NR_DRX
1319                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], gConfigInfo.gPhyDeltaUl + SCHED_DELTA);
1320 #endif
1321                   }
1322                }
1323             }
1324
1325             if(isUlGrantPending || isDlMsgPending)
1326             {
1327                if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1328                {
1329                   cmLListAdd2Tail(&fcfsCell->ueToBeScheduled, cmLListDelFrm(&fcfsCell->ueToBeScheduled, pendingUeNode));
1330                }
1331                else
1332                {
1333                   schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1334                }
1335             }
1336          }
1337       }
1338       if(!isUlGrantPending && !isDlMsgPending && !isRarPending && !isMsg4Pending)
1339       {
1340          DU_LOG("\nERROR  -->  SCH: In SchFcfsScheduleSlot, UE:%d is wrongly queued\
1341                in Pending UE List without any actions, Removing the UE from the list",ueId);
1342          schFcfsRemoveUeFrmScheduleLst(cell, pendingUeNode);
1343       }
1344       if(cell->schDlSlotInfo[slotInd->slot]->prbAlloc.numPrbAlloc >= MAX_NUM_RB)
1345       {
1346          DU_LOG("\nINFO   -->  SCH: No PRB available to proceed with next UE");
1347          return;     
1348       }
1349       pendingUeNode = fcfsCell->ueToBeScheduled.first;
1350       ueCount--;
1351    }
1352 }
1353
1354 /*******************************************************************
1355  *
1356  * @brief Initializes all function pointers to FCFS function handler
1357  *
1358  * @details
1359  *
1360  *    Function : schFcfsAllApisInit
1361  *
1362  *    Functionality: Initializes all function pointers to FCFS 
1363  *       function handler
1364  *
1365  * @params[in] Function pointer array
1366  * @return void
1367  *
1368  * ****************************************************************/
1369 void schFcfsAllApisInit(SchAllApis *allFcfsApi)
1370 {
1371     /* Interface API function pointers */
1372     allFcfsApi->SchCellCfgReq = schFcfsCellCfgReq;
1373     allFcfsApi->SchCellDeleteReq = schFcfsCellDelReq;
1374     allFcfsApi->SchAddUeConfigReq = SchFcfsAddUeConfigReq;
1375     allFcfsApi->SchModUeConfigReq = SchFcfsModUeConfigReq;
1376     allFcfsApi->SchUeDeleteReq = SchFcfsUeDeleteReq; 
1377     allFcfsApi->SchDlHarqInd = SchFcfsDlHarqInd; 
1378     allFcfsApi->SchCrcInd = schFcfsProcessCrcInd;
1379     allFcfsApi->SchRachInd = schFcfsProcessRachInd;
1380     allFcfsApi->SchPagingInd = schFcfsPagingInd;
1381     allFcfsApi->SchRachRsrcReq = schFcfsRachRsrcReq; 
1382     allFcfsApi->SchRachRsrcRel = schFcfsRachRsrcRel;
1383     allFcfsApi->SchDlRlcBoInfo = schFcfsDlRlcBoInfo;
1384     allFcfsApi->SchSrUciInd = schFcfsSrUciInd;
1385     allFcfsApi->SchBsr = schFcfsBsr;
1386
1387     /* Internal API function pointers */
1388     allFcfsApi->SchAddToDlHqRetxList = schFcfsAddToDlHqRetxList;
1389     allFcfsApi->SchAddToUlHqRetxList = schFcfsAddToUlHqRetxList;
1390     allFcfsApi->SchRemoveFrmDlHqRetxList = schFcfsRemoveFrmDlHqRetxList;
1391     allFcfsApi->SchRemoveFrmUlHqRetxList = schFcfsRemoveFrmUlHqRetxList;
1392     allFcfsApi->SchAddUeToSchedule = schFcfsAddUeToSchedule;
1393     allFcfsApi->SchRemoveUeFrmScheduleLst = schFcfsRemoveUeFrmScheduleLst;
1394     allFcfsApi->SchInitDlHqProcCb = schFcfsInitDlHqProcCb;
1395     allFcfsApi->SchInitUlHqProcCb = schFcfsInitUlHqProcCb;
1396     allFcfsApi->SchFreeDlHqProcCb = schFcfsFreeDlHqProcCb;
1397     allFcfsApi->SchFreeUlHqProcCb = schFcfsFreeUlHqProcCb;
1398     allFcfsApi->SchDeleteDlHqProcCb = schFcfsDeleteDlHqProcCb;
1399     allFcfsApi->SchDeleteUlHqProcCb = schFcfsDeleteUlHqProcCb;
1400     allFcfsApi->SchScheduleSlot = schFcfsScheduleSlot;
1401     allFcfsApi->SchScheduleDlLc = schFcfsScheduleDlLc;
1402     allFcfsApi->SchScheduleUlLc = schFcfsScheduleUlLc;
1403 }
1404 /**********************************************************************
1405     End of file
1406 **********************************************************************/
1407