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