Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_cfg.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_cfg.c
28  
29 **********************************************************************/
30
31 /** @file rg_cfg.c
32 @brief This module handles the configuration of MAC by RRC and RRM.
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=180;
37 static int RLOG_MODULE_ID=4096;
38
39 /* header include files -- defines (.h) */
40 #include "envopt.h"        /* environment options */
41 #include "envdep.h"        /* environment dependent */
42 #include "envind.h"        /* environment independent */
43 #include "gen.h"           /* general layer */
44 #include "ssi.h"           /* system service interface */
45 #include "cm_hash.h"       /* common hash list */
46 #include "cm_mblk.h"       /* common memory link list library */
47 #include "cm_llist.h"      /* common linked list library */
48 #include "cm_err.h"        /* common error */
49 #include "cm_lte.h"        /* common LTE */
50 #include "lrg.h"           /* Layer manager interface includes*/
51 #include "crg.h"           /* CRG interface includes*/
52 #include "rgu.h"           /* RGU interface includes*/
53 #include "tfu.h"           /* TFU interface includes */
54 #include "rg_sch_inf.h"    /* SCH interface includes */
55 #include "rg_prg.h"       /* PRG (MAC-MAC) interface includes*/
56 #include "rg_env.h"       /* MAC environmental includes*/
57 #include "rg.h"           /* MAC includes*/
58 #include "rg_err.h"       /* MAC error includes*/
59
60 /* header/extern include files (.x) */
61 #include "gen.x"           /* general layer typedefs */
62 #include "ssi.x"           /* system services typedefs */
63 #include "cm5.x"           /* common timers */
64 #include "cm_hash.x"       /* common hash list */
65 #include "cm_lib.x"        /* common library */
66 #include "cm_llist.x"      /* common linked list */
67 #include "cm_mblk.x"       /* memory management */
68 #include "cm_tkns.x"       /* common tokens */
69 #include "cm_lte.x"       /* common tokens */
70 #include "rgu.x"           /* RGU types */
71 #include "tfu.x"           /* RGU types */
72 #include "lrg.x"           /* layer management typedefs for MAC */
73 #include "crg.x"           /* CRG interface includes */
74 #include "rg_sch_inf.x"    /* SCH interface typedefs */
75 #include "rg_prg.x"        /* PRG (MAC-MAC) Interface typedefs */
76 #include "rg.x"            /* typedefs for MAC */
77 #ifdef LTE_ADV
78 #include "rg_pom_scell.x"
79 #endif
80 /* LTE-MAC Control Block Structure */
81 PUBLIC RgCb rgCb[RG_MAX_INST];
82
83 /* local defines */
84 PRIVATE S16 rgCFGVldtCrgDedLcCfg ARGS((Inst inst,CrgLchCfg *lcCfg, RgCellCb **cell,
85          RgUeCb **ue, RgErrInfo *errInfo));
86 PRIVATE S16 rgCFGVldtCrgCmnLcCfg ARGS((Inst inst,CrgLchCfg *lcCfg, RgCellCb **cell,
87          RgErrInfo *errInfo));
88 PRIVATE S16 rgCFGCrgDedLcCfg ARGS((RgCellCb *cell, RgUeCb *ue,
89          CrgLchCfg *lcCfg, RgErrInfo *errInfo));
90 PRIVATE S16 rgCFGCrgCmnLcCfg ARGS((Inst inst,RgCellCb *cell, CrgLchCfg *lcCfg,
91          RgErrInfo *errInfo));
92
93 PRIVATE Void rgCFGFreeCmnLcLst ARGS((RgCellCb *cell));
94 PRIVATE Void rgCFGFreeUeLst ARGS((RgCellCb *cell));
95 /* Added support for SPS*/
96 #ifdef LTEMAC_SPS
97 PRIVATE Void rgCFGFreeSpsUeLst ARGS((RgCellCb *cell));
98 #endif /* LTEMAC_SPS */
99
100
101 /* local typedefs */
102  
103 /* local externs */
104  
105 /* forward references */
106
107
108
109
110 /**
111  * @brief Validates the cell configuration request from RRC to MAC.
112  *
113  * @details
114  *
115  *     Function : rgCFGVldtCrgCellCfg
116  *
117  *     Processing Steps:
118  *      - Validate the cell configuration request from RRC to MAC at CFG:
119  *        validate the value range for the configured values.
120  *      - If validated successfully,
121  *        - Return ROK.
122  *      - Else 
123  *        - Return RFAILED.
124  *
125  *  @param[in]  Inst        inst
126  *  @param[in]  CrgCellCfg  *cellCfg
127  *  @param[out] RgErrInfo   *errInfo
128  *  @return  S16
129  *      -# ROK
130  *      -# RFAILED
131  **/
132 #ifdef ANSI
133 PUBLIC S16 rgCFGVldtCrgCellCfg
134 (
135 Inst        inst,
136 CrgCellCfg  *cellCfg,
137 RgErrInfo   *errInfo
138 )
139 #else
140 PUBLIC S16 rgCFGVldtCrgCellCfg(inst,cellCfg, errInfo)
141 Inst        inst;
142 CrgCellCfg  *cellCfg;
143 RgErrInfo   *errInfo;
144 #endif
145 {
146    TRC2(rgCFGVldtCrgCellCfg);
147
148    errInfo->errCause = RGERR_CFG_INVALID_CRG_CELL_CFG;
149    if ((rgCb[inst].cell != NULLP)
150          || rgCb[inst].inactiveCell != NULLP)
151    {
152       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Cell already exists");
153       RETVALUE(RFAILED);
154    }
155    if ((cellCfg->bwCfg.dlTotalBw < RG_MIN_DL_BW
156             || cellCfg->bwCfg.dlTotalBw > RG_MAX_DL_BW)
157          || (cellCfg->bwCfg.ulTotalBw < RG_MIN_UL_BW
158             || cellCfg->bwCfg.ulTotalBw > RG_MAX_UL_BW))
159    {
160       RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, 
161             "Invalid Bandwidth configuration: ul %d dl %d",
162             cellCfg->bwCfg.ulTotalBw, cellCfg->bwCfg.dlTotalBw);
163       RETVALUE(RFAILED);
164    }
165    if (cellCfg->rachCfg.maxMsg3Tx < RG_MIN_HQ_TX)
166    {
167       RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId,
168                 "Invalid RACH configuration: maxMsg3Tx %d",cellCfg->rachCfg.maxMsg3Tx);
169       RETVALUE(RFAILED);
170    }
171 #ifdef TENB_MULT_CELL_SUPPRT
172    if((cellCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
173       (cellCfg->rguUlSapId > rgCb[inst].numRguSaps))
174    {
175       RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for CellId %d failed\n",
176                cellCfg->rguDlSapId,
177                cellCfg->rguUlSapId,
178                cellCfg->cellId));
179       RETVALUE(RFAILED);
180    }
181 #endif
182    errInfo->errCause = RGERR_NONE;
183    RETVALUE(ROK);
184 }  /* rgCFGVldtCrgCellCfg */
185
186
187 /**
188  * @brief Validates the UE configuration request from RRC to MAC.
189  *
190  * @details
191  *
192  *     Function : rgCFGVldtCrgUeCfg
193  *
194  *     Processing Steps:
195  *      - Validate the UE configuration request from RRC to MAC at CFG:
196  *        validate the value range for the configured values.
197  *      - If validated successfully,
198  *        - Return ROK and pointer to the cell of UE.
199  *      - Else 
200  *        - Return RFAILED.
201  *
202  *  @param[in]  Inst        inst
203  *  @param[in]  CrgUeCfg  *ueCfg
204  *  @param[out] RgCellCb  **cell
205  *  @param[out] RgErrInfo *errInfo
206  *  @return  S16
207  *      -# ROK
208  *      -# RFAILED
209  **/
210 #ifdef ANSI
211 PUBLIC S16 rgCFGVldtCrgUeCfg
212 (
213 Inst      inst,
214 CrgUeCfg  *ueCfg,
215 RgCellCb  **cell,
216 RgErrInfo *errInfo
217 )
218 #else
219 PUBLIC S16 rgCFGVldtCrgUeCfg(inst,ueCfg, cell, errInfo)
220 Inst      inst;
221 CrgUeCfg  *ueCfg;
222 RgCellCb  **cell;
223 RgErrInfo *errInfo;
224 #endif
225 {
226    TRC2(rgCFGVldtCrgUeCfg);
227
228    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_CFG;
229    if ((ueCfg->txMode.pres == PRSNT_NODEF) && 
230        (ueCfg->txMode.tm == CRG_UE_TM_5))
231    {
232       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Transmission Mode=%d not supported",
233             ueCfg->txMode.tm);
234       RETVALUE(RFAILED);
235    }
236    
237    /* Fetch the Active cell */
238    if(((*cell = rgCb[inst].cell) == NULLP) ||
239        ((*cell)->cellId != ueCfg->cellId))
240    {
241       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Active Cell does not exist for cellId%d",
242             ueCfg->cellId);
243       RETVALUE(RFAILED);
244    }
245    /* Check if Ue already configured */
246    if (rgDBMGetUeCb(*cell, ueCfg->crnti) != NULLP)
247    {
248       RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Ue already exists");
249       RETVALUE(RFAILED);
250    }
251
252    if (ueCfg->ueUlHqCfg.maxUlHqTx < RG_MIN_HQ_TX)
253    {
254       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti, "Invalid Uplink HARQ config %d ",
255             ueCfg->ueUlHqCfg.maxUlHqTx);
256       RETVALUE(RFAILED);
257    }
258 #ifdef TENB_MULT_CELL_SUPPRT
259    if((ueCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
260       (ueCfg->rguUlSapId > rgCb[inst].numRguSaps))
261    {
262       RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for ueId %d failed\n",
263                ueCfg->rguDlSapId,
264                ueCfg->rguUlSapId,
265                ueCfg->crnti));
266       RETVALUE(RFAILED);
267    }
268 #endif
269
270    errInfo->errCause = RGERR_NONE;
271    RETVALUE(ROK);
272 }  /* rgCFGVldtCrgUeCfg */
273
274
275 /**
276  * @brief Validates the logical channel configuration request from RRC to MAC.
277  *
278  * @details
279  *
280  *     Function : rgCFGVldtCrgLcCfg
281  *
282  *     Processing Steps:
283  *      - Validate the logical channel configuration request from RRC to
284  *        MAC at CFG: validate if configured values are within the range.
285  *      - If validated successfully,
286  *        - Return ROK and pointer to the cell for common channels. Return
287  *          pointer to cell and UE for dedicated logical channels.
288  *      - Else 
289  *        - Return RFAILED.
290  *
291  *  @param[in]  CrgLchCfg  *lcCfg
292  *  @param[in]  Inst        inst
293  *  @param[out] RgCellCb   **cell
294  *  @param[out] RgUeCb     **ue
295  *  @param[out] RgErrInfo  *errInfo
296  *  @return  S16
297  *      -# ROK
298  *      -# RFAILED
299  **/
300 #ifdef ANSI
301 PUBLIC S16 rgCFGVldtCrgLcCfg
302 (
303 Inst       inst, 
304 CrgLchCfg  *lcCfg,
305 RgCellCb   **cell,
306 RgUeCb     **ue,
307 RgErrInfo  *errInfo
308 )
309 #else
310 PUBLIC S16 rgCFGVldtCrgLcCfg(inst,lcCfg, cell, ue, errInfo)
311 Inst       inst;
312 CrgLchCfg  *lcCfg;
313 RgCellCb   **cell;
314 RgUeCb     **ue;
315 RgErrInfo  *errInfo;
316 #endif
317 {
318
319    TRC2(rgCFGVldtCrgLcCfg);
320
321    if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
322    {
323       /* Dedicated logical channels */
324       if ((rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)) != ROK)
325       {
326          RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for dedicated LC failed");
327          RETVALUE(RFAILED);
328       }
329    }
330    else if (lcCfg->lcType == CM_LTE_LCH_BCCH
331          || lcCfg->lcType == CM_LTE_LCH_PCCH
332          || lcCfg->lcType == CM_LTE_LCH_CCCH)
333    {
334       if ((rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)) != ROK)
335       {
336          RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for common logical channels failed");
337          RETVALUE(RFAILED);
338       }
339    }
340    else
341    {
342       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel type %d",
343                 lcCfg->lcType);
344       RETVALUE(RFAILED);
345    }
346 #ifdef LTE_L2_MEAS
347    if ( lcCfg->qci <  RG_QCI_MIN ||
348         lcCfg->qci >  RG_QCI_MAX
349       )
350    {
351       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid qci %x",lcCfg->qci);
352       RETVALUE(RFAILED);
353    }
354    /*validate qci */
355 #endif /*LTE_L2_MEAS */
356
357    errInfo->errCause = RGERR_NONE;
358    RETVALUE(ROK);
359 }  /* rgCFGVldtCrgLcCfg */
360
361
362 /**
363  * @brief Validates the cell re-configuration request from RRC to MAC.
364  *
365  * @details
366  *
367  *     Function : rgCFGVldtCrgCellRecfg
368  *
369  *     Processing Steps:
370  *      - Retrieve the cell control block.
371  *      - If successful,
372  *        - Validate the range of re-configured values recieved in
373  *          re-configuration request.
374  *        - If validated successfully,
375  *          - Return ROK and pointer to the cell.
376  *        - Else 
377  *          - Return RFAILED.
378  *      - Else return RFAILED.
379  *
380  *  @param[in]  Inst        inst
381  *  @param[in]  CrgCellRecfg  *cellRecfg
382  *  @param[out] RgCellCb      **cell
383  *  @param[out] RgErrInfo     *errInfo
384  *  @return  S16
385  *      -# ROK
386  *      -# RFAILED
387  **/
388 #ifdef ANSI
389 PUBLIC S16 rgCFGVldtCrgCellRecfg
390 (
391 Inst          inst,
392 CrgCellRecfg  *cellRecfg,
393 RgCellCb      **cell,
394 RgErrInfo     *errInfo
395 )
396 #else
397 PUBLIC S16 rgCFGVldtCrgCellRecfg(inst,cellRecfg, cell, errInfo)
398 Inst          inst;
399 CrgCellRecfg  *cellRecfg;
400 RgCellCb      **cell;
401 RgErrInfo     *errInfo;
402 #endif
403 {
404    TRC2(rgCFGVldtCrgCellRecfg);
405
406    errInfo->errCause = RGERR_CFG_INVALID_CRG_CELL_RECFG;
407    
408    if (((*cell = rgCb[inst].cell) == NULLP)
409          && ((*cell = rgCb[inst].inactiveCell) == NULLP))
410    {
411       RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Cell does not exist");
412       RETVALUE(RFAILED);
413    }
414
415    if((*cell)->cellId != cellRecfg->cellId)
416    {
417       RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId, "Cell does not exist %d\n",cellRecfg->cellId);
418       RETVALUE(RFAILED);
419    }
420    if (cellRecfg->rachRecfg.maxMsg3Tx < RG_MIN_HQ_TX)
421    {
422       RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId,
423                 "Invalid RACH configuration: maxMsg3Tx %d",cellRecfg->rachRecfg.maxMsg3Tx);
424       RETVALUE(RFAILED);
425    }
426    errInfo->errCause = RGERR_NONE;
427    RETVALUE(ROK);
428 }  /* rgCFGVldtCrgCellRecfg */
429
430
431 /**
432  * @brief Validates the UE re-configuration request from RRC to MAC.
433  *
434  * @details
435  *
436  *     Function : rgCFGVldtCrgUeRecfg
437  *
438  *     Processing Steps:
439  *      - Retrieve the UE control block.
440  *      - If successful,
441  *        - Validate the range of re-configured values recieved in
442  *          re-configuration request.
443  *        - If validated successfully,
444  *          - Return ROK and pointer to the cell and ue.
445  *        - Else 
446  *          - Return RFAILED.
447  *      - Else return RFAILED.
448  *
449  *  @param[in]  Inst        inst
450  *  @param[in]  CrgUeRecfg *ueRecfg
451  *  @param[out] RgCellCb   **cell
452  *  @param[out] RgUeCb     **ue
453  *  @param[out] RgErrInfo *errInfo
454  *  @return  S16
455  *      -# ROK
456  *      -# RFAILED
457  **/
458 #ifdef ANSI
459 PUBLIC S16 rgCFGVldtCrgUeRecfg
460 (
461 Inst        inst,
462 CrgUeRecfg  *ueRecfg,
463 RgCellCb    **cell,
464 RgUeCb      **ue,
465 RgErrInfo   *errInfo
466 )
467 #else
468 PUBLIC S16 rgCFGVldtCrgUeRecfg(inst,ueRecfg, cell, ue, errInfo)
469 Inst        inst;
470 CrgUeRecfg  *ueRecfg;
471 RgCellCb    **cell;
472 RgUeCb      **ue;
473 RgErrInfo   *errInfo;
474 #endif
475 {
476    TRC2(rgCFGVldtCrgUeRecfg);
477
478    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RECFG;
479    
480    if ((ueRecfg->txMode.pres == PRSNT_NODEF) && 
481        (ueRecfg->txMode.tm == CRG_UE_TM_5))
482    {
483       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Transmission Mode=%d not supported",
484                 ueRecfg->txMode.tm);
485       RETVALUE(RFAILED);
486    }
487
488     /* Fetch the Active cell */
489    if (((*cell = rgCb[inst].cell) == NULLP) 
490         || ((*cell)->cellId != ueRecfg->cellId))
491    {
492       RLOG_ARG0(L_ERROR,DBG_CELLID,ueRecfg->cellId, "Active Cell does not exist\n");
493       RETVALUE(RFAILED);
494    }
495  
496    /* Fix : syed UE ID change at MAC will now be controlled
497     * by SCH. */
498    if ((*ue = rgDBMGetUeCb(*cell, ueRecfg->oldCrnti)) == NULLP)
499    {
500       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"[%d]Old Ue does not exist", ueRecfg->oldCrnti);
501       RETVALUE(RFAILED);
502    }
503    if (ueRecfg->ueUlHqRecfg.maxUlHqTx < RG_MIN_HQ_TX)
504    {
505       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid Uplink HARQ config for UE %d",
506             ueRecfg->ueUlHqRecfg.maxUlHqTx);
507       RETVALUE(RFAILED);
508    }
509    errInfo->errCause = RGERR_NONE;
510    RETVALUE(ROK);
511 }  /* rgCFGVldtCrgUeRecfg */
512
513
514 /**
515  * @brief Validates the logical channel re-configuration request from
516  * RRC to MAC.
517  *
518  * @details
519  *
520  *     Function : rgCFGVldtCrgLcRecfg
521  *
522  *     Processing Steps:
523  *      - Retrieve the uplink and downlink logical channel control block.
524  *      - If successful,
525  *        - Validate the range of re-configured values recieved in
526  *          re-configuration request.
527  *        - If validated successfully,
528  *          - Return ROK and pointer to the cell, UE and logical channel.
529  *        - Else 
530  *          - Return RFAILED.
531  *      - Else return RFAILED.
532  *
533  *  @param[in]  Inst        inst
534  *  @param[in]  CrgLchRecfg  *lcRecfg
535  *  @param[out] RgCellCb     **cell
536  *  @param[out] RgUeCb       **ue
537  *  @param[out] RgUlLcCb     **ulLc
538  *  @param[out] RgDlLcCb     **dlLc
539  *  @param[out] RgErrInfo    *errInfo
540  *  @return  S16
541  *      -# ROK
542  *      -# RFAILED
543  **/
544 #ifdef ANSI
545 PUBLIC S16 rgCFGVldtCrgLcRecfg
546 (
547 Inst        inst,
548 CrgLchRecfg *lcRecfg,
549 RgCellCb    **cell,
550 RgUeCb      **ue,
551 RgUlLcCb    **ulLc,
552 RgErrInfo   *errInfo
553 )
554 #else
555 PUBLIC S16 rgCFGVldtCrgLcRecfg(inst,lcRecfg, cell, ue, ulLc, errInfo)
556 Inst        inst;
557 CrgLchRecfg  *lcRecfg;
558 RgCellCb     **cell;
559 RgUeCb       **ue;
560 RgUlLcCb     **ulLc;
561 RgErrInfo    *errInfo;
562 #endif
563 {
564    TRC2(rgCFGVldtCrgLcRecfg);
565
566    errInfo->errCause = RGERR_CFG_INVALID_CRG_LC_RECFG;
567
568    /* Fetch the cell */
569    if ((((*cell = rgCb[inst].cell)) == NULLP)
570       || ((*cell)->cellId != lcRecfg->cellId))
571    {
572       RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Active Cell %u does not exist for UE %u", lcRecfg->cellId, lcRecfg->crnti);
573       RETVALUE(RFAILED);
574    }
575    /* Fetch the Ue for dedicated channels */
576    if ((*ue = rgDBMGetUeCb(*cell, lcRecfg->crnti)) == NULLP)
577    {
578       RLOG_ARG0(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Ue does not exist for dedicated logical channel");
579       RETVALUE(RFAILED);
580    }
581
582    if ((*ulLc = rgDBMGetUlDedLcCb((*ue), lcRecfg->lcId)) == NULLP)
583    {
584       RLOG_ARG1(L_ERROR, DBG_CRNTI,lcRecfg->crnti,"Dedicated UL LC does not exist %d",lcRecfg->lcId);
585       RETVALUE(RFAILED);
586    }
587
588    if (lcRecfg->ulRecfg.lcgId > (RG_MAX_LCG_PER_UE - 1))
589    {
590       RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Invalid lcgId for uplink logical channel lcg %d lc %d",
591                 lcRecfg->ulRecfg.lcgId, lcRecfg->lcId);
592       RETVALUE(RFAILED);
593    }
594
595    errInfo->errCause = RGERR_NONE;
596    RETVALUE(ROK);
597 }  /* rgCFGVldtCrgLcRecfg */
598
599 /* Start: LTEMAC_2.1_DEV_CFG */
600 /**
601  * @brief Validates the UE Reset request from RRC to MAC.
602  *
603  * @details
604  *
605  *     Function : rgCFGVldtCrgUeReset
606  *
607  *     Processing Steps:
608  *      - Retrieve the CELL control block.
609  *      - If Failue,
610  *          - Return RFAILED.
611  *      - Retrieve the UE control block.
612  *      - If Failue,
613  *          - Return RFAILED.
614  *
615  *  @param[in]  Inst        inst
616  *  @param[in]  CrgRst     *reset,
617  *  @param[out] RgCellCb   **cell
618  *  @param[out] RgUeCb     **ue
619  *  @param[out] RgErrInfo *errInfo
620  *  @return  S16
621  *      -# ROK
622  *      -# RFAILED
623  **/
624 #ifdef ANSI
625 PUBLIC S16 rgCFGVldtCrgUeReset
626 (
627 Inst       inst,
628 CrgRst     *reset,
629 RgCellCb    **cell,
630 RgUeCb      **ue,
631 RgErrInfo   *errInfo
632 )
633 #else
634 PUBLIC S16 rgCFGVldtCrgUeReset(inst,reset, cell, ue, errInfo)
635 Inst       inst;
636 CrgRst     *reset;
637 RgCellCb    **cell;
638 RgUeCb      **ue;
639 RgErrInfo   *errInfo;
640 #endif
641 {
642    TRC2(rgCFGVldtCrgUeReset);
643
644    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RESET;
645    
646    /* Fetch the Active cell */
647    if (((*cell = rgCb[inst].cell) == NULLP)
648       || ((*cell)->cellId != reset->cellId))
649    {
650       RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist %d\n",reset->crnti, reset->cellId));
651       RLOG_ARG1(L_ERROR,DBG_CRNTI,reset->crnti,"Active Cell does not exist %d",reset->cellId);
652       RETVALUE(RFAILED);
653    }
654
655    /* Fetch the Ue */
656    if ((*ue = rgDBMGetUeCb(*cell, reset->crnti)) == NULLP)
657    {
658       RLOG_ARG0(L_ERROR,DBG_CRNTI,reset->crnti,"UE does not exist");
659       RETVALUE(RFAILED);
660    }
661
662    errInfo->errCause = RGERR_NONE;
663    RETVALUE(ROK);
664 }  /* rgCFGVldtCrgUeReset*/
665 /* End: LTEMAC_2.1_DEV_CFG */
666
667
668
669 /**
670  * @brief Handler for the cell configuration request from RRC to MAC.
671  *
672  * @details
673  *
674  *     Function : rgCFGCrgCellCfg
675  *
676  *     Processing Steps:
677  *      - Allocate and create cell control block.
678  *      - Update cell control block with the values recieved in the
679  *        configuration.
680  *      - Add the control block to hash list of cells.
681  *      - Update the statistics.
682  *      - If successful, return ROK else return RFAILED.
683  *
684  *  @param[in]  Inst        inst
685  *  @param[in]  CrgCellCfg  *cellCfg
686  *  @param[out] RgErrInfo   *errInfo
687  *  @return  S16
688  *      -# ROK
689  *      -# RFAILED
690  **/
691 #ifdef ANSI
692 PUBLIC S16 rgCFGCrgCellCfg
693 (
694 Inst        inst,
695 CrgCellCfg  *cellCfg,
696 RgErrInfo   *errInfo
697 )
698 #else
699 PUBLIC S16 rgCFGCrgCellCfg(inst,cellCfg, errInfo)
700 Inst        inst;
701 CrgCellCfg  *cellCfg;
702 RgErrInfo   *errInfo;
703 #endif
704 {
705    S16        ret;
706    RgCellCb   *cell = NULLP;
707    U8         idx;
708    SuId       rguUlSapId = 0;
709    SuId       rguDlSapId = 0;
710    /* RLC SAP to allocate flowCntrlInd buffer*/
711    Pst        *pst ;
712
713    TRC2(rgCFGCrgCellCfg);
714
715    errInfo->errCause = RGERR_CFG_CRG_CELL_CFG;
716    
717    /* Allocate the cell control block */
718    if((ret = rgAllocSBuf(inst,(Data**)&cell, sizeof(RgCellCb))) != ROK)
719    {
720       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell");
721       RETVALUE(RFAILED);
722    }
723    if (cell == NULLP)
724    {
725       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Memory allocation FAILED for cell");
726       RETVALUE(RFAILED);
727    }
728
729    /* Initialize the cell */
730    cell->cellId  = cellCfg->cellId;
731    cell->rachCfg = cellCfg->rachCfg;
732    cell->bwCfg   = cellCfg->bwCfg;
733 #ifdef EMTC_ENABLE
734    if(cellCfg->emtcEnable)
735     {  
736      cell->emtcEnable = cellCfg->emtcEnable;
737     }
738 #endif
739    /* Initialize UL and DL CCCH logical channels */
740    cell->ulCcchId = RG_INVALID_LC_ID;
741    cell->dlCcchId = RG_INVALID_LC_ID;
742
743    
744    /* Initialize the lists of the cell */
745    ret = rgDBMInitCell(cell);
746    if (ret != ROK)
747    {
748       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"DBM initialization for cell failed");
749       rgCFGFreeInactvCellCb(cell);
750       RETVALUE(RFAILED);
751    }
752
753 #ifdef LTE_ADV
754    if (RFAILED == RgLaaCellCbInit(cell))
755    {
756       rgCFGFreeInactvCellCb(cell);
757       RETVALUE(RFAILED);
758    }
759 #endif
760
761    for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
762    {
763       cell->subFrms[idx].txDone = TRUE;
764    }
765   
766    cell->macInst           = inst + RG_INST_START; 
767    /* Insert cell in the incative cell list */
768    rgCb[inst].inactiveCell = cell;
769    rgCb[inst].cell         = NULLP;
770 #ifdef TENB_MULT_CELL_SUPPRT
771    rguDlSapId              = cellCfg->rguDlSapId;
772    rguUlSapId              = cellCfg->rguUlSapId;
773 #else
774    if(rgCb[inst].numRguSaps > 1)
775    {
776       rguDlSapId              = 1;
777    }
778 #endif
779    cell->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
780    cell->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
781
782
783 #ifdef LTE_L2_MEAS
784    cmLListInit(&cell->l2mList);
785    for(idx = 0; idx < RG_NUM_UL_SUB_FRAMES; idx++)
786    {
787       cmMemset((U8 *)&cell->ulSf[idx], 0, sizeof(RgUlSf));
788    }
789
790    cell->ttiCycle = (U32)RG_TTI_CYCLE_INVLD;   
791 #endif
792    /* Update Statistics */
793    rgUpdtCellCnt(inst,RG_CFG_ADD);
794    errInfo->errCause = RGERR_NONE;
795   
796    pst = &rgCb[inst].rguSap[rguDlSapId].sapCfg.sapPst;
797    /* Allocate a buffer for flowCntrlInd.*/
798    SGetSBuf(pst->region, pst->pool, (Data **)&cell->flowCntrlInd, 
799               sizeof(RguFlowCntrlInd));
800    RETVALUE(ROK);
801 }  /* rgCFGCrgCellCfg */
802
803 #ifdef LTE_ADV
804 /**
805  * @brief Add SCell Cfg recvd from primary MAC instance.
806  *
807  * @details
808  *
809  *     Function : rgCfgAddUeSCellCfg
810  *
811  *     Processing Steps:
812  *      - Allocate and create UE control block.
813  *      - Update UE control block with the values recieved in the
814  *        configuration.
815  *      - If successful, add the control block to hash list of UEs for the cell
816  *        else Rollback and FAIL.
817  *
818  *  @param[in]  Inst                 dstMacInst
819  *  @param[in]  RgPrgUeSCellCfgInfo  *ueSCellCb
820  *  @param[in]  RgCellCb              cell
821
822  *  @return  S16
823  *      -# ROK
824  *      -# RFAILED
825  **/
826 #ifdef ANSI
827 PUBLIC S16 rgCfgAddUeSCellCfg
828 (
829 Inst        dstMacInst,    
830 RgPrgUeSCellCfgInfo *ueSCellCb,
831 RgCellCb    *cell
832 )
833 #else
834 PUBLIC S16 rgCfgAddUeSCellCfg(dstMacInst, ueSCellCb, cell)
835 Inst        dstMacInst;    
836 RgPrgUeSCellCfgInfo *ueSCellCb;
837 RgCellCb    *cell;
838 #endif
839 {
840    RgUeCb     *ueCb = NULLP;
841    SuId       rguUlSapId = 0;
842    SuId       rguDlSapId = 0;
843    U8        idx;
844    RgErrInfo  errInfo;
845
846    TRC2(rgCfgAddUeSCellCfg);
847    
848 #ifdef LTE_ADV
849    rguDlSapId              = ueSCellCb->rguDlSapId;
850    rguUlSapId              = ueSCellCb->rguUlSapId;
851 #endif
852 #ifndef TENB_MULT_CELL_SUPPRT
853    if(rgCb[dstMacInst].numRguSaps > 1)
854    {
855       rguDlSapId              = 1;
856    }
857 #endif
858
859    if ((ueCb = rgDBMGetUeCb(cell, ueSCellCb->ueId)) != NULLP)
860    {
861       RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
862                "[%d]Ue already exist in scell %d during scell addition\n", 
863                ueSCellCb->ueId,
864                cell->cellId));
865       RETVALUE(RFAILED);
866    }
867
868    /* Create UeCb */
869    if((ueCb = rgRAMCreateUeCb(cell, ueSCellCb->ueId,
870                FALSE, &errInfo)) == NULLP)
871    {
872       RGDBGERRNEW(dstMacInst, (rgPBuf(dstMacInst),
873                "[%d]UeCb creation failed\n", ueSCellCb->ueId));
874       RETVALUE(RFAILED);
875    }
876
877    if(rgDHMHqEntInit(dstMacInst, &ueCb->dl.hqEnt, 
878             (rgCb[dstMacInst].cell)->maxDlHqProcPerUe) != ROK)
879    {
880       RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
881                "[%d]UeCb Harq Entity Initialization failed\n", ueSCellCb->ueId));
882       RETVALUE(RFAILED);
883    }
884    rgDBMInsUeCb(cell, ueCb);
885
886
887    ueCb->rguDlSap          = &(rgCb[dstMacInst].rguSap[rguDlSapId]);
888    ueCb->rguUlSap          = &(rgCb[dstMacInst].rguSap[rguUlSapId]);
889
890    /* Update satistics */
891    rgUpdtUeCnt(dstMacInst, RG_CFG_ADD);
892    /*Commit Added SCell info to UeCb */
893    /*
894    ueCb->sCelAddInfo[idx].isSCellAdded = TRUE;
895    ueCb->sCelAddInfo[idx].macInst = dstMacInst;
896    ueCb->sCelAddInfo[idx].sCellId = ueSCellCb->cellId;
897    */
898
899    ueCb->txMode = ueSCellCb->txMode;
900    ueCb->ul.hqEnt.maxHqRetx = ueSCellCb->maxUlHqRetx;
901
902    for (idx =0; idx <RG_MAX_LC_PER_UE; idx++)
903    {
904       ueCb->ul.lcCb[idx] = ueSCellCb->ulLcInfo[idx];
905       ueCb->dl.lcCb[idx] = ueSCellCb->dlLcInfo[idx];
906    }
907
908    for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
909    {
910       ueCb->ul.lcgArr[idx].lcgId = ueSCellCb->lcgInfo[idx].lcgId;
911       ueCb->ul.lcgArr[idx].lcCount = ueSCellCb->lcgInfo[idx].lcCount;
912       ueCb->ul.lcgArr[idx].isGbr = ueSCellCb->lcgInfo[idx].isGbr;
913    }
914    RETVALUE(ROK);
915 }/* rgCfgAddUeSCellCfg */
916
917 /**
918  * @brief SCell Config Filling for added cell from RRC to MAC.
919  *
920  * @details
921  *
922  *     Function : rgFillAndAddSCellCfg 
923  *
924  *     Processing Steps:
925  *      - Update UE control block with the values recieved in the
926  *        configuration.
927  *      - Update UE control block with the values present in the
928  *        CellCb
929  *      - If successful, add the control block to hash list of UEs for the cell
930  *        else Rollback and FAIL.
931  *
932  *  @param[in]  Inst          inst
933  *  @param[in]  RgCellCb      *cell
934  *  @param[in]  CrgUeCfg      *ueCfg
935  *  @param[in]  CrgCfgTransId transId
936  *  @return  S16
937  *      -# ROK
938  *      -# RFAILED
939  **/
940 #ifdef ANSI
941 PUBLIC S16 rgFillAndAddSCellCfg
942 (
943 Inst            inst,
944 RgCellCb        *cell,
945 CrgUeRecfg      *ueRecfg,
946 CrgCfgTransId   transId,
947 Bool            *isCfmRqrd
948 )
949 #else
950 PUBLIC S16 rgFillAndAddSCellCfg(inst, cell, ueRecfg, transId, isCfmRqrd)
951 Inst            inst;
952 RgCellCb        *cell;
953 CrgUeRecfg      *ueRecfg;
954 CrgCfgTransId   transId;
955 Bool            *isCfmRqrd;
956 #endif
957 {
958    RgUeCb     *ue = NULLP;
959    U8          idx = 0;
960    Inst        dstMacInst;
961    RgPrgUeSCellCfgInfo ueSCellCb;
962    Pst          dstInstPst;
963
964    TRC2(rgFillAndAddSCellCfg);
965   
966   /* Fetch the Active cell */
967    if(((cell = rgCb[inst].cell) == NULLP) ||
968        (cell->cellId != ueRecfg->cellId))
969    {
970       RGDBGERRNEW(inst,(rgPBuf(inst), 
971                        "[%d]Active Cell does not exist %d\n",
972                                   ueRecfg->oldCrnti, ueRecfg->cellId));
973       RETVALUE(RFAILED);
974    }
975
976    RGDBGPRM(inst,(rgPBuf(inst), 
977             "Filling SCell Config : cellId %d ueId %d\n",
978             cell->cellId, cell->ueId));
979
980    if ((ue = rgDBMGetUeCb(cell, ueRecfg->oldCrnti)) == NULLP)
981    {
982       RGDBGERRNEW(inst,(rgPBuf(inst), 
983                "[%d]Ue does not exist\n", ueRecfg->oldCrnti));
984       RETVALUE(RFAILED);
985    }
986
987    /* Initialize cfgCfmInfo in the ueCb. This is used while processing SCellAdd
988     *confirmation*/
989    ue->cfgCfmInfo.numSCells = ueRecfg->crgSCellCfg.numSCells;
990    ue->cfgCfmInfo.cfgCfgCount = 0;
991    ue->cfgCfmInfo.mask = 0x0;
992
993    cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
994          sizeof(CrgCfgTransId));
995    ueSCellCb.ueId = ueRecfg->oldCrnti;
996    ueSCellCb.txMode = ue->txMode;
997    ueSCellCb.maxUlHqRetx = ue->ul.hqEnt.maxHqRetx;
998    cmMemcpy((U8 *)ueSCellCb.ulLcInfo, (U8 *)ue->ul.lcCb, sizeof(ue->ul.lcCb));
999    cmMemcpy((U8 *)ueSCellCb.dlLcInfo, (U8 *)ue->dl.lcCb, sizeof(ue->dl.lcCb));
1000    for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
1001    {
1002       ueSCellCb.lcgInfo[idx].lcgId = ue->ul.lcgArr[idx].lcgId;
1003       ueSCellCb.lcgInfo[idx].lcCount = ue->ul.lcgArr[idx].lcCount;
1004       ueSCellCb.lcgInfo[idx].isGbr = ue->ul.lcgArr[idx].isGbr;
1005    }
1006
1007    for(idx = 0; 
1008          idx < ueRecfg->crgSCellCfg.numSCells; idx++)
1009    {
1010       dstMacInst = ueRecfg->crgSCellCfg.ueSCellCfg[idx].macInst - RG_INST_START;
1011       ueSCellCb.cellId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].sCellId;
1012       ueSCellCb.rguDlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguDlSapId;
1013       ueSCellCb.rguUlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguUlSapId;
1014
1015       /* Get post structure of the cell to whom ueSCellCb needs to be sent
1016        * And then send the sCell Add based on Mac instances */
1017       rgGetPstToInst(&dstInstPst, inst, dstMacInst);
1018       RgPrgPMacSMacUeSCellCfg(&dstInstPst, &ueSCellCb);
1019
1020       /*Commit Added SCell info to UeCb is moved to config confirm*/
1021    } /*end of for loop */
1022    *isCfmRqrd = FALSE;
1023
1024    RETVALUE(ROK);
1025 }  /* rgFillAndAddSCellCfg */
1026 #endif /* LTE_ADV */
1027
1028 /**
1029  * @brief Handler for the UE configuration request from RRC to MAC.
1030  *
1031  * @details
1032  *
1033  *     Function : rgCFGCrgUeCfg
1034  *
1035  *     Processing Steps:
1036  *      - Allocate and create UE control block.
1037  *      - Update UE control block with the values recieved in the
1038  *        configuration.
1039  *      - Invoke RAM, SCH, UHM and DHM with created UE control block, to
1040  *        update random access, scheduler, uplink harq and downlink harq
1041  *        specific information respectively.
1042  *      - If successful, add the control block to hash list of UEs for the cell
1043  *        else Rollback and FAIL.
1044  *
1045  *  @param[in]  Inst        inst
1046  *  @param[in]  RgCellCb  *cell
1047  *  @param[in]  CrgUeCfg  *ueCfg
1048  *  @param[out] RgErrInfo *errInfo
1049  *  @return  S16
1050  *      -# ROK
1051  *      -# RFAILED
1052  **/
1053 #ifdef ANSI
1054 PUBLIC S16 rgCFGCrgUeCfg
1055 (
1056 Inst      inst,
1057 RgCellCb  *cell,
1058 CrgUeCfg  *ueCfg,
1059 RgErrInfo *errInfo
1060 )
1061 #else
1062 PUBLIC S16 rgCFGCrgUeCfg(inst,cell, ueCfg, errInfo)
1063 Inst      inst;
1064 RgCellCb  *cell;
1065 CrgUeCfg  *ueCfg;
1066 RgErrInfo *errInfo;
1067 #endif
1068 {
1069    RgUeCb    *ue = NULLP;
1070    Bool      handover = FALSE;
1071    SuId       rguUlSapId = 0;
1072    SuId       rguDlSapId = 0;
1073
1074    TRC2(rgCFGCrgUeCfg);
1075
1076    errInfo->errCause = RGERR_CFG_CRG_UE_CFG;
1077
1078 /* Start: LTEMAC_2.1_DEV_CFG */
1079    if ((ue = rgDBMGetUeCbFromRachLst(cell, ueCfg->crnti)) == NULLP)
1080    {
1081       /* Create UeCb and Insert in Rach List */
1082       if((ue=rgRAMCreateUeCb(cell, ueCfg->crnti, FALSE, errInfo)) == NULLP)
1083       {
1084          RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb creation failed");
1085          RETVALUE(RFAILED);
1086       }
1087       if(rgDHMHqEntInit(inst,&ue->dl.hqEnt, cell->maxDlHqProcPerUe) != ROK)
1088       {
1089          RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb Harq Entity Initialization failed");
1090          RETVALUE(RFAILED);
1091       }
1092       handover = TRUE;
1093    }
1094 /* End: LTEMAC_2.1_DEV_CFG */
1095
1096    if(handover == FALSE)
1097    {
1098       /* Remove from the rachLst */
1099       rgDBMDelUeCbFromRachLst(cell, ue);
1100    }
1101
1102
1103    /* Initialize uplink HARQ related information for UE */
1104    rgUHMCrgUeCfg(cell, ue, ueCfg);
1105
1106    rgDBMInsUeCb(cell, ue);
1107
1108 #ifdef TENB_MULT_CELL_SUPPRT
1109    rguDlSapId              = ueCfg->rguDlSapId;
1110    rguUlSapId              = ueCfg->rguUlSapId;
1111 #else
1112    if(rgCb[inst].numRguSaps > 1)
1113    {
1114       rguDlSapId              = 1;
1115    }
1116 #endif
1117
1118    ue->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
1119    ue->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
1120
1121
1122    /* Update satistics */
1123    rgUpdtUeCnt(inst,RG_CFG_ADD);
1124    errInfo->errCause = RGERR_NONE;
1125    RETVALUE(ROK);
1126 }  /* rgCFGCrgUeCfg */
1127
1128
1129 /**
1130  * @brief Handler for the logical channel configuration request from
1131  * RRC to MAC.
1132  *
1133  * @details
1134  *
1135  *     Function : rgCFGCrgLcCfg
1136  *
1137  *     Processing Steps:
1138  *      - Check if the configuration is for dedicated or common logical channel.
1139  *      - For Dedicated logical channels:
1140  *        - Update the dedicated logical channel Cb with the configured values.
1141  *        - Invoke SCH will cell, UE and logical channel Cb to update scheduler
1142  *          specific information.
1143  *      - For Common logical channels:
1144  *        - Update the common logical channel Cb with the configured values.
1145  *        - Move cell to active list of cells if cell becomes ACTIVE.
1146  *      - If successful, return ROK else RFAILED.
1147  *
1148  *  @param[in]  Inst        inst
1149  *  @param[in]  RgCellCb    *cell
1150  *  @param[in]  RgUeCb      *ue
1151  *  @param[in]  CrgLchCfg   *lcCfg
1152  *  @param[out] RgErrInfo   *errInfo
1153  *  @param[in]  Bool        *isCfmRqrd
1154  *  @return  S16
1155  *      -# ROK
1156  *      -# RFAILED
1157  **/
1158 #ifdef ANSI
1159 PUBLIC S16 rgCFGCrgLcCfg
1160 (
1161 Inst            inst,
1162 RgCellCb        *cell,
1163 RgUeCb          *ue,
1164 CrgLchCfg       *lcCfg,
1165 RgErrInfo       *errInfo,
1166 Bool            *isCfmRqrd,
1167 CrgCfgTransId   transId
1168 )
1169 #else
1170 PUBLIC S16 rgCFGCrgLcCfg(inst,cell, ue, lcCfg, errInfo, isCfmRqrd,transId)
1171 Inst        inst;
1172 RgCellCb    *cell;
1173 RgUeCb      *ue;
1174 CrgLchCfg   *lcCfg;
1175 RgErrInfo   *errInfo;
1176 Bool        *isCfmRqrd;
1177 CrgCfgTransId   transId;
1178 #endif
1179 {
1180
1181    TRC2(rgCFGCrgLcCfg);
1182    
1183    /* Handle Config for dedicated/common logical channels */
1184    if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
1185    {
1186
1187       if ((rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)) != ROK)
1188       {
1189          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,
1190                "Dedicated logical channel configuration failed %d",lcCfg->lcId);
1191          RETVALUE(RFAILED);
1192       }
1193 #ifdef LTE_ADV
1194       /*ERAB Multl Cell fix*/
1195        cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
1196             sizeof(CrgCfgTransId));
1197        rgPomSndUeSCellLchAddToSmac(inst, cell, ue, lcCfg,isCfmRqrd);
1198 #endif
1199    }
1200    else
1201    {
1202       if ((rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)) != ROK)
1203       {
1204          RLOG_ARG1(L_ERROR, DBG_CRNTI, lcCfg->crnti, "Common logical channel configuration"
1205                   "failed %d\n", lcCfg->lcId);
1206          RETVALUE(RFAILED);
1207       }
1208    }
1209
1210    errInfo->errCause = RGERR_NONE;
1211    RLOG_ARG1(L_INFO, DBG_CRNTI,lcCfg->crnti, "CRG LC config done for UE: lcId %d\n", lcCfg->lcId);
1212    RETVALUE(ROK);
1213 }  /* rgCFGCrgLcCfg */
1214
1215
1216 /**
1217  * @brief Handler for the cell re-configuration request from RRC to MAC.
1218  *
1219  * @details
1220  *
1221  *     Function : rgCFGCrgCellRecfg
1222  *
1223  *     Processing Steps:
1224  *      - Invoke SCH with updated Cell Cb to update scheduler specific
1225  *        parameters.
1226  *      - Update the cell Cb with the reconfigured values.
1227  *      - If successful, return ROK else RFAILED.
1228  *
1229  *  @param[in]  Inst        inst
1230  *  @param[in]  RgCellCb      *cell
1231  *  @param[in]  CrgCellRecfg  *cellRecfg
1232  *  @param[out] RgErrInfo     *errInfo
1233  *  @return  S16
1234  *      -# ROK
1235  *      -# RFAILED
1236  **/
1237 #ifdef ANSI
1238 PUBLIC S16 rgCFGCrgCellRecfg
1239 (
1240 Inst          inst,
1241 RgCellCb      *cell,
1242 CrgCellRecfg  *cellRecfg,
1243 RgErrInfo     *errInfo
1244 )
1245 #else
1246 PUBLIC S16 rgCFGCrgCellRecfg(inst,cell, cellRecfg, errInfo)
1247 Inst          inst;
1248 RgCellCb      *cell;
1249 CrgCellRecfg  *cellRecfg;
1250 RgErrInfo     *errInfo;
1251 #endif
1252 {
1253    TRC2(rgCFGCrgCellRecfg);
1254
1255    /* Store the given rachCfg */
1256    cell->rachCfg = cellRecfg->rachRecfg;
1257
1258    errInfo->errCause = RGERR_NONE;
1259    RETVALUE(ROK);
1260 }  /* rgCFGCrgCellRecfg */
1261
1262
1263 /**
1264  * @brief Handler for the UE re-configuration request from RRC to MAC.
1265  *
1266  * @details
1267  *
1268  *     Function : rgCFGCrgUeRecfg
1269  *
1270  *     Processing Steps:
1271  *      - If rnti changes,
1272  *        - Invoke RAM for UE reconfiguration.
1273  *        - Delete old UE from the list.
1274  *        - Update the new rnti and re-insert the UE in the list.
1275  *      - Update the UE control block with the reconfigured values.
1276  *      - Invoke SCH, UHM and DHM with updated UE control block to 
1277  *        update scheduler, uplink HARQ and downlink HARQ specific
1278  *        parameters.
1279  *      - If successful, return ROK else RFAILED.
1280  *
1281  *  @param[in]  Inst        inst
1282  *  @param[in]  RgCellCb    *cell
1283  *  @param[in]  RgUeCb      *ue
1284  *  @param[in]  CrgUeRecfg  *ueRecfg
1285  *  @param[out] RgErrInfo   *errInfo
1286  *  @return  S16
1287  *      -# ROK
1288  *      -# RFAILED
1289  **/
1290 #ifdef ANSI
1291 PUBLIC S16 rgCFGCrgUeRecfg
1292 (
1293 Inst        inst,
1294 RgCellCb    *cell,
1295 RgUeCb      *ue,
1296 CrgUeRecfg  *ueRecfg,
1297 RgErrInfo   *errInfo
1298 )
1299 #else
1300 PUBLIC S16 rgCFGCrgUeRecfg(inst,cell, ue, ueRecfg, errInfo)
1301 Inst        inst;
1302 RgCellCb    *cell;
1303 RgUeCb      *ue;
1304 CrgUeRecfg  *ueRecfg;
1305 RgErrInfo   *errInfo;
1306 #endif
1307 {
1308    TRC2(rgCFGCrgUeRecfg);
1309
1310    errInfo->errCause = RGERR_CFG_CRG_UE_RECFG;
1311
1312    /* Fix : syed UE ID change at MAC will now be controlled
1313     * by SCH. */
1314
1315    /* Update uplink HARQ related information for UE */
1316    rgUHMCrgUeRecfg(cell, ue, ueRecfg);
1317
1318    errInfo->errCause = RGERR_NONE;
1319    RETVALUE(ROK);
1320 }  /* rgCFGCrgUeRecfg */
1321
1322
1323 /**
1324  * @brief Handler for the logical channel re-configuration request from
1325  * RRC to MAC.
1326  *
1327  * @details
1328  *
1329  *     Function : rgCFGCrgLcRecfg
1330  *
1331  *     Processing Steps:
1332  *      - Invoke scheduler to update scheduler specific information.
1333  *      - Update the dedicated logical channel Cb with the re-configured
1334  *        values.
1335  *      - If successful, return ROK else RFAILED.
1336  *
1337  *  @param[in]  Inst        inst
1338  *  @param[in]  RgUlCellCb  *cell
1339  *  @param[in]  RgUlUeCb    *ue
1340  *  @param[in]  RgUlLcCb    *ulLc
1341  *  @param[in]  RgDlLcCb    *dlLc
1342  *  @param[in]  CrgLchRecfg *lcRecfg
1343  *  @param[out] RgErrInfo   *errInfo
1344  *  @return  S16
1345  *      -# ROK
1346  *      -# RFAILED
1347  **/
1348 #ifdef ANSI
1349 PUBLIC S16 rgCFGCrgLcRecfg
1350 (
1351 Inst        inst,
1352 RgCellCb    *cell,
1353 RgUeCb      *ue,
1354 RgUlLcCb    *ulLc,
1355 CrgLchRecfg *lcRecfg,
1356 RgErrInfo   *errInfo,
1357 Bool        *isCfmRqrd
1358 )
1359 #else
1360 PUBLIC S16 rgCFGCrgLcRecfg(inst,cell, ue, ulLc, lcRecfg, errInfo, isCfmRqrd)
1361 Inst        inst;
1362 RgCellCb    *cell;
1363 RgUeCb      *ue;
1364 RgUlLcCb    *ulLc;
1365 CrgLchRecfg *lcRecfg;
1366 RgErrInfo   *errInfo;
1367 Bool        *isCfmRqrd;
1368 #endif
1369 {
1370    TRC2(rgCFGCrgLcRecfg);
1371
1372    if (ulLc->lcgId != lcRecfg->ulRecfg.lcgId)
1373    {
1374       rgDBMUpdUlDedLcCb(ue, ulLc, lcRecfg->ulRecfg.lcgId);
1375 #ifdef LTE_ADV
1376       rgPomSndUeSCellLchModToSmac(inst, cell, ue,  lcRecfg,isCfmRqrd);
1377 #endif
1378    }
1379
1380    errInfo->errCause = RGERR_NONE;
1381    RETVALUE(ROK);
1382 }  /* rgCFGCrgLcRecfg */
1383
1384 /* Start: LTEMAC_2.1_DEV_CFG */
1385 /**
1386  * @brief Handler for the logical channel re-configuration request from
1387  * RRC to MAC.
1388  *
1389  * @details
1390  *
1391  *     Function : rgCFGCrgUeReset
1392  *
1393  *     Processing Steps:
1394  *
1395  *  @param[in]  RgUlCellCb  *cell
1396  *  @param[in]  RgUlUeCb    *ue
1397  *  @param[in]  CrgRst     *reset
1398  *  @param[out] RgErrInfo   *errInfo
1399  *  @return  S16
1400  *      -# ROK
1401  *      -# RFAILED
1402  **/
1403 #ifdef ANSI
1404 PUBLIC S16 rgCFGCrgUeReset
1405 (
1406 RgCellCb    *cell,
1407 RgUeCb      *ue,
1408 CrgRst     *reset,
1409 RgErrInfo   *errInfo
1410 )
1411 #else
1412 PUBLIC S16 rgCFGCrgUeReset(cell, ue, reset, errInfo)
1413 RgCellCb    *cell;
1414 RgUeCb      *ue;
1415 CrgRst     *reset;
1416 RgErrInfo   *errInfo;
1417 #endif
1418 {
1419    TRC2(rgCFGCrgUeReset);
1420
1421    RLOG_ARG1(L_DEBUG, DBG_CRNTI, ue->ueId, "UE: of cell %d Reset\n", cell->cellId);
1422    rgDHMUeReset(cell, &ue->dl.hqEnt);
1423
1424    errInfo->errCause = RGERR_NONE;
1425
1426    RETVALUE(ROK);
1427 }  /* rgCFGCrgUeReset */
1428 /* End: LTEMAC_2.1_DEV_CFG */
1429
1430 /**
1431  * @brief Handler for the cell delete request from RRC to MAC.
1432  *
1433  * @details
1434  *
1435  *     Function : rgCFGCrgCellDel
1436  *
1437  *     Processing Steps:
1438  *      - Fetch the cell control block.
1439  *      - Remove the cell control block from the hash list of cells.
1440  *      - Free the cell control block.
1441  *      - If successful, return ROK else return RFAILED.
1442  *
1443  *  @param[in]  Inst        inst
1444  *  @param[in]  CrgDel      *cellDelInfo
1445  *  @param[out] RgErrInfo   *errInfo
1446  *  @return  S16
1447  *      -# ROK
1448  *      -# RFAILED
1449  **/
1450 #ifdef ANSI
1451 PUBLIC S16 rgCFGCrgCellDel
1452 (
1453 Inst        inst,
1454 CrgDel      *cellDelInfo,
1455 RgErrInfo   *errInfo
1456 )
1457 #else
1458 PUBLIC S16 rgCFGCrgCellDel(inst,cellDelInfo, errInfo)
1459 Inst        inst,
1460 CrgDel      *cellDelInfo;
1461 RgErrInfo   *errInfo;
1462 #endif
1463 {
1464    RgCellCb      *cell;
1465    U8 idx;
1466
1467    TRC2(rgCFGCrgCellDel);
1468
1469    errInfo->errCause = RGERR_CFG_CRG_CELL_DEL;
1470    if (((cell = rgCb[inst].cell) == NULLP)
1471        ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
1472    {
1473       if(((cell = rgCb[inst].inactiveCell) == NULLP)
1474           ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
1475       {
1476
1477          
1478          RLOG_ARG0(L_ERROR,DBG_CELLID,cellDelInfo->u.cellDel.cellId,"Cell does not exist");
1479          RETVALUE(RFAILED);
1480       }
1481
1482       /* Delete cell from inactive list */
1483       rgCb[inst].inactiveCell = NULLP ;
1484
1485       /* Free the inactive cell */
1486       rgCFGFreeInactvCellCb(cell);
1487
1488       errInfo->errCause = RGERR_NONE;
1489       RETVALUE(ROK);
1490    }
1491
1492    /* Delete from the cell list */
1493    //rgDBMDelCellCb(cell);
1494    for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
1495    {
1496       rgTOMRlsSf(inst,&cell->subFrms[idx]);
1497    }
1498
1499    /* Free the active cell */
1500    rgCFGFreeCellCb(cell);
1501
1502    rgCb[inst].cell = NULLP;
1503
1504    errInfo->errCause    = RGERR_NONE;
1505    RGDBGINFO(inst,(rgPBuf(inst), "Cell %d deleted\n", cellDelInfo->u.cellDel.cellId));
1506    RETVALUE(ROK);
1507 }  /* rgCFGCrgCellDel */
1508
1509
1510 /**
1511  * @brief Handler for the UE delete request from RRC to MAC.
1512  *
1513  * @details
1514  *
1515  *     Function : rgCFGCrgUeDel
1516  *
1517  *     Processing Steps:
1518  *      - Fetch the UE control block.
1519  *      - Remove the UE control block from the hash list of UEs for the cell.
1520  *      - Free the UE control block.
1521  *      - If successful, return ROK else return RFAILED.
1522  *
1523  *  @param[in]  Inst        inst
1524  *  @param[in]  CrgDel      *ueDelInfo
1525  *  @param[out] RgErrInfo   *errInfo
1526  *  @return  S16
1527  *      -# ROK
1528  *      -# RFAILED
1529  **/
1530 #ifdef ANSI
1531 PUBLIC S16 rgCFGCrgUeDel
1532 (
1533 Inst        inst,
1534 CrgDel      *ueDelInfo,
1535 RgErrInfo   *errInfo
1536 )
1537 #else
1538 PUBLIC S16 rgCFGCrgUeDel(inst,ueDelInfo, errInfo)
1539 Inst        inst;
1540 CrgDel      *ueDelInfo;
1541 RgErrInfo   *errInfo;
1542 #endif
1543 {
1544    TRC2(rgCFGCrgUeDel);
1545
1546    errInfo->errCause = RGERR_CFG_CRG_UE_DEL;
1547
1548    RLOG_ARG1(L_DEBUG, DBG_CRNTI, ueDelInfo->u.ueDel.crnti, "UE %d Deletion Req at MAC\n", \
1549             ueDelInfo->u.ueDel.crnti);
1550    if ((rgCb[inst].cell == NULLP)
1551        || (rgCb[inst].cell->cellId != ueDelInfo->u.ueDel.cellId))
1552    {
1553       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueDelInfo->u.ueDel.crnti,"Cell does not exist %d",
1554                 ueDelInfo->u.ueDel.cellId);
1555       RETVALUE(RFAILED);
1556    }
1557
1558    errInfo->errCause = RGERR_NONE;
1559    /* Fix: syed Context Deletion is relied upon SCH indication */
1560    RETVALUE(ROK);
1561 }  /* rgCFGCrgUeDel */
1562
1563
1564 /**
1565  * @brief Handler for the logical channel delete request from
1566  * RRC to MAC.
1567  *
1568  * @details
1569  *
1570  *     Function : rgCFGCrgLcDel
1571  *
1572  *     Processing Steps:
1573  *      - Fetch the logical channel control block.
1574  *      - Free the logical channel control block.
1575  *      - If successful, return ROK else return RFAILED.
1576  *
1577  *  @param[in]  Inst        inst
1578  *  @param[in]  CrgDel      *lcDelInfo
1579  *  @param[out] RgErrInfo   *errInfo
1580  *  @return  S16
1581  *      -# ROK
1582  *      -# RFAILED
1583  **/
1584 #ifdef ANSI
1585 PUBLIC S16 rgCFGCrgLcDel
1586 (
1587 Inst        inst,
1588 CrgDel      *lcDelInfo,
1589 RgErrInfo   *errInfo,
1590 Bool        *isCfmRqrd,
1591 CrgCfgTransId transId
1592 )
1593 #else
1594 PUBLIC S16 rgCFGCrgLcDel(inst,lcDelInfo, errInfo,isCfmRqrd,transId)
1595 Inst        inst;
1596 CrgDel      *lcDelInfo;
1597 RgErrInfo   *errInfo;
1598 CrgCfgTransId transId;
1599 #endif
1600 {
1601    Bool      dirVld = FALSE;
1602    RgCellCb  *cell;
1603    RgUeCb    *ue;
1604    RgUlLcCb  *ulLc;
1605    RgDlLcCb  *dlLc;
1606
1607    TRC2(rgCFGCrgLcDel);
1608
1609    errInfo->errCause = RGERR_CFG_CRG_LC_DEL;
1610
1611    /* Fetch the Active cell */
1612    if (((cell = rgCb[inst].cell) == NULLP) ||
1613        (rgCb[inst].cell->cellId != lcDelInfo->u.lchDel.cellId))
1614    {
1615       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Cell does not exist %d",
1616                 lcDelInfo->u.lchDel.cellId);
1617       RETVALUE(RFAILED);
1618    }
1619
1620    /* Fetch the Ue */
1621    if ((ue = rgDBMGetUeCb(cell, lcDelInfo->u.lchDel.crnti)) == NULLP)
1622    {
1623       RLOG_ARG0(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,
1624                 "UE does not exist for dedicated logical channel");
1625       RETVALUE(RFAILED);
1626    }
1627
1628    /* Validate downlink info */
1629    if (lcDelInfo->u.lchDel.dir & CRG_DIR_TX)
1630    {
1631       if ((dlLc = rgDBMGetDlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
1632             == NULLP)
1633       {
1634          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"DL LC %d does not exist",
1635                    lcDelInfo->u.lchDel.lcId);
1636          RETVALUE(RFAILED);
1637       }
1638       rgDBMDelDlDedLcCb(ue, dlLc);
1639       dirVld = TRUE;
1640    }
1641
1642    /* Validate uplink info */
1643    if (lcDelInfo->u.lchDel.dir & CRG_DIR_RX)
1644    {
1645       if ((ulLc = rgDBMGetUlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
1646             == NULLP)
1647       {
1648          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"UL LC %d does not exist",
1649                    lcDelInfo->u.lchDel.lcId);
1650          RETVALUE(RFAILED);
1651       }
1652       rgDBMDelUlDedLcCb(ue, ulLc);
1653       dirVld = TRUE;
1654    }
1655
1656    if (!dirVld)
1657    {
1658       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Invalid direction %d for LC Delete",
1659             lcDelInfo->u.lchDel.dir);
1660       RETVALUE(RFAILED);
1661    }
1662 #ifdef LTE_ADV
1663    /*ERAB - multicell fix*/
1664    cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
1665          sizeof(CrgCfgTransId));
1666    rgPomSndUeSCellLchDelToSmac(inst, lcDelInfo, isCfmRqrd);
1667 #endif
1668    errInfo->errCause = RGERR_NONE;
1669    RETVALUE(ROK);
1670 }  /* rgCFGCrgLcDel */
1671
1672 /***********************************************************
1673  *
1674  *     Func : rgCFGVldtCrgDedLcCfg
1675  *
1676  *
1677  *     Desc : Validates dedicated logical channel configuration recieved from RRC.
1678  *
1679  *     Ret  : S16
1680  *            ROK - Success
1681  *            RFAILED - Failed
1682  *
1683  *     Notes:
1684  *
1685  *     File :
1686  *
1687  **********************************************************/
1688 #ifdef ANSI
1689 PRIVATE S16 rgCFGVldtCrgDedLcCfg
1690 (
1691 Inst          inst, 
1692 CrgLchCfg     *lcCfg,
1693 RgCellCb      **cell,
1694 RgUeCb        **ue,
1695 RgErrInfo     *errInfo
1696 )
1697 #else
1698 PRIVATE S16 rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)
1699 Inst          inst;
1700 CrgLchCfg     *lcCfg;
1701 RgCellCb      **cell;
1702 RgUeCb        **ue;
1703 RgErrInfo     *errInfo;
1704 #endif
1705 {
1706    U8         dirVld   = FALSE;
1707    TRC2(rgCFGVldtCrgDedLcCfg);
1708
1709    errInfo->errCause = RGERR_CFG_INVALID_CRG_DED_LC_CFG;
1710
1711    /* Fetch the Active cell */
1712    if (((*cell = rgCb[inst].cell) == NULLP)
1713       || ((*cell)->cellId != lcCfg->cellId))
1714    {
1715       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Active Cell does not exist: Cell %d",
1716                 lcCfg->cellId);
1717       RETVALUE(RFAILED);
1718    }
1719
1720    /* Fetch the Ue */
1721    if ((*ue = rgDBMGetUeCb(*cell, lcCfg->crnti)) == NULLP)
1722    {
1723       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE  does not exist for dedicated logical channel %d",
1724                 lcCfg->lcId);
1725       RETVALUE(RFAILED);
1726    }
1727
1728    /* Validate logical channel Id */
1729    if ((lcCfg->lcId < RG_DEDLC_MIN_LCID)
1730             ||(lcCfg->lcId > RG_DEDLC_MAX_LCID))
1731    {
1732       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel Id %d",
1733                 lcCfg->lcId);
1734       RETVALUE(RFAILED);
1735    }
1736
1737    /* Validate downlink info */
1738    if (lcCfg->dir & CRG_DIR_TX)
1739    {
1740       if (rgDBMGetDlDedLcCb((*ue), lcCfg->lcId) != NULLP)
1741       {
1742          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated DL LC %d already configured",
1743                     lcCfg->lcId);
1744          RETVALUE(RFAILED);
1745       }
1746       dirVld = TRUE;
1747    }
1748
1749    /* Validate uplink info */
1750    if (lcCfg->dir & CRG_DIR_RX)
1751    {
1752       if (lcCfg->ulInfo.lcgId > (RG_MAX_LCG_PER_UE - 1))
1753       {
1754          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Invalid lcgId for uplink logical channel %d",
1755                    lcCfg->ulInfo.lcgId);
1756          RETVALUE(RFAILED);
1757       }
1758       if (rgDBMGetUlDedLcCb((*ue), lcCfg->lcId) != NULLP)
1759       {
1760          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated UL LC %d already configured",
1761                    lcCfg->lcId);
1762          RETVALUE(RFAILED);
1763       }
1764       dirVld = TRUE;
1765    }
1766
1767    if (!dirVld)
1768    {
1769       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid Direction %d",
1770                lcCfg->dir);
1771       RETVALUE(RFAILED);
1772    }
1773
1774    RETVALUE(ROK);
1775 }  /* rgCFGVldtCrgDedLcCfg */
1776
1777
1778 /***********************************************************
1779  *
1780  *     Func : rgCFGVldtCrgCmnLcCfg
1781  *
1782  *
1783  *     Desc : Validates common logical channel configuration recieved from RRC.
1784  *
1785  *     Ret  : S16
1786  *            ROK - Success
1787  *            RFAILED - Failed
1788  *
1789  *     Notes:
1790  *
1791  *     File :
1792  *
1793  **********************************************************/
1794 #ifdef ANSI
1795 PRIVATE S16 rgCFGVldtCrgCmnLcCfg
1796 (
1797 Inst          inst,
1798 CrgLchCfg     *lcCfg,
1799 RgCellCb      **cell,
1800 RgErrInfo     *errInfo
1801 )
1802 #else
1803 PRIVATE S16 rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)
1804 Inst          inst;
1805 CrgLchCfg     *lcCfg;
1806 RgCellCb      **cell;
1807 RgErrInfo     *errInfo;
1808 #endif
1809 {
1810    U8         dirVld  = FALSE;
1811
1812    TRC2(rgCFGVldtCrgCmnLcCfg);
1813
1814    errInfo->errCause = RGERR_CFG_INVALID_CRG_CMN_LC_CFG;
1815
1816    /* Ensure cell is not in the active list */
1817    if (((*cell = rgCb[inst].cell) != NULLP)
1818       && ((*cell)->cellId != lcCfg->cellId))
1819    {
1820       RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Active Cell exists for common channels");
1821       RETVALUE(RFAILED);
1822    }
1823
1824    /* Fetch the inactive cell for common logical channels */
1825    if (((*cell = rgCb[inst].inactiveCell) == NULLP)
1826         || ((*cell)->cellId != lcCfg->cellId))
1827    {
1828       
1829       RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Inactive Cell does not exist for common channels");
1830       RETVALUE(RFAILED);
1831    }
1832    /* Validate downlink info */
1833    if (lcCfg->dir & CRG_DIR_TX)
1834    {
1835       if (lcCfg->lcType == CM_LTE_LCH_BCCH)
1836       {
1837          if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
1838          {
1839             if (rgDBMGetBcchOnDlsch(*cell,lcCfg->lcId) != NULLP)
1840             {
1841                RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on DLSCH already configured for cell");
1842                RETVALUE(RFAILED);
1843             }
1844          }
1845          else if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_BCH)
1846          {
1847             if (rgDBMGetBcchOnBch(*cell) != NULLP)
1848             {
1849                RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on BCH already configured for cell %d");
1850                RETVALUE(RFAILED);
1851             }
1852          }
1853          else
1854          {
1855             RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid transport channel %d for cell",
1856                   lcCfg->dlInfo.dlTrchType);
1857             RETVALUE(RFAILED);
1858          }
1859       }
1860       else if (lcCfg->lcType == CM_LTE_LCH_PCCH)
1861       {
1862          if (rgDBMGetPcch(*cell) != NULLP)
1863          {
1864             RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"PCCH already configured for cell");
1865             RETVALUE(RFAILED);
1866          }
1867       }
1868       else if (RG_DLCCCH_ISCFGD(*cell))
1869       {
1870          RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"DL CCCH already configured for cell %d");
1871          RETVALUE(RFAILED);
1872       }
1873       dirVld = TRUE;
1874    }
1875
1876    /* Validate uplink info */
1877    if (lcCfg->dir & CRG_DIR_RX)
1878    {
1879       /* Uplink CCCH */
1880       if (lcCfg->lcType != CM_LTE_LCH_CCCH)
1881       {
1882          RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid UL common lcType %d for cell ",
1883                   lcCfg->lcType);
1884          RETVALUE(RFAILED);
1885       }
1886       if (RG_ULCCCH_ISCFGD(*cell))
1887       {
1888          RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"UL CCCH already configured for cell ");
1889          RETVALUE(RFAILED);
1890       }
1891       dirVld = TRUE;
1892    }
1893
1894    /* Invalid direction */
1895    if (!dirVld)
1896    {
1897       RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid Direction %d", lcCfg->dir);
1898       RETVALUE(RFAILED);
1899    }
1900
1901    RETVALUE(ROK);
1902 }  /* rgCFGVldtCrgCmnLcCfg */
1903
1904 /***********************************************************
1905  *
1906  *     Func : rgCFGCrgDedLcCfg
1907  *
1908  *
1909  *     Desc : Handles dedicated logical channel configuration 
1910  *     recieved from RRC.
1911  *
1912  *     Ret  : S16
1913  *            ROK - Success
1914  *            RFAILED - Failed
1915  *
1916  *     Notes:
1917  *
1918  *     File :
1919  *
1920  **********************************************************/
1921 #ifdef ANSI
1922 PRIVATE S16 rgCFGCrgDedLcCfg
1923 (
1924 RgCellCb      *cell,
1925 RgUeCb        *ue,
1926 CrgLchCfg     *lcCfg,
1927 RgErrInfo     *errInfo
1928 )
1929 #else
1930 PRIVATE S16 rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)
1931 RgCellCb      *cell;
1932 RgUeCb        *ue;
1933 CrgLchCfg     *lcCfg;
1934 RgErrInfo     *errInfo;
1935 #endif
1936 {
1937    //Inst     inst = cell->macInst - RG_INST_START;
1938    TRC2(rgCFGCrgDedLcCfg);
1939
1940    errInfo->errCause = RGERR_CFG_CRG_DED_LC_CFG;
1941
1942    /* Uplink/Bi-directional logical channel */
1943    if (lcCfg->dir & CRG_DIR_RX)
1944    {
1945 #ifdef LTE_L2_MEAS
1946       rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId, lcCfg->qci);
1947       cell->qciArray[lcCfg->qci].qci = lcCfg->qci;
1948       if(lcCfg->lcType == CM_LTE_LCH_DTCH)
1949       {
1950         rgAddToL2MeasPerQci(cell,lcCfg->qci);/*LTE_L2_MEAS_PHASE2*/ 
1951       }
1952 #else
1953       rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId);
1954 #endif
1955    }
1956
1957    /* Downlink/Bi-directional logical channel */
1958    if (lcCfg->dir & CRG_DIR_TX)
1959    {
1960       rgDBMInsDlDedLcCb(ue, lcCfg->lcId);
1961    }
1962    RETVALUE(ROK);
1963 }  /* rgCFGCrgDedLcCfg */
1964
1965
1966 /***********************************************************
1967  *
1968  *     Func : rgCFGCrgCmnLcCfg
1969  *
1970  *
1971  *     Desc : Handles dedicated logical channel configuration 
1972  *     recieved from RRC.
1973  *
1974  *     Ret  : S16
1975  *            ROK - Success
1976  *            RFAILED - Failed
1977  *
1978  *     Notes:
1979  *
1980  *     File :
1981  *
1982  **********************************************************/
1983 #ifdef ANSI
1984 PRIVATE S16 rgCFGCrgCmnLcCfg
1985 (
1986 Inst          inst,
1987 RgCellCb      *cell,
1988 CrgLchCfg     *lcCfg,
1989 RgErrInfo     *errInfo
1990 )
1991 #else
1992 PRIVATE S16 rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)
1993 Inst          inst;
1994 RgCellCb      *cell;
1995 CrgLchCfg     *lcCfg;
1996 RgErrInfo     *errInfo;
1997 #endif
1998 {
1999    TRC2(rgCFGCrgCmnLcCfg);
2000
2001    errInfo->errCause = RGERR_CFG_CRG_CMN_LC_CFG;
2002
2003    /* Handle configuration for CCCH/BCCH/PCCH */
2004    if (lcCfg->lcType == CM_LTE_LCH_CCCH)
2005    {
2006       /* UL and DL CCCH configuration */
2007       if (lcCfg->dir & CRG_DIR_TX)
2008       {
2009          cell->dlCcchId = lcCfg->lcId;
2010          cell->cellActvState |= RG_DL_CCCH_CFG_DONE;
2011       }
2012
2013       if (lcCfg->dir & CRG_DIR_RX)
2014       {
2015          cell->ulCcchId = lcCfg->lcId;
2016          cell->cellActvState |= RG_UL_CCCH_CFG_DONE;
2017       }
2018    }
2019    else
2020    {
2021       if (lcCfg->lcType == CM_LTE_LCH_BCCH)
2022       {
2023          /* BCCH on BCH and DLSCH configuration */
2024          if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
2025          {
2026             rgDBMInsBcchOnDlsch(cell, lcCfg->lcId);
2027             
2028             if(cell->cellActvState & RG_BCCH_DLSCH_CFG1_DONE)
2029             {
2030                cell->cellActvState |= RG_BCCH_DLSCH_CFG2_DONE;
2031             }
2032             else
2033             {
2034                cell->cellActvState |= RG_BCCH_DLSCH_CFG1_DONE;
2035             }
2036          }
2037          else
2038          {
2039             rgDBMInsBcchOnBch(cell, lcCfg->lcId);
2040             cell->cellActvState |= RG_BCCH_BCH_CFG_DONE;
2041          }
2042       }
2043       else  /* PCCH configuration */
2044       {
2045          rgDBMInsPcch(cell, lcCfg->lcId);
2046          cell->cellActvState |= RG_PCCH_CFG_DONE;
2047       }
2048    }
2049
2050    /* Add to active cell list if cell is active */
2051    if (cell->cellActvState == RG_CELL_ACTIVE)
2052    {
2053       rgCb[inst].cell = cell;
2054       rgCb[inst].inactiveCell = NULLP;
2055       RLOG_ARG1(L_DEBUG, DBG_CELLID, cell->cellId, "Cell %d added to active list after common LC %d\
2056                config\n", lcCfg->lcId);
2057    }
2058
2059    RETVALUE(ROK);
2060 }  /* rgCFGCrgCmnLcCfg */
2061 #ifdef LTE_L2_MEAS
2062 /***********************************************************
2063  *
2064  *     Func : rgCFGFreeUeUlAlloc 
2065  *
2066  *
2067  *     Desc :
2068  *     - Processing Steps:
2069  *        - Frees cell control block.
2070  *
2071  *     Ret  : Void
2072  *
2073  *     Notes:
2074  *
2075  *     File :
2076  *
2077  **********************************************************/
2078 #ifdef ANSI
2079 PRIVATE Void rgCFGFreeUeUlAlloc
2080 (
2081 RgCellCb      *cell
2082 )
2083 #else
2084 PRIVATE Void rgCFGFreeUeUlAlloc(cell)
2085 RgCellCb      *cell;
2086 #endif
2087 {
2088    U8    sfIdx;
2089    Inst inst = cell->macInst - RG_INST_START;
2090    
2091    TRC2(rgCFGFreeUeUlAlloc);
2092
2093    for(sfIdx = 0; sfIdx < RG_NUM_UL_SUB_FRAMES; sfIdx++)
2094    {
2095       if(cell->ulSf[sfIdx].ueUlAllocInfo != NULLP)
2096       {
2097          /*ccpu00117052 - MOD- Passing double pointer for proper
2098           *                    NULLP assignment */
2099          rgFreeSBuf(inst,(Data **)&(cell->ulSf[sfIdx].ueUlAllocInfo), 
2100                (cell->ulSf[sfIdx].numUe * sizeof(RgUeUlAlloc)));
2101       }
2102    }
2103 }/* rgCFGFreeUeUlAlloc */
2104 #endif
2105 /***********************************************************
2106  *
2107  *     Func : rgCFGFreeCellCb
2108  *
2109  *
2110  *     Desc :
2111  *     - Processing Steps:
2112  *        - Frees cell control block.
2113  *
2114  *     Ret  : Void
2115  *
2116  *     Notes:
2117  *
2118  *     File :
2119  *
2120  **********************************************************/
2121 #ifdef ANSI
2122 PUBLIC Void rgCFGFreeCellCb
2123 (
2124 RgCellCb      *cell
2125 )
2126 #else
2127 PUBLIC Void rgCFGFreeCellCb(cell)
2128 RgCellCb      *cell;
2129 #endif
2130 {
2131    Inst inst = cell->macInst - RG_INST_START;
2132    TRC2(rgCFGFreeCellCb);
2133
2134 #ifdef LTE_ADV
2135    RgLaaCellCbDeInit(cell);
2136 #endif
2137    /* Free lists of the cell */
2138 #ifdef LTEMAC_SPS
2139    rgCFGFreeSpsUeLst(cell);
2140 #endif /* LTEMAC_SPS */
2141    rgCFGFreeUeLst(cell);
2142    rgRAMFreeCell(cell);
2143    rgCFGFreeCmnLcLst(cell);
2144 #ifdef LTE_L2_MEAS
2145    rgCFGFreeUeUlAlloc(cell);
2146 #endif
2147    /* ccpu00117052 - MOD - Passing double pointer for proper NULLP 
2148                            assignment */
2149    /* Update satistics */
2150    rgUpdtCellCnt(inst,RG_CFG_DEL);
2151    rgDHMFreeAllTbBufs(inst);
2152
2153    rgFreeSBuf(inst,(Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
2154
2155    /* De-allocate the Cell */
2156    rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
2157  
2158
2159    RGDBGINFO(inst,(rgPBuf(inst), "Cell freed\n"));
2160
2161   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2162   RETVOID; 
2163 }  /* rgCFGFreeCellCb */
2164
2165
2166 /***********************************************************
2167  *
2168  *     Func : rgCFGFreeInactvCellCb
2169  *
2170  *
2171  *     Desc :
2172  *     - Processing Steps:
2173  *        - Frees inactive cell control block.
2174  *
2175  *     Ret  : Void
2176  *
2177  *     Notes:
2178  *
2179  *     File :
2180  *
2181  **********************************************************/
2182 #ifdef ANSI
2183 PUBLIC Void rgCFGFreeInactvCellCb
2184 (
2185 RgCellCb      *cell
2186 )
2187 #else
2188 PUBLIC Void rgCFGFreeInactvCellCb(cell)
2189 RgCellCb      *cell;
2190 #endif
2191 {
2192    Inst      inst = cell->macInst - RG_INST_START;
2193    TRC2(rgCFGFreeInactvCellCb);
2194    
2195    /* De-initialize the Ue list */
2196    rgDBMDeInitUeCbLst(cell);
2197 #ifdef LTEMAC_SPS
2198    rgDBMDeInitSpsUeCbLst(cell);
2199 #endif
2200
2201    rgCFGFreeCmnLcLst(cell);
2202
2203    rgFreeSBuf(inst, (Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
2204    /*ccpu00117052 - MOD- Passing double pointer for proper
2205                         NULLP assignment */
2206    /* De-allocate the Cell */
2207    rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
2208
2209    /* Update satistics */
2210    rgUpdtCellCnt(inst,RG_CFG_DEL);
2211
2212
2213   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2214   RETVOID; 
2215 }  /* rgCFGFreeInactvCellCb */
2216
2217
2218 /***********************************************************
2219  *
2220  *     Func : rgCFGFreeUeCb
2221  *
2222  *
2223  *     Desc :
2224  *     - Processing Steps:
2225  *        - Frees UE control block.
2226  *
2227  *     Ret  : Void
2228  *
2229  *     Notes:
2230  *
2231  *     File :
2232  *
2233  **********************************************************/
2234 #ifdef ANSI
2235 PUBLIC Void rgCFGFreeUeCb
2236 (
2237 RgCellCb    *cell,
2238 RgUeCb      *ue
2239 )
2240 #else
2241 PUBLIC Void rgCFGFreeUeCb(cell, ue)
2242 RgCellCb    *cell;
2243 RgUeCb      *ue;
2244 #endif
2245 {
2246    Inst inst = cell->macInst - RG_INST_START;
2247
2248    TRC2(rgCFGFreeUeCb);
2249
2250    rgDHMFreeUe(inst,&ue->dl.hqEnt);
2251
2252    /* ccpu00117052 - MOD - Passing double pointer for proper NULLP
2253                           assignment */
2254    /* De-allocate the Ue */
2255    rgFreeSBuf(inst,(Data **)&ue, sizeof(*ue));
2256
2257    /* Update Statistics */
2258    rgUpdtUeCnt(inst,RG_CFG_DEL);
2259
2260
2261   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2262   RETVOID; 
2263 }  /* rgCFGFreeUeCb */
2264
2265 /***********************************************************
2266  *
2267  *     Func : rgCFGFreeCmnLcLst
2268  *
2269  *
2270  *     Desc :
2271  *     - Processing Steps:
2272  *        - Frees common logical channels in cell control block.
2273  *
2274  *     Ret  : Void
2275  *
2276  *     Notes:
2277  *
2278  *     File :
2279  *
2280  **********************************************************/
2281 #ifdef ANSI
2282 PRIVATE Void rgCFGFreeCmnLcLst
2283 (
2284 RgCellCb      *cell
2285 )
2286 #else
2287 PRIVATE Void rgCFGFreeCmnLcLst(cell)
2288 RgCellCb      *cell;
2289 #endif
2290 {
2291    TRC2(rgCFGFreeCmnLcLst);
2292
2293    rgDBMFreeCmnLcLst(cell);
2294
2295
2296   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2297   RETVOID; 
2298 }  /* rgCFGFreeCmnLcLst */
2299
2300
2301 /***********************************************************
2302  *
2303  *     Func : rgCFGFreeUeLst
2304  *
2305  *
2306  *     Desc :
2307  *     - Processing Steps:
2308  *        - Frees UE list in cell control block.
2309  *
2310  *     Ret  : Void
2311  *
2312  *     Notes:
2313  *
2314  *     File :
2315  *
2316  **********************************************************/
2317 #ifdef ANSI
2318 PRIVATE Void rgCFGFreeUeLst
2319 (
2320 RgCellCb      *cell
2321 )
2322 #else
2323 PRIVATE Void rgCFGFreeUeLst(cell)
2324 RgCellCb      *cell;
2325 #endif
2326 {
2327    RgUeCb     *ue;
2328
2329    TRC2(rgCFGFreeUeLst);
2330
2331    /* Free Ues in the list */
2332    while ((ue = rgDBMGetNextUeCb(cell, NULLP)) != NULLP)
2333    {
2334 #ifdef LTE_ADV
2335       rgDelUeFrmAllSCell(cell,ue);
2336 #endif
2337       rgDBMDelUeCb(cell, ue);
2338       rgCFGFreeUeCb(cell, ue);
2339    }
2340
2341    /* De-initialize the Ue list */
2342    rgDBMDeInitUeCbLst(cell);
2343
2344
2345   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2346   RETVOID; 
2347 }  /* rgCFGFreeUeLst */
2348
2349 #ifdef LTEMAC_SPS
2350 /***********************************************************
2351  *
2352  *     Func : rgCFGFreeSpsUeLst
2353  *
2354  *
2355  *     Desc :
2356  *     - Processing Steps:
2357  *        - Frees Sps UE list in cell control block.
2358  *
2359  *     Ret  : Void
2360  *
2361  *     Notes:
2362  *
2363  *     File :
2364  *
2365  **********************************************************/
2366 #ifdef ANSI
2367 PRIVATE Void rgCFGFreeSpsUeLst
2368 (
2369 RgCellCb      *cell
2370 )
2371 #else
2372 PRIVATE Void rgCFGFreeSpsUeLst(cell)
2373 RgCellCb      *cell;
2374 #endif
2375 {
2376    RgUeCb     *ue;
2377
2378    TRC2(rgCFGFreeSpsUeLst);
2379
2380    /* Free Ues in the list */
2381    while ((ue = rgDBMGetNextSpsUeCb(cell, NULLP)))
2382    {
2383       rgDBMDelSpsUeCb(cell, ue);
2384    }
2385
2386    /* De-initialize the Ue list */
2387    rgDBMDeInitSpsUeCbLst(cell);
2388
2389 }  /* rgCFGFreeSpsUeLst */
2390
2391 #endif /* LTEMAC_SPS */
2392
2393 /**
2394  * @brief Function for registering cell- scheduler instance mapping
2395  *
2396  * @details
2397  *
2398  *     Function : RgSchMacCellRegReq
2399  *     
2400  *     This function shall be invoked whenever scheduler is done with the
2401  *     cell configuration successfully.
2402  *     This shall create a mapping of the cell, scheduler instance that
2403  *     is serving the cell and the unique identifier of the cell on the 
2404  *     scheduler at MAC. This mapping shall be used for further 
2405  *     communication to the scheduler instance for this cell.
2406  *     
2407  *           
2408  *  @param[in] Pst*                pst,
2409  *  @param[in] CmLteCellId         cellId,
2410  *  @param[in] RaRespReqInfo       raRespReq
2411  *  @return  S16
2412  *      -# ROK 
2413  **/
2414 #ifdef ANSI
2415 PUBLIC S16 RgSchMacCellRegReq
2416 (
2417 Pst*                pst,
2418 RgInfCellReg*       regReq 
2419 )
2420 #else
2421 PUBLIC S16 RgSchMacCellRegReq(pst, regReq)
2422 Pst*                pst;
2423 RgInfCellReg*       regReq;
2424 #endif
2425 {
2426    Inst      inst;
2427    RgCellCb *cell = NULLP;
2428
2429    TRC3(RgSchMacCellRegReq)
2430
2431    RG_IS_INST_VALID(pst->dstInst);
2432    inst = pst->dstInst - RG_INST_START;
2433    cell = rgCb[inst].cell;
2434
2435    if(NULLP == regReq)
2436    {
2437       RETVALUE(RFAILED);
2438    }
2439       
2440    if((cell  == NULLP) || (cell->cellId != regReq->cellId))
2441    {
2442       RETVALUE(RFAILED);
2443    }
2444    if(regReq->maxDlHqProcPerUe > RG_MAX_DL_HARQ_NUM) 
2445    {
2446       RETVALUE(RFAILED);
2447    }
2448    /* Initialize */
2449    cell->schInstMap.cellSapId = regReq->cellSapId;
2450    cell->schInstMap.schInst   = pst->srcInst;
2451    cell->maxDlHqProcPerUe = regReq->maxDlHqProcPerUe;
2452
2453    RETVALUE(ROK);
2454
2455 } /* end of RgSchMacCellRegReq */
2456
2457 /*Added Ue for Onging L2 Meas*/
2458 #ifdef LTE_L2_MEAS
2459 /*LTE_L2_MEAS_PHASE2*/
2460 PUBLIC S16 rgAddToL2MeasPerQci(RgCellCb  *cell,U8 qci)
2461 {
2462  S16      ret = ROK;    
2463  CmLList   *lnk;
2464  RgL2MeasCb  *measCb;
2465  U16          idx;
2466  
2467  lnk = cell->l2mList.first;
2468   while(lnk != NULLP )
2469    {
2470       measCb = (RgL2MeasCb *)lnk->node;
2471       if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)
2472       {
2473               for(idx = 0;idx< measCb->measReq.t.prbReq.numQci;idx++)
2474               {
2475                       if(measCb->measReq.t.prbReq.qci[idx] == qci)
2476                       {
2477                               break; /*exit from for loop*/
2478                       } 
2479               } 
2480               if(idx == measCb->measReq.t.prbReq.numQci)
2481               {
2482                       cell->qciArray[qci].mask = TRUE; 
2483                       measCb->measReq.t.prbReq.qci[measCb->measReq.t.prbReq.numQci++] = qci;
2484               }         
2485       }           
2486       lnk = lnk->next;
2487    }  /* End of While*/
2488  
2489                  
2490        
2491  RETVALUE(ret);
2492 }
2493
2494
2495 #endif
2496
2497 /**********************************************************************
2498  
2499          End of file
2500 **********************************************************************/