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