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