ece81a09b9a1a6f89bb73f4631ee2f31e223ed46
[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_tmr.h"
44 #include "sch_utils.h"
45 #include "sch_slice_based.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 : schSliceBasedCellCfgReq
57  *
58  *    Functionality: This function configures cell paremeters
59  *       required for Slice Based scheduling
60  *
61  * @params[in] SchCellCb *cellCb, Cell control block
62  * @return ROK
63  *         RFAILED
64  *
65  * ****************************************************************/
66 uint8_t schSliceBasedCellCfgReq(SchCellCb *cellCb)
67 {
68    SchSliceBasedCellCb *schSpcCellCb = NULLP;
69    
70    SCH_ALLOC(schSpcCellCb, sizeof(SchSliceBasedCellCb));
71    if(!schSpcCellCb)
72    {
73       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedCellCfgReq");
74       return RFAILED;
75    }
76    cmLListInit(&schSpcCellCb->ueToBeScheduled);
77    cellCb->schSpcCell = (void *)schSpcCellCb;
78    return ROK;
79 }
80
81 /*******************************************************************
82  *
83  * @brief Function to handle Cell configuration request
84  *
85  * @details
86  *
87  *    Function : schSliceBasedCellDelReq
88  *
89  *    Functionality: This function deletes/frees cell params
90  *       specific to Slice Based scheduling
91  *
92  * @params[in] Pointer to Cell control block
93  * @return void
94  *
95  * ****************************************************************/
96 void schSliceBasedCellDelReq(SchCellCb *cellCb)
97 {
98    SchSliceBasedCellCb *schSpcCellCb = NULLP;
99    CmLList *node=NULL, *next=NULL;
100
101    schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
102    /* Remove all UE from ueToBeScheduled list and deallocate */
103    node = schSpcCellCb->ueToBeScheduled.first;
104    while(node)
105    {
106       next = node->next;
107       SCH_FREE(node->node, sizeof(uint8_t));
108       cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
109       SCH_FREE(node, sizeof(CmLList));
110       node = next;
111    }
112    SCH_FREE(schSpcCellCb, sizeof(SchSliceBasedCellCb));
113    cellCb->schSpcCell = NULLP;
114 }
115
116 /*******************************************************************
117  *
118  * @brief Function to handle UE configuration request
119  *
120  * @details
121  *
122  *    Function : SchSliceBasedAddUeConfigReq
123  *
124  *    Functionality: Adds/Configures UE parameters required for
125  *       Slice Based scheduling
126  *
127  * @params[in] Pointer to UE control block
128  * @return ROK
129  *         RFAILED
130  *
131  * ****************************************************************/
132 uint8_t SchSliceBasedAddUeConfigReq(SchUeCb *ueCb)
133 {
134    SchSliceBasedUeCb *ueSliceBasedCb;
135
136    SCH_ALLOC(ueSliceBasedCb, sizeof(SchSliceBasedHqCb));
137    if(!ueSliceBasedCb)
138    {
139       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in SchSliceBasedAddUeConfigReq");
140       return RFAILED;
141    }
142    
143    cmLListInit(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
144    cmLListInit(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
145    ueCb->schSpcUeCb = (void *)ueSliceBasedCb;
146    
147    return ROK;
148 }
149
150 /*******************************************************************
151  *
152  * @brief Handles UE reconfiguration request
153  *
154  * @details
155  *
156  *    Function : SchSliceBasedModUeConfigReq
157  *
158  *    Functionality: 
159  *
160  * @params[in] Pointer to UE control block
161  * @return void
162  *
163  * ****************************************************************/
164 void SchSliceBasedModUeConfigReq(SchUeCb *ueCb)
165 {
166    /*TBD: No action required for Slice Based*/
167    return;
168 }
169
170 /*******************************************************************
171  *
172  * @brief Handles UE Delete Request
173  *
174  * @details
175  *
176  *    Function : SchSliceBasedUeDeleteReq 
177  *
178  *    Functionality: Deletes/Frees UE parameters specific to 
179  *       Slice Based scheduling
180  *
181  * @params[in] Pointer to UE control block
182  * @return void
183  *
184  * ****************************************************************/
185 void SchSliceBasedUeDeleteReq(SchUeCb *ueCb)
186 {
187    SchSliceBasedCellCb *schSpcCellCb = NULLP;
188    SchSliceBasedUeCb *ueSliceBasedCb = NULLP;
189    CmLList *node=NULL, *next=NULL;
190    uint8_t ueId = 0;
191
192    schSpcCellCb = (SchSliceBasedCellCb *)ueCb->cellCb->schSpcCell;
193    /* Remove all UE from ueToBeScheduled list and deallocate */
194    node = schSpcCellCb->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(&schSpcCellCb->ueToBeScheduled, node);
203         SCH_FREE(node, sizeof(CmLList));
204         break;
205       }
206       node = next;
207    }
208    
209    ueSliceBasedCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
210    cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
211    cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
212
213    SCH_FREE(ueSliceBasedCb, sizeof(SchSliceBasedUeCb));
214    ueCb->schSpcUeCb = NULLP;
215    return;
216 }
217
218 /*******************************************************************
219  *
220  * @brief Intializes HARQ Process control block
221  *
222  * @details
223  *
224  *    Function : schSliceBasedInitDlHqProcCb
225  *
226  *    Functionality: Intitialized parameters of HARQ process control
227  *       block specific to Slice Based scheduling in Downlink
228  *
229  * @params[in] Pointer to Downlink HARQ Process control block
230  * @return ROK
231  *         RFAILED
232  *
233  * ****************************************************************/
234 uint8_t schSliceBasedInitDlHqProcCb(SchDlHqProcCb *hqP)
235 {
236    SchSliceBasedHqProcCb *schSpcHqP;
237
238    SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
239    if(!schSpcHqP)
240    {
241       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitDlHqProcCb");
242       return RFAILED;
243    }
244
245    cmLListInit(&schSpcHqP->lcCb.dedLcList);
246    cmLListInit(&schSpcHqP->lcCb.defLcList);
247    hqP->schSpcDlHqProcCb = (void *)schSpcHqP;
248
249    return ROK;
250 }
251
252 /*******************************************************************
253  *
254  * @brief Handles HARQ Process delete request
255  *
256  * @details 
257  *
258  *    Function : schSliceBasedDeleteDlHqProcCb
259  *
260  *    Functionality: Deletes HARQ Process parameters specific to 
261  *       Slice Based scheduling in Downlink
262  *
263  * @params[in] Pointer to Downlink HARQ Process control block
264  * @return void
265  *
266  * ****************************************************************/
267 void schSliceBasedDeleteDlHqProcCb(SchDlHqProcCb *hqP)
268 {
269    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
270    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
271    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
272    SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
273    hqP->schSpcDlHqProcCb = NULLP;
274 }
275
276 /*******************************************************************
277  *
278  * @brief Intializes HARQ Process control block
279  *
280  * @details
281  *
282  *    Function : schSliceBasedInitUlHqProcCb
283  *
284  *    Functionality: Intitialized parameters of HARQ process control
285  *       block specific to Slice Based scheduling in Uplink
286  *
287  * @params[in] Pointer to Uplink HARQ Process control block
288  * @return ROK
289  *         RFAILED
290  *
291  * ****************************************************************/
292 uint8_t schSliceBasedInitUlHqProcCb(SchUlHqProcCb *hqP)
293 {
294    SchSliceBasedHqProcCb *schSpcHqP;
295
296    SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
297    if(!schSpcHqP)
298    {
299       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitUlHqProcCb");
300       return RFAILED;
301    }
302    cmLListInit(&schSpcHqP->lcCb.dedLcList);
303    cmLListInit(&schSpcHqP->lcCb.defLcList);
304    hqP->schSpcUlHqProcCb = (void *)schSpcHqP;
305  
306    return ROK;
307 }
308
309 /*******************************************************************
310  *
311  * @brief Handled Deletion of HARQ Process control block
312  *
313  * @details
314  *
315  *    Function : schSliceBasedDeleteUlHqProcCb
316  *
317  *    Functionality: Deletes HARQ Process parameters specific to 
318  *       Slice Based scheduling in Uplink
319  *
320  * @params[in] Pointer to Uplink HARQ Process Control block
321  * @return void
322  *
323  * ****************************************************************/
324 void schSliceBasedDeleteUlHqProcCb(SchUlHqProcCb *hqP)
325 {
326    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
327    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
328    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
329    SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
330    hqP->schSpcUlHqProcCb = NULLP;
331 }
332
333 /*******************************************************************
334  *
335  * @brief Handles freeing of HARQ Process
336  *
337  * @details
338  *
339  *    Function : schSliceBasedFreeDlHqProcCb
340  *
341  *    Functionality: Frees HARQ Process parameters specific to 
342  *       Slice Based 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 schSliceBasedFreeDlHqProcCb(SchDlHqProcCb *hqP)
349 {
350    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
351
352    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
353    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
354 }
355
356 /*******************************************************************
357  *
358  * @brief Handles freeing of HARQ Process
359  *
360  * @details
361  *
362  *    Function : schSliceBasedFreeUlHqProcCb
363  *
364  *    Functionality: Frees HARQ Process parameters specific to 
365  *       Slice Based 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 schSliceBasedFreeUlHqProcCb(SchUlHqProcCb *hqP)
372 {
373    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
374
375    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
376    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
377 }
378
379 /*******************************************************************
380  *
381  * @brief Adds HARQ process to retransmission list
382  *
383  * @details
384  *
385  *    Function : schSliceBasedAddToDlHqRetxList
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 schSliceBasedAddToDlHqRetxList(SchDlHqProcCb *hqP)
394 {
395    SchSliceBasedUeCb *schSpcUeCb;
396
397    schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
398    cmLListAdd2Tail(&(schSpcUeCb->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       schSliceBasedAddUeToSchedule(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 : schSliceBasedAddToUlHqRetxList
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 schSliceBasedAddToUlHqRetxList(SchUlHqProcCb *hqP)
426 {
427    SchSliceBasedUeCb *schSpcUeCb;
428
429    schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
430    cmLListAdd2Tail(&(schSpcUeCb->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       schSliceBasedAddUeToSchedule(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 : schSliceBasedAddUeToSchedule
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 schSliceBasedAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
464 {
465    SchSliceBasedCellCb *schSpcCellCb = NULLP;
466    uint8_t *ueId;
467    CmLList *node;
468
469    schSpcCellCb = (SchSliceBasedCellCb *)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 = schSpcCellCb->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 schSliceBasedAddUeToSchedule");
486       return RFAILED;
487    }
488    *ueId = ueIdToAdd;
489    if(addNodeToLList(&schSpcCellCb->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 : schSliceBasedProcessCrcInd
504  *
505  *    Functionality: Processes CRC Indication as required for Slice Based
506  *       scheduling
507  *
508  * @params[in] Pointer to Cell control block
509  *             UE Id
510  * @return void
511  *
512  * ****************************************************************/
513 void schSliceBasedProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
514 {
515    schSliceBasedAddUeToSchedule(cellCb, ueId);   
516 }
517
518 /*******************************************************************
519  *
520  * @brief Processes Buffer Occupancy report from RLC
521  *
522  * @details
523  *
524  *    Function : schSliceBasedDlRlcBoInfo
525  *
526  *    Functionality: Process buffer occupany report 
527  *
528  * @params[in]
529  * @return
530  *
531  * ****************************************************************/
532 void schSliceBasedDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
533 {
534    schSliceBasedAddUeToSchedule(cellCb, ueId);   
535 }
536
537 /*******************************************************************
538  *
539  * @brief Processes BSR request
540  *
541  * @details
542  *
543  *    Function : schSliceBasedBsr
544  *
545  *    Functionality: Processes BSR as per Slice Based scheduling
546  *
547  * @params[in] Pointer to Cell 
548  *             UE ID
549  * @return void
550  *
551  * ****************************************************************/
552 void schSliceBasedBsr(SchCellCb *cellCb, uint16_t ueId)
553 {
554    schSliceBasedAddUeToSchedule(cellCb, ueId);   
555 }
556
557 /*******************************************************************
558  *
559  * @brief Processed UCI Indication
560  *
561  * @details
562  *
563  *    Function : schSliceBasedSrUciInd
564  *
565  *    Functionality: Processing of UCI indication specific to 
566  *       Slice Based scheduling
567  *
568  * @params[in] Pointer to Cell
569  *             UE Id
570  * @return void
571  *
572  * ****************************************************************/
573 void schSliceBasedSrUciInd(SchCellCb *cellCb, uint16_t ueId)
574 {
575    schSliceBasedAddUeToSchedule(cellCb, ueId);   
576 }
577
578 /*******************************************************************
579  *
580  * @brief Processing of RACH Indication
581  *
582  * @details
583  *
584  *    Function : schSliceBasedProcessRachInd
585  *
586  *    Functionality: Processing of RACH Indication specific to 
587  *       Slice Based scheduling
588  *
589  * @params[in] Pointer to Cell Cb
590  *             UE Id
591  * @return void
592  *
593  * ****************************************************************/
594 void schSliceBasedProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
595 {
596    schSliceBasedAddUeToSchedule(cellCb, ueId);   
597 }
598
599 /*******************************************************************
600  *
601  * @brief Processing of DL HARQ Indication
602  *
603  * @details
604  *
605  *    Function : SchSliceBasedDlHarqInd
606  *
607  *    Functionality:
608  *
609  * @params[in] 
610  * @return void
611  *
612  * ****************************************************************/
613 void SchSliceBasedDlHarqInd()
614 {
615    return;
616 }
617
618 /*******************************************************************
619  *
620  * @brief Processing of Paging indication
621  *
622  * @details
623  *
624  *    Function : schSliceBasedPagingInd
625  *
626  *    Functionality:
627  *
628  * @params[in]
629  * @return void
630  *
631  * ****************************************************************/
632 void schSliceBasedPagingInd()
633 {
634    return;
635 }
636
637 /*******************************************************************
638  *
639  * @brief Processing of RACH Resource Request
640  *
641  * @details
642  *
643  *    Function : schSliceBasedRachRsrcReq
644  *
645  *    Functionality:
646  *
647  * @params[in]
648  * @return void
649  *
650  * ****************************************************************/
651 void schSliceBasedRachRsrcReq()
652 {
653    return;
654 }
655
656 /*******************************************************************
657  *
658  * @brief Processing of RACH Resource Release
659  *
660  * @details
661  *
662  *    Function : schSliceBasedRachRsrcRel
663  *
664  *    Functionality:
665  *
666  * @params[in]
667  * @return void
668  *
669  * ****************************************************************/
670 void schSliceBasedRachRsrcRel()
671 {
672    return;
673 }
674
675 /*******************************************************************
676  *
677  * @brief Remove entry from HARQ retransmission list
678  *
679  * @details
680  *
681  *    Function : schSliceBasedRemoveFrmDlHqRetxList
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 schSliceBasedRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
691 {
692    SchSliceBasedUeCb *schSpcUeCb;
693
694    schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
695    cmLListDelFrm(&schSpcUeCb->hqRetxCb.dlRetxHqList, node);
696 }
697
698 /*******************************************************************
699  *
700  * @brief Remove entry from HARQ retransmission list
701  *
702  * @details
703  *
704  *    Function : schSliceBasedRemoveFrmUlHqRetxList
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 schSliceBasedRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
714 {
715    SchSliceBasedUeCb *schSpcUeCb;
716
717    schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
718    cmLListDelFrm(&schSpcUeCb->hqRetxCb.ulRetxHqList, node);
719 }
720
721 /*******************************************************************
722  *
723  * @brief Remove UE from Scheduling List
724  *
725  * @details
726  *
727  *    Function : schSliceBasedRemoveUeFrmScheduleLst
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 schSliceBasedRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
737 {
738    SchSliceBasedCellCb *schSpcCell;
739
740    schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
741    SCH_FREE(node->node, sizeof(uint8_t));
742    deleteNodeFromLList(&schSpcCell->ueToBeScheduled, node);
743 }
744
745 /*******************************************************************
746  *
747  * @brief  Handler to calculate TBS size for BSR requested
748  *
749  * @details
750  *
751  *    Function :  schSliceBasedCalculateUlTbs
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 schSliceBasedCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
770                           uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchSliceBasedHqProcCb *schSpcHqP)
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 = &(schSpcHqP->lcCb.dedLcList);
794          rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
795       }
796       else
797       {
798          lcLL = &(schSpcHqP->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 ((schSpcHqP->lcCb.defLcList.count == 0) && (schSpcHqP->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((schSpcHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
832       {
833          schSpcHqP->lcCb.sharedNumPrb = maxFreePRB;
834          DU_LOG("\nDEBUG  -->  SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
835                schSpcHqP->lcCb.sharedNumPrb);
836
837          /*PRB Alloc for Default LCs*/
838          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
839                &(schSpcHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
840       }
841       else
842       {
843          schSpcHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
844
845          /*PRB Alloc for Dedicated LCs*/
846          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
847                &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
848                NULLP, &(ueCb->srRcvd));
849
850          /*PRB Alloc for Default LCs*/
851          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
852                &(schSpcHqP->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(schSpcHqP->lcCb.dedLcList.count != 0)
859       updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
860
861    updateGrantSizeForBoRpt(&(schSpcHqP->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 schSliceBasedScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
902 {
903    SchCellCb *cell;
904    SchSliceBasedHqProcCb *schSpcHqProcCb;
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    schSpcHqProcCb = (SchSliceBasedHqProcCb *)(*hqP)->schSpcUlHqProcCb;
915    ret = schSliceBasedCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, schSpcHqProcCb);
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(schSpcHqProcCb->lcCb.dedLcList.count != 0)
926                updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
927
928             updateBsrAndLcList(&(schSpcHqProcCb->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                ueCb->srRcvd = false;
946                ueCb->bsrRcvd = false;
947                cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
948                if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
949                   updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
950                updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
951                cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);                  
952                return ROK;
953             }
954          }
955       }
956       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
957          updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
958       updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
959    }
960    return ROK;
961 }
962
963 /*******************************************************************
964  *
965  * @brief Grants resources to LC in downlink 
966  *
967  * @details
968  *
969  *    Function : schSliceBasedScheduleDlLc 
970  *
971  *    Functionality: Grants resources to LC in uplink
972  *
973  * @params[in] PDCCH Time
974  *
975  * @return ROK
976  *         RFAILED
977  *
978  * ****************************************************************/
979 uint32_t schSliceBasedScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols,\
980                                     uint16_t *startPrb, bool isRetx, SchDlHqProcCb **hqP)
981 {
982    SchSliceBasedHqProcCb *schSpcHqProcCb;
983    SchUeCb *ueCb;
984    uint8_t lcIdx = 0;
985    uint16_t maxFreePRB = 0;
986    uint16_t mcsIdx = 0;
987    uint32_t accumalatedSize = 0;
988    CmLListCp *lcLL = NULLP;
989    uint16_t rsvdDedicatedPRB = 0;
990    DlMsgSchInfo *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    schSpcHqProcCb = (SchSliceBasedHqProcCb *)((*hqP)->schSpcDlHqProcCb);
1001
1002    if (isRetx == FALSE)
1003    {
1004       /*Re-Initalization per UE*/
1005       /* scheduled LC data fill */
1006       dciSlotAlloc->transportBlock[0].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 = &(schSpcHqProcCb->lcCb.dedLcList);
1019                rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1020             }
1021             else
1022             {
1023                lcLL = &(schSpcHqProcCb->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->dlMsgPdschCfg)
1033                {
1034                   SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1035                   (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1036                }
1037                return accumalatedSize;
1038             }
1039          }
1040       }//End of for loop
1041
1042       if ((schSpcHqProcCb->lcCb.defLcList.count == 0) && (schSpcHqProcCb->lcCb.dedLcList.count == 0))
1043       {
1044          DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
1045          UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1046
1047          /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1048          if(!dciSlotAlloc->dlMsgPdschCfg)
1049          {
1050             SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1051             (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1052          }
1053          /*TRUE because this UE has nothing to be scheduled*/
1054          return accumalatedSize;
1055       }
1056    }
1057
1058    /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1059    maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, startPrb, DIR_DL);
1060
1061    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1062     * the list based on RRM policy*/
1063
1064    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
1065     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1066    if(isRetx == FALSE)
1067    {
1068       if(maxFreePRB != 0)
1069       {
1070          mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1071
1072          if((schSpcHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1073          { 
1074             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1075             DU_LOG("\nDEBUG  -->  SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1076                   schSpcHqProcCb->lcCb.sharedNumPrb);
1077
1078             /*PRB Alloc for Default LCs*/
1079             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1080                   &(schSpcHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1081          }
1082          else
1083          {
1084             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1085             /*PRB Alloc for Dedicated LCs*/
1086             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1087                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1088
1089             /*PRB Alloc for Default LCs*/
1090             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1091                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1092          }
1093       }
1094    }
1095
1096    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1097     * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1098    if (isRetx == FALSE)
1099    {
1100       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
1101          updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1102
1103       updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1104    }
1105    else
1106    {
1107       accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1108    }
1109
1110    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1111    if (!accumalatedSize)
1112    {
1113       if(maxFreePRB == 0)
1114       {
1115          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
1116       }
1117       else
1118       {
1119          /*Schedule the LC for next slot*/
1120          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
1121       }
1122       /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1123        * Allocation can be done in next slot*/
1124       accumalatedSize = 0;
1125    }
1126
1127    return accumalatedSize;
1128 }
1129
1130 /*******************************************************************
1131  *
1132  * @brief Scheduling of Slots in UL And DL 
1133  *
1134  * @details
1135  *
1136  *    Function : schSliceBasedScheduleSlot
1137  *
1138  *    Functionality: Scheduling of slots in UL and DL specific to 
1139  *       Slice Based scheduling
1140  *
1141  * @params[in] Pointer to Cell
1142  *             Slot timing info
1143  *             Scheduler instance
1144  * @return void
1145  *
1146  * ****************************************************************/
1147 void schSliceBasedScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1148 {
1149    SchSliceBasedCellCb  *schSpcCell;
1150    SchSliceBasedUeCb    *schSpcUeCb;
1151    SchDlHqProcCb  *hqP = NULLP;
1152    SchUlHqProcCb  *ulHqP = NULLP;
1153    CmLList        *pendingUeNode;
1154    CmLList        *node;
1155    uint8_t        ueId;
1156    bool           isRarPending = false, isRarScheduled = false;
1157    bool           isMsg4Pending = false, isMsg4Scheduled = false;
1158    bool           isDlMsgPending = false, isDlMsgScheduled = false;
1159    bool           isUlGrantPending = false, isUlGrantScheduled = false;
1160
1161    schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
1162    
1163    /* Select first UE in the linked list to be scheduled next */
1164    pendingUeNode = schSpcCell->ueToBeScheduled.first;
1165    if(pendingUeNode)
1166    {
1167       if(pendingUeNode->node)
1168       {
1169          ueId = *(uint8_t *)(pendingUeNode->node);
1170          schSpcUeCb = (SchSliceBasedUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1171
1172          /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
1173           * PUSCH to receive MSG3 as per k0-k2 configuration*/
1174          if(cell->raReq[ueId-1] != NULLP)
1175          {
1176             isRarPending = true;
1177             isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1178          }
1179
1180          /*MSG3 retransmisson*/
1181          if(cell->raCb[ueId-1].retxMsg3HqProc)
1182          {            
1183             schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1184          }
1185
1186          /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1187           * PUCCH to receive UL msg as per k0-k1 configuration  */
1188          if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1189          {
1190             /* Retransmission of MSG4 */
1191             isMsg4Pending = true;
1192             if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1193                isMsg4Scheduled = true;
1194          }
1195          else
1196          {
1197             /* First transmission of MSG4 */
1198             if(cell->raCb[ueId-1].msg4recvd)
1199             {
1200                isMsg4Pending = true;
1201                if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1202                   isMsg4Scheduled = true;
1203
1204                /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1205                if(!isMsg4Scheduled)
1206                   schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1207             }
1208          }
1209
1210          if(isRarPending || isMsg4Pending)
1211          {
1212             /* If RAR or MSG is successfully scheduled then
1213              * remove UE from linked list since no pending msgs for this UE */
1214             if(isRarScheduled || isMsg4Scheduled)
1215             {
1216                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1217             }
1218             /* If RAR/MSG4 is pending but couldnt be scheduled then,
1219              * put this UE at the end of linked list to be scheduled later */
1220             else
1221             {
1222                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1223             }
1224          }
1225
1226 #ifdef NR_DRX 
1227          if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1228          {
1229             if(pendingUeNode->node)
1230             {
1231                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1232             }
1233          }
1234          else 
1235 #endif
1236          {
1237
1238             /* DL Data */
1239             node = NULLP;
1240             if(schSpcUeCb)
1241                node = schSpcUeCb->hqRetxCb.dlRetxHqList.first;
1242             if(node != NULLP)
1243             {
1244                /* DL Data ReTransmisson */
1245                isDlMsgPending = true;
1246                isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1247                if(isDlMsgScheduled)
1248                {
1249 #ifdef NR_DRX 
1250                   schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1251 #endif
1252                   schSliceBasedRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1253                }
1254             }
1255             else
1256             {
1257                /* DL Data new transmission */
1258                if((cell->boIndBitMap) & (1<<ueId))
1259                {
1260                   isDlMsgPending = true;               
1261                   isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1262
1263                   /* If DL scheduling failed, free the newly assigned HARQ process */
1264                   if(!isDlMsgScheduled)
1265                      schDlReleaseHqProcess(hqP);
1266                   else
1267                   {
1268 #ifdef NR_DRX
1269                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
1270 #endif
1271                   }
1272                }
1273             }
1274
1275             /* Scheduling of UL grant */
1276             node = NULLP;
1277             if(schSpcUeCb)
1278                node = schSpcUeCb->hqRetxCb.ulRetxHqList.first;
1279             if(node != NULLP)
1280             {
1281                /* UL Data ReTransmisson */
1282                isUlGrantPending = true;
1283                isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1284                if(isUlGrantScheduled)
1285                {
1286 #ifdef NR_DRX 
1287                   schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1288 #endif
1289                   schSliceBasedRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1290                }
1291             }
1292             else
1293             {
1294                /* UL Data new transmission */
1295                if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1296                {
1297                   isUlGrantPending = true;
1298                   isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1299                   if(!isUlGrantScheduled)
1300                      schUlReleaseHqProcess(ulHqP, FALSE);
1301                   else
1302                   {
1303 #ifdef NR_DRX
1304                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
1305 #endif
1306                   }
1307                }
1308             }
1309
1310             if(!isUlGrantPending && !isDlMsgPending)
1311             {
1312                /* No action required */  
1313             }
1314             else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1315             {
1316                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1317             }
1318             else
1319             {
1320                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1321             }
1322          }
1323       }
1324    }
1325 }
1326
1327 /*******************************************************************
1328  *
1329  * @brief Initializes all function pointers to Slice Based function handler
1330  *
1331  * @details
1332  *
1333  *    Function : schSliceBasedAllApisInit
1334  *
1335  *    Functionality: Initializes all function pointers to Slice Based 
1336  *       function handler
1337  *
1338  * @params[in] Function pointer array
1339  * @return void
1340  *
1341  * ****************************************************************/
1342 void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi)
1343 {
1344     /* Interface API function pointers */
1345     allSliceBasedApi->SchCellCfgReq = schSliceBasedCellCfgReq;
1346     allSliceBasedApi->SchCellDeleteReq = schSliceBasedCellDelReq;
1347     allSliceBasedApi->SchAddUeConfigReq = SchSliceBasedAddUeConfigReq;
1348     allSliceBasedApi->SchModUeConfigReq = SchSliceBasedModUeConfigReq;
1349     allSliceBasedApi->SchUeDeleteReq = SchSliceBasedUeDeleteReq; 
1350     allSliceBasedApi->SchDlHarqInd = SchSliceBasedDlHarqInd; 
1351     allSliceBasedApi->SchCrcInd = schSliceBasedProcessCrcInd;
1352     allSliceBasedApi->SchRachInd = schSliceBasedProcessRachInd;
1353     allSliceBasedApi->SchPagingInd = schSliceBasedPagingInd;
1354     allSliceBasedApi->SchRachRsrcReq = schSliceBasedRachRsrcReq; 
1355     allSliceBasedApi->SchRachRsrcRel = schSliceBasedRachRsrcRel;
1356     allSliceBasedApi->SchDlRlcBoInfo = schSliceBasedDlRlcBoInfo;
1357     allSliceBasedApi->SchSrUciInd = schSliceBasedSrUciInd;
1358     allSliceBasedApi->SchBsr = schSliceBasedBsr;
1359
1360     /* Internal API function pointers */
1361     allSliceBasedApi->SchAddToDlHqRetxList = schSliceBasedAddToDlHqRetxList;
1362     allSliceBasedApi->SchAddToUlHqRetxList = schSliceBasedAddToUlHqRetxList;
1363     allSliceBasedApi->SchRemoveFrmDlHqRetxList = schSliceBasedRemoveFrmDlHqRetxList;
1364     allSliceBasedApi->SchRemoveFrmUlHqRetxList = schSliceBasedRemoveFrmUlHqRetxList;
1365     allSliceBasedApi->SchAddUeToSchedule = schSliceBasedAddUeToSchedule;
1366     allSliceBasedApi->SchRemoveUeFrmScheduleLst = schSliceBasedRemoveUeFrmScheduleLst;
1367     allSliceBasedApi->SchInitDlHqProcCb = schSliceBasedInitDlHqProcCb;
1368     allSliceBasedApi->SchInitUlHqProcCb = schSliceBasedInitUlHqProcCb;
1369     allSliceBasedApi->SchFreeDlHqProcCb = schSliceBasedFreeDlHqProcCb;
1370     allSliceBasedApi->SchFreeUlHqProcCb = schSliceBasedFreeUlHqProcCb;
1371     allSliceBasedApi->SchDeleteDlHqProcCb = schSliceBasedDeleteDlHqProcCb;
1372     allSliceBasedApi->SchDeleteUlHqProcCb = schSliceBasedDeleteUlHqProcCb;
1373     allSliceBasedApi->SchScheduleSlot = schSliceBasedScheduleSlot;
1374     allSliceBasedApi->SchScheduleDlLc = schSliceBasedScheduleDlLc;
1375     allSliceBasedApi->SchScheduleUlLc = schSliceBasedScheduleUlLc;
1376 }
1377 /**********************************************************************
1378     End of file
1379 **********************************************************************/
1380