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