dbb5cd62fe1379bc9a8a46fb2d6e9cabb1758456
[o-du/l2.git] / src / 5gnrsch / rg_sch_lmm.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 Layer Manager Interface Module 
26   
27      File:     rg_sch_lmm.c 
28   
29 **********************************************************************/
30
31 /** @file rg_sch_lmm.c
32 @brief This file contains the Layer Management interface module implementation for scheduler.
33        The functions for the configuration, control, status and statistics 
34        request primitives are defined here.
35 */
36
37
38 /* header include files (.h) */
39 #include "common_def.h"
40 #include "rg_env.h"        /* MAC Environment Defines */
41 #include "rgr.h"           /* RGR Interface defines */
42 #include "tfu.h"           /* RGU Interface defines */
43 #include "lrg.h"           /* LRG Interface defines */
44 #include "rgm.h"           /* RGM Interface defines */
45 #include "rg_sch.h"        /* Scheduler defines */
46 #include "rg_sch_inf.h"        /* Scheduler defines */
47 #include "rg_sch_err.h"        /* MAC error defines */
48 #ifdef LTE_L2_MEAS
49 #include "rg_sch_cmn.h"    /* typedefs for Scheduler */
50 #endif
51 #include "sch_utils.h"
52 /* header/extern include files (.x) */
53 #include "rgr.x"           /* RGR Interface includes */
54 #include "rgm.x"           /* RGM Interface includes */
55 #include "tfu.x"           /* RGU Interface includes */
56 #include "lrg.x"           /* LRG Interface includes */
57 #include "rg_sch_inf.x"    /* Scheduler defines */
58 #include "rg_sch.x"        /* Scheduler includes */
59 #ifdef LTE_L2_MEAS
60 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
61 #endif 
62 #ifndef LTE_L2_MEAS
63 Void rgSCHCmnInit ARGS((Void));
64 #endif 
65 /* forward references */
66 extern int schActvInit(Ent entity, Inst instId, Region region, Reason reason);
67 #ifdef UNUSE_FUN
68 static uint16_t rgSCHLmmSapCfg ARGS((
69    Inst           inst,
70    RgCfg          *cfg,
71    uint8_t             sapIdx,
72    Elmnt          sapType
73 ));
74 #endif
75 static Void rgSCHLmmShutdown ARGS((
76    Inst inst
77 ));
78
79
80 void printSchCellInfo(void)
81 {
82    uint8_t idx=0;
83    uint8_t inst=0;
84    for (idx = 0; idx < rgSchCb[inst].numSaps; idx++)
85    {
86       /* Unbind all the TFU SAP */
87       /* Free the memory held by the cell associated
88        * with this SAP */
89       if (rgSchCb[inst].tfuSap[idx].cell != NULLP)
90       {
91          DU_LOG("\nINFO  -->  SCH : CELL %d\n", idx);
92          DU_LOG("\nINFO  -->  SCH : NUM UEs :%d\n",rgSchCb[inst].tfuSap[idx].cell->ueLst.nmbEnt);
93       }
94    }
95 }
96
97 /**
98  * @brief SAP Configuration Handler. 
99  *
100  * @details
101  *
102  *     Function : rgSCHLmmSapCfg
103  *     
104  *     This function in called by SchProcGenCfgReq(). It handles the
105  *     interface SAP configuration of the scheduler instance. It 
106  *     initializes the sapState to LRG_UNBND. Returns
107  *     reason for success/failure of this function.
108  *     
109  *  @param[in]  RgCfg *cfg, the Configuaration information 
110  *  @return  uint16_t
111  *      -# LCM_REASON_GENCFG_NOT_DONE
112  *      -# LCM_REASON_INVALID_SAP
113  *      -# LCM_REASON_NOT_APPL
114  **/
115 #ifdef UNUSE_FUN
116 static uint16_t rgSCHLmmSapCfg
117 (
118 Inst  dInst,
119 RgCfg *cfg,            /* Configuaration information */
120 uint8_t sapIdx,          /* SAP index */
121 Elmnt sapType             /* SAP Type */
122 )
123 {
124    uint16_t                  ret = LCM_REASON_NOT_APPL;
125    RgSchLowSapCfgInfo   *lowSapCfg = NULLP;
126    RgSchUpSapCfgInfo    *upSapCfg = NULLP;
127    Inst  inst = (dInst - SCH_INST_START);
128
129    /* Check if Gen Config has been done */
130
131    switch(sapType)
132    {   
133       case STRGRSAP:
134 #ifndef CL_MAC_LWLC
135          if ((cfg->s.schInstCfg.rgrSap[sapIdx].selector != ODU_SELECTOR_TC) &&
136              (cfg->s.schInstCfg.rgrSap[sapIdx].selector != ODU_SELECTOR_LC))
137          {
138             ret = LCM_REASON_INVALID_PAR_VAL;
139             DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCfg(): unsupported"
140                " Selector value for RGR.");
141             break;
142          }
143 #endif
144          if(rgSchCb[inst].rgrSap[sapIdx].sapSta.sapState == LRG_NOT_CFG)
145          { 
146             rgSchCb[inst].rgrSap[sapIdx].sapSta.sapState = LRG_UNBND;
147          }
148          upSapCfg = &rgSchCb[inst].rgrSap[sapIdx].sapCfg;
149
150          upSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.rgrSap[sapIdx].ent;
151          upSapCfg->sapPst.dstInst = cfg->s.schInstCfg.rgrSap[sapIdx].inst;
152          upSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.rgrSap[sapIdx].procId;
153          upSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent;
154          upSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst +
155          SCH_INST_START;
156          upSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId;
157          upSapCfg->sapPst.region = cfg->s.schInstCfg.rgrSap[sapIdx].mem.region;
158          upSapCfg->sapPst.pool = cfg->s.schInstCfg.rgrSap[sapIdx].mem.pool;
159          upSapCfg->sapPst.selector = cfg->s.schInstCfg.rgrSap[sapIdx].selector;
160          upSapCfg->sapPst.route = cfg->s.schInstCfg.rgrSap[sapIdx].route;
161          upSapCfg->sapPst.intfVer = 0; 
162          upSapCfg->sapPst.event = 0; 
163          upSapCfg->sapPst.prior = cfg->s.schInstCfg.rgrSap[sapIdx].prior;
164          upSapCfg->suId = cfg->s.schInstCfg.rgrSap[sapIdx].suId;
165          upSapCfg->spId = cfg->s.schInstCfg.rgrSap[sapIdx].spId;
166          break;
167       case STTFUSAP:
168 #ifndef CL_MAC_LWLC
169          if ((cfg->s.schInstCfg.tfuSap[sapIdx].selector != ODU_SELECTOR_TC) &&
170              (cfg->s.schInstCfg.tfuSap[sapIdx].selector != ODU_SELECTOR_LC))
171          {
172             ret = LCM_REASON_INVALID_PAR_VAL;
173             DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCfg(): unsupported"
174                      " Selector value for TFU.");
175             break;
176          }
177 #endif
178          if (rgSchCb[inst].tfuSap[sapIdx].sapSta.sapState == LRG_NOT_CFG) 
179          { 
180             rgSchCb[inst].tfuSap[sapIdx].sapSta.sapState = LRG_UNBND;
181          }
182          /* Initialize the  sap timer */
183          cmInitTimers(&(rgSchCb[inst].tfuSap[sapIdx].tmrBlk), 1);
184          lowSapCfg = &rgSchCb[inst].tfuSap[sapIdx].sapCfg;
185
186          lowSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.tfuSap[sapIdx].ent;
187          lowSapCfg->sapPst.dstInst = cfg->s.schInstCfg.tfuSap[sapIdx].inst;
188          lowSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.tfuSap[sapIdx].procId;
189          lowSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent;
190          lowSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst +
191          SCH_INST_START;
192          lowSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId;
193          lowSapCfg->sapPst.region = cfg->s.schInstCfg.tfuSap[sapIdx].mem.region;
194          lowSapCfg->sapPst.pool = cfg->s.schInstCfg.tfuSap[sapIdx].mem.pool;
195          lowSapCfg->sapPst.selector = cfg->s.schInstCfg.tfuSap[sapIdx].selector;
196          lowSapCfg->sapPst.route = cfg->s.schInstCfg.tfuSap[sapIdx].route;
197          lowSapCfg->sapPst.intfVer = 0; 
198           lowSapCfg->sapPst.event = 0; 
199          lowSapCfg->sapPst.prior = cfg->s.schInstCfg.tfuSap[sapIdx].prior;
200          lowSapCfg->suId = cfg->s.schInstCfg.tfuSap[sapIdx].suId;
201          lowSapCfg->spId = cfg->s.schInstCfg.tfuSap[sapIdx].spId;
202          memcpy(&lowSapCfg->bndTmr, 
203                   &cfg->s.schInstCfg.tfuSap[sapIdx].bndTmr,
204                   sizeof(TmrCfg));
205          break;
206       case STRGMSAP:
207 #ifndef RGM_LWLC
208          if ((cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_LWLC) &&
209              (cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_LC) &&
210              (cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_TC))
211          {
212             ret = LCM_REASON_INVALID_PAR_VAL;
213             DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCfg(): unsupported"
214                      " Selector value for RGM.");
215             break;
216          }
217 #endif
218          if (rgSchCb[inst].rgmSap[sapIdx].sapSta.sapState == LRG_NOT_CFG) 
219          { 
220             rgSchCb[inst].rgmSap[sapIdx].sapSta.sapState = LRG_UNBND;
221          }
222          upSapCfg = &rgSchCb[inst].rgmSap[sapIdx].sapCfg;
223          upSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.rgmSap[sapIdx].ent;
224          upSapCfg->sapPst.dstInst = cfg->s.schInstCfg.rgmSap[sapIdx].inst;
225          upSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.rgmSap[sapIdx].procId;
226          upSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent;
227          upSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst +
228          SCH_INST_START;
229          upSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId;
230          upSapCfg->sapPst.region = cfg->s.schInstCfg.rgmSap[sapIdx].mem.region;
231          upSapCfg->sapPst.pool = cfg->s.schInstCfg.rgmSap[sapIdx].mem.pool;
232          upSapCfg->sapPst.selector = cfg->s.schInstCfg.rgmSap[sapIdx].selector;
233          upSapCfg->sapPst.route = cfg->s.schInstCfg.rgmSap[sapIdx].route;
234          upSapCfg->sapPst.intfVer = 0; 
235          upSapCfg->sapPst.event = 0; 
236          upSapCfg->sapPst.prior = cfg->s.schInstCfg.rgmSap[sapIdx].prior;
237          upSapCfg->suId = cfg->s.schInstCfg.rgmSap[sapIdx].suId;
238          upSapCfg->spId = cfg->s.schInstCfg.rgmSap[sapIdx].spId;
239
240          break;
241       default:
242          /* would never reach here */
243          break;
244    }
245    return (ret);
246 }
247 #endif
248 \f
249 /***********************************************************
250  *
251  *     Func : rgSCHLmmShutdown
252  *        
253  *
254  *     Desc : Handles the scheduler instance shutdown request. Calls 
255  *     rgSCHCfgFreeCellCb(RgSchCellCb*) to handle each cellCb deallocation.
256  *            
257  *
258  *     Ret  : Void
259  *
260  *     Notes: 
261  *
262  *     File : rg_sch_lmm.c 
263  *
264  **********************************************************/
265 static Void rgSCHLmmShutdown(Inst inst)
266 {
267    Inst          dInst = inst + SCH_INST_START;
268    uint8_t       idx;
269 #ifdef LTE_L2_MEAS
270    CmLList       *lnk = NULLP;
271    RgSchCb       *instCb =  &rgSchCb[inst];
272    RgSchCellCb   *cell = NULLP;
273    RgSchL2MeasCb *measCb;
274    uint8_t       ulAllocIdx;
275    RgSchCmnUlCell *cellUl;
276    RgSchClcBoRpt  *bo = NULL;
277 #endif
278
279 #ifdef LTE_L2_MEAS
280    for (idx = 0; idx < instCb->numSaps; idx++)
281    {
282      /* got the cell break the loop */
283      cell = instCb->rgrSap[idx].cell;
284      if(cell != NULLP)
285      {
286         /* Free the memory held up by  ulAllocInfo */
287         cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
288 #ifdef LTE_TDD
289         for(ulAllocIdx = 0; ulAllocIdx < RGSCH_SF_ALLOC_SIZE; ulAllocIdx++)
290 #else
291         for(ulAllocIdx = 0; ulAllocIdx < RGSCH_NUM_SUB_FRAMES; ulAllocIdx++)
292 #endif
293         {
294            if(cell->sfAllocArr[ulAllocIdx].ulUeInfo.ulAllocInfo != NULLP)
295            {
296              /* ccpu00117052 - MOD - Passing double pointer
297              for proper NULLP assignment*/
298              rgSCHUtlFreeSBuf(cell->instIdx, 
299                     (Data **)(&(cell->sfAllocArr[ulAllocIdx].ulUeInfo.\
300                                 ulAllocInfo)),
301                     cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc));
302            }
303         }
304         /* Free the memory allocated to measCb */
305         lnk = cell->l2mList.first;
306         while(lnk != NULLP)
307         {
308            measCb = (RgSchL2MeasCb *)lnk->node;
309            cmLListDelFrm(&cell->l2mList, lnk);
310            lnk = lnk->next;
311              /* ccpu00117052 - MOD - Passing double pointer
312              for proper NULLP assignment*/
313            rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\
314                           sizeof(RgSchL2MeasCb));
315         }
316
317         /* Free mem if any present for boLst for common channels */
318         for(idx = 0; idx < RGSCH_MAX_CMN_LC_CB; idx++)
319         {
320            lnk = (CmLList *)cell->cmnLcCb[idx].boLst.first;
321            while (lnk)
322            {
323               bo = (RgSchClcBoRpt *)(lnk->node);
324               lnk = lnk->next;
325               cmLListDelFrm(&cell->cmnLcCb[idx].boLst, &bo->boLstEnt);
326               rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt));
327            }
328         }
329      }
330    }
331 #endif
332
333 #ifdef LTE_ADV
334    rgSCHLaaDeInitEnbCb(&rgSchCb[inst]);
335 #endif
336    for (idx = 0; idx < rgSchCb[inst].numSaps; idx++)
337    {
338       /* Unbind all the TFU SAP */
339       if(rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_WAIT_BNDCFM)
340       {
341          //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, LRG_UNBND);
342          if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
343          {
344             rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[idx]); 
345          }
346          rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND;
347       }
348       if(rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND)
349       {
350          //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, LRG_UNBND);
351          rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND;
352       }
353       /* Free the memory held by the cell associated with this SAP */
354       if (rgSchCb[inst].tfuSap[idx].cell != NULLP)
355          rgSCHCfgFreeCellCb(rgSchCb[inst].tfuSap[idx].cell);
356       rgSchCb[inst].tfuSap[idx].cell = NULLP;
357    }
358    /* Free the memory held by the scheduler instance */
359    /* Deallocate RGR saps */
360    SCH_FREE(rgSchCb[inst].rgrSap,
361                 (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps));
362    rgSchCb[inst].rgrSap = NULLP;
363    /* Deallocate RGM saps */
364    SCH_FREE(rgSchCb[inst].rgmSap,
365                 (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps));
366    rgSchCb[inst].rgmSap = NULLP;
367
368    /* Deallocate TFU saps */
369    SCH_FREE(rgSchCb[inst].tfuSap,
370                 (sizeof(RgSchLowSapCb) * rgSchCb[inst].numSaps));
371    rgSchCb[inst].tfuSap = NULLP;
372
373    /* Deallocate bndCfmResponses */
374    SCH_FREE(rgSchCb[inst].genCfg.bndCfmResp,
375                 (sizeof(RgSchLmResponse) * rgSchCb[inst].numSaps));
376    rgSchCb[inst].genCfg.bndCfmResp = NULLP;
377    /* De-register the Timer Service */
378    (Void) SDeregTmrMt(rgSchCb[inst].rgSchInit.ent, dInst,
379                      (S16)rgSchCb[inst].genCfg.tmrRes, schActvTmr); 
380
381    /* call back the task initialization function to intialize
382     * the global rgSchCb[inst] Struct */
383    schActvInit(rgSchCb[inst].rgSchInit.ent, dInst, rgSchCb[inst].rgSchInit.region, 
384               rgSchCb[inst].rgSchInit.reason);
385    
386    /* Set Config done in TskInit */
387    rgSchCb[inst].rgSchInit.cfgDone = FALSE;
388
389    return;
390 }
391
392 \f
393 /***********************************************************
394  *
395  *     Func : rgSCHLmmGenCntrl 
396  *        
397  *
398  *     Desc : Processes the LM control request for STGEN elmnt.
399  *            
400  *
401  *     Ret  : Void
402  *
403  *     Notes: 
404  *
405  *     File : rg_sch_lmm.c 
406  *
407  **********************************************************/
408 Void rgSCHLmmGenCntrl(RgMngmt *cntrl,RgMngmt *cfm,Pst  *cfmPst)
409 {
410    Inst      inst = (cfmPst->srcInst - SCH_INST_START); /* Scheduler instance ID */
411
412    cfm->cfm.status = LCM_PRIM_OK;
413    cfm->cfm.reason = LCM_REASON_NOT_APPL;
414    
415
416    switch(cntrl->t.cntrl.action)
417    {
418       case AENA:
419          /* Action is Enable */
420          switch(cntrl->t.cntrl.subAction)
421          {
422             case SAUSTA:   
423             /* Enable Unsolicited Status (alarms) */
424                rgSchCb[inst].rgSchInit.usta = TRUE;
425                /*Store the response and TransId for sending the Alarms */
426                memcpy(&rgSchCb[inst].genCfg.ustaResp.response, 
427                &cntrl->hdr.response, sizeof(Resp));
428                rgSchCb[inst].genCfg.ustaResp.transId = cntrl->hdr.transId;
429                break;
430             case SADBG:
431             /* Enable Debug Printing */
432 #ifdef DEBUGP
433                rgSchCb[inst].rgSchInit.dbgMask |= cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
434 #endif
435                break;
436 #ifdef PHY_ERROR_LOGING
437             case SAELMNT:
438                {
439                   rgSchUlAllocCntr.mcs = cntrl->t.cntrl.s.rgSchUlAllocCntrl.mcs;
440                   rgSchUlAllocCntr.numOfRb = cntrl->t.cntrl.s.rgSchUlAllocCntrl.numOfRb;
441                   rgSchUlAllocCntr.rbStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.rbStart;
442                   rgSchUlAllocCntr.testStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.testStart;
443                   rgSchUlAllocCntr.enaLog = cntrl->t.cntrl.s.rgSchUlAllocCntrl.enaLog;
444                   rgSchUlAllocCntr.logTime = cntrl->t.cntrl.s.rgSchUlAllocCntrl.logTime;
445                   rgSchUlAllocCntr.crcOk = 0;
446                   rgSchUlAllocCntr.crcErr = 0;
447                   rgSchUlAllocCntr.numUlPackets = 0;
448                   rgSchUlAllocCntr.numPrach = 0;
449                   rgSchUlAllocCntr.taZero = 0;
450 #ifdef MAC_SCH_STATS
451                   /* Reset
452                    * L2
453                    * statistics
454                    * */
455                   memset(&hqRetxStats, 0, sizeof(RgSchHqRetxStats));
456                   memset(&hqFailStats, 0, sizeof(RgSchNackAckStats));
457 #endif
458                   break;
459                }
460 #endif
461             default:
462                cfm->cfm.status = LCM_PRIM_NOK;
463                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
464                DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl(): "
465                   "invalid subaction=%d", cntrl->t.cntrl.subAction);
466                break;
467          }
468          break;
469       case ADISIMM:
470          /* Action is Diable immidiately */
471          switch(cntrl->t.cntrl.subAction)
472          {
473             case SAUSTA:
474             /* Disable Unsolicited Status (alarms) */
475                rgSchCb[inst].rgSchInit.usta = FALSE;
476                break;
477             case SADBG:
478             /* Disable Debug Printing */
479 #ifdef DEBUGP
480                rgSchCb[inst].rgSchInit.dbgMask &=\
481                           ~cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
482 #endif
483                break;
484
485             default:
486                cfm->cfm.status = LCM_PRIM_NOK;
487                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
488                DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl():"
489                  " invalid subaction=%d", cntrl->t.cntrl.subAction);
490                break;
491          }
492          break;
493       case ASHUTDOWN:
494          /* Free all the memory dynamically allocated by MAC */
495          rgSCHLmmShutdown(inst);
496          break;
497       default:
498          cfm->cfm.status = LCM_PRIM_NOK;
499          cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
500          DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl(): invalid"
501           " action=%d", cntrl->t.cntrl.action);
502          break;
503    }
504    RgMiLrgSchCntrlCfm(cfmPst, cfm);
505    return;
506 }
507
508 \f
509 /***********************************************************
510  *
511  *     Func : rgSCHLmmSapCntrl 
512  *        
513  *
514  *     Desc : Processes the LM control request for STxxxSAP elmnt.
515  *            
516  *
517  *     Ret  : Void
518  *
519  *     Notes: 
520  *
521  *     File : rg_sch_lmm.c 
522  *
523  **********************************************************/
524 Void rgSCHLmmSapCntrl 
525 (
526 RgMngmt       *cntrl,
527 RgMngmt       *cfm,
528 Pst           *cfmPst
529 )
530 {
531    uint8_t       idx;
532
533    /* TODO Pass InstId instead of using InstId from cfmPst */
534    Inst      inst = (cfmPst->srcInst - SCH_INST_START); /* Scheduler instance Id */
535
536    /* Only TFU SAP can be controlled by LM */
537    switch(cntrl->hdr.elmId.elmnt)
538    {
539       case STTFUSAP:
540          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.suId;
541          if (idx > LRG_MAX_SAPS_PER_INST)
542          {
543             cfm->cfm.status = LCM_PRIM_NOK;
544             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
545          }
546          switch(cntrl->t.cntrl.action)
547          {
548             case ABND:
549                /* Bind Enable Request */
550                if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) ||
551                    (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND))
552                {
553                   cfm->cfm.status = LCM_PRIM_NOK;
554                   cfm->cfm.reason = LCM_REASON_INVALID_SAP;
555                }
556                else
557                {
558                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
559                   {
560                      rgSCHLmmStartTmr(inst, RGSCH_BNDREQ_TMR,
561                                   rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.val, 
562                                   (PTR)&rgSchCb[inst].tfuSap[idx]);
563                   }
564                   /* Change SAP state */
565                   rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_WAIT_BNDCFM;
566                   rgSchCb[inst].tfuSap[idx].numBndRetries++;
567                   /* Store the response and TransId for sending 
568                    * the Control confirm */
569                   memcpy(&rgSchCb[inst].genCfg.bndCfmResp[idx].response,
570                            &cntrl->hdr.response, sizeof(Resp));
571                   rgSchCb[inst].genCfg.bndCfmResp[idx].transId = 
572                                                 cntrl->hdr.transId;
573                   
574                   cfm->cfm.status = LCM_PRIM_OK_NDONE;
575                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
576
577                   /* Sending Control Confirm before sending Bind
578                    * Request to TFU  */
579                   RgMiLrgSchCntrlCfm(cfmPst, cfm);
580                   
581                   //rgSCHUtlTfuBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg.suId, 
582                     //             rgSchCb[inst].tfuSap[idx].sapCfg.spId);
583                  return; 
584                }
585                break;
586             case AUBND:
587             /* Unbind request */
588
589                /* Check if the SAP is configured */
590                if( (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) ||
591                      (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_UNBND))
592                {
593                   cfm->cfm.status = LCM_PRIM_NOK;
594                   cfm->cfm.reason = LCM_REASON_INVALID_MSGTYPE;
595                }
596                else
597                {
598                   //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg,
599                     //              TFU_UBNDREQ_MNGMT);
600                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
601                   {
602                      rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, 
603                                        (PTR)&rgSchCb[inst].tfuSap[idx]);
604                   }
605                   /* Change SAP state */
606                   rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND;
607                   cfm->cfm.status = LCM_PRIM_OK;
608                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
609                }
610                break;
611             case ADEL:
612                /* Delete SAP, does initialization of SAP */
613                if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_WAIT_BNDCFM) ||
614                    (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND))
615                {
616                   //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg,
617                     //              TFU_UBNDREQ_MNGMT);
618                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
619                   {
620                      rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR,
621                                      (PTR)&rgSchCb[inst].tfuSap[idx]);
622                   }
623                }
624                memset(&rgSchCb[inst].tfuSap[idx], 0, sizeof(RgSchLowSapCb));
625                rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_NOT_CFG;
626                cfm->cfm.status = LCM_PRIM_OK;
627                cfm->cfm.reason = LCM_REASON_NOT_APPL;
628                break;
629             default:
630                cfm->cfm.status = LCM_PRIM_NOK;
631                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
632                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
633                   "invalid action=%d", cntrl->t.cntrl.action);
634                break;
635          }
636          break;
637       case STRGRSAP:
638          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.spId;
639          if (idx > LRG_MAX_SAPS_PER_INST)
640          {
641             cfm->cfm.status = LCM_PRIM_NOK;
642             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
643          }
644          switch(cntrl->t.cntrl.action)
645          {
646             case ADEL:
647                memset(&rgSchCb[inst].rgrSap[idx], 0, sizeof(RgSchUpSapCb));
648                rgSchCb[inst].rgrSap[idx].sapSta.sapState = LRG_NOT_CFG;
649                cfm->cfm.status = LCM_PRIM_OK;
650                cfm->cfm.reason = LCM_REASON_NOT_APPL;
651                break;
652             default:
653                cfm->cfm.status = LCM_PRIM_NOK;
654                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
655                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
656                      "invalid action=%d", cntrl->t.cntrl.action);
657                break;
658          }
659          break;
660       case STRGMSAP:
661          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.spId;
662          if (idx > LRG_MAX_SAPS_PER_INST)
663          {
664             cfm->cfm.status = LCM_PRIM_NOK;
665             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
666          }
667          switch(cntrl->t.cntrl.action)
668          {
669             case ADEL:
670                memset(&rgSchCb[inst].rgmSap[idx], 0, sizeof(RgSchUpSapCb));
671                rgSchCb[inst].rgmSap[idx].sapSta.sapState = LRG_NOT_CFG;
672                cfm->cfm.status = LCM_PRIM_OK;
673                cfm->cfm.reason = LCM_REASON_NOT_APPL;
674                break;
675             default:
676                cfm->cfm.status = LCM_PRIM_NOK;
677                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
678                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
679                      "invalid action=%d", cntrl->t.cntrl.action);
680                break;
681          }
682          break;
683
684        default:
685          /* Would never come here. */
686          return;
687    }
688    RgMiLrgSchCntrlCfm(cfmPst, cfm);
689    return;
690 }
691
692 \f
693 /***********************************************************
694  *
695  *     Func : SchFillCfmPst 
696  *        
697  *
698  *     Desc : Fills the Confirmation Post Structure cfmPst using the reqPst 
699  *            and the cfm->hdr.response.
700  *            
701  *
702  *     Ret  : Void
703  *
704  *     Notes: 
705  *
706  *     File : rg_sch_lmm.c 
707  *
708  **********************************************************/
709 Void SchFillCfmPst
710 (
711 Pst           *reqPst,
712 Pst           *cfmPst,
713 RgMngmt       *cfm
714 )
715 {
716    Inst inst;
717
718    inst = (reqPst->dstInst - SCH_INST_START);
719
720    cfmPst->srcEnt    = ENTMAC;
721    cfmPst->srcInst   = (Inst) 1;
722    cfmPst->srcProcId = rgSchCb[inst].rgSchInit.procId;
723    cfmPst->dstEnt    = ENTMAC;
724    cfmPst->dstInst   = (Inst) 0;
725    cfmPst->dstProcId = reqPst->srcProcId;
726
727    cfmPst->selector  = cfm->hdr.response.selector;
728    cfmPst->region    = cfm->hdr.response.mem.region;
729    cfmPst->pool      = cfm->hdr.response.mem.pool;
730
731    return;
732 }
733
734 \f
735 /**
736  * @brief Timer start handler. 
737  *
738  * @details
739  *
740  *     Function : rgSCHLmmStartTmr
741  *     
742  *     This function based on the input parameters starts the timer for 
743  *     "tmrVal" duration. As of now scheduler instance uses the timer 
744  *     functionality for BndReq only. Hence there is no conditional
745  *     code based on "tmrEvnt".
746  *     
747  *  @param[in]  S16   tmrEvnt, the Timer Event    
748  *  @param[in]  uint32_t   tmrVal,  the Wait Time
749  *  @param[in]  PTR   cb,  Entry for which Timer expired
750  *  @return  S16
751  *      -# ROK
752  **/
753 S16 rgSCHLmmStartTmr
754 (
755 Inst       inst,
756 S16        tmrEvnt,            /* Timer Event */
757 uint32_t   tmrVal,             /* Wait Time */
758 PTR        cb                  /* Entry for which Timer Expired */
759 )
760 {
761    CmTmrArg    arg;
762 /*   Inst        dInst = inst + SCH_INST_START; */
763
764    UNUSED(tmrEvnt);
765
766    /* Initialize the arg structure */
767    memset(&arg, 0, sizeof(CmTmrArg));
768
769    arg.tqCp = &rgSchCb[inst].tmrTqCp;
770    arg.tq = rgSchCb[inst].tmrTq;
771    arg.timers = &((RgSchLowSapCb *)cb)->tmrBlk;
772    arg.cb = cb;
773    arg.tNum = 0;
774    arg.max = RGSCH_MAX_TIMER;
775    arg.evnt = RGSCH_BNDREQ_TMR;
776    arg.wait = tmrVal;      
777    cmPlcCbTq(&arg);
778
779    return ROK;
780 }
781
782 \f
783 /**
784  * @brief Timer stop handler. 
785  *
786  * @details
787  *
788  *     Function : rgSCHLmmStopTmr
789  *     
790  *     This function based on the input parameters stops the timer for 
791  *     "tmrEvnt". As of now Scheduler instance uses the timer functionality for
792  *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
793  *     Once the bind happens and this timer is stopped, the timer functionality
794  *     is deregistered with SSI. As there is no further use of timer processing.
795  *     
796  *  @param[in]  S16   tmrEvnt, the Timer Event    
797  *  @param[in]  PTR   cb,  Entry for which Timer expired
798  *  @return  S16
799  *      -# ROK
800  *      -# RFAILED
801  **/
802 S16 rgSCHLmmStopTmr
803 (
804 Inst inst,             /* Scheduler instance */
805 S16  tmrEvnt,            /* Timer Event */
806 PTR  cb                  /* Entry for which Timer Expired */
807 )
808 {
809    CmTmrArg   arg;
810    uint8_t    i;
811    S16        ret; 
812
813    ret = RFAILED;
814
815    for(i=0;i<RGSCH_MAX_TIMER;i++)
816    {
817       /* Search for the Timer Blocks */
818       if(((RgSchLowSapCb *)cb)->tmrBlk.tmrEvnt == tmrEvnt)
819       {
820          /* Initialize the arg structure */
821          memset(&arg, 0, sizeof(CmTmrArg));
822
823          arg.tqCp = &rgSchCb[inst].tmrTqCp;
824          arg.tq = rgSchCb[inst].tmrTq;
825          arg.timers = &(((RgSchLowSapCb *)cb)->tmrBlk);
826          arg.cb = cb;
827          arg.max = RGSCH_MAX_TIMER;
828          arg.evnt = tmrEvnt;
829
830          arg.tNum = i;   
831          cmRmvCbTq(&arg);
832          ret = ROK;
833          break;
834       }
835
836    }
837
838
839    return (ret);
840 }
841
842 \f
843 /**
844  * @brief Timer Expiry handler. 
845  *
846  * @details
847  *
848  *     Function : rgSCHLmmTmrExpiry
849  *     
850  *     This is a callback function used as an input parameter to cmPrcTmr()
851  *     to check expiry of any timer. In this function, we are only concerned
852  *     about tmrEvnt=Bind timer.
853  *     
854  *  @param[in]  PTR   cb,  Entry for which Timer expired
855  *  @param[in]  S16   tmrEvnt, the Timer Event    
856  *  @return  S16
857  *      -# ROK
858  **/
859 S16 rgSCHLmmTmrExpiry
860 (
861 PTR cb,               /* Pointer to timer control block */
862 S16 tmrEvnt           /* Timer Event */
863 )
864 {
865    S16           ret = ROK;
866    RgSchLowSapCb *tfuSap = (RgSchLowSapCb *)cb;
867
868    
869    switch(tmrEvnt)
870    {
871       case RGSCH_BNDREQ_TMR:
872          tfuSap->numBndRetries++;
873          if(tfuSap->numBndRetries > RGSCH_MAX_BNDRETRY)
874          {
875             rgSCHLmmStaInd((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
876                            (uint16_t)LCM_CATEGORY_INTERFACE, (uint16_t)LCM_EVENT_BND_FAIL,
877                            (uint16_t)LCM_CAUSE_TMR_EXPIRED, (RgUstaDgn *)NULLP);
878          }
879          else
880          {
881             /* Restart the bind timer */
882             if (tfuSap->sapCfg.bndTmr.enb == TRUE)
883             {
884                ret = rgSCHLmmStartTmr((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
885                                   RGSCH_BNDREQ_TMR, 
886                                  (uint32_t)tfuSap->sapCfg.bndTmr.val, cb);
887             }
888
889             /* Send bind request */
890             //rgSCHUtlTfuBndReq((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START), 
891             //tfuSap->sapCfg.suId, tfuSap->sapCfg.spId);
892          }
893          break;
894       default:
895          DU_LOG("\nERROR  -->  SCH : rgSCHLmmTmrExpiry(): Invalid"
896                  " tmrEvnt=%d", tmrEvnt);
897          ret = RFAILED;
898          break;
899    }
900    return (ret);
901 }
902
903 \f
904 /**
905  * @brief Layer Manager Control Confirm generation handler
906  *        for Bind Confirm reception at TFU interface.
907  *        RgLiTfuBndCfm() forwards the confirmation to this 
908  *        function. All SAP state related handling is restricted
909  *        to LMM modules, hence the cfm forwarding.
910  *
911  * @details
912  *
913  *     Function : rgSCHLmmBndCfm 
914  *     
915  *     This API is used by the LIM module of MAC to forward
916  *     the Bind Confirm it receives over the TFU interface.
917  *     
918  *  @param[in]   Pst *pst, Post Structure
919  *  @param[in]   SuId suId, Service user ID
920  *  @param[in]   uint8_t status, Status
921  *  @return  S16
922  *      -# ROK
923  **/
924 S16 rgSCHLmmBndCfm
925 (
926 Pst *pst,               /* Post Structure */
927 SuId suId,              /* Service user ID */
928 uint8_t status               /* Status */
929 )
930 {
931    S16       ret = ROK;
932    RgMngmt   cntrlCfm;
933    Pst       cfmPst;
934    Inst      inst = (pst->dstInst - SCH_INST_START); /* scheduler instance */
935
936
937    /* check the SAP State */
938    switch(rgSchCb[inst].tfuSap[suId].sapSta.sapState)
939    {
940       case LRG_WAIT_BNDCFM:
941          break;
942       case LRG_BND:
943          /* SAP is already bound */
944          return ROK;
945       default:
946          return RFAILED;
947    }
948
949    cfmPst = rgSchCb[inst].rgSchInit.lmPst;
950    cfmPst.selector = rgSchCb[inst].genCfg.bndCfmResp[suId].response.selector;
951    cfmPst.prior = rgSchCb[inst].genCfg.bndCfmResp[suId].response.prior;
952    cfmPst.route = rgSchCb[inst].genCfg.bndCfmResp[suId].response.route;
953    cfmPst.region = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.region;
954    cfmPst.pool = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.pool;
955    
956    memset(&cntrlCfm, 0, sizeof(RgMngmt));
957
958    switch(status)
959    {
960       case CM_BND_OK: /* status is OK */
961          /* Change SAP state to Bound */
962          rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_BND;
963          if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE)
964          {
965             ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]);
966          }
967          /* Send Control Confirm with status as OK to Layer Manager */
968          cntrlCfm.cfm.status = LCM_PRIM_OK;
969          cntrlCfm.cfm.reason = LCM_REASON_NOT_APPL;
970         /* Sending Status Indication to Layer Manager */
971          rgSCHLmmStaInd((uint8_t)(rgSchCb[inst].tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
972                LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_OK,
973                LCM_CAUSE_LYR_SPECIFIC, (RgUstaDgn *)NULLP);
974          break;
975
976       default:
977          /* Change SAP state to UnBound */
978          rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_UNBND;
979          if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE)
980          {
981             ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]);
982          }
983          /* Send Control Confirm with status as NOK to Layer Manager */
984          cntrlCfm.cfm.status = LCM_PRIM_NOK;
985          cntrlCfm.cfm.reason = LCM_REASON_NEG_CFM;
986          break;
987    }
988    rgSchCb[inst].tfuSap[suId].numBndRetries = 0;
989    cntrlCfm.hdr.elmId.elmnt = STTFUSAP;
990    cntrlCfm.hdr.transId = rgSchCb[inst].genCfg.bndCfmResp[suId].transId;
991
992    ret = RgMiLrgSchCntrlCfm(&cfmPst, &cntrlCfm);
993
994    return (ret);
995 }
996
997 /**
998  * @brief Layer Manager Unsolicited Status Indication generation. 
999  *
1000  * @details
1001  *
1002  *     Function : rgSCHLmmStaInd 
1003  *     
1004  *     This API is used by the other modules of MAC to send a unsolicited
1005  *     status indication to the Layer Manager.
1006  *     
1007  *  @param[in]  uint16_t category, the Alarm category
1008  *  @param[in]  uint16_t event, the Alarm event
1009  *  @param[in]  uint16_t cause, the cause of the Alarm
1010  *  @param[in]  RgUstaDgn *dgn, Alarm Diagonostics
1011  *  @return  S16
1012  *      -# ROK
1013  **/
1014 S16 rgSCHLmmStaInd
1015 (
1016 Inst inst,
1017 uint16_t  category,
1018 uint16_t  event,
1019 uint16_t  cause,
1020 RgUstaDgn *dgn
1021 )
1022 {
1023    RgMngmt    usta;
1024
1025    if(rgSchCb[inst].rgSchInit.usta == FALSE)
1026    {
1027       return ROK;
1028    }
1029    memset(&usta, 0, sizeof(RgMngmt));
1030
1031    SGetDateTime(&usta.t.usta.cmAlarm.dt);
1032    usta.t.usta.cmAlarm.category = category;
1033    usta.t.usta.cmAlarm.event = event;
1034    usta.t.usta.cmAlarm.cause = cause;
1035    if (dgn != NULLP)
1036    {
1037       memcpy(&usta.t.usta.dgn, dgn, sizeof(RgUstaDgn));
1038    }
1039
1040    rgSchCb[inst].rgSchInit.lmPst.selector = 
1041                        rgSchCb[inst].genCfg.ustaResp.response.selector;
1042    rgSchCb[inst].rgSchInit.lmPst.prior = 
1043                        rgSchCb[inst].genCfg.ustaResp.response.prior;
1044    rgSchCb[inst].rgSchInit.lmPst.route = 
1045                        rgSchCb[inst].genCfg.ustaResp.response.route;
1046    rgSchCb[inst].rgSchInit.lmPst.region = 
1047                        rgSchCb[inst].genCfg.ustaResp.response.mem.region;
1048    rgSchCb[inst].rgSchInit.lmPst.pool = 
1049                        rgSchCb[inst].genCfg.ustaResp.response.mem.pool;
1050    usta.hdr.transId = rgSchCb[inst].genCfg.ustaResp.transId;
1051
1052    return (RgMiLrgSchStaInd(&rgSchCb[inst].rgSchInit.lmPst, &usta));
1053 }
1054
1055 \f
1056 /**********************************************************************
1057  
1058          End of file
1059 **********************************************************************/