Merge "MIB periodicity fix Jira ID : ODUHIGH-183"
[o-du/l2.git] / src / 5gnrsch / sch.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:     sch.c
22   
23      Type:     C source file
24   
25      Desc:     C source code for scheduler fucntions
26   
27      File:     sch.c
28   
29 **********************************************************************/
30
31 /** @file sch.c
32 @brief This file implements the schedulers main access to MAC layer code.
33 */
34 #include "stdbool.h"
35 #include "envopt.h"        /* environment options */
36 #include "envdep.h"        /* environment dependent */
37 #include "envind.h"        /* environment independent */
38 #include "gen.h"           /* general layer */
39 #include "ssi.h"           /* system service interface */
40 #include "cm_tkns.h"       /* Common Token Defines */
41 #include "cm_llist.h"      /* Common Link List Defines */
42 #include "cm_hash.h"       /* Common Hash List Defines */
43 #include "cm_mblk.h"       /* common memory link list library */
44 #include "cm_lte.h"        /* Common LTE Defines */
45 #include "lrg.h"
46 #include "rgr.h"
47 #include "tfu.h"
48 #include "rg_sch_inf.h"
49 #include "rg_sch.h"
50 #include "gen.x"           /* general layer typedefs */
51 #include "ssi.x"           /* system services typedefs */
52 #include "cm5.x"           /* system services */
53 #include "cm_tkns.x"       /* Common Token Definitions */
54 #include "cm_llist.x"      /* Common Link List Definitions */
55 #include "cm_lib.x"        /* Common Library Definitions */
56 #include "cm_hash.x"       /* Common Hash List Definitions */
57 #include "cm_mblk.x"       /* common memory link list library */
58 #include "cm_lte.x"        /* Common LTE Defines */
59 #include "tfu.x"           /* TFU types */
60 #include "lrg.x"           /* layer management typedefs for MAC */
61 #include "rgr.x"           /* layer management typedefs for MAC */
62 #include "rg_sch_inf.x"         /* typedefs for Scheduler */
63 #include "du_app_mac_inf.h"
64 #include "mac_sch_interface.h"
65 #include "sch.h"
66 #include "sch_utils.h"
67 #include "du_log.h"
68 #include "common_def.h"
69
70 extern SchCb schCb[SCH_MAX_INST];
71 void SchFillCfmPst(Pst *reqPst,Pst *cfmPst,RgMngmt *cfm);
72 /* local defines */
73 SchCellCfgCfmFunc SchCellCfgCfmOpts[] = 
74 {
75         packSchCellCfgCfm,     /* LC */
76         MacProcSchCellCfgCfm,  /* TC */
77         packSchCellCfgCfm      /* LWLC */
78 };
79
80
81 /**
82  * @brief Task Initiation function. 
83  *
84  * @details
85  *
86  *     Function : schActvInit
87  *     
88  *     This function is supplied as one of parameters during MAC's 
89  *     task registration. MAC will invoke this function once, after
90  *     it creates and attaches this TAPA Task to a system task.
91  *     
92  *  @param[in]  Ent Entity, the entity ID of this task.     
93  *  @param[in]  Inst Inst, the instance ID of this task.
94  *  @param[in]  Region Region, the region ID registered for memory 
95  *              usage of this task.
96  *  @param[in]  Reason Reason.
97  *  @return  int
98  *      -# ROK
99  **/
100 int schActvInit
101 (
102 Ent    entity,            /* entity */
103 Inst   instId,             /* instance */
104 Region region,         /* region */
105 Reason reason          /* reason */
106 )
107 {
108    Inst inst = (instId  - SCH_INST_START);
109
110    /* Initialize the MAC TskInit structure to zero */
111    cmMemset ((uint8_t *)&schCb[inst], 0, sizeof(schCb));
112
113    /* Initialize the MAC TskInit with received values */
114    schCb[inst].schInit.ent = entity;
115    schCb[inst].schInit.inst = inst;
116    schCb[inst].schInit.region = region;
117    schCb[inst].schInit.pool = 0;
118    schCb[inst].schInit.reason = reason;
119    schCb[inst].schInit.cfgDone = FALSE;
120    schCb[inst].schInit.acnt = FALSE;
121    schCb[inst].schInit.usta = FALSE;
122    schCb[inst].schInit.trc = FALSE;
123    schCb[inst].schInit.procId = SFndProcId();
124
125    RETVALUE(ROK);
126 } /* schActvInit */
127
128 /**
129  * @brief Scheduler instance Configuration Handler. 
130  *
131  * @details
132  *
133  *     Function : SchInstCfg
134  *     
135  *     This function in called by HandleSchGenCfgReq(). It handles the
136  *     general configurations of the scheduler instance. Returns
137  *     reason for success/failure of this function.
138  *     
139  *  @param[in]  RgCfg *cfg, the Configuaration information 
140  *  @return  U16
141  *      -# LCM_REASON_NOT_APPL 
142  *      -# LCM_REASON_INVALID_MSGTYPE
143  *      -# LCM_REASON_MEM_NOAVAIL
144  **/
145 PUBLIC U16 SchInstCfg
146 (
147 RgCfg *cfg,            /* Configuaration information */
148 Inst  dInst
149 )
150 {
151    uint16_t ret = LCM_REASON_NOT_APPL;
152    Inst     inst = (dInst - SCH_INST_START);
153
154    printf("\nEntered SchInstCfg()");
155    /* Check if Instance Configuration is done already */
156    if (schCb[inst].schInit.cfgDone == TRUE)
157    {
158       RETVALUE(LCM_REASON_INVALID_MSGTYPE);
159    }
160    /* Update the Pst structure for LM interface */
161    cmMemcpy((U8 *)&schCb[inst].schInit.lmPst,
162             (U8 *)&cfg->s.schInstCfg.genCfg.lmPst,
163              sizeof(Pst));
164    
165    schCb[inst].schInit.inst = inst;
166    schCb[inst].schInit.lmPst.srcProcId = schCb[inst].schInit.procId;
167    schCb[inst].schInit.lmPst.srcEnt = schCb[inst].schInit.ent;
168    schCb[inst].schInit.lmPst.srcInst = schCb[inst].schInit.inst +
169    SCH_INST_START;
170    schCb[inst].schInit.lmPst.event = EVTNONE;
171
172    schCb[inst].schInit.region = cfg->s.schInstCfg.genCfg.mem.region;
173    schCb[inst].schInit.pool = cfg->s.schInstCfg.genCfg.mem.pool;
174    schCb[inst].genCfg.tmrRes = cfg->s.schInstCfg.genCfg.tmrRes;
175 #ifdef LTE_ADV
176    schCb[inst].genCfg.forceCntrlSrbBoOnPCel =  cfg->s.schInstCfg.genCfg.forceCntrlSrbBoOnPCel;
177    schCb[inst].genCfg.isSCellActDeactAlgoEnable =  cfg->s.schInstCfg.genCfg.isSCellActDeactAlgoEnable;
178 #endif
179    schCb[inst].genCfg.startCellId    = cfg->s.schInstCfg.genCfg.startCellId;
180 #if 0
181    /* Initialzie the timer queue */   
182    cmMemset((U8 *)&schCb[inst].tmrTq, 0, sizeof(CmTqType)*RGSCH_TQ_SIZE);
183    /* Initialize the timer control point */
184    cmMemset((U8 *)&schCb[inst].tmrTqCp, 0, sizeof(CmTqCp));
185    schCb[inst].tmrTqCp.tmrLen = RGSCH_TQ_SIZE;
186
187    /* SS_MT_TMR needs to be enabled as schActvTmr needs instance information */
188    /* Timer Registration request to SSI */
189    if (SRegTmrMt(schCb[inst].schInit.ent, dInst,
190       (S16)schCb[inst].genCfg.tmrRes, schActvTmr) != ROK)
191    {
192       RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "SchInstCfg(): Failed to "
193              "register timer.");
194       RETVALUE(LCM_REASON_MEM_NOAVAIL);
195    }   
196 #endif               
197    /* Set Config done in TskInit */
198    schCb[inst].schInit.cfgDone = TRUE;
199    printf("\nScheduler gen config done");
200    
201    RETVALUE(ret);
202 }
203
204 /**
205  * @brief Layer Manager Configuration request handler. 
206  *
207  * @details
208  *
209  *     Function : HandleSchGenCfgReq
210  *     
211  *     This function handles the configuration
212  *     request received at scheduler instance from the Layer Manager.
213  *     -# Based on the cfg->hdr.elmId.elmnt value it invokes one of the
214  *        functions rgHdlGenCfg() or rgHdlSapCfg().
215  *     -# Invokes RgMiLrgSchCfgCfm() to send back the confirmation to the LM.
216  *     
217  *  @param[in]  Pst *pst, the post structure     
218  *  @param[in]  RgMngmt *cfg, the configuration parameter's structure
219  *  @return  S16
220  *      -# ROK
221  **/
222 int HandleSchGenCfgReq
223 (
224 Pst      *pst,    /* post structure  */
225 RgMngmt  *cfg     /* config structure  */
226 )
227 {
228    uint16_t       ret = LCM_PRIM_OK;
229    uint16_t       reason = LCM_REASON_NOT_APPL;
230    RgMngmt   cfm;
231    Pst       cfmPst;
232
233    if(pst->dstInst < SCH_INST_START)
234    {
235       DU_LOG("\nInvalid inst ID");
236       DU_LOG("\nHandleSchGenCfgReq(): "
237                 "pst->dstInst=%d SCH_INST_START=%d", pst->dstInst,SCH_INST_START); 
238       RETVALUE(ROK);
239    }
240    printf("\nReceived scheduler gen config");
241    /* Fill the post structure for sending the confirmation */
242         memset(&cfmPst, 0 , sizeof(Pst));
243    SchFillCfmPst(pst, &cfmPst, cfg);
244
245    cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt));
246
247 #ifdef LMINT3
248    cfm.hdr.transId =
249       cfg->hdr.transId;
250 #endif
251
252    cfm.hdr.elmId.elmnt = cfg->hdr.elmId.elmnt;
253    switch(cfg->hdr.elmId.elmnt)
254    {
255       case STSCHINST:
256          reason = SchInstCfg(&cfg->t.cfg,pst->dstInst );
257          break;
258       default:
259          ret = LCM_PRIM_NOK;
260          reason = LCM_REASON_INVALID_ELMNT;
261          DU_LOG("\nInvalid Elmnt=%d", cfg->hdr.elmId.elmnt);
262          break;
263    }
264
265    if (reason != LCM_REASON_NOT_APPL)
266    {
267       ret = LCM_PRIM_NOK;
268    }
269
270    cfm.cfm.status = ret;
271    cfm.cfm.reason = reason;
272
273    SchSendCfgCfm(&cfmPst, &cfm);
274    /*   SPutSBuf(pst->region, pst->pool, (Data *)cfg, sizeof(RgMngmt)); */
275    
276    RETVALUE(ROK);
277 }/*-- HandleSchGenCfgReq --*/
278
279 /**
280  * @brief slot indication from MAC to SCH.
281  *
282  * @details
283  *
284  *     Function : macSchSlotInd 
285  *      
286  *      This API is invoked by PHY to indicate slot indication to Scheduler for
287  *      a cell.
288  *           
289  *  @param[in]  Pst            *pst
290  *  @param[in]  SlotIndInfo    *slotInd
291  *  @return  S16
292  *      -# ROK 
293  *      -# RFAILED 
294  **/
295 int macSchSlotInd 
296 (
297 Pst                 *pst, 
298 SlotIndInfo         *slotInd
299 )
300 {
301    Inst  inst = pst->dstInst-SCH_INST_START;
302
303    /* Now call the TOM (Tfu ownership module) primitive to process further */
304    schProcessSlotInd(slotInd, inst);
305
306    RETVALUE(ROK);
307 }  /* macSchSlotInd */
308
309 /*******************************************************************
310  *
311  * @brief Processes Rach indication from MAC 
312  *
313  * @details
314  *
315  *    Function : macSchRachInd
316  *
317  *    Functionality:
318  *      Processes Rach indication from MAC
319  *
320  * @params[in] 
321  * @return ROK     - success
322  *         RFAILED - failure
323  *
324  * ****************************************************************/
325 int macSchRachInd(Pst *pst, RachIndInfo *rachInd)
326 {
327    Inst  inst = pst->dstInst-SCH_INST_START;
328    DU_LOG("\nSCH : Received Rach indication");
329    schProcessRachInd(rachInd, inst);
330    return ROK;
331 }
332
333 /*******************************************************************
334  *
335  * @brief Processes CRC indication from MAC 
336  *
337  * @details
338  *
339  *    Function : macSchCrcInd
340  *
341  *    Functionality:
342  *      Processes CRC indication from MAC
343  *
344  * @params[in] Post structure
345  *             Crc Indication
346  * @return ROK     - success
347  *         RFAILED - failure
348  *
349  * ****************************************************************/
350 int macSchCrcInd(Pst *pst, CrcIndInfo *crcInd)
351 {
352    switch(crcInd->crcInd[0])
353         {
354       case CRC_FAILED:
355          DU_LOG("\nSCH : Received CRC indication. CRC Status [FAILURE]");
356                         break;
357       case CRC_PASSED:
358          DU_LOG("\nSCH : Received CRC indication. CRC Status [PASS]");
359                         break;
360            default:
361                         DU_LOG("\nSCH : Invalid CRC state %d", crcInd->crcInd[0]);
362                         return RFAILED;
363         }
364    return ROK;
365 }
366
367
368 /**
369  * @brief inti cellCb based on cellCfg
370  *
371  * @details
372  *
373  *     Function : InitSchCellCb 
374  *      
375  *      This API is invoked after receiving schCellCfg
376  *           
377  *  @param[in]  schCellCb *cell
378  *  @param[in]  SchCellCfg *schCellCfg
379  *  @return  int
380  *      -# ROK 
381  *      -# RFAILED 
382  **/
383 int InitSchCellCb(Inst inst, SchCellCfg *schCellCfg)
384 {
385    SchCellCb *cell;
386    SCH_ALLOC(cell, sizeof(SchCellCb));
387         if(!cell)
388         {
389       DU_LOG("\nMemory allocation failed in InitSchCellCb");
390                 return RFAILED;
391         }
392
393         cell->cellId = schCellCfg->cellId; 
394         cell->instIdx = inst;
395         switch(schCellCfg->ssbSchCfg.scsCommon)
396         {
397            case SCH_SCS_15KHZ:
398                 {
399                         cell->numSlots = SCH_NUM_SLOTS;
400                 }
401                 break;
402                 default:
403                    DU_LOG("\nSCS %d not supported", schCellCfg->ssbSchCfg.scsCommon);
404         }
405   
406    for(uint8_t idx=0; idx<SCH_NUM_SLOTS; idx++)
407         {
408                 SchDlSlotInfo *schDlSlotInfo;
409                 SchUlSlotInfo *schUlSlotInfo;
410
411       /* DL Alloc */
412                 SCH_ALLOC(schDlSlotInfo, sizeof(SchDlSlotInfo));
413                 if(!schDlSlotInfo)
414                 {
415                         DU_LOG("\nMemory allocation failed in InitSchCellCb");
416                         return RFAILED;
417                 }
418
419       /* UL Alloc */
420                 SCH_ALLOC(schUlSlotInfo, sizeof(SchUlSlotInfo));
421                 if(!schUlSlotInfo)
422                 {
423                         DU_LOG("\nMemory allocation failed in InitSchCellCb");
424                         return RFAILED;
425                 }
426
427       memset(schDlSlotInfo, 0, sizeof(SchDlSlotInfo));
428                 memset(schUlSlotInfo, 0, sizeof(SchUlSlotInfo));
429
430       schDlSlotInfo->totalPrb = schUlSlotInfo->totalPrb = MAX_NUM_RB;
431
432                 for(uint8_t itr=0; itr<SCH_SYMBOL_PER_SLOT; itr++)
433                 {
434                         schDlSlotInfo->assignedPrb[itr] = 0;
435                         schUlSlotInfo->assignedPrb[itr] = 0;
436                 }
437                 schUlSlotInfo->schPuschInfo = NULLP;
438
439                 for(uint8_t itr=0; itr<MAX_SSB_IDX; itr++)
440                 {
441                         memset(&schDlSlotInfo->ssbInfo[itr], 0, sizeof(SsbInfo));
442                 }
443
444                 cell->schDlSlotInfo[idx] = schDlSlotInfo;
445                 cell->schUlSlotInfo[idx] = schUlSlotInfo;
446
447         }
448         schCb[inst].cells[inst] = cell;
449
450    DU_LOG("\nCell init completed for cellId:%d", cell->cellId);
451
452    return ROK;   
453 }
454
455 void fillSchSib1Cfg(
456 Inst         schInst,
457 SchSib1Cfg   *sib1SchCfg,
458 uint16_t     pci,
459 uint8_t      offsetPointA
460 )
461 {
462    uint8_t coreset0Idx = 0;
463    uint8_t searchSpace0Idx = 0;
464    //uint8_t ssbMuxPattern = 0;
465    uint8_t numRbs = 0;
466    uint8_t numSymbols = 0;
467    uint8_t offset = 0;
468    uint8_t oValue = 0;
469    //uint8_t numSearchSpacePerSlot = 0;
470    uint8_t mValue = 0;
471    uint8_t firstSymbol = 0; /* need to calculate using formula mentioned in 38.213 */
472    uint8_t slotIndex = 0;
473    uint8_t FreqDomainResource[6] = {0};
474    uint16_t tbSize = 0;
475         uint8_t numPdschSymbols = 12; /* considering pdsch region from 2 to 13 */
476
477    PdcchCfg *pdcch = &(sib1SchCfg->sib1PdcchCfg);
478    PdschCfg *pdsch = &(sib1SchCfg->sib1PdschCfg);
479    BwpCfg *bwp = &(sib1SchCfg->bwp);
480
481    coreset0Idx     = sib1SchCfg->coresetZeroIndex;
482    searchSpace0Idx = sib1SchCfg->searchSpaceZeroIndex;
483
484    /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */
485    //ssbMuxPattern = coresetIdxTable[coreset0Idx][0];
486    numRbs        = coresetIdxTable[coreset0Idx][1];
487    numSymbols    = coresetIdxTable[coreset0Idx][2];
488    offset        = coresetIdxTable[coreset0Idx][3];
489
490    /* derive the search space params from table 13-11 spec 38.213 */
491    oValue                = searchSpaceIdxTable[searchSpace0Idx][0];
492    //numSearchSpacePerSlot = searchSpaceIdxTable[searchSpace0Idx][1];
493    mValue                = searchSpaceIdxTable[searchSpace0Idx][2];
494    firstSymbol           = searchSpaceIdxTable[searchSpace0Idx][3];
495
496    /* calculate the n0, need to add the formulae, as of now the value is 0 
497     * Need to add the even and odd values of i during configuration 
498     * [(O . 2^u + i . M )  ] mod numSlotsPerSubframe 
499     * assuming u = 0, i = 0, numSlotsPerSubframe = 10
500     * Also, from this configuration, coreset0 is only on even subframe */
501    slotIndex = ((oValue * 1) + (0 * mValue)) % 10; 
502    sib1SchCfg->n0 = slotIndex;
503  
504    /* calculate the PRBs */
505    schAllocFreqDomRscType0(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource);
506
507    /* fill BWP */
508    bwp->freqAlloc.numPrb   = MAX_NUM_RB; /* whole of BW */
509    bwp->freqAlloc.startPrb = 0;
510    bwp->subcarrierSpacing  = 0;         /* 15Khz */
511    bwp->cyclicPrefix       = 0;              /* normal */
512
513    /* fill the PDCCH PDU */
514    pdcch->coreset0Cfg.coreSet0Size = numRbs;
515    pdcch->coreset0Cfg.startSymbolIndex = firstSymbol;
516    pdcch->coreset0Cfg.durationSymbols = numSymbols;
517    memcpy(pdcch->coreset0Cfg.freqDomainResource,FreqDomainResource,6);
518    pdcch->coreset0Cfg.cceRegMappingType = 1; /* coreset0 is always interleaved */
519    pdcch->coreset0Cfg.regBundleSize = 6;    /* spec-38.211 sec 7.3.2.2 */
520    pdcch->coreset0Cfg.interleaverSize = 2;  /* spec-38.211 sec 7.3.2.2 */
521    pdcch->coreset0Cfg.coreSetType = 0;
522    pdcch->coreset0Cfg.shiftIndex = pci;
523    pdcch->coreset0Cfg.precoderGranularity = 0; /* sameAsRegBundle */
524    pdcch->numDlDci = 1;
525    pdcch->dci.rnti = SI_RNTI;
526    pdcch->dci.scramblingId = pci;
527    pdcch->dci.scramblingRnti = 0;
528    pdcch->dci.cceIndex = 0;
529    pdcch->dci.aggregLevel = 4;
530    pdcch->dci.beamPdcchInfo.numPrgs = 1;
531    pdcch->dci.beamPdcchInfo.prgSize = 1;
532    pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
533    pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
534    pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
535    pdcch->dci.txPdcchPower.powerValue = 0;
536    pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
537         /* Storing pdschCfg pointer here. Required to access pdsch config while
538         fillig up pdcch pdu */
539    pdcch->dci.pdschCfg = pdsch; 
540
541    /* fill the PDSCH PDU */
542         uint8_t cwCount = 0;
543    pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */
544    pdsch->rnti = 0xFFFF; /* SI-RNTI */
545    pdsch->pduIndex = 0;
546    pdsch->numCodewords = 1;
547         for(cwCount = 0; cwCount < pdsch->numCodewords; cwCount++)
548         {
549       pdsch->codeword[cwCount].targetCodeRate = 308;
550       pdsch->codeword[cwCount].qamModOrder = 2;
551       pdsch->codeword[cwCount].mcsIndex = sib1SchCfg->sib1Mcs;
552       pdsch->codeword[cwCount].mcsTable = 0; /* notqam256 */
553       pdsch->codeword[cwCount].rvIndex = 0;
554       tbSize = schCalcTbSize(sib1SchCfg->sib1PduLen);
555       pdsch->codeword[cwCount].tbSize = tbSize;
556    }
557    pdsch->dataScramblingId                   = pci;
558    pdsch->numLayers                          = 1;
559    pdsch->transmissionScheme                 = 0;
560    pdsch->refPoint                           = 0;
561    pdsch->dmrs.dlDmrsSymbPos                 = 2;
562    pdsch->dmrs.dmrsConfigType                = 0; /* type-1 */
563    pdsch->dmrs.dlDmrsScramblingId            = pci;
564    pdsch->dmrs.scid                          = 0;
565    pdsch->dmrs.numDmrsCdmGrpsNoData          = 1;
566    pdsch->dmrs.dmrsPorts                     = 0;
567    pdsch->pdschFreqAlloc.resourceAllocType   = 1; /* RAT type-1 RIV format */
568         pdsch->pdschFreqAlloc.freqAlloc.startPrb  = offset + SCH_SSB_NUM_PRB; /* the RB numbering starts from coreset0,
569         and PDSCH is always above SSB */
570    pdsch->pdschFreqAlloc.freqAlloc.numPrb    = schCalcNumPrb(tbSize,sib1SchCfg->sib1Mcs,numPdschSymbols);
571    pdsch->pdschFreqAlloc.vrbPrbMapping       = 0; /* non-interleaved */
572    pdsch->pdschTimeAlloc.rowIndex            = 1;
573    pdsch->pdschTimeAlloc.timeAlloc.startSymb = 2; /* spec-38.214, Table 5.1.2.1-1 */
574    pdsch->pdschTimeAlloc.timeAlloc.numSymb   = numPdschSymbols;
575    pdsch->beamPdschInfo.numPrgs              = 1;
576    pdsch->beamPdschInfo.prgSize              = 1;
577    pdsch->beamPdschInfo.digBfInterfaces      = 0;
578    pdsch->beamPdschInfo.prg[0].pmIdx         = 0;
579    pdsch->beamPdschInfo.prg[0].beamIdx[0]    = 0;
580    pdsch->txPdschPower.powerControlOffset    = 0;
581    pdsch->txPdschPower.powerControlOffsetSS  = 0;
582
583 }
584
585 /**
586  * @brief Fill SSB start symbol
587  *
588  * @details
589  *
590  *     Function : fillSsbStartSymb 
591  *      
592  *      This API stores SSB start index per beam
593  *           
594  *  @param[in]  SchCellCb     *cellCb
595  *  @return  int
596  *      -# ROK 
597  *      -# RFAILED 
598  **/
599 void fillSsbStartSymb(SchCellCb *cellCb)
600 {
601         uint8_t cnt, scs;
602
603         scs = cellCb->cellCfg.ssbSchCfg.scsCommon;
604         uint8_t ssbStartSymbArr[SCH_MAX_SSB_BEAM];
605
606    memset(ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
607         /* Determine value of "n" based on Section 4.1 of 3GPP TS 38.213 */
608         switch(scs)
609         {
610                 case SCH_SCS_15KHZ:
611                         {
612                                 uint8_t symbIdx=0;
613                                 cnt = 2;/* n = 0, 1 for SCS = 15KHz */
614                                 for(uint8_t idx=0; idx<cnt; idx++)
615                                 {
616                                         /* start symbol determined using {2, 8} + 14n */
617                                         ssbStartSymbArr[symbIdx++] = 2 +        SCH_SYMBOL_PER_SLOT*idx;
618                                         ssbStartSymbArr[symbIdx++]      = 8 +   SCH_SYMBOL_PER_SLOT*idx;
619                                 }
620                         }
621                         break;
622                 default:
623                         DU_LOG("\nSCS %d is currently not supported", scs);
624         }
625    memset(cellCb->ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
626    memcpy(cellCb->ssbStartSymbArr, ssbStartSymbArr, SCH_MAX_SSB_BEAM);
627
628 }
629
630 /**
631  * @brief cell config from MAC to SCH.
632  *
633  * @details
634  *
635  *     Function : macSchCellCfgReq
636  *      
637  *      This API is invoked by MAC to send cell config to SCH
638  *           
639  *  @param[in]  Pst            *pst
640  *  @param[in]  SchCellCfg     *schCellCfg
641  *  @return  int
642  *      -# ROK 
643  *      -# RFAILED 
644  **/
645 int SchHdlCellCfgReq
646 (
647 Pst                 *pst, 
648 SchCellCfg          *schCellCfg
649 )
650 {
651    int ret = ROK;
652    SchCellCb *cellCb;
653         SchCellCfgCfm schCellCfgCfm;
654         Pst rspPst;
655         Inst inst = pst->dstInst-1; 
656
657         InitSchCellCb(inst, schCellCfg);
658         cellCb = schCb[inst].cells[inst]; //cells is of MAX_CELLS, why inst
659    cellCb->macInst = pst->srcInst;
660
661    /* derive the SIB1 config parameters */
662         fillSchSib1Cfg(
663            inst,
664            &(schCellCfg->sib1SchCfg),
665                 schCellCfg->phyCellId,
666                 schCellCfg->ssbSchCfg.ssbOffsetPointA);
667    memcpy(&cellCb->cellCfg, schCellCfg, sizeof(SchCellCfg));
668
669    memset(&rspPst, 0, sizeof(Pst));
670    SCH_FILL_RSP_PST(rspPst, inst);
671         rspPst.event = EVENT_SCH_CELL_CFG_CFM;
672         schCellCfgCfm.rsp = RSP_OK;
673   
674    ret = (*SchCellCfgCfmOpts[rspPst.selector])(&rspPst, &schCellCfgCfm);
675
676    return ret;
677
678 }
679
680 /*******************************************************************
681  *
682  * @brief Processes DL RLC BO info from MAC
683  *
684  * @details
685  *
686  *    Function : macSchDlRlcBoInfo
687  *
688  *    Functionality:
689  *       Processes DL RLC BO info from MAC
690  *
691  * @params[in] 
692  * @return ROK     - success
693  *         RFAILED - failure
694  *
695  * ****************************************************************/
696 uint8_t macSchDlRlcBoInfo(Pst *pst, DlRlcBOInfo *dlBoInfo)
697 {
698    uint16_t  lcIdx;
699    Inst  inst = pst->dstInst-SCH_INST_START;
700    DU_LOG("\nSCH : Received RLC BO Status indication");
701
702    SchCellCb *cell = schCb[inst].cells[inst];
703    SchDlSlotInfo *schDlSlotInfo = \
704       cell->schDlSlotInfo[(cell->slotInfo.slot + SCHED_DELTA + PHY_DELTA + MSG4_DELAY) % SCH_NUM_SLOTS];
705   
706    for(lcIdx = 0; lcIdx < dlBoInfo->numLc; lcIdx++)
707         {
708            if(dlBoInfo->boInfo[lcIdx].lcId == CCCH_LCID)
709                 {
710               SCH_ALLOC(schDlSlotInfo->msg4Info, sizeof(Msg4Info));
711               if(!schDlSlotInfo->msg4Info)
712               {
713                  DU_LOG("\nSCH : Memory allocation failed for msg4Info");
714                       schDlSlotInfo = NULL;
715                       return RFAILED;
716               }
717          schDlSlotInfo->msg4Info->crnti = dlBoInfo->crnti;
718                         schDlSlotInfo->msg4Info->ndi = 1;
719                         schDlSlotInfo->msg4Info->harqProcNum = 0;
720                         schDlSlotInfo->msg4Info->dlAssignIdx = 0;
721                         schDlSlotInfo->msg4Info->pucchTpc = 0;
722                         schDlSlotInfo->msg4Info->pucchResInd = 0;
723                         schDlSlotInfo->msg4Info->harqFeedbackInd = 0;
724                         schDlSlotInfo->msg4Info->dciFormatId = 1;
725            }
726         }
727
728    return ROK;
729 }
730
731 /**********************************************************************
732          End of file
733 **********************************************************************/