5dee41a766762366c93082bba47516b426a03858
[o-du/l2.git] / src / 5gnrsch / rg_sch_gom.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:     LTE-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for Entry point fucntions
26   
27      File:     rg_sch_gom.c 
28   
29 **********************************************************************/
30
31 /** @file rg_sch_gom.c 
32 @brief This module does processing related to handling of upper interface APIs 
33 invoked by RRM towards MAC.
34 */
35
36
37 /* header include files -- defines (.h) */
38 #include "common_def.h"
39 #include "lrg.h"
40 #include "rgr.h"
41 #include "tfu.h"
42 #include "rg_env.h"
43 #include "rg_sch_inf.h"
44 #include "rg_sch.h"
45 #include "rg_sch_err.h"
46
47 /* header/extern include files (.x) */
48 #include "lrg.x"
49 #include "rgr.x"
50 #include "tfu.x"
51 #include "rg_sch_inf.x"
52 #include "rg_sch.x"
53
54 /* local defines */
55 static S16 rgSCHGomHndlCfgReq ARGS((RgSchCb *instCb, SpId spId,
56          RgrCfg  *cfg, RgSchErrInfo *errInfo));
57 static S16 rgSCHGomHndlRecfgReq ARGS((RgSchCb *instCb, SpId spId,
58          RgrRecfg  *recfg, RgSchErrInfo *errInfo));
59 static S16 rgSCHGomHndlResetReq ARGS((RgSchCb *instCb,SpId spId,RgrRst *reset,
60          RgSchErrInfo  *errInfo));
61 static S16 rgSCHGomGetCellIdFrmCfgReq ARGS((RgrCfgReqInfo *rgrCfgReq,
62          CmLteCellId *cellId));
63 static S16 rgSCHGomCfgReq ARGS((Region reg, Pool pool, RgSchCb *instCb,
64          RgrCfgTransId transId, RgrCfgReqInfo *cfgReqInfo));
65 static S16 rgSCHGomEnqCfgReq ARGS((Region reg, Pool pool, RgSchCellCb *cell,
66          RgrCfgTransId transId, RgrCfgReqInfo *rgrCfgReq));
67 static S16 rgSCHGomHndlDelReq ARGS((RgSchCb  *instCb,SpId spId, 
68          RgrDel  *del,RgSchErrInfo  *errInfo));
69 #ifdef LTE_ADV
70 static S16 rgSCHGomHndlSCellActDeactReq ARGS((RgSchCb *instCb, SpId spId,
71          RgrSCellActDeactEvnt  *sCellActDeactEvnt, RgSchErrInfo *errInfo, uint8_t action));
72 #endif /* LTE_ADV */
73 #ifdef EMTC_ENABLE
74 S16 rgSchEmtcGetSiWinPerd ARGS((
75 RgSchCellCb   *cell,
76 uint16_t  *siWinSize,
77 uint16_t  *minPeriod 
78 ));
79 extern S16 rgSCHEmtcUtlCalMcsAndNPrb
80 (
81  RgSchCellCb         *cell,
82  uint8_t                  cfgType,
83  MsgLen              msgLen,
84  uint8_t                  siId
85  );
86
87 S32 rgSCHEmtcUtlGetAllwdCchTbSzForSI ARGS(
88 (
89 uint32_t bo
90 ));
91
92 Void rgSCHEmtcWarningSiCfg ARGS(
93 (
94 RgSchCellCb             *cell,
95 RgrWarningSiCfgReqInfo  *warningSiCfgReqInfo,
96 uint16_t                     idx
97 ));
98 #endif
99
100
101 /* local typedefs */
102  
103 /* local externs */
104  
105 /* forward references */
106
107 \f
108
109 /**
110  * @brief Handler for config request from RRM to Schedular.
111  *
112  * @details
113  *
114  *     Function: rgSCHGomHndlCfg
115  *     
116  *     This API is called from schedulers UIM and it handles config request
117  *     from RRM to Scheduler.
118  *     
119  *     Processing Steps:
120  *      - If the request is for the inactive cell, 
121  *       - Handle request.Call rgSCHGomCfgReq.
122  *      - Else,
123  *       - Enqueue the request. Call rgSCHGomEnqCfgReq.
124  *         
125  *  @param[in]  Pst           *pst
126  *  @param[in]  RgSchCb       *instCb
127  *  @param[in]  RgrCfgTransId transId
128  *  @param[in]  RgrCfgReqInfo *cfgReqInfo
129  *  @return  S16
130  *      -# ROK 
131  *      -# RFAILED 
132  **/
133 S16 rgSCHGomHndlCfg(Pst *pst,RgSchCb  *instCb,RgrCfgTransId transId,RgrCfgReqInfo *cfgReqInfo)
134 {
135    S16           ret;
136    SpId          spId = 0;
137    CmLteCellId   cellId;
138    RgSchCellCb   *cell = NULLP;    
139    uint8_t       cfmStatus = RGR_CFG_CFM_NOK;
140
141    /* Apply the configuration for Cell Configuration or Delete */
142    if (cfgReqInfo->action != RGR_RECONFIG)
143    {
144       ret = rgSCHGomCfgReq (pst->region, pst->pool, instCb, 
145             transId, cfgReqInfo);
146       return (ret);
147    }
148
149    /* Fetch the cell Id for the recieved request */
150    if((rgSCHGomGetCellIdFrmCfgReq(cfgReqInfo, &cellId)) != ROK)
151    {
152       DU_LOG("\nERROR  -->  SCH : Action.Config Type Error");
153
154       SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, 
155             (Size)sizeof(*cfgReqInfo));
156       cfgReqInfo = NULLP;
157       schSendCfgCfm(pst->region, pst->pool, transId, cfmStatus); 
158       return RFAILED;
159    }
160    /* Extract the cell and Enquee Config Request */
161    if(NULLP != instCb->rgrSap[spId].cell)
162    {
163       if(cellId != instCb->rgrSap[spId].cell->cellId) 
164       {
165          DU_LOG("\nERROR  -->  SCH : Cell with Id %d already exists "
166            "on sap %d", instCb->rgrSap[spId].cell->cellId, spId);  
167
168          SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, 
169                (Size)sizeof(*cfgReqInfo));
170          cfgReqInfo = NULLP;
171          schSendCfgCfm(pst->region, pst->pool, transId, cfmStatus); 
172          return RFAILED;
173       }
174       cell = instCb->rgrSap[spId].cell;
175
176       /* Enqueue the configuration */
177       ret = rgSCHGomEnqCfgReq(pst->region, pst->pool, cell, transId, cfgReqInfo);
178       if (ret != ROK)
179       {
180          DU_LOG("\nERROR  -->  SCH : rgSCHGomHndlCfg: Enqueuing CfgReq "
181               "Failed ");
182
183          SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, 
184                (Size)sizeof(*cfgReqInfo));
185          cfgReqInfo = NULLP;
186          schSendCfgCfm(pst->region, pst->pool, transId, cfmStatus); 
187          return RFAILED;
188       }
189
190       return ROK;
191    }
192    SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, 
193          (Size)sizeof(*cfgReqInfo));
194    cfgReqInfo = NULLP;
195    schSendCfgCfm(pst->region, pst->pool, transId, cfmStatus); 
196    return RFAILED;
197
198 }/* rgSCHGomHndlCfg */
199
200
201 /**
202  * @brief Handler to handle config request from RRM to Scheduler.
203  *
204  * @details
205  *
206  *     Function: rgSCHGomCfgReq
207  *     
208  *     This API handles processing for config request from RRM to Scheduler.
209  *     
210  *     Processing Steps: 
211  *      - If Configuration request, call rgSCHGomHndlCfgReq.
212  *      - Else if Reconfiguration request, call rgSCHGomHndlRecfgReq.
213  *      - If successful, send configuration confirm to RRM.
214  *        Call schSendCfgCfm else FAIL.
215  *
216  *  @param[in]  Region        reg
217  *  @param[in]  Pool          pool
218  *  @param[in]  RgSchCb       *instCb
219  *  @param[in]  RgrCfgTransId transId
220  *  @param[in]  RgrCfgReqInfo *cfgReqInfo
221  *  @return  S16
222  *      -# ROK 
223  *      -# RFAILED 
224  **/
225 static S16 rgSCHGomCfgReq(Region  reg,Pool  pool,RgSchCb *instCb,RgrCfgTransId transId,RgrCfgReqInfo *cfgReqInfo)
226 {
227    SpId            spId = 0;
228    uint8_t         cfmStatus = RGR_CFG_CFM_OK;
229    S16             ret;
230    RgSchErrInfo    errInfo;
231 #ifdef EMTC_ENABLE
232 printf("\nDEBUG  -->  SCH: AT MAC rgSCHGomCfgReq \n");
233 #endif
234
235    /* Process Config/Reconfig/Delete request from RRM */
236    switch (cfgReqInfo->action)
237    {
238       case SCH_CONFIG:
239          {
240             ret = rgSCHGomHndlCfgReq(instCb, spId, 
241                              &cfgReqInfo->u.cfgInfo, &errInfo);
242             break;
243          }
244       case RGR_RECONFIG:
245          {
246             ret = rgSCHGomHndlRecfgReq(instCb, spId, 
247                              &cfgReqInfo->u.recfgInfo, &errInfo);
248             break;
249          }
250       case RGR_RESET:
251          {
252             ret = rgSCHGomHndlResetReq(instCb, spId, 
253                              &cfgReqInfo->u.rstInfo, &errInfo);
254             break;
255          }
256       case RGR_DELETE:
257          {
258             ret = rgSCHGomHndlDelReq(instCb, spId,
259                              &cfgReqInfo->u.delInfo, &errInfo);
260             break;
261          } 
262 #ifdef LTE_ADV
263       case RGR_SCELL_ACT:
264       case RGR_SCELL_DEACT: 
265       case RGR_SCELL_READY: 
266          {
267             ret = rgSCHGomHndlSCellActDeactReq(instCb, spId,
268                              &cfgReqInfo->u.sCellActDeactEvnt, &errInfo, cfgReqInfo->action);
269             break;
270          }
271 #endif /* LTE_ADV */
272       default:
273          {
274             DU_LOG("\nERROR  -->  SCH : Invalid configuration "
275                "action %d", cfgReqInfo->action);
276             ret = RFAILED;
277          }
278    } /* End of switch */
279
280    if (ret != ROK)
281    {
282       cfmStatus = RGR_CFG_CFM_NOK;
283    }
284
285    SPutSBuf(reg, pool, (Data *)cfgReqInfo, 
286          (Size)sizeof(*cfgReqInfo));
287    cfgReqInfo = NULLP;
288 #ifdef EMTC_ENABLE
289 printf("\nDEBUG  -->  SCH: AT MAC sending RGR cfg cfm \n");
290 #endif
291
292    /* Send back confirmation status to RRM */   
293    schSendCfgCfm(reg, pool, transId, cfmStatus); 
294 #ifdef EMTC_ENABLE
295 printf("\nDEBUG  -->  SCH: AT MAC RGR cfg cfm sent\n");
296 #endif
297
298    return (ret);
299 }  /* rgSCHGomCfgReq */
300
301
302 /**
303  * @brief Handler to enqueuing config request from RRM to Scheduler.
304  *
305  * @details
306  *
307  *     Function: rgSCHGomEnqCfgReq
308  *     
309  *     This API enqueues config request from RRM to MAC. 
310  *     
311  *     Processing Steps:
312  *      - Allocate the configuration request element.
313  *      - Copy the contents of the recieved configuration to config request
314  *        element and free the recieved configuration pointer.
315  *      - If the configuration is without activation time,
316  *         - Enqueue the request in crntRgrCfgLst of the cell at the end of 
317  *           the list.
318  *      - Else
319  *         - Enqueue the request in pndngRgrCfgLst of the cell.
320  *         
321  *  @param[in]  Region        reg,
322  *  @param[in]  Pool          pool
323  *  @param[in]  RgSchCellCb   *cell
324  *  @param[in]  RgrCfgTransId transId
325  *  @param[in]  RgrCfgReqInfo *rgrCfgReq
326  *  @return  S16
327  *      -# ROK 
328  *      -# RFAILED 
329  **/
330 static S16 rgSCHGomEnqCfgReq(Region reg,Pool pool,RgSchCellCb *cell,RgrCfgTransId transId,RgrCfgReqInfo *rgrCfgReq)
331 {
332    S16                ret;
333    uint32_t           sfDiff;
334    RgSchCfgElem       *rgrCfgElem  = NULLP;
335    CmLteTimingInfo    actvTime; 
336    Inst               inst = cell->instIdx;
337
338    /* Allocate memory for config Element */
339    ret = rgSCHUtlAllocSBuf(inst, (Data **)&rgrCfgElem, sizeof(RgSchCfgElem));
340    if ((ret != ROK) || ((uint8_t *)rgrCfgElem == NULLP))
341    {
342       return RFAILED;
343    }
344
345    /* Initialize the configuration element */
346    memcpy(rgrCfgElem->rgrCfg.transId.trans,transId.trans,
347          sizeof(transId.trans));
348    rgrCfgElem->rgrCfg.reg = reg;
349    rgrCfgElem->rgrCfg.pool = pool;
350    rgrCfgElem->rgrCfg.rgrCfgReq = rgrCfgReq;
351    rgrCfgElem->cfgReqLstEnt.prev = NULLP;
352    rgrCfgElem->cfgReqLstEnt.next = NULLP;
353    rgrCfgElem->cfgReqLstEnt.node = (PTR )rgrCfgElem;
354
355    /* Add configuration element to current/pending cfgLst */
356    if (((rgrCfgReq->action == RGR_RECONFIG) &&
357             (rgrCfgReq->u.recfgInfo.recfgType == RGR_CELL_CFG) &&
358             (rgrCfgReq->u.recfgInfo.u.cellRecfg.recfgActvTime.pres == TRUE)))
359
360    {
361       actvTime = 
362          rgrCfgReq->u.recfgInfo.u.cellRecfg.recfgActvTime.actvTime;
363
364       /* Check if the activation time is valid */
365       if (actvTime.sfn >= RGSCH_MAX_SFN 
366             || actvTime.slot >= RGSCH_NUM_SUB_FRAMES_5G)
367       {
368          DU_LOG("\nERROR  -->  SCH : Invalid activation time for RGR "
369            "config request: activation sfn %d activation slot %d current "
370            "sfn %d current slot %d", actvTime.sfn, actvTime.slot, 
371            cell->crntTime.sfn, cell->crntTime.slot);
372          /* ccpu00117052 - MOD - Passing double pointer
373          for proper NULLP assignment*/
374          rgSCHUtlFreeSBuf(inst, (Data **)&rgrCfgElem, sizeof(*rgrCfgElem));
375          return RFAILED;
376       }
377
378       sfDiff = RGSCH_CALC_SF_DIFF(actvTime, cell->crntTime);
379
380       if (sfDiff > (RGR_ACTV_WIN_SIZE * RGSCH_NUM_SUB_FRAMES_5G))
381       {
382          DU_LOG("\nERROR  -->  SCH : Invalid activation time for RGR"
383               " config request: activation sfn %d activation slot %d "
384               "current sfn %d current slot %d", actvTime.sfn,
385               actvTime.slot, cell->crntTime.sfn, cell->crntTime.slot);
386          /* ccpu00117052 - MOD - Passing double pointer
387          for proper NULLP assignment*/
388          rgSCHUtlFreeSBuf(inst, (Data **)&rgrCfgElem, sizeof(*rgrCfgElem));
389          return RFAILED;
390       }
391
392       if (sfDiff)
393       {
394          /* Add to pending cfgReqLst */
395          rgrCfgElem->actvTime = actvTime; 
396          rgSCHDbmInsPndngRgrCfgElem(cell, rgrCfgElem);
397          /* Cfm to be sent only after applying request */
398          return ROK;
399       }
400    }
401
402    /* Add to current cfgReq list */
403    rgSCHDbmInsCrntRgrCfgElem(cell, rgrCfgElem);
404    /* Cfm to be sent only after applying request */
405    return ROK;
406 }  /* rgSCHGomEnqCfgReq */
407
408
409 /**
410  * @brief Handler for TTI processing for configurations recieved from RRM.
411  *
412  * @details
413  *
414  *     Function: rgSCHGomTtiHndlr
415  *     
416  *     This API does TTI processing for configurations recieved from RRM.
417  *     
418  *     Processing Steps:
419  *      - It dequeues config request from the current configuration list.
420  *        For each config request in the list: 
421  *        - Processes the request. Call rgSCHGomCfgReq.
422  *      - It dequeues config request for the current tti from the pending 
423  *        configuration list. For each config request in the list:
424  *        - Processes the request. Call rgSCHGomCfgReq.
425  *
426  *  @param[in]  RgSchCellCb *cell
427  *  @return  S16
428  *      -# ROK 
429  *      -# RFAILED 
430  **/
431 S16 rgSCHGomTtiHndlr(RgSchCellCb *cell,SpId  spId)
432 {
433    RgSchCfgElem       *cfgElem;
434    Inst               inst= cell->instIdx;
435
436    /* Dequeue from current config list */
437    while ((cfgElem = rgSCHDbmGetNextCrntRgrCfgElem(cell, NULLP)) != NULLP)
438    {
439       rgSCHDbmDelCrntRgrCfgElem(cell, cfgElem);
440       rgSCHGomCfgReq(cfgElem->rgrCfg.reg,cfgElem->rgrCfg.pool,
441             &rgSchCb[inst], cfgElem->rgrCfg.transId, 
442             cfgElem->rgrCfg.rgrCfgReq);
443       /* ccpu00117052 - MOD - Passing double pointer
444       for proper NULLP assignment*/
445       rgSCHUtlFreeSBuf(inst, (Data **)&cfgElem, sizeof(*cfgElem));
446    }
447
448    /* Handle config requests from pending config list */
449    while((cfgElem = rgSCHDbmGetPndngRgrCfgElemByKey(cell, cell->crntTime)) != NULLP)
450    {
451       rgSCHDbmDelPndngRgrCfgElem(cell, cfgElem);
452       rgSCHGomCfgReq(cfgElem->rgrCfg.reg, cfgElem->rgrCfg.pool, 
453             &rgSchCb[inst], cfgElem->rgrCfg.transId, 
454             cfgElem->rgrCfg.rgrCfgReq);
455       /* ccpu00117052 - MOD - Passing double pointer
456       for proper NULLP assignment*/
457       rgSCHUtlFreeSBuf(inst, (Data **)&cfgElem, sizeof(*cfgElem));
458    } 
459
460    return ROK;
461 }
462
463
464 /**
465  * @brief Handler to handle configuration request from RRM to MAC.
466  *
467  * @details
468  *
469  *     Function: rgSCHGomHndlCfgReq
470  *     
471  *     This API handles processing for configuration request from RRM to MAC.
472  *     
473  *     - Processing Steps: 
474  *        - Validate configuration request parameters at CFG module. 
475  *          Call rgSCHCfgVldtRgrCellCfg for cell configuration.
476  *        - If validated successfully, send configuration request to CFG.
477  *          Call rgSCHCfgRgrCellCfg else FAIL.
478  *          
479  *  @param[in]  RgSchCb      *instCb
480  *  @param[in]  SpId         spId
481  *  @param[in]  RgrCfg       *cfg
482  *  @param[out] RgSchErrInfo *errInfo
483  *  @return  S16
484  *      -# ROK 
485  *      -# RFAILED 
486  **/
487 static S16 rgSCHGomHndlCfgReq(RgSchCb *instCb,SpId spId,RgrCfg *cfg,RgSchErrInfo *errInfo)
488 {
489    S16          ret;
490    RgSchCellCb  *cell = instCb->rgrSap[spId].cell;
491    Inst         inst = (instCb->rgSchInit.inst );
492    RgSchUeCb    *ue;
493
494    errInfo->errType = RGSCHERR_GOM_CFG_REQ;
495    
496    /* Validate and process the configuration request */ 
497    switch (cfg->cfgType)
498    {
499       case RGR_CELL_CFG:
500       {
501          ret = rgSCHCfgVldtRgrCellCfg(inst, &cfg->u.cellCfg, cell, errInfo);
502             if (ret != ROK)
503             {
504                DU_LOG("\nERROR  -->  SCH : Rgr Cell configuration "
505                   "validation FAILED: Cell %d", cfg->u.cellCfg.cellId);
506                return RFAILED;
507             }
508          ret = rgSCHCfgRgrCellCfg(instCb, spId, &cfg->u.cellCfg, errInfo);
509          break;
510       }
511       case RGR_UE_CFG:
512       case RGR_SCELL_UE_CFG:
513       {
514          ret = rgSCHCfgVldtRgrUeCfg(inst, &cfg->u.ueCfg, &cell, errInfo);
515          if (ret != ROK)
516          {
517             DU_LOG("\nERROR  -->  SCH : Ue configuration validation"
518                " FAILED: CRNTI:%d", cfg->u.ueCfg.crnti);
519             return RFAILED;
520          }
521          ret = rgSCHCfgRgrUeCfg(cell, &cfg->u.ueCfg, errInfo);
522          break;
523       }
524       case RGR_LCH_CFG:
525       {
526          ret = rgSCHCfgVldtRgrLcCfg(inst, &cfg->u.lchCfg, &cell, &ue, errInfo);
527          if (ret != ROK)
528          {
529             DU_LOG("\nERROR  -->  SCH : LC configuration validation "
530               "FAILED: LCID:%d", cfg->u.lchCfg.lcId);
531             return RFAILED;
532          }
533          ret = rgSCHCfgRgrLchCfg(cell, ue, &cfg->u.lchCfg, errInfo); 
534          break;
535       }
536       case RGR_LCG_CFG:
537       {
538          ret = rgSCHCfgVldtRgrLcgCfg(inst, &cfg->u.lcgCfg, &cell, &ue, errInfo);
539          if (ret != ROK)
540          {
541             DU_LOG("\nERROR  -->  SCH : LCG configuration validation "
542               "FAILED: LCGID:%d", cfg->u.lcgCfg.ulInfo.lcgId);
543             return RFAILED;
544          }
545          ret = rgSCHCfgRgrLcgCfg(cell, ue, &cfg->u.lcgCfg, errInfo); 
546          break;
547       }
548       case MAC_GNB_CFG:
549       {
550          ret = rgSCHCfgVldtRgrSchedEnbCfg(inst, &cfg->u.schedEnbCfg, errInfo);
551          if (ret != ROK)
552          {
553             DU_LOG("\nERROR  -->  SCH : SCH ENB configuration validation FAILED: \n");
554             return RFAILED;
555          }
556          ret = rgSCHCfgRgrSchedEnbCfg(inst, spId, &cfg->u.schedEnbCfg, errInfo); 
557          break;
558       }
559       default:
560       {
561 #if(ERRCLASS & ERRCLS_INT_PAR)
562             DU_LOG("\nERROR  -->  SCH : Should never come here: "
563                 "cfgType %d", cfg->cfgType);
564 #endif
565             return RFAILED;
566       }
567    }
568    
569    return (ret);
570 }  /* rgSCHGomHndlCfgReq */
571
572 #ifdef LTE_ADV
573 /**
574  * @brief Handler to handle re-configuration request from RRM to MAC.
575  *
576  * @details
577  *
578  *     Function: rgSCHGomHndlSCellActDeactReq
579  *     
580  *     This API handles processing for SCell Activation Request from RRM to SCH.
581  *     
582  *     - Processing Steps: 
583  *        - Validate sCell Actication request parameters at CFG module. 
584  *        - If validated successfully, send configuration request to CFG.
585  *        - call activation function for each SCells configured
586  *
587  *  @param[in]  RgSchCb      *instCb
588  *  @param[in]  SpId         spId
589  *  @param[in]  RgrSCellActDeactEvnt  *sCellActDeactEvnt
590  *  @param[in]  uint8_t action
591  *  @param[out] RgSchErrInfo *errInfo
592  *  @return  S16
593  *      -# ROK 
594  *      -# RFAILED 
595  **/
596 static S16 rgSCHGomHndlSCellActDeactReq(RgSchCb  *instCb,SpId  spId,RgrSCellActDeactEvnt  *sCellActDeactEvnt,RgSchErrInf *errInfo,uint8_t action)
597 {
598    RgSchUeCb    *ue = NULLP;
599    uint16_t     idx = 0;
600    uint16_t     sCellIdx = 0;
601    RgSchCellCb  *cell = instCb->rgrSap[spId].cell;
602    Inst         inst = (instCb->rgSchInit.inst);
603
604    DU_LOG(("\nDEBUG  -->  SCH : Processing RGR SCell Actication request:"
605                   "%d\n", sCellActDeactEvnt->crnti));
606
607    errInfo->errType = RGSCHERR_GOM_SCELL_REQ;
608
609    /* Fetch the Ue */
610    if ((ue = rgSCHDbmGetUeCb(cell, sCellActDeactEvnt->crnti)) == NULLP)
611    {
612       DU_LOG(("\nERROR  -->  SCH : [%d]UE: does not exist\n", 
613             sCellActDeactEvnt->crnti));
614       return RFAILED;
615    }
616    
617    for(idx = 0; idx < sCellActDeactEvnt->numOfSCells; idx++)
618    {
619       sCellIdx = sCellActDeactEvnt->sCellActDeactInfo[idx].sCellIdx;
620
621       if (ROK != (rgSCHSCellTrigActDeact(cell, ue, sCellIdx, action)))
622       {
623             DU_LOG("\nERROR  -->  SCH : SCell Actication failed"
624                      "for UE [%d] with SCellIdx [%d]\n", 
625                      sCellActDeactEvnt->crnti, idx);
626             return RFAILED;
627
628       }
629
630    DU_LOG("\nINFO  -->  SCH : RGR Reconfiguration processed\n");
631    return ROK;
632 }  /* rgSCHGomHndlSCellActDeactReq */
633
634 #endif /* LTE_ADV */
635 /**
636  * @brief Handler to handle re-configuration request from RRM to MAC.
637  *
638  * @details
639  *
640  *     Function: rgSCHGomHndlRecfgReq
641  *     
642  *     This API handles processing for re-configuration request from RRM to MAC.
643  *     
644  *     - Processing Steps: 
645  *        - Validate re-configuration request parameters at CFG module. 
646  *          Call rgSCHCfgVldtRgrCellRecfg for cell re-configuration.
647  *        - If validated successfully, send configuration request to CFG.
648  *          Call rgSCHCfgRgrCellRecfg else FAIL.
649  *
650  *  @param[in]  RgSchCb      *instCb
651  *  @param[in]  SpId         spId
652  *  @param[in]  RgrRecfg     *recfg
653  *  @param[out] RgSchErrInfo *errInfo
654  *  @return  S16
655  *      -# ROK 
656  *      -# RFAILED 
657  **/
658 static S16 rgSCHGomHndlRecfgReq(RgSchCb  *instCb,SpId  spId,RgrRecfg *recfg,RgSchErrInfo  *errInfo)
659 {
660    RgSchUeCb    *ue = NULLP;
661    RgSchDlLcCb  *dlLc = NULLP; /* PURIFY_FIX:UMR */
662    S16          ret; 
663    RgSchCellCb  *cell = instCb->rgrSap[spId].cell;
664    Inst         inst = (instCb->rgSchInit.inst );
665
666    errInfo->errType = RGSCHERR_GOM_RECFG_REQ;
667    
668    /* Validate and process the re-configuration request */
669    switch (recfg->recfgType)
670    {
671       case RGR_CELL_CFG:
672       {
673          ret = rgSCHCfgVldtRgrCellRecfg(inst, &recfg->u.cellRecfg, &cell,
674                errInfo);
675          if (ret != ROK) 
676          {
677             DU_LOG("\nERROR  -->  SCH : Rgr Cell Recfg Validation "
678                      "FAILED");
679             return RFAILED;
680          }
681          ret = rgSCHCfgRgrCellRecfg(cell, &recfg->u.cellRecfg, errInfo);
682          break;
683       }
684       case RGR_UE_CFG:
685       case RGR_SCELL_UE_CFG:
686       {
687          ret = rgSCHCfgVldtRgrUeRecfg(inst, &recfg->u.ueRecfg, &cell, &ue, errInfo);
688          if ( ret != ROK)
689          {
690             DU_LOG("\nERROR  -->  SCH : Ue Recfg Validation FAILED"
691                       "OLD CRNTI:%d",recfg->u.ueRecfg.oldCrnti);
692             return RFAILED;
693          }
694          ret = rgSCHCfgRgrUeRecfg(cell, ue, &recfg->u.ueRecfg, errInfo);
695          break;
696       }
697       case RGR_LCH_CFG:
698       {
699          ret = rgSCHCfgVldtRgrLchRecfg(inst, &recfg->u.lchRecfg, &cell, &ue, 
700                &dlLc, errInfo);
701          if (ret != ROK)
702          {
703             DU_LOG("\nERROR  -->  SCH : Lc Recfg Validation FAILED"
704                       "LCID:%d",recfg->u.lchRecfg.lcId);
705             return RFAILED;
706          }
707          ret = rgSCHCfgRgrLchRecfg(cell, ue, dlLc, &recfg->u.lchRecfg, errInfo);
708          break;
709       }
710       case RGR_LCG_CFG:
711       {
712          ret = rgSCHCfgVldtRgrLcgRecfg(inst, &recfg->u.lcgRecfg, cell, &ue,
713                errInfo);
714          if (ret != ROK)
715          {
716             DU_LOG("\nERROR  -->  SCH : Lcg Recfg Validation FAILED"
717                       "LCGID:%d",recfg->u.lcgRecfg.ulRecfg.lcgId);
718             return RFAILED;
719          }
720          ret = rgSCHCfgRgrLcgRecfg(cell, ue, &recfg->u.lcgRecfg, errInfo);
721          break;
722       }
723       default:
724       {
725 #if(ERRCLASS & ERRCLS_INT_PAR)
726          DU_LOG("\nERROR  -->  SCH : Should never come here: recfgType %d", recfg->recfgType);
727 #endif
728          return RFAILED;
729       }
730    }
731
732    return (ret);
733 }  /* rgSCHGomHndlRecfgReq */
734
735 /**
736  * @brief Handler to handle UE reset request from RRM to Scheduler.
737  *
738  * @details
739  *
740  *     Function: rgSCHGomHndlResetReq
741  *     
742  *     This API handles processing for UE reset request from RRM to Scheduler.
743  *     
744  *     - Processing Steps: 
745  *        - Validate UE reset request parameters at CFG module. 
746  *          Call rgSCHCfgVldtRgrUeReset for UE reset.
747  *        - If validated successfully, send UE reset request to CFG.
748  *          Call rgSCHCfgRgrUeReset else FAIL.
749  *
750  *  @param[in]  RgrRst   *rstInfo
751  *  @param[out] RgSchErrInfo *errInfo
752  *  @return  S16
753  *      -# ROK 
754  *      -# RFAILED 
755  **/
756 static S16 rgSCHGomHndlResetReq(RgSchCb  *instCb,SpId spId,RgrRst *reset,RgSchErrInfo  *errInfo)
757 {
758    S16          ret; 
759    RgSchCellCb  *cell= instCb->rgrSap[spId].cell;
760    Inst         inst = (instCb->rgSchInit.inst );
761    RgSchUeCb    *ue = NULLP;
762
763    errInfo->errType = RGSCHERR_GOM_RESET_REQ;
764    
765    /* Validate and process the UE reset request */
766    ret = rgSCHCfgVldtRgrUeReset(inst, reset, cell, &ue, errInfo);
767    if (ret != ROK) 
768    {
769       DU_LOG("\nERROR  -->  SCH : Rgr UE Reset Validation FAILED"
770                "CRNTI:%d",reset->crnti);
771       return RFAILED;
772    }
773    
774    ret = rgSCHCfgRgrUeReset(cell, ue, reset, errInfo);
775    if (ret != ROK) 
776    {
777       DU_LOG("\nERROR  -->  SCH : Rgr UE Reset FAILED"
778                "CRNTI:%d",reset->crnti);
779       return RFAILED;
780    }
781
782    return (ret);
783 }  /* rgSCHGomHndlResetReq */
784
785
786 /**
787  * @brief Handler for processing Cell/Ue/Logical channel delete request
788  * recieved from RRM.
789  *
790  * @details
791  *
792  *     Function: rgSCHGomHndlDelReq
793  *     
794  *     This API handles processing of delete request from RRM to MAC. 
795  *     
796  *     Processing Steps:
797  *        - Fetch corresponding control block and pass it to CFG module.
798  *        - If control block does not exist, FAIL.
799  *
800  *  @param[in]  RgSchCb      *instCb
801  *  @param[in]  SpId         spId
802  *  @param[in]  RgrDel       *del
803  *  @param[out] RgSchErrInfo *errInfo
804  *  @return  S16
805  *      -# ROK 
806  *      -# RFAILED 
807  **/
808 static S16 rgSCHGomHndlDelReq(RgSchCb *instCb,SpId spId,RgrDel *del,RgSchErrInfo  *errInfo)
809 {
810
811    S16       ret;
812    volatile uint32_t     startTime=0;
813
814    errInfo->errType = RGSCHERR_GOM_DEL_REQ;
815
816    if(instCb->rgrSap[spId].cell == NULLP)
817    {
818       DU_LOG("\nERROR  -->  SCH : Cell doesnt exist");
819       return RFAILED; 
820    }
821    
822    /* Process the delete request */ 
823    switch (del->delType)
824    {
825       case RGR_CELL_CFG:
826       {
827          ret = rgSCHCfgRgrCellDel(instCb->rgrSap[spId].cell, del, errInfo);
828          if(ret == ROK)
829          {
830             /* TODO::Needs to be revisited after tti flow CaDev Start */
831             uint8_t idx = (uint8_t)((instCb->rgrSap[spId].cell->cellId - instCb->genCfg.startCellId)&(CM_LTE_MAX_CELLS-1));
832             instCb->cells[idx] = NULLP;
833             /* CaDev End */
834             instCb->rgrSap[spId].cell = NULLP;
835             instCb->tfuSap[spId].cell = NULLP;
836          }
837          break;
838       }
839       case RGR_UE_CFG:
840       case RGR_SCELL_UE_CFG:
841       {
842
843          /*starting Task*/
844          SStartTask(&startTime, PID_SCH_UE_DEL);
845
846          ret = rgSCHCfgRgrUeDel(instCb->rgrSap[spId].cell, del, errInfo);
847
848          /*stoping Task*/
849          SStopTask(startTime, PID_SCH_UE_DEL);
850
851          break;
852       }
853       case RGR_LCH_CFG:
854       {
855          ret = rgSCHCfgRgrLcDel(instCb->rgrSap[spId].cell, del, errInfo);
856          break;
857       }
858       case RGR_LCG_CFG:
859       {
860          ret = rgSCHCfgRgrLcgDel(instCb->rgrSap[spId].cell, del, errInfo);
861          break;
862       }
863       default:
864       {
865 #if(ERRCLASS & ERRCLS_INT_PAR)
866          DU_LOG("\nERROR  -->  SCH : Should never come here: delType %d", del->delType);
867 #endif
868          return RFAILED;
869       }
870    }
871
872    return (ret);
873 }  /* rgSCHGomHndlDelReq */
874
875
876
877
878 /***********************************************************
879  *
880  *     Func : rgSCHGomGetCellIdFrmCfgReq
881  *        
882  *
883  *     Desc : 
884  *     - Processing Steps: 
885  *        - Retrieves the cell Id for a config request.
886  *
887  *  @param[in]  RgrCfgReqInfo *rgrCfgReq
888  *  @param[out] CmLteCellId   *cellId
889  *     Ret  : ROK on fetching cellId
890  *            RFAILED on failure
891  *
892  *     Notes: 
893  *
894  *     File : rg_sch_gom.c 
895  *
896  **********************************************************/
897 static S16 rgSCHGomGetCellIdFrmCfgReq(RgrCfgReqInfo *rgrCfgReq,CmLteCellId   *cellId)
898 {
899
900    /* Extract CellId depending on the action and Config Type in the Request 
901     * As of now this function is called for only re configuration so removed
902     * othe CASES below if needed we can add them*/
903    switch (rgrCfgReq->action)
904    {
905       case RGR_RECONFIG:
906          {
907             if (rgrCfgReq->u.recfgInfo.recfgType ==RGR_CELL_CFG)
908             {
909                *cellId = rgrCfgReq->u.recfgInfo.u.cellRecfg.cellId;
910             }
911             else if ((rgrCfgReq->u.recfgInfo.recfgType ==  RGR_SCELL_UE_CFG) || 
912                   (rgrCfgReq->u.recfgInfo.recfgType == RGR_UE_CFG))
913             {
914                *cellId = rgrCfgReq->u.recfgInfo.u.ueRecfg.cellId;
915             }
916             else if (rgrCfgReq->u.recfgInfo.recfgType == RGR_LCH_CFG)
917             {
918                *cellId = rgrCfgReq->u.recfgInfo.u.lchRecfg.cellId;
919             }
920             else if (rgrCfgReq->u.recfgInfo.recfgType == RGR_LCG_CFG) 
921             {
922                *cellId = rgrCfgReq->u.recfgInfo.u.lcgRecfg.cellId;
923             }
924             else
925             {
926                return RFAILED;
927             }
928             break;
929          }
930       default:
931       {
932          return RFAILED;
933       }
934    }  /* End of Switch */
935
936    return ROK;
937 }  /* rgSCHGomGetCellIdFrmCfgReq */
938
939 #ifdef RGR_SI_SCH
940 /**
941  * @brief Handler to handle SI configuration request from RRM to MAC.
942  *
943  * @details
944  *
945  *     Function: rgSCHGomHndlSiCfg
946  *     
947  *     This API handles processing for SI configuration request from RRM to MAC.
948  *     
949  *     - Processing Steps: 
950  *        - Validate SI configuration request parameters at CFG module. 
951  *          Call rgSCHCfgVldtSiCfg for SI configuration.
952  *        - If validated successfully, send configuration request to CFG.
953  *          Call rgSCHCfgRgrCellCfg else FAIL.
954  *          
955  *  @param[in]  Region        reg
956  *  @param[in]  Pool          pool
957  *  @param[in]  RgSchCb       *instCb
958  *  @param[in]  SpId          spId
959  *  @param[in]  RgrCfgTransId transId
960  *  @param[in]  RgrSiCfgReqInfo *cfgReqInfo
961  *  @return  S16
962  *      -# ROK 
963  *      -# RFAILED 
964  **/
965 S16 rgSCHGomHndlSiCfg(Region reg,Pool pool,RgSchCb *instCb,SpId spId,RgrCfgTransId transId,RgrSiCfgReqInfo *cfgReqInfo)
966 {
967    S16          ret;
968    RgSchCellCb  *cell = instCb->rgrSap[spId].cell;
969    Inst         inst = (instCb->rgSchInit.inst );
970    RgSchErrInfo errInfo;
971    uint8_t      cfmStatus = RGR_CFG_CFM_NOK;
972    MsgLen       msgLen = 0, pduLen;
973    S32          tbSz   = 0;
974    uint8_t      nPrb   = 0; 
975    uint8_t      mcs    = 0;
976
977
978    /* check if cell does not exists */
979    if (((uint8_t *)cell == NULLP) || (cell->cellId != cfgReqInfo->cellId))
980    {
981       DU_LOG("\nERROR  -->  SCH : Cell Control block does not exist");
982       RGSCH_FREE_MSG(cfgReqInfo->pdu);
983       SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
984       cfgReqInfo = NULLP;
985       rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); 
986       return RFAILED;
987    }
988
989    /*Validate the received SI configuration */
990    ret = rgSCHCfgVldtRgrSiCfg(inst, cfgReqInfo, cell, &errInfo);
991    if (ret != ROK)
992    {
993       DU_LOG("\nERROR  -->  SCH : Rgr SI configuration "
994                "validation FAILED");
995       RGSCH_FREE_MSG(cfgReqInfo->pdu);
996       SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
997       cfgReqInfo = NULLP;
998       rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); 
999       return RFAILED;
1000    }
1001    /*ccpu00140789: Stopping SI scheduling*/
1002    if(RGR_SI_STOP == cfgReqInfo->cfgType)
1003    {
1004       if((cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si != NULLP)&&
1005                       (cell->siCb.siArray[cfgReqInfo->siId-1].si != NULLP))
1006       {
1007          cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si = NULLP;
1008          RGSCH_FREE_MSG(cell->siCb.siArray[cfgReqInfo->siId-1].si);
1009          cell->siCb.siArray[cfgReqInfo->siId-1].si = NULLP;
1010          if(cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si != NULLP)
1011          {
1012             RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si);
1013             cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si = NULLP;
1014          }
1015          SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo));
1016          cfgReqInfo = NULLP;   
1017          cfmStatus = RGR_CFG_CFM_OK;
1018          rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus);
1019          return ROK; 
1020        }
1021        else
1022        {
1023           SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo));
1024           cfgReqInfo = NULLP;
1025           rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus);
1026           return RFAILED; 
1027        }
1028    }
1029
1030    /* Check if the pdu sent from application
1031     * matches a transport block size. if not,
1032     * add padding bytes. This is usually done
1033     * by RRC but since we are bypassing RRC,
1034     * MAC is taking over that responsibility
1035     */
1036    if ( RGR_SI_CFG_TYPE_MIB != cfgReqInfo->cfgType )
1037    {
1038       SFndLenMsg(cfgReqInfo->pdu, &msgLen);
1039
1040       /* check if the application pdu matches a tb size */
1041       tbSz = rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs);
1042
1043       if ( tbSz != (msgLen*8) )
1044       {
1045          MsgLen  nmPadBytes = 0;
1046          Data*   padding    = NULLP;
1047
1048          /* need to add padding bytes */
1049          nmPadBytes = (tbSz - (msgLen*8))/8;
1050
1051          if ( SGetSBuf(reg,pool,&padding,nmPadBytes) != ROK)
1052          {
1053             DU_LOG("\nERROR  -->  SCH : Rgr SI configuration "
1054                      "SGetSBuf failed for padding failed");
1055             SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1056             cfgReqInfo = NULLP;
1057             rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1058                                                            cfmStatus); 
1059             return RFAILED;
1060          }
1061
1062          memset(padding,0,nmPadBytes);
1063
1064 #ifdef MS_MBUF_CORRUPTION 
1065    MS_BUF_ADD_ALLOC_CALLER();
1066 #endif 
1067          if ( SAddPstMsgMult((Data*)padding,nmPadBytes,cfgReqInfo->pdu) != ROK)
1068          {
1069             DU_LOG("\nERROR  -->  SCH : Rgr SI configuration "
1070                      "Failed to add padding bytes");
1071             SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1072             cfgReqInfo = NULLP;
1073             SPutSBuf(reg, pool, (Data* )padding,(Size)nmPadBytes);
1074             padding = NULLP;
1075             rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1076                                                             cfmStatus); 
1077             return RFAILED;
1078          }
1079          SPutSBuf(reg, pool, (Data* )padding,(Size)nmPadBytes);
1080          padding = NULLP;
1081       }/* if (tbSz != ...*/
1082    }/* if (RGR_SI_CFG_TYPE_SI...*/
1083
1084    /*Set the received pdu at the appropriate place */
1085    switch(cfgReqInfo->cfgType)
1086    {
1087       case RGR_SI_CFG_TYPE_MIB:   /* SI CFG Type MIB */
1088          RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.mib, 
1089                cell->siCb.newSiInfo.mib, 
1090                cfgReqInfo->pdu, cell->siCb.siBitMask, 
1091                RGSCH_SI_MIB_UPD);
1092          break;
1093
1094       case RGR_SI_CFG_TYPE_SIB1_PWS:
1095          {
1096             SFndLenMsg(cfgReqInfo->pdu, &pduLen);
1097             ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen,0);
1098             if (ret != ROK)
1099             {
1100                DU_LOG("\nERROR  -->  SCH : Failed to get MCS and NPRB" 
1101                      "value");
1102                RGSCH_FREE_MSG(cfgReqInfo->pdu);
1103                SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1104                cfgReqInfo = NULLP;
1105                rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1106                      cfmStatus); 
1107                return RFAILED;
1108             }
1109
1110             RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.sib1Info.sib1, 
1111                   cell->siCb.newSiInfo.sib1Info.sib1, 
1112                   cfgReqInfo->pdu, cell->siCb.siBitMask, 
1113                   RGSCH_SI_SIB1_PWS_UPD);
1114          }
1115          break;
1116
1117       case RGR_SI_CFG_TYPE_SIB1:
1118          SFndLenMsg(cfgReqInfo->pdu, &pduLen);
1119          ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen,0);
1120          if (ret != ROK)
1121          {
1122             DU_LOG("\nERROR  -->  SCH : Failed to get MCS and NPRB" 
1123                      "value");
1124             RGSCH_FREE_MSG(cfgReqInfo->pdu);
1125             SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1126             cfgReqInfo = NULLP;
1127             rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1128                                                                  cfmStatus); 
1129             return RFAILED;
1130          }
1131          RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.sib1Info.sib1, 
1132                cell->siCb.newSiInfo.sib1Info.sib1, 
1133                cfgReqInfo->pdu, cell->siCb.siBitMask, 
1134                RGSCH_SI_SIB1_UPD);
1135          break;
1136
1137       case RGR_SI_CFG_TYPE_SI:    /* SI CFG TYPE SI */
1138          SFndLenMsg(cfgReqInfo->pdu, &pduLen);
1139          ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen, 
1140                                                      cfgReqInfo->siId);
1141          if (ret != ROK)
1142          {
1143             DU_LOG("\nERROR  -->  SCH : Failed to get MCS and NPRB" 
1144                      "value");
1145             RGSCH_FREE_MSG(cfgReqInfo->pdu);
1146             SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1147             cfgReqInfo = NULLP;
1148             rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1149                                                                  cfmStatus); 
1150             return RFAILED;
1151          }
1152          /* Si recfg, where numSi changes */
1153          if (cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) 
1154          {
1155             Buffer **newSiPdu = &cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si;
1156             if(*newSiPdu != NULLP)
1157             {
1158                RGSCH_FREE_MSG(*newSiPdu);
1159             }
1160             *newSiPdu = (Buffer *)cfgReqInfo->pdu;
1161             cell->siCb.siBitMask |= RGSCH_SI_SI_UPD;
1162          }
1163          else /* Initial Si cfg  or si recfg where numSi did not change */
1164          {
1165             uint8_t bitMask;
1166             /* Initial Si cfg */
1167             if (cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si == NULLP)
1168             {
1169                cell->siCb.siArray[cfgReqInfo->siId-1].si = cfgReqInfo->pdu;
1170                cell->siCb.siArray[cfgReqInfo->siId-1].isWarningSi = FALSE;
1171                bitMask = RGSCH_SI_DFLT;
1172             }
1173             else
1174             {
1175                bitMask = RGSCH_SI_SI_UPD;
1176             }
1177
1178             RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si, 
1179                 cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si, 
1180                 cfgReqInfo->pdu, 
1181                 cell->siCb.siBitMask, bitMask);
1182          }
1183          break;
1184
1185       case RGR_SI_CFG_TYPE_SIB8_CDMA:    /* SI CFG TYPE SIB 8 CDMA */
1186          SFndLenMsg(cfgReqInfo->pdu, &pduLen);
1187          ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen, 
1188                                                      cfgReqInfo->siId);
1189          if (ret != ROK)
1190          {
1191             DU_LOG("\nERROR  -->  SCH : Failed to get MCS and NPRB" 
1192                      "value");
1193             RGSCH_FREE_MSG(cfgReqInfo->pdu);
1194             SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1195             cfgReqInfo = NULLP;
1196             rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1197                                                                  cfmStatus); 
1198             return RFAILED;
1199          }
1200          /* No need to wait for Modification period boundary */
1201          cell->siCb.siArray[cfgReqInfo->siId-1].si = cfgReqInfo->pdu;
1202          RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si,
1203                cfgReqInfo->pdu);
1204          cell->siCb.siArray[cfgReqInfo->siId-1].isWarningSi = FALSE;
1205          break;
1206       default:
1207          DU_LOG("\nERROR  -->  SCH : Invalid cfgType "
1208                   "parameter value");
1209          RGSCH_FREE_MSG(cfgReqInfo->pdu);
1210          SPutSBuf(reg, pool, (Data *)cfgReqInfo, 
1211                (Size)sizeof(*cfgReqInfo)); 
1212          cfgReqInfo = NULLP;
1213          rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, 
1214                cfmStatus); 
1215          return RFAILED;
1216    }
1217
1218    SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); 
1219    cfgReqInfo = NULLP;
1220    cfmStatus = RGR_CFG_CFM_OK;
1221    rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); 
1222
1223
1224    return ROK;
1225 }  /* rgSCHGomHndlSiCfg */
1226
1227
1228 /**
1229  * @brief Handler to handle Warning SI configuration request from RRM to MAC.
1230  *
1231  * @details
1232  *
1233  *     Function: rgSCHGomHndlWarningSiCfg
1234  *     
1235  *     This API handles processing for Warning SI configuration request from 
1236  *     RRM to MAC.
1237  *     
1238  *          
1239  *  @param[in]  Region        reg
1240  *  @param[in]  Pool          pool
1241  *  @param[in]  RgSchCb       *instCb
1242  *  @param[in]  SpId          spId
1243  *  @param[in]  RgrWarningSiCfgReqInfo  *warningSiCfgReqInfo
1244  *  @return  S16
1245  *      -# ROK 
1246  *      -# RFAILED 
1247  **/
1248 S16 rgSCHGomHndlWarningSiCfg
1249 (
1250 Region        reg,
1251 Pool          pool,
1252 RgSchCb       *instCb,
1253 SpId          spId,
1254 RgrCfgTransId transId,
1255 RgrWarningSiCfgReqInfo *warningSiCfgReqInfo
1256 )
1257 {
1258    RgSchCellCb       *cell = instCb->rgrSap[spId].cell;
1259    uint8_t           cfmStatus = RGR_CFG_CFM_NOK;
1260    uint16_t          idx;
1261    uint8_t           siId = warningSiCfgReqInfo->siId; 
1262    uint8_t           j, mcs=0, nPrb=0;
1263    RgSchWarningSiSeg *warningSiMsg;
1264    RgSchWarningSiPdu *pduNode;
1265    CmLList           *node;
1266    MsgLen            msgLen = 0;
1267    Bool              freeNodeFound = FALSE;
1268    uint16_t          siWinSize = 0;
1269    uint16_t          minPeriod = 0;
1270 #ifdef EMTC_ENABLE
1271    uint8_t           isEmtc = warningSiCfgReqInfo->emtcEnable;
1272 #endif
1273
1274 #ifdef EMTC_ENABLE
1275    if(TRUE == isEmtc)
1276    {
1277       rgSchEmtcGetSiWinPerd(cell, &siWinSize, &minPeriod);
1278    }
1279    else
1280 #endif
1281    {
1282       siWinSize = cell->siCfg.siWinSize;
1283       minPeriod = cell->siCfg.minPeriodicity;
1284    }
1285    /* check if cell does not exists */
1286    if (((uint8_t *)cell == NULLP) || 
1287          (cell->cellId != warningSiCfgReqInfo->cellId) ||
1288          (warningSiCfgReqInfo->siId > 
1289           ((minPeriod * 10)/siWinSize)))
1290    {
1291       DU_LOG("\nERROR  -->  SCH : Warning SI Cfg Failed for siId = %d"
1292                 "warning cellID:%d",warningSiCfgReqInfo->siId,warningSiCfgReqInfo->cellId);
1293       rgSCHUtlFreeWarningSiSeg(reg, pool, &warningSiCfgReqInfo->siPduLst);
1294       SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, 
1295             sizeof(RgrWarningSiCfgReqInfo)); 
1296       warningSiCfgReqInfo = NULLP;
1297       rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId, siId, transId, 
1298             cfmStatus); 
1299       return RFAILED;
1300    }
1301
1302    /* Search for free index in WarningSi */
1303    for(idx = 0; idx < RGR_MAX_NUM_WARNING_SI; idx++)
1304    {
1305       if((cell->siCb.warningSi[idx].siId == 0 ||
1306                cell->siCb.warningSi[idx].siId == warningSiCfgReqInfo->siId))
1307       {
1308          warningSiMsg = (RgSchWarningSiSeg *)&cell->siCb.warningSi[idx].warningSiMsg; 
1309
1310          /* Search for free SI node */
1311          /* ccpu00136659: CMAS ETWS design changes */
1312          if (warningSiMsg->segLstCp.first == NULLP) /* Free SI Node */
1313          {
1314             warningSiMsg->transId = transId;
1315             pduNode = (RgSchWarningSiPdu *)&cell->siCb.warningSi[idx].
1316                warningSiMsg.pduNode;
1317             CM_LLIST_FIRST_NODE(&warningSiCfgReqInfo->siPduLst, node);
1318             j = 0;
1319
1320             /* Get the PDUs one by one from the received pduLst of warning 
1321              * message and calculate the MCS and nPrb of each pdu once.
1322              * Store the pdu in warningSiMsg pduLst, which will be scheduled 
1323              * later while sending warning message as part of SIB11/SIB12 
1324              */   
1325             while((node != NULLP) && (j < RGR_MAX_WARNING_SI_SEG))
1326
1327             {
1328                pduNode[j].pdu = (Buffer *)node->node;
1329                if(pduNode[j].pdu != NULLP)
1330                {
1331                   SFndLenMsg(pduNode[j].pdu, &msgLen);
1332                   /*Get the nPrb and mcs parametr values */
1333 #ifdef EMTC_ENABLE
1334                   if (rgSCHEmtcUtlGetAllwdCchTbSzForSI(msgLen*8) != (msgLen*8))
1335 #else
1336                   if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
1337 #endif
1338
1339                   {
1340                      DU_LOG("\nERROR  -->  SCH : rgSCHGomHndlWarningSiCfg():msgLen does not match\
1341                            any valid TB Size.");
1342                      DU_LOG("\nERROR  -->  SCH : Warning SI Cfg Failed" 
1343                            "for siId = %d", warningSiCfgReqInfo->siId);
1344                      rgSCHUtlFreeWarningSiSeg(reg, pool, 
1345                            &warningSiCfgReqInfo->siPduLst);
1346                      SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, 
1347                            sizeof(RgrWarningSiCfgReqInfo)); 
1348                      warningSiCfgReqInfo = NULLP;
1349                      rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId,
1350                            siId, transId,cfmStatus); 
1351                      return RFAILED;
1352
1353                   }
1354                }
1355                pduNode[j].mcs = mcs;
1356                pduNode[j].nPrb = nPrb;
1357                pduNode[j].msgLen = msgLen;
1358                /* ccpu00136659: CMAS ETWS design changes */
1359                cmLListAdd2Tail(&warningSiMsg->segLstCp, &pduNode[j].lnk);
1360                pduNode[j].lnk.node = (PTR)&pduNode[j];
1361                j++;
1362                node = node->next;
1363             }
1364
1365             /* ccpu00132385-  nodes in received SI config linked list should 
1366              * be freed after processing the config.*/
1367             while(warningSiCfgReqInfo->siPduLst.first != NULLP)
1368             {
1369                node = warningSiCfgReqInfo->siPduLst.first;
1370                cmLListDelFrm(&(warningSiCfgReqInfo->siPduLst), node);
1371                SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList));
1372                node = NULLP;
1373             } 
1374
1375             cell->siCb.warningSi[idx].siId = warningSiCfgReqInfo->siId;
1376             cell->siCb.warningSi[idx].idx = idx;
1377 #ifdef EMTC_ENABLE
1378             if(TRUE == isEmtc)
1379             {
1380                rgSCHEmtcWarningSiCfg(cell,warningSiCfgReqInfo,idx);
1381             }
1382             else
1383 #endif
1384             {
1385                cell->siCb.siArray[warningSiCfgReqInfo->siId-1].si = 
1386                   &cell->siCb.warningSi[idx];
1387                cell->siCb.siArray[warningSiCfgReqInfo->siId-1].isWarningSi =
1388                   TRUE;
1389             }
1390             freeNodeFound = TRUE;
1391             break;
1392          }
1393       }
1394    }
1395
1396    if (freeNodeFound == FALSE)
1397    {
1398       DU_LOG("\nDEBUG  -->  SCH : No SI Index is free");
1399       rgSCHUtlFreeWarningSiSeg(reg, pool, &warningSiCfgReqInfo->siPduLst);
1400       SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, 
1401             sizeof(RgrWarningSiCfgReqInfo)); 
1402       warningSiCfgReqInfo = NULLP;
1403       rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId, siId, transId, 
1404             cfmStatus); 
1405       return RFAILED;
1406    }
1407
1408    SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, 
1409          sizeof(RgrWarningSiCfgReqInfo)); 
1410    warningSiCfgReqInfo = NULLP;
1411    return ROK;
1412 }
1413
1414 \f
1415 /**
1416  * @brief Handler to handle SI Stop request from RRM to MAC.
1417  *
1418  * @details
1419  *
1420  *     Function: rgSCHGomHndlWarningSiStopReq
1421  *     
1422  *     This API handles processing for SI stop request from RRM to MAC.
1423  *     
1424  *  @param[in]  Region        reg
1425  *  @param[in]  Pool          pool
1426  *  @param[in]  RgSchCb       *instCb
1427  *  @param[in]  SpId          siId
1428  *  @return  void
1429  **/
1430 Void rgSCHGomHndlWarningSiStopReq(Region reg,Pool pool,RgSchCb *instCb,uint8_t siId,RgrCfgTransId transId,SpId spId)
1431 {
1432    RgSchCellCb        *cell = instCb->rgrSap[spId].cell;
1433    uint16_t           idx;
1434    CmLList            *node;
1435    RgSchWarningSiPdu  *warningSiPdu;
1436    Buffer             *pdu;
1437
1438    for(idx = 0; idx < RGR_MAX_NUM_WARNING_SI; idx++)
1439    {
1440       if(cell->siCb.warningSi[idx].siId == siId)
1441       {
1442          if ((cmMemcmp ((uint8_t *)&cell->siCb.warningSi[idx].warningSiMsg.transId, 
1443                      (uint8_t *)&transId, sizeof(RgrCfgTransId))) == 0)
1444          {
1445             /* ccpu00136659: CMAS ETWS design changes */
1446             CM_LLIST_FIRST_NODE(&cell->siCb.warningSi[idx].warningSiMsg.segLstCp, node);
1447             while(node != NULLP)
1448             {
1449                /* On receiving the warning stop message, remove one by one
1450                 * each PDU from the warning SI list
1451                 */  
1452                /* ccpu00136659: CMAS ETWS design changes */
1453                node = (CmLList *)&cell->siCb.warningSi[idx].warningSiMsg.segLstCp.first;
1454                warningSiPdu = (RgSchWarningSiPdu *)node->node;
1455                pdu = warningSiPdu->pdu;
1456                cmLListDelFrm(&cell->siCb.warningSi[idx].warningSiMsg.segLstCp, node);
1457                RGSCH_FREE_MSG(pdu);
1458                node = node->next;
1459             }
1460          }
1461       }
1462    }
1463    return;
1464 }
1465
1466 #endif/*RGR_SI_SCH */
1467 \f
1468 /* LTE_ADV_FLAG_REMOVED_START */
1469
1470 /**
1471  * @brief This function sets the Phigh range for CC users corresponding to the CC Pool
1472  * @details
1473  *
1474  *     Function: rgSchUpdtRNTPInfo
1475  *
1476  *     Invoked by: rgSCHGomHndlLoadInf
1477  *
1478  *  @param[in]  RgSchCellCb*     cell
1479  *  @param[in]  RgSubFrm*     subFrm
1480  *  @param[in]  RgrLoadInfReqInfo   *loadInfReq
1481  *  @return  S16
1482  *
1483  **/
1484 S16 rgSchUpdtRNTPInfo(RgSchCellCb *cell,RgSchDlSf *sf,RgrLoadInfReqInfo *loadInfReq)
1485 {
1486    /*  Initialise the variables */
1487    RgSchSFRPoolInfo *sfrCCPool;
1488    CmLListCp   *l;
1489    CmLList     *n;
1490    S16 ret = RFAILED;
1491
1492    l = &sf->sfrTotalPoolInfo.ccPool;
1493
1494    /*Get the first node from the CC Pool*/
1495    n = cmLListFirst(l);
1496    while(n)
1497    {
1498       sfrCCPool = (RgSchSFRPoolInfo*)n->node;
1499       if (sfrCCPool->poolendRB == loadInfReq->rgrCcPHighEndRb)
1500       {
1501          sfrCCPool->pwrHiCCRange.endRb   = loadInfReq->rgrCcPHighEndRb;
1502          sfrCCPool->pwrHiCCRange.startRb = loadInfReq->rgrCcPHighStartRb;
1503          return ROK;
1504       }
1505       else
1506       {
1507          n = cmLListNext(l);
1508       }
1509    }
1510    return (ret);
1511 }
1512 /**
1513  * @brief Handler to handle LOAD INF request from RRM to MAC.
1514  *
1515  * @details
1516  *
1517  *     Function: rgSCHGomHndlLoadInf
1518  *
1519  *     This API handles processing for LOAD INF request from RRM to MAC.
1520  *
1521  *     - Processing Steps:
1522  *        - Validate LOAD INF request parameters at CFG module.
1523  *          Call rgSCHCfgVldtRgrLoadInf for SI configuration.
1524  *        - If validated successfully, send configuration request.
1525  *
1526  *  @param[in]  Region            reg
1527  *  @param[in]  Pool              pool
1528  *  @param[in]  RgSchCb           *instCb
1529  *  @param[in]  SpId              spId
1530  *  @param[in]  RgrCfgTransId     transId
1531  *  @param[in]  RgrLoadInfReqInfo *loadInfReq
1532  *  @return  S16
1533  *      -# ROK
1534  *      -# RFAILED
1535  **/
1536 S16 rgSCHGomHndlLoadInf(Region reg,Pool pool,RgSchCb *instCb,SpId spId,RgrCfgTransId transId,RgrLoadInfReqInfo *loadInfReq)
1537 {
1538    S16          ret;
1539    RgSchCellCb  *cell = instCb->rgrSap[spId].cell;
1540    Inst         inst  = (instCb->rgSchInit.inst );
1541    RgSchErrInfo errInfo;
1542    uint16_t i;
1543
1544    /* check if cell does not exists */
1545    if (((uint8_t *)cell == NULLP) || (cell->cellId != loadInfReq->cellId))
1546    {
1547       DU_LOG("\nERROR  -->  SCH : Cell Control block does not exist"
1548              "for load cellId:%d",loadInfReq->cellId);
1549       SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq));
1550       return RFAILED;
1551    }
1552
1553    if (cell->lteAdvCb.dsfrCfg.status == RGR_DISABLE)
1554    {
1555       DU_LOG("\nERROR  -->  SCH : rgSCHGomHndlLoadInf(): DSFR Feature not enabled");
1556       SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq));
1557       return RFAILED;
1558    }
1559    /* Validate the received LOAD INF Configuration */
1560    ret = rgSCHCfgVldtRgrLoadInf(inst, loadInfReq, cell, &errInfo);
1561    if (ret != ROK)
1562    {
1563       DU_LOG("\nERROR  -->  SCH : Rgr LOAD INF Configuration "
1564                "validation FAILED");
1565       SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq));
1566       return RFAILED;
1567    }
1568    /* Update the RNTP info rcvd in the respective cell centre pool so that Phigh can be
1569       sent for the UEs scheduled in that particular RB range*/
1570    for(i = 0; i < RGSCH_NUM_DL_slotS; i++)
1571    {
1572       if((rgSchUpdtRNTPInfo(cell, cell->subFrms[i], loadInfReq) != ROK))
1573       {
1574          return RFAILED;
1575       }
1576    }
1577
1578    SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq));
1579
1580
1581    return ROK;
1582 }  /* rgSCHGomHndlLoadInf */
1583 /* LTE_ADV_FLAG_REMOVED_END */
1584 \f
1585 /**********************************************************************
1586  
1587          End of file
1588 **********************************************************************/