Merge "Fixes for SSB transmission in Radio mode integration [Issue-ID: ODUHIGH-267]"
[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
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    SPutSBuf(rgSchCb[inst].rgSchInit.region,
361                 rgSchCb[inst].rgSchInit.pool,
362                 (Data *)rgSchCb[inst].rgrSap,
363                 (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps));
364    rgSchCb[inst].rgrSap = NULLP;
365    /* Deallocate RGM saps */
366    SPutSBuf(rgSchCb[inst].rgSchInit.region,
367                 rgSchCb[inst].rgSchInit.pool,
368                 (Data *)rgSchCb[inst].rgmSap,
369                 (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps));
370    rgSchCb[inst].rgmSap = NULLP;
371
372    /* Deallocate TFU saps */
373    SPutSBuf(rgSchCb[inst].rgSchInit.region,
374                 rgSchCb[inst].rgSchInit.pool,
375                 (Data *)rgSchCb[inst].tfuSap,
376                 (sizeof(RgSchLowSapCb) * rgSchCb[inst].numSaps));
377    rgSchCb[inst].tfuSap = NULLP;
378
379    /* Deallocate bndCfmResponses */
380    SPutSBuf(rgSchCb[inst].rgSchInit.region,
381                 rgSchCb[inst].rgSchInit.pool,
382                 (Data *)rgSchCb[inst].genCfg.bndCfmResp,
383                 (sizeof(RgSchLmResponse) * rgSchCb[inst].numSaps));
384    rgSchCb[inst].genCfg.bndCfmResp = NULLP;
385    /* De-register the Timer Service */
386    (Void) SDeregTmrMt(rgSchCb[inst].rgSchInit.ent, dInst,
387                      (S16)rgSchCb[inst].genCfg.tmrRes, schActvTmr); 
388
389    /* call back the task initialization function to intialize
390     * the global rgSchCb[inst] Struct */
391    schActvInit(rgSchCb[inst].rgSchInit.ent, dInst, rgSchCb[inst].rgSchInit.region, 
392               rgSchCb[inst].rgSchInit.reason);
393    
394    /* Set Config done in TskInit */
395    rgSchCb[inst].rgSchInit.cfgDone = FALSE;
396
397    return;
398 }
399
400 \f
401 /***********************************************************
402  *
403  *     Func : rgSCHLmmGenCntrl 
404  *        
405  *
406  *     Desc : Processes the LM control request for STGEN elmnt.
407  *            
408  *
409  *     Ret  : Void
410  *
411  *     Notes: 
412  *
413  *     File : rg_sch_lmm.c 
414  *
415  **********************************************************/
416 Void rgSCHLmmGenCntrl(RgMngmt *cntrl,RgMngmt *cfm,Pst  *cfmPst)
417 {
418    Inst      inst = (cfmPst->srcInst - SCH_INST_START); /* Scheduler instance ID */
419
420    cfm->cfm.status = LCM_PRIM_OK;
421    cfm->cfm.reason = LCM_REASON_NOT_APPL;
422    
423
424    switch(cntrl->t.cntrl.action)
425    {
426       case AENA:
427          /* Action is Enable */
428          switch(cntrl->t.cntrl.subAction)
429          {
430             case SAUSTA:   
431             /* Enable Unsolicited Status (alarms) */
432                rgSchCb[inst].rgSchInit.usta = TRUE;
433                /*Store the response and TransId for sending the Alarms */
434                memcpy(&rgSchCb[inst].genCfg.ustaResp.response, 
435                &cntrl->hdr.response, sizeof(Resp));
436                rgSchCb[inst].genCfg.ustaResp.transId = cntrl->hdr.transId;
437                break;
438             case SADBG:
439             /* Enable Debug Printing */
440 #ifdef DEBUGP
441                rgSchCb[inst].rgSchInit.dbgMask |= cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
442 #endif
443                break;
444 #ifdef PHY_ERROR_LOGING
445             case SAELMNT:
446                {
447                   rgSchUlAllocCntr.mcs = cntrl->t.cntrl.s.rgSchUlAllocCntrl.mcs;
448                   rgSchUlAllocCntr.numOfRb = cntrl->t.cntrl.s.rgSchUlAllocCntrl.numOfRb;
449                   rgSchUlAllocCntr.rbStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.rbStart;
450                   rgSchUlAllocCntr.testStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.testStart;
451                   rgSchUlAllocCntr.enaLog = cntrl->t.cntrl.s.rgSchUlAllocCntrl.enaLog;
452                   rgSchUlAllocCntr.logTime = cntrl->t.cntrl.s.rgSchUlAllocCntrl.logTime;
453                   rgSchUlAllocCntr.crcOk = 0;
454                   rgSchUlAllocCntr.crcErr = 0;
455                   rgSchUlAllocCntr.numUlPackets = 0;
456                   rgSchUlAllocCntr.numPrach = 0;
457                   rgSchUlAllocCntr.taZero = 0;
458 #ifdef MAC_SCH_STATS
459                   /* Reset
460                    * L2
461                    * statistics
462                    * */
463                   memset(&hqRetxStats, 0, sizeof(RgSchHqRetxStats));
464                   memset(&hqFailStats, 0, sizeof(RgSchNackAckStats));
465 #endif
466                   break;
467                }
468 #endif
469             default:
470                cfm->cfm.status = LCM_PRIM_NOK;
471                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
472                DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl(): "
473                   "invalid subaction=%d", cntrl->t.cntrl.subAction);
474                break;
475          }
476          break;
477       case ADISIMM:
478          /* Action is Diable immidiately */
479          switch(cntrl->t.cntrl.subAction)
480          {
481             case SAUSTA:
482             /* Disable Unsolicited Status (alarms) */
483                rgSchCb[inst].rgSchInit.usta = FALSE;
484                break;
485             case SADBG:
486             /* Disable Debug Printing */
487 #ifdef DEBUGP
488                rgSchCb[inst].rgSchInit.dbgMask &=\
489                           ~cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
490 #endif
491                break;
492
493             default:
494                cfm->cfm.status = LCM_PRIM_NOK;
495                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
496                DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl():"
497                  " invalid subaction=%d", cntrl->t.cntrl.subAction);
498                break;
499          }
500          break;
501       case ASHUTDOWN:
502          /* Free all the memory dynamically allocated by MAC */
503          rgSCHLmmShutdown(inst);
504          break;
505       default:
506          cfm->cfm.status = LCM_PRIM_NOK;
507          cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
508          DU_LOG("\nERROR  -->  SCH : rgSCHLmmGenCntrl(): invalid"
509           " action=%d", cntrl->t.cntrl.action);
510          break;
511    }
512    RgMiLrgSchCntrlCfm(cfmPst, cfm);
513    return;
514 }
515
516 \f
517 /***********************************************************
518  *
519  *     Func : rgSCHLmmSapCntrl 
520  *        
521  *
522  *     Desc : Processes the LM control request for STxxxSAP elmnt.
523  *            
524  *
525  *     Ret  : Void
526  *
527  *     Notes: 
528  *
529  *     File : rg_sch_lmm.c 
530  *
531  **********************************************************/
532 Void rgSCHLmmSapCntrl 
533 (
534 RgMngmt       *cntrl,
535 RgMngmt       *cfm,
536 Pst           *cfmPst
537 )
538 {
539    uint8_t       idx;
540
541    /* TODO Pass InstId instead of using InstId from cfmPst */
542    Inst      inst = (cfmPst->srcInst - SCH_INST_START); /* Scheduler instance Id */
543
544    /* Only TFU SAP can be controlled by LM */
545    switch(cntrl->hdr.elmId.elmnt)
546    {
547       case STTFUSAP:
548          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.suId;
549          if (idx > LRG_MAX_SAPS_PER_INST)
550          {
551             cfm->cfm.status = LCM_PRIM_NOK;
552             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
553          }
554          switch(cntrl->t.cntrl.action)
555          {
556             case ABND:
557                /* Bind Enable Request */
558                if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) ||
559                    (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND))
560                {
561                   cfm->cfm.status = LCM_PRIM_NOK;
562                   cfm->cfm.reason = LCM_REASON_INVALID_SAP;
563                }
564                else
565                {
566                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
567                   {
568                      rgSCHLmmStartTmr(inst, RGSCH_BNDREQ_TMR,
569                                   rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.val, 
570                                   (PTR)&rgSchCb[inst].tfuSap[idx]);
571                   }
572                   /* Change SAP state */
573                   rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_WAIT_BNDCFM;
574                   rgSchCb[inst].tfuSap[idx].numBndRetries++;
575                   /* Store the response and TransId for sending 
576                    * the Control confirm */
577                   memcpy(&rgSchCb[inst].genCfg.bndCfmResp[idx].response,
578                            &cntrl->hdr.response, sizeof(Resp));
579                   rgSchCb[inst].genCfg.bndCfmResp[idx].transId = 
580                                                 cntrl->hdr.transId;
581                   
582                   cfm->cfm.status = LCM_PRIM_OK_NDONE;
583                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
584
585                   /* Sending Control Confirm before sending Bind
586                    * Request to TFU  */
587                   RgMiLrgSchCntrlCfm(cfmPst, cfm);
588                   
589                   //rgSCHUtlTfuBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg.suId, 
590                     //             rgSchCb[inst].tfuSap[idx].sapCfg.spId);
591                  return; 
592                }
593                break;
594             case AUBND:
595             /* Unbind request */
596
597                /* Check if the SAP is configured */
598                if( (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) ||
599                      (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_UNBND))
600                {
601                   cfm->cfm.status = LCM_PRIM_NOK;
602                   cfm->cfm.reason = LCM_REASON_INVALID_MSGTYPE;
603                }
604                else
605                {
606                   //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg,
607                     //              TFU_UBNDREQ_MNGMT);
608                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
609                   {
610                      rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, 
611                                        (PTR)&rgSchCb[inst].tfuSap[idx]);
612                   }
613                   /* Change SAP state */
614                   rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND;
615                   cfm->cfm.status = LCM_PRIM_OK;
616                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
617                }
618                break;
619             case ADEL:
620                /* Delete SAP, does initialization of SAP */
621                if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_WAIT_BNDCFM) ||
622                    (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND))
623                {
624                   //rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg,
625                     //              TFU_UBNDREQ_MNGMT);
626                   if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE)
627                   {
628                      rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR,
629                                      (PTR)&rgSchCb[inst].tfuSap[idx]);
630                   }
631                }
632                memset(&rgSchCb[inst].tfuSap[idx], 0, sizeof(RgSchLowSapCb));
633                rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_NOT_CFG;
634                cfm->cfm.status = LCM_PRIM_OK;
635                cfm->cfm.reason = LCM_REASON_NOT_APPL;
636                break;
637             default:
638                cfm->cfm.status = LCM_PRIM_NOK;
639                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
640                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
641                   "invalid action=%d", cntrl->t.cntrl.action);
642                break;
643          }
644          break;
645       case STRGRSAP:
646          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.spId;
647          if (idx > LRG_MAX_SAPS_PER_INST)
648          {
649             cfm->cfm.status = LCM_PRIM_NOK;
650             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
651          }
652          switch(cntrl->t.cntrl.action)
653          {
654             case ADEL:
655                memset(&rgSchCb[inst].rgrSap[idx], 0, sizeof(RgSchUpSapCb));
656                rgSchCb[inst].rgrSap[idx].sapSta.sapState = LRG_NOT_CFG;
657                cfm->cfm.status = LCM_PRIM_OK;
658                cfm->cfm.reason = LCM_REASON_NOT_APPL;
659                break;
660             default:
661                cfm->cfm.status = LCM_PRIM_NOK;
662                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
663                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
664                      "invalid action=%d", cntrl->t.cntrl.action);
665                break;
666          }
667          break;
668       case STRGMSAP:
669          idx = (uint8_t)cntrl->t.cntrl.s.rgSapCntrl.spId;
670          if (idx > LRG_MAX_SAPS_PER_INST)
671          {
672             cfm->cfm.status = LCM_PRIM_NOK;
673             cfm->cfm.reason = LCM_REASON_INVALID_SAP;
674          }
675          switch(cntrl->t.cntrl.action)
676          {
677             case ADEL:
678                memset(&rgSchCb[inst].rgmSap[idx], 0, sizeof(RgSchUpSapCb));
679                rgSchCb[inst].rgmSap[idx].sapSta.sapState = LRG_NOT_CFG;
680                cfm->cfm.status = LCM_PRIM_OK;
681                cfm->cfm.reason = LCM_REASON_NOT_APPL;
682                break;
683             default:
684                cfm->cfm.status = LCM_PRIM_NOK;
685                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
686                DU_LOG("\nERROR  -->  SCH : rgSCHLmmSapCntrl(): "
687                      "invalid action=%d", cntrl->t.cntrl.action);
688                break;
689          }
690          break;
691
692        default:
693          /* Would never come here. */
694          return;
695    }
696    RgMiLrgSchCntrlCfm(cfmPst, cfm);
697    return;
698 }
699
700 \f
701 /***********************************************************
702  *
703  *     Func : SchFillCfmPst 
704  *        
705  *
706  *     Desc : Fills the Confirmation Post Structure cfmPst using the reqPst 
707  *            and the cfm->hdr.response.
708  *            
709  *
710  *     Ret  : Void
711  *
712  *     Notes: 
713  *
714  *     File : rg_sch_lmm.c 
715  *
716  **********************************************************/
717 Void SchFillCfmPst
718 (
719 Pst           *reqPst,
720 Pst           *cfmPst,
721 RgMngmt       *cfm
722 )
723 {
724    Inst inst;
725
726    inst = (reqPst->dstInst - SCH_INST_START);
727
728    cfmPst->srcEnt    = ENTMAC;
729    cfmPst->srcInst   = (Inst) 1;
730    cfmPst->srcProcId = rgSchCb[inst].rgSchInit.procId;
731    cfmPst->dstEnt    = ENTMAC;
732    cfmPst->dstInst   = (Inst) 0;
733    cfmPst->dstProcId = reqPst->srcProcId;
734
735    cfmPst->selector  = cfm->hdr.response.selector;
736    cfmPst->region    = cfm->hdr.response.mem.region;
737    cfmPst->pool      = cfm->hdr.response.mem.pool;
738
739    return;
740 }
741
742 \f
743 /**
744  * @brief Timer start handler. 
745  *
746  * @details
747  *
748  *     Function : rgSCHLmmStartTmr
749  *     
750  *     This function based on the input parameters starts the timer for 
751  *     "tmrVal" duration. As of now scheduler instance uses the timer 
752  *     functionality for BndReq only. Hence there is no conditional
753  *     code based on "tmrEvnt".
754  *     
755  *  @param[in]  S16   tmrEvnt, the Timer Event    
756  *  @param[in]  uint32_t   tmrVal,  the Wait Time
757  *  @param[in]  PTR   cb,  Entry for which Timer expired
758  *  @return  S16
759  *      -# ROK
760  **/
761 S16 rgSCHLmmStartTmr
762 (
763 Inst       inst,
764 S16        tmrEvnt,            /* Timer Event */
765 uint32_t   tmrVal,             /* Wait Time */
766 PTR        cb                  /* Entry for which Timer Expired */
767 )
768 {
769    CmTmrArg    arg;
770 /*   Inst        dInst = inst + SCH_INST_START; */
771
772    UNUSED(tmrEvnt);
773
774    /* Initialize the arg structure */
775    memset(&arg, 0, sizeof(CmTmrArg));
776
777    arg.tqCp = &rgSchCb[inst].tmrTqCp;
778    arg.tq = rgSchCb[inst].tmrTq;
779    arg.timers = &((RgSchLowSapCb *)cb)->tmrBlk;
780    arg.cb = cb;
781    arg.tNum = 0;
782    arg.max = RGSCH_MAX_TIMER;
783    arg.evnt = RGSCH_BNDREQ_TMR;
784    arg.wait = tmrVal;      
785    cmPlcCbTq(&arg);
786
787    return ROK;
788 }
789
790 \f
791 /**
792  * @brief Timer stop handler. 
793  *
794  * @details
795  *
796  *     Function : rgSCHLmmStopTmr
797  *     
798  *     This function based on the input parameters stops the timer for 
799  *     "tmrEvnt". As of now Scheduler instance uses the timer functionality for
800  *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
801  *     Once the bind happens and this timer is stopped, the timer functionality
802  *     is deregistered with SSI. As there is no further use of timer processing.
803  *     
804  *  @param[in]  S16   tmrEvnt, the Timer Event    
805  *  @param[in]  PTR   cb,  Entry for which Timer expired
806  *  @return  S16
807  *      -# ROK
808  *      -# RFAILED
809  **/
810 S16 rgSCHLmmStopTmr
811 (
812 Inst inst,             /* Scheduler instance */
813 S16  tmrEvnt,            /* Timer Event */
814 PTR  cb                  /* Entry for which Timer Expired */
815 )
816 {
817    CmTmrArg   arg;
818    uint8_t    i;
819    S16        ret; 
820
821    ret = RFAILED;
822
823    for(i=0;i<RGSCH_MAX_TIMER;i++)
824    {
825       /* Search for the Timer Blocks */
826       if(((RgSchLowSapCb *)cb)->tmrBlk.tmrEvnt == tmrEvnt)
827       {
828          /* Initialize the arg structure */
829          memset(&arg, 0, sizeof(CmTmrArg));
830
831          arg.tqCp = &rgSchCb[inst].tmrTqCp;
832          arg.tq = rgSchCb[inst].tmrTq;
833          arg.timers = &(((RgSchLowSapCb *)cb)->tmrBlk);
834          arg.cb = cb;
835          arg.max = RGSCH_MAX_TIMER;
836          arg.evnt = tmrEvnt;
837
838          arg.tNum = i;   
839          cmRmvCbTq(&arg);
840          ret = ROK;
841          break;
842       }
843
844    }
845
846
847    return (ret);
848 }
849
850 \f
851 /**
852  * @brief Timer Expiry handler. 
853  *
854  * @details
855  *
856  *     Function : rgSCHLmmTmrExpiry
857  *     
858  *     This is a callback function used as an input parameter to cmPrcTmr()
859  *     to check expiry of any timer. In this function, we are only concerned
860  *     about tmrEvnt=Bind timer.
861  *     
862  *  @param[in]  PTR   cb,  Entry for which Timer expired
863  *  @param[in]  S16   tmrEvnt, the Timer Event    
864  *  @return  S16
865  *      -# ROK
866  **/
867 S16 rgSCHLmmTmrExpiry
868 (
869 PTR cb,               /* Pointer to timer control block */
870 S16 tmrEvnt           /* Timer Event */
871 )
872 {
873    S16           ret = ROK;
874    RgSchLowSapCb *tfuSap = (RgSchLowSapCb *)cb;
875
876    
877    switch(tmrEvnt)
878    {
879       case RGSCH_BNDREQ_TMR:
880          tfuSap->numBndRetries++;
881          if(tfuSap->numBndRetries > RGSCH_MAX_BNDRETRY)
882          {
883             rgSCHLmmStaInd((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
884                            (uint16_t)LCM_CATEGORY_INTERFACE, (uint16_t)LCM_EVENT_BND_FAIL,
885                            (uint16_t)LCM_CAUSE_TMR_EXPIRED, (RgUstaDgn *)NULLP);
886          }
887          else
888          {
889             /* Restart the bind timer */
890             if (tfuSap->sapCfg.bndTmr.enb == TRUE)
891             {
892                ret = rgSCHLmmStartTmr((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
893                                   RGSCH_BNDREQ_TMR, 
894                                  (uint32_t)tfuSap->sapCfg.bndTmr.val, cb);
895             }
896
897             /* Send bind request */
898             //rgSCHUtlTfuBndReq((uint8_t)(tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START), 
899             //tfuSap->sapCfg.suId, tfuSap->sapCfg.spId);
900          }
901          break;
902       default:
903          DU_LOG("\nERROR  -->  SCH : rgSCHLmmTmrExpiry(): Invalid"
904                  " tmrEvnt=%d", tmrEvnt);
905          ret = RFAILED;
906          break;
907    }
908    return (ret);
909 }
910
911 \f
912 /**
913  * @brief Layer Manager Control Confirm generation handler
914  *        for Bind Confirm reception at TFU interface.
915  *        RgLiTfuBndCfm() forwards the confirmation to this 
916  *        function. All SAP state related handling is restricted
917  *        to LMM modules, hence the cfm forwarding.
918  *
919  * @details
920  *
921  *     Function : rgSCHLmmBndCfm 
922  *     
923  *     This API is used by the LIM module of MAC to forward
924  *     the Bind Confirm it receives over the TFU interface.
925  *     
926  *  @param[in]   Pst *pst, Post Structure
927  *  @param[in]   SuId suId, Service user ID
928  *  @param[in]   uint8_t status, Status
929  *  @return  S16
930  *      -# ROK
931  **/
932 S16 rgSCHLmmBndCfm
933 (
934 Pst *pst,               /* Post Structure */
935 SuId suId,              /* Service user ID */
936 uint8_t status               /* Status */
937 )
938 {
939    S16       ret = ROK;
940    RgMngmt   cntrlCfm;
941    Pst       cfmPst;
942    Inst      inst = (pst->dstInst - SCH_INST_START); /* scheduler instance */
943
944
945    /* check the SAP State */
946    switch(rgSchCb[inst].tfuSap[suId].sapSta.sapState)
947    {
948       case LRG_WAIT_BNDCFM:
949          break;
950       case LRG_BND:
951          /* SAP is already bound */
952          return ROK;
953       default:
954          return RFAILED;
955    }
956
957    cfmPst = rgSchCb[inst].rgSchInit.lmPst;
958    cfmPst.selector = rgSchCb[inst].genCfg.bndCfmResp[suId].response.selector;
959    cfmPst.prior = rgSchCb[inst].genCfg.bndCfmResp[suId].response.prior;
960    cfmPst.route = rgSchCb[inst].genCfg.bndCfmResp[suId].response.route;
961    cfmPst.region = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.region;
962    cfmPst.pool = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.pool;
963    
964    memset(&cntrlCfm, 0, sizeof(RgMngmt));
965
966    switch(status)
967    {
968       case CM_BND_OK: /* status is OK */
969          /* Change SAP state to Bound */
970          rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_BND;
971          if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE)
972          {
973             ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]);
974          }
975          /* Send Control Confirm with status as OK to Layer Manager */
976          cntrlCfm.cfm.status = LCM_PRIM_OK;
977          cntrlCfm.cfm.reason = LCM_REASON_NOT_APPL;
978         /* Sending Status Indication to Layer Manager */
979          rgSCHLmmStaInd((uint8_t)(rgSchCb[inst].tfuSap->sapCfg.sapPst.srcInst - SCH_INST_START),
980                LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_OK,
981                LCM_CAUSE_LYR_SPECIFIC, (RgUstaDgn *)NULLP);
982          break;
983
984       default:
985          /* Change SAP state to UnBound */
986          rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_UNBND;
987          if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE)
988          {
989             ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]);
990          }
991          /* Send Control Confirm with status as NOK to Layer Manager */
992          cntrlCfm.cfm.status = LCM_PRIM_NOK;
993          cntrlCfm.cfm.reason = LCM_REASON_NEG_CFM;
994          break;
995    }
996    rgSchCb[inst].tfuSap[suId].numBndRetries = 0;
997    cntrlCfm.hdr.elmId.elmnt = STTFUSAP;
998    cntrlCfm.hdr.transId = rgSchCb[inst].genCfg.bndCfmResp[suId].transId;
999
1000    ret = RgMiLrgSchCntrlCfm(&cfmPst, &cntrlCfm);
1001
1002    return (ret);
1003 }
1004
1005 /**
1006  * @brief Layer Manager Unsolicited Status Indication generation. 
1007  *
1008  * @details
1009  *
1010  *     Function : rgSCHLmmStaInd 
1011  *     
1012  *     This API is used by the other modules of MAC to send a unsolicited
1013  *     status indication to the Layer Manager.
1014  *     
1015  *  @param[in]  uint16_t category, the Alarm category
1016  *  @param[in]  uint16_t event, the Alarm event
1017  *  @param[in]  uint16_t cause, the cause of the Alarm
1018  *  @param[in]  RgUstaDgn *dgn, Alarm Diagonostics
1019  *  @return  S16
1020  *      -# ROK
1021  **/
1022 S16 rgSCHLmmStaInd
1023 (
1024 Inst inst,
1025 uint16_t  category,
1026 uint16_t  event,
1027 uint16_t  cause,
1028 RgUstaDgn *dgn
1029 )
1030 {
1031    RgMngmt    usta;
1032
1033    if(rgSchCb[inst].rgSchInit.usta == FALSE)
1034    {
1035       return ROK;
1036    }
1037    memset(&usta, 0, sizeof(RgMngmt));
1038
1039    SGetDateTime(&usta.t.usta.cmAlarm.dt);
1040    usta.t.usta.cmAlarm.category = category;
1041    usta.t.usta.cmAlarm.event = event;
1042    usta.t.usta.cmAlarm.cause = cause;
1043    if (dgn != NULLP)
1044    {
1045       memcpy(&usta.t.usta.dgn, dgn, sizeof(RgUstaDgn));
1046    }
1047
1048    rgSchCb[inst].rgSchInit.lmPst.selector = 
1049                        rgSchCb[inst].genCfg.ustaResp.response.selector;
1050    rgSchCb[inst].rgSchInit.lmPst.prior = 
1051                        rgSchCb[inst].genCfg.ustaResp.response.prior;
1052    rgSchCb[inst].rgSchInit.lmPst.route = 
1053                        rgSchCb[inst].genCfg.ustaResp.response.route;
1054    rgSchCb[inst].rgSchInit.lmPst.region = 
1055                        rgSchCb[inst].genCfg.ustaResp.response.mem.region;
1056    rgSchCb[inst].rgSchInit.lmPst.pool = 
1057                        rgSchCb[inst].genCfg.ustaResp.response.mem.pool;
1058    usta.hdr.transId = rgSchCb[inst].genCfg.ustaResp.transId;
1059
1060    return (RgMiLrgSchStaInd(&rgSchCb[inst].rgSchInit.lmPst, &usta));
1061 }
1062
1063 \f
1064 /**********************************************************************
1065  
1066          End of file
1067 **********************************************************************/