a7d4ba9f7b124991b3ecfbc65e43d388b8e4358f
[o-du/l2.git] / src / 5gnrsch / rg_sch_pwr.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 power control functionality
26  
27      File:     rg_sch_pwr.c
28  
29 **********************************************************************/
30
31 /** @file rg_sch_pwr.c
32 @brief This module handles schedulers' power control functionality
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=188;
38 /* header include files -- defines (.h) */
39 #include "envopt.h"        /* environment options */
40 #include "envdep.h"        /* environment dependent */
41 #include "envind.h"        /* environment independent */
42 #include "gen.h"           /* general layer */
43 #include "ssi.h"           /* system service interface */
44 #include "cm_hash.h"       /* common hash list */
45 #include "cm_llist.h"      /* common linked list library */
46 #include "cm_err.h"        /* common error */
47 #include "cm_lte.h"        /* common LTE */
48 #include "cm_math.h"       /* common MATH functions */
49 #include "lrg.h"
50 #include "rgr.h"
51 #include "rgm.h"
52 #include "tfu.h"
53 #include "rg_env.h"
54 #include "rg_sch_inf.h"
55 #include "rg_sch_err.h"
56 #include "rg_sch.h"
57 #include "rg_sch_cmn.h"
58
59 /* header/extern include files (.x) */
60 #include "gen.x"           /* general layer typedefs */
61 #include "ssi.x"           /* system services typedefs */
62 #include "cm5.x"           /* common timers */
63 #include "cm_hash.x"       /* common hash list */
64 #include "cm_lib.x"        /* common library */
65 #include "cm_llist.x"      /* common linked list */
66 #include "cm_mblk.x"       /* memory management */
67 #include "cm_tkns.x"       /* common tokens */
68 #include "cm_lte.x"        /* common tokens */
69 #include "cm_math.x"       /* common MATH functions */
70 #include "tfu.x"           /* RGU types */
71 #include "lrg.x"           /* layer management typedefs for MAC */
72 #include "rgr.x"           /* layer management typedefs for MAC */
73 #include "rgm.x"           /* layer management typedefs for MAC */
74 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
75 #include "rg_sch.x"        /* typedefs for Scheduler */
76 #include "rg_sch_cmn.x"
77 #include "rl_interface.h"
78 #include "rl_common.h"
79
80
81 /* Current specs have 23 dBm as max tx power capability for UEs */
82 #define RG_SCH_PWR_UE_MAX_PWR    23
83
84 #define RG_SCH_REF_PCMAX         0xFF
85
86 #define RG_SCH_CMN_GET_UL_UE(_ue,_cell) (&(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\
87                [RG_SCH_CELLINDEX(_cell)]])->sch))->ul))
88 #define RG_SCH_PWR_GETUEPWR(_ue, _cell) &(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\
89                [RG_SCH_CELLINDEX(_cell)]])->sch))->ul.ulPwrCb)
90 #define RG_SCH_PWR_GETCELLPWR(cell) &((RgSchCmnCell *)((cell)->sc.sch))->ul.ulPwrCb
91
92
93 typedef S8 RgSchCmnUlPwrCqiToPwrTbl[RG_SCH_CMN_UL_NUM_CQI];
94
95 PRIVATE RgSchCmnUlPwrCqiToPwrTbl rgSchPwrCqiToPwrTbl;
96
97 /* This table maps a given number of RBs (given by array index)
98  * to the power in dB that these many RBs map to. */
99 CONSTANT U8 rgSchPwrRbToPwrTbl[111] = { 0,    /* First entry is dummy */
100    0,  3,  4,  6,  7,  7,  8,  9,  9,  10,
101    10, 10, 11, 11, 11, 12, 12, 12, 12, 13,
102    13, 13, 13, 13, 14, 14, 14, 14, 14, 14,
103    15, 15, 15, 15, 15, 15, 15, 15, 16, 16,
104    16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
105    17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
106    17, 18, 18, 18, 18, 18, 18, 18, 18, 18,
107    18, 18, 18, 18, 18, 18, 18, 19, 19, 19,
108    19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
109    19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
110    20, 20, 20, 20, 20, 20, 20, 20, 20, 20
111 };
112
113
114 /* This table maps power (in dB) to number of RBs */
115 /* The array size comes from max power in rgSchPwrRbToPwrTbl */
116 CONSTANT U8 rgSchPwrToRbTbl[20+1] = {
117   1, 1, 2, 2, 3, 4, 5, 6, 7, 9, 11,
118   13, 17, 21, 26, 33, 41, 52, 65, 82, 103 
119 };
120
121
122
123 PRIVATE S8 rgSCHPwrGetCqiPwr ARGS((
124          U8                  cqi
125          ));
126 PRIVATE S8 rgSCHPwrGetCqiPwrForUe ARGS((
127          RgSchCellCb          *cell,
128          RgSchUeCb          *ue,
129          U8                  cqi
130          ));
131 PRIVATE S8 rgSCHPwrCalcEfficncyPwr ARGS((
132          U32                 eff
133          ));
134 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi ARGS((
135          U8                  crntCqi,
136          U8                  trgCqi,
137          RgSchUeCb           *ue,
138          RgSchCellCb         *cell
139          ));
140 PRIVATE Void rgSCHPwrGetPuschTpc ARGS((
141          U8                  isAcc,
142          S8                  delta,
143          S8                  availPwr,
144          U8                 *tpc,
145          S8                 *tpcDelta
146          ));
147 PRIVATE U8 rgSCHPwrGetMaxRb ARGS((
148          RgSchCellCb          *cell,
149          S8                  pwr
150          ));
151 PRIVATE U8 rgSCHPwrRbToPwr ARGS((
152          RgSchCellCb          *cell,
153          U8                  numRb
154          ));
155 PRIVATE Void rgSCHPwrSchedPucchRnti ARGS((
156          RgSchCellCb          *cell,
157          RgSchCmnTpcRntiCb    *cb,
158          RgSchPdcch           *pdcch,
159          RgSchDlSf            *dlSf,
160          Bool                 *sched
161          ));
162 PRIVATE Void rgSCHPwrPuschCntrl ARGS((
163          RgSchCellCb          *cell,
164          RgSchUeCb            *ue
165          ));
166 PRIVATE Void rgSCHPwrPucchCntrl ARGS((
167          RgSchCellCb *cell,
168          RgSchUeCb   *ue
169          ));
170 PRIVATE Void rgSCHPwrSchedPuschRnti ARGS((
171          RgSchCellCb          *cell,
172          RgSchCmnTpcRntiCb    *cb,
173          RgSchPdcch           *pdcch,
174          RgSchUlSf            *ulSf,
175          Bool                 *sched
176          ));
177 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe ARGS((
178          RgSchUeCb            *ue,
179          U8                   *tpc,
180          S8                   *delta
181          ));
182 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe ARGS((
183          RgSchUeCb            *ue,
184          U8                   *tpc,
185          S8                   *delta
186          ));
187 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe ARGS((
188          RgSchUeCb            *ue,
189          U8                   *tpc,
190          S8                   *delta
191          ));
192 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe ARGS((
193          RgSchUeCb            *ue,
194          U8                   *tpc,
195          S8                   *delta
196          ));
197 PRIVATE Void rgSCHPwrGetAcc1bitTpc ARGS((
198          S8                    remPwr,
199          U8                   *tpc,
200          S8                   *delta
201          ));
202 PRIVATE Void rgSCHPwrGetAcc2bitTpc ARGS((
203          S8                   remPwr,
204          U8                  *tpc,
205          S8                  *delta
206          ));
207 PRIVATE Void rgSCHPwrGetAbsTpc ARGS((
208          S8                   remPwr,
209          U8                  *tpc,
210          S8                  *delta
211          ));
212 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe  ARGS((
213          RgSchCellCb          *cell,
214          RgSchUeCb            *ue,
215          S8                    delta
216          ));
217 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe  ARGS((
218          RgSchCellCb          *cell,
219          RgSchUeCb            *ue,
220          S8                    delta
221          ));
222 PRIVATE Bool rgSCHPwrIsDlUeSched ARGS((
223          RgSchCellCb            *cell,
224          RgSchUeCb            *ue,
225          RgSchDlSf            *sf
226          ));
227 PRIVATE Bool rgSCHPwrIsUlUeSched ARGS((
228          RgSchCellCb          *cell,
229          RgSchUeCb            *ue,
230          RgSchUlSf            *sf
231          ));
232 PRIVATE Void rgSCHPwrOnSchedPucchTpc ARGS((
233          RgSchCellCb           *cell,
234          RgSchUeCb             *ue,
235          S8                     delta
236          ));
237 PRIVATE Void rgSCHPwrOnSchedPuschTpc ARGS((
238          RgSchCellCb           *cell,
239          RgSchUeCb             *ue
240          ));
241 PRIVATE S16 rgSCHPwrApplyUePwrCfg  ARGS((
242          RgSchCellCb          *cell,
243          RgSchUeCb            *ue,
244          RgrUeUlPwrCfg        *pwrCfg
245          ));
246 PRIVATE Void rgSCHPwrUeResetPucch ARGS((
247          RgSchCellCb          *cell,
248          RgSchUeCb            *ue
249          ));
250 PRIVATE Void rgSCHPwrUeResetPusch ARGS((
251          RgSchCellCb          *cell,
252          RgSchUeCb            *ue
253          ));
254 PRIVATE Void rgSCHPwrOnPuschPwrUpd ARGS((
255          RgSchCellCb          *cell,
256          RgSchUeCb            *ue
257          ));
258 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst  ARGS((
259          RgSchCellCb          *cell,
260          CmLteRnti             rnti,
261          Bool                  isFmt3a
262          ));
263 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst  ARGS((
264          RgSchCellCb          *cell,
265          CmLteRnti             rnti,
266          Bool                  isFmt3a
267          ));
268 PRIVATE Void rgSCHPwrInitTpcRntiCb  ARGS((
269          RgSchCmnTpcRntiCb    *cb,
270          CmLteRnti             rnti,
271          Bool                  isFmt3a
272          ));
273 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb ARGS((
274          RgSchCellCb *cell,
275          CmLteRnti   tpcRnti
276          ));
277 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb ARGS((
278          RgSchCellCb *cell,
279          CmLteRnti   tpcRnti
280          ));
281 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb ARGS((
282          RgSchCellCb           *cell,
283          RgSchCmnTpcRntiCb     *cb,
284          RgSchUeCb             *ue
285          ));
286 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb ARGS((
287          RgSchCellCb           *cell,
288          RgSchCmnTpcRntiCb     *cb,
289          RgSchUeCb             *ue
290          ));
291 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb ARGS((
292          RgSchCellCb           *cell,
293          RgSchCmnTpcRntiCb     *cb,
294          RgSchUeCb             *ue
295          ));
296 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb ARGS((
297          RgSchCellCb           *cell,
298          RgSchCmnTpcRntiCb     *cb,
299          RgSchUeCb             *ue
300          ));
301 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb ARGS((
302          RgSchCellCb           *cell,
303          RgSchCmnTpcRntiCb     *cb
304          ));
305 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb ARGS((
306          RgSchCellCb           *cell,
307          RgSchCmnTpcRntiCb     *cb,
308          RgSchUeCb             *ue
309          ));
310 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb ARGS((
311          RgSchCellCb           *cell,
312          RgSchCmnTpcRntiCb     *cb
313          ));
314 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb ARGS((
315          RgSchCmnTpcRntiCb     *cb,
316          RgSchUeCb             *ue
317          ));
318 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb ARGS((
319          RgSchCellCb           *cell,
320          RgSchCmnTpcRntiCb     *cb,
321          RgSchUeCb             *ue
322          ));
323 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb ARGS((
324          RgSchCellCb           *cell,
325          RgSchCmnTpcRntiCb     *cb,
326          RgSchUeCb             *ue
327          ));
328 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb ARGS((
329          RgSchCellCb           *cell,
330          RgSchCmnTpcRntiCb     *cb,
331          RgSchUeCb             *ue
332          ));
333 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb ARGS((
334          RgSchCellCb           *cell,
335          RgSchCmnTpcRntiCb     *cb,
336          RgSchUeCb             *ue
337          ));
338 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb ARGS((
339          RgSchCellCb           *cell,
340          RgSchCmnTpcRntiCb     *cb
341          ));
342 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb ARGS((
343          RgSchCellCb           *cell,
344          RgSchCmnTpcRntiCb     *cb
345          ));
346 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx ARGS((
347          RgSchCmnTpcRntiCb     *cb,
348          U8                     idx
349          ));
350 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx ARGS((
351          RgSchCmnTpcRntiCb     *cb,
352          U8                     idx
353          ));
354 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx ARGS((
355          RgSchCmnTpcRntiCb     *cb,
356          U8                     idx
357          ));
358 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx ARGS((
359          RgSchCmnTpcRntiCb     *cb,
360          U8                     idx
361          ));
362 PRIVATE S16 rgSCHPwrChkTpcRntiIdx ARGS((
363          RgSchCmnTpcRntiCb     *cb,
364          U8                     idx
365          ));
366 PRIVATE S8 rgSCHPwrGetPhValFromPhr ARGS((
367          U8                    phr
368          ));
369 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax ARGS((
370          U8                    pCMax
371          ));
372
373 /* local defines */
374
375
376 /**
377  * @brief Does power related initialisation (not cell specific).
378  *        
379  *
380  * @details
381  *
382  *     Function : rgSCHPwrInit
383  *
384  *     Processing Steps:
385  *      - This shall precompute coding efficiency to power
386  *        mappings (assuming beta of 1).
387  *
388  *  @return  Void
389  **/
390 #ifdef ANSI
391 PUBLIC Void rgSCHPwrInit
392 (
393 Void
394 )
395 #else
396 PUBLIC Void rgSCHPwrInit()
397 #endif
398 {
399    U8             idx;
400    TRC2(rgSCHPwrInit);
401
402    rgSchPwrCqiToPwrTbl[0] = 0;  /* This should never be used anyway */
403    for (idx = 1; idx < RG_SCH_CMN_UL_NUM_CQI; ++idx)
404    {
405       rgSchPwrCqiToPwrTbl[idx] = rgSCHPwrCalcEfficncyPwr(rgSchCmnUlCqiTbl[idx].eff);
406    }
407    RETVOID;
408 }
409
410 /***********************************************************
411  *
412  *     Func : rgSCHPwrGetCqiPwr
413  *
414  *     Desc : Returns power corresponding to coding efficiency
415  *            when beta pusch is assumed 1.
416  *
417  *     Ret  : U8
418  *
419  *     Notes:
420  *
421  *     File :
422  *
423  **********************************************************/
424 #ifdef ANSI
425 PRIVATE S8 rgSCHPwrGetCqiPwr
426 (
427 U8                  cqi
428 )
429 #else
430 PRIVATE S8 rgSCHPwrGetCqiPwr(cqi)
431 U8                  cqi;
432 #endif
433 {
434    TRC2(rgSCHPwrGetCqiPwr);
435
436    RETVALUE(rgSchPwrCqiToPwrTbl[cqi]);
437 }  /* rgSCHPwrGetCqiPwr */
438
439 /***********************************************************
440  *
441  *     Func : rgSCHPwrGetCqiPwrForUe
442  *
443  *     Desc : If MCS control is enabled for UE, returns
444  *            power corresponding to CQI, else 0.
445  *
446  *     Ret  : U8
447  *
448  *     Notes:
449  *
450  *     File :
451  *
452  **********************************************************/
453 #ifdef ANSI
454 PRIVATE S8 rgSCHPwrGetCqiPwrForUe
455 (
456 RgSchCellCb        *cell,
457 RgSchUeCb          *ue,
458 U8                  cqi
459 )
460 #else
461 PRIVATE S8 rgSCHPwrGetCqiPwrForUe(cell, ue, cqi)
462 RgSchCellCb        *cell;
463 RgSchUeCb          *ue;
464 U8                  cqi;
465 #endif
466 {
467    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
468    TRC2(rgSCHPwrGetCqiPwrForUe);
469
470    if (!uePwr->deltaMcsEnbld)
471    {
472       RETVALUE(0);
473    }
474    RETVALUE(rgSCHPwrGetCqiPwr(cqi));
475 }  /* rgSCHPwrGetCqiPwrForUe */
476
477 /***********************************************************
478  *
479  *     Func : rgSCHPwrCalcEfficncyPwr
480  *
481  *     Desc : Computes power corresponding to a coding
482  *            efficiency.
483  *
484  *     Ret  : U8
485  *
486  *     Notes: Assumes beta pusch to be 1
487  *
488  *     File :
489  *
490  **********************************************************/
491 #ifdef ANSI
492 PRIVATE S8 rgSCHPwrCalcEfficncyPwr
493 (
494 U32                 eff
495 )
496 #else
497 PRIVATE S8 rgSCHPwrCalcEfficncyPwr(eff)
498 U32                 eff;
499 #endif
500 {
501    F64          ks = 1.25; /* or F64 */
502    F64          tmp = cmPow(2, ks*eff/1024) - 1;
503    TRC2(rgSCHPwrCalcEfficncyPwr);
504
505    if (tmp <= 0)
506       RETVALUE(0);
507    RETVALUE((S8)(10 * cmLog10(tmp)));
508 }  /* rgSCHPwrCalcEfficncyPwr */
509
510
511 /**
512  * @brief Returns TPC to be sent in UL allocation
513  *
514  * @details
515  *
516  *     Function : rgSCHPwrPuschTpcForUe
517  *
518  *     Invoking Module Processing:
519  *      - After allocation for UE, this function shall
520  *        be invoked to retrieve TPC.
521  *      - This assumes that rgSCHPwrGetMaxUlRb() was
522  *        invoked prior to final allocation for UE.
523  *        
524  *     Processing Steps:
525  *     - Just return TPC that was determined
526  *       earlier.
527  *     - After this, do necessary updates.
528  *
529  *  @param[in]  RgSchCellCb  *cell
530  *  @param[in]  RgSchUeCb    *ue
531  *  @return  U8
532  **/
533 #ifdef ANSI
534 PUBLIC U8 rgSCHPwrPuschTpcForUe
535 (
536 RgSchCellCb *cell,
537 RgSchUeCb   *ue
538 )
539 #else
540 PUBLIC U8 rgSCHPwrPuschTpcForUe(cell, ue)
541 RgSchCellCb *cell;
542 RgSchUeCb   *ue;
543 #endif
544 {
545    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue,cell);
546
547    UNUSED(cell);
548    TRC2(rgSCHPwrPuschTpcForUe);
549
550    rgSCHPwrOnSchedPuschTpc(cell, ue);
551    RETVALUE(uePwr->puschTpc);
552 }
553
554 /**
555  * @brief Handles Pusch power control for DCI format 0
556  *
557  * @details
558  *
559  *     Function : rgSCHPwrGetMaxUlRb
560  *
561  *     Invoking Module Processing:
562  *      - This shall be invoked to determine maximum
563  *        number of UL RBs for scheduling.
564  *      - This is expected to be invoked every time
565  *        priority to attempt at UE allocation. Later
566  *        TPC retrieval depends on it.
567  *
568  *     Processing Steps:
569  *     - Returns maximum allowed UL RBs to be granted
570  *       after invoking Pusch power control.
571  *
572  *  @param[in]  RgSchCellCb  *cell
573  *  @param[in]  RgSchUeCb    *ue
574  *  @return  Void
575  **/
576 #ifdef ANSI
577 PUBLIC U8 rgSCHPwrGetMaxUlRb
578 (
579 RgSchCellCb *cell,
580 RgSchUeCb   *ue
581 )
582 #else
583 PUBLIC U8 rgSCHPwrGetMaxUlRb(cell, ue)
584 RgSchCellCb *cell;
585 RgSchUeCb   *ue;
586 #endif
587 {
588    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
589    TRC2(rgSCHPwrGetMaxUlRb);
590
591    rgSCHPwrPuschCntrl(cell, ue); /* This stores tpc, delta and maxRb
592                                   * in uePwr */
593    RETVALUE(uePwr->maxUlRbs);
594 }
595
596 /**
597  * @brief Handles Pusch power control for DCI format 0
598  *
599  * @details
600  *
601  *     Function : rgSCHPwrPuschCntrl
602  *
603  *     Invoking Module Processing:
604  *      - This shall be invoked to determine TPC
605  *      and maximum number of UL RBs for scheduling
606  *      (through DCI format 0).
607  *
608  *     Processing Steps:
609  *     - 'remPuschPwr' is the final delta power that the UE
610  *       should apply to get to target CQI.
611  *     - The available headroom (availPwr) is determined.
612  *     - Power command is given by considering remPuschPwr and
613  *       availPwr.
614  *     - After factoring in the power command into availPwr, the
615  *       maximum number of RBs that can be supported is determined
616  *       assuming that UE is going to use transmission efficiency
617  *       corresponding to current CQI.
618  *     - The results determined in this function are stored
619  *       in the UE power control block.
620  *     - [Not doing anything of power control of msg3
621  *        retransmissions now]
622  *
623  *  @param[in]  RgSchCellCb  *cell
624  *  @param[in]  RgSchUeCb    *ue
625  *  @return  Void
626  **/
627 #ifdef ANSI
628 PRIVATE Void rgSCHPwrPuschCntrl
629 (
630 RgSchCellCb *cell,
631 RgSchUeCb   *ue
632 )
633 #else
634 PRIVATE Void rgSCHPwrPuschCntrl(cell, ue)
635 RgSchCellCb *cell;
636 RgSchUeCb   *ue;
637 #endif
638 {
639    RgSchCmnUlUe       *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
640    RgSchCmnUeUlPwrCb  *uePwr   = RG_SCH_PWR_GETUEPWR(ue, cell);
641    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
642    S8                  delta;
643 #ifdef TFU_UPGRADE
644    U8                  cqi     = ueUl->validUlCqi;
645    S32                 tmp;
646 #else
647    U8                  cqi     = ueUl->crntUlCqi[0];
648 #endif
649    Bool                isAcc   = uePwr->isAccumulated;
650    U8                  tpc;
651    S8                  availPwr;
652    U8                  maxRb;
653
654    UNUSED(cell);
655
656    TRC2(rgSCHPwrPuschCntrl);
657
658    if (!uePwr->isPhrAvail)
659    {
660       availPwr = 60; /* setting a large value so that availPwr does
661                       * not constrain delta */
662    }
663    else
664    {
665       availPwr = uePwr->maxUePwr - uePwr->pwrPerRb;
666       availPwr -= rgSCHPwrGetCqiPwrForUe(cell, ue, cqi);
667    }
668    delta = uePwr->remPuschPwr;
669    rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, &tpc, &delta);
670    availPwr -= delta;
671
672    maxRb = rgSCHPwrGetMaxRb(cell,availPwr);
673
674    /* Store the results in ue power control block to be used later */
675    if(maxRb < cellUl->sbSize)
676    {
677        maxRb = cellUl->sbSize;
678 #ifdef TFU_UPGRADE
679        if(uePwr->maxPwrDeltaByPhr < 0)
680        {
681           tmp = ueUl->validUlCqi;
682           tmp = tmp + uePwr->maxPwrDeltaByPhr;
683           if (tmp < 1 )
684           {
685               ueUl->validUlCqi = 1;
686           }
687           else
688           {
689               ueUl->validUlCqi = tmp;
690           }
691        }
692 #endif
693    }
694    RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
695          "UEID:%d Output Max Rb (%d), phVal (%d) AvailPwr (%d) ",
696          ue->ueId, maxRb, uePwr->phVal, availPwr);
697    RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
698          "UEID:%d pwrPerRb %d remPuschPwr %d", 
699          ue->ueId,
700          uePwr->pwrPerRb,
701          uePwr->remPuschPwr);
702    uePwr->delta   = delta;
703    uePwr->maxUlRbs = maxRb;
704    uePwr->puschTpc = tpc;
705    RETVOID;
706 }
707
708 /**
709  * @brief Returns TPC to be sent in DL allocation
710  *
711  * @details
712  *
713  *     Function : rgSCHPwrPucchTpcForUe
714  *
715  *     Invoking Module Processing:
716  *      - After DL allocation for UE, this function shall
717  *        be invoked to obtain TPC.
718  *
719  *     Processing Steps:
720  *     - Do Pucch power control processing
721  *       and return TPC
722  *
723  *  @param[in]  RgSchCellCb  *cell
724  *  @param[in]  RgSchUeCb    *ue
725  *  @return  U8
726  **/
727 #ifdef ANSI
728 PUBLIC U8 rgSCHPwrPucchTpcForUe
729 (
730 RgSchCellCb *cell,
731 RgSchUeCb   *ue
732 )
733 #else
734 PUBLIC U8 rgSCHPwrPucchTpcForUe(cell, ue)
735 RgSchCellCb *cell;
736 RgSchUeCb   *ue;
737 #endif
738 {
739    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
740    TRC2(rgSCHPwrPucchTpcForUe);
741
742    rgSCHPwrPucchCntrl(cell, ue);
743    RETVALUE(uePwr->pucchTpc);
744 }
745
746 /***********************************************************
747  *
748  *     Func : rgSCHPwrGetDelta2FrmCqi
749  *
750  *     Desc : Get power to be applied to achieve
751  *            target CQI (the power returned is
752  *            twice is actual power)
753  *
754  *     Ret  : S8
755  *
756  *     Notes:
757  *
758  *     File :
759  *
760  **********************************************************/
761 #ifdef ANSI
762 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi
763 (
764 U8                  crntCqi,
765 U8                  trgCqi,
766 RgSchUeCb           *ue,
767 RgSchCellCb         *cell
768
769 )
770 #else
771 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi(crntCqi, trgCqi)
772 U8                  crntCqi;
773 U8                  trgCqi;
774 RgSchUeCb           *ue;
775 RgSchCellCb         *cell;
776 #endif
777 {
778    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
779    TRC2(rgSCHPwrGetDelta2FrmCqi);
780  
781    if (uePwr->isPhrAvail)
782    {
783       //uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb - uePwr->remPuschPwr;
784       uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb;
785    }
786    else
787    {
788       uePwr->maxPwrDeltaByPhr = 0;         
789    }
790    
791    if (uePwr->maxPwrDeltaByPhr < 0 && (trgCqi - crntCqi) * 
792          RG_SCH_UL_CQI_DB_STEP_2 > 0)
793    {
794       RETVALUE(0);
795    }
796    RETVALUE(RGSCH_MIN(uePwr->maxPwrDeltaByPhr, 
797            (trgCqi - crntCqi) * RG_SCH_UL_CQI_DB_STEP_2));
798 }  /* rgSCHPwrGetDelta2FrmCqi */
799
800 /***********************************************************
801  *
802  *     Func : rgSCHPwrGetPuschTpc
803  *
804  *     Desc : Based on whether accumulation is enabled or
805  *            not, this returns an applicable power delta
806  *            to be applied based on the input delta.
807  *
808  *     Ret  : S8
809  *
810  *     Notes:
811  *
812  *     File :
813  *
814  **********************************************************/
815 #ifdef ANSI
816 PRIVATE Void rgSCHPwrGetPuschTpc
817 (
818 U8                  isAcc,
819 S8                  delta,
820 S8                  availPwr,
821 U8                 *tpc,
822 S8                 *tpcDelta
823 )
824 #else
825 PRIVATE Void rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, tpc, tpcDelta)
826 U8                  isAcc;
827 S8                  delta;
828 S8                  availPwr;
829 U8                 *tpc;
830 S8                 *tpcDelta;
831 #endif
832 {
833    TRC2(rgSCHPwrGetPuschTpc);
834
835    delta = RGSCH_MIN(delta, availPwr);
836
837    /* As of now, the functions below possibly cause delta
838     * to be breached by 1 only. So calling these as is. */
839    if (isAcc)
840    {
841       rgSCHPwrGetAcc2bitTpc(delta, tpc, tpcDelta);
842    }
843    else
844    {
845       rgSCHPwrGetAbsTpc(delta, tpc, tpcDelta);
846    }
847    RETVOID;
848 }  /* rgSCHPwrGetPuschTpc */
849
850 /***********************************************************
851  *
852  *     Func : rgSCHPwrGetMaxRb
853  *
854  *     Desc : Get the maximum number of RBs that can be
855  *            expected to be supported by the passed
856  *            power headroom.
857  *
858  *     Ret  : U8
859  *
860  *     Notes:
861  *
862  *     File :
863  *
864  **********************************************************/
865 #ifdef ANSI
866 PRIVATE U8 rgSCHPwrGetMaxRb
867 (
868 RgSchCellCb        *cell,
869 S8                  pwr
870 )
871 #else
872 PRIVATE U8 rgSCHPwrGetMaxRb(cell, pwr)
873 RgSchCellCb        *cell;
874 S8                  pwr;
875 #endif
876 {
877    RgSchCmnUlCell  *cellUl;
878
879    TRC2(rgSCHPwrGetMaxRb);
880    
881    cellUl    = RG_SCH_CMN_GET_UL_CELL(cell);
882    if (pwr <= 0)
883    {
884       /* Give 4 RBS so that UE can report changed power status*/
885       /* [ccpu00119916] Mod -return 0th index of rgSchPwrToRbTbl when pwr <=0
886        *  Change the Macros from RGSCH_MAX_DL_BW to RGSCH_MAX_UL_BW*/
887       RETVALUE(rgSchPwrToRbTbl[0]);
888    }
889    if (pwr > rgSchPwrRbToPwrTbl[cellUl->maxUlBwPerUe])
890    {
891       RETVALUE(cellUl->maxUlBwPerUe);
892    }
893    RETVALUE(RGSCH_MIN(cellUl->maxUlBwPerUe,rgSchPwrToRbTbl[(U8)pwr]));
894 }  /* rgSCHPwrGetMaxRb */
895
896 /***********************************************************
897  *
898  *     Func : rgSCHPwrRbToPwr
899  *
900  *     Desc : Get the power corresponding to number of RBs
901  *
902  *     Ret  : U8
903  *
904  *     Notes:
905  *
906  *     File :
907  *
908  **********************************************************/
909 #ifdef ANSI
910 PRIVATE U8 rgSCHPwrRbToPwr
911 (
912 RgSchCellCb          *cell,
913 U8                  numRb
914 )
915 #else
916 PRIVATE U8 rgSCHPwrRbToPwr(cell,numRb)
917 RgSchCellCb          *cell;
918 U8                  numRb;
919 #endif
920 {
921 #ifndef NO_ERRCLS
922    RgSchCmnUlCell  *cellUl;
923 #endif
924    TRC2(rgSCHPwrRbToPwr);
925 #if (ERRCLASS & ERRCLS_DEBUG)
926    cellUl    = RG_SCH_CMN_GET_UL_CELL(cell);
927    if (numRb > cellUl->maxUlBwPerUe)
928    {
929       numRb = cellUl->maxUlBwPerUe;
930    }
931 #endif
932    RETVALUE(rgSchPwrRbToPwrTbl[numRb]);
933 }  /* rgSCHPwrRbToPwr */
934
935
936 /**
937  * @brief Handles Pucch power control for DCI formats 1A/1B/1D/1/2A/2 
938  *
939  * @details
940  *
941  *     Function : rgSCHPwrPucchCntrl
942  *
943  *     Processing Steps:
944  *     - Determine 2 bit TPC to be sent using remPucchPwr.
945  *     - Update remPucchPwr appropriately
946  *
947  *  @param[in]  RgSchCellCb  *cell
948  *  @param[in]  RgSchUeCb    *ue
949  *  @return  Void
950  **/
951 #ifdef ANSI
952 PRIVATE Void rgSCHPwrPucchCntrl
953 (
954 RgSchCellCb *cell,
955 RgSchUeCb   *ue
956 )
957 #else
958 PRIVATE Void rgSCHPwrPucchCntrl(cell, ue)
959 RgSchCellCb *cell;
960 RgSchUeCb   *ue;
961 #endif
962 {
963    S8                     delta;
964    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
965    TRC2(rgSCHPwrPucchCntrl);
966
967    rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, &uePwr->pucchTpc, &delta);
968    rgSCHPwrOnSchedPucchTpc(cell, ue, delta);
969    RETVOID;
970 }
971
972 /**
973  * @brief Handles group power control for DCI formats 3/3A for Pucch and Pusch
974  *
975  * @details
976  *
977  *     Function : rgSCHPwrGrpCntrlPucch
978  *
979  *     Invoking Module Processing:
980  *      - This shall be invoked to do group power control for
981  *        all TPC RNTIs for which it is deemed necessary to
982  *        do the same (group power control).
983  *      - This function should only be invoked after all UEs
984  *        have been scheduled for uplink (re)transmissions
985  *        requiring DL DCI format in the passed subframe.
986  *
987  *     Processing Steps:
988  *     - For Pucch group power control
989  *       - For each TPC-Pucch-RNTI in the pucchGrpPwr List and 
990  *         TPC-Pusch-RNTI in the puschGrpPwr List,
991  *          - Request for PDCCH, skip if not available
992  *          - Form DCI format 3/3A information depending
993  *            on the format type of the TPC-RNTI and add it to the sub-frame.
994  *          - For each Ue in ueLst of TPC RNTI Cb
995  *             - if (fmtType == 3A)
996  *              - if((Ue not scheduled DL dci formats)
997  *                     && (remPwr >= 2 || remPwr <= -2))
998  *                  - Determine TPC. Set puschTpc/pucchTpc.
999  *                  - remPwr -= TPC
1000  *                  - if (remPwr >= -1 && remPwr <= 1)
1001  *                    - If already added, remove from toBeSchdLst
1002  *              - else
1003  *                  - Toggle the remainig power value
1004  *             - else if (fmtType == 3)
1005  *              - if((Ue not scheduled DL dci formats)
1006  *                    && (remPwr))
1007  *                  - Determine TPC. Set puschTpc/pucchTpc.
1008  *                  - remPwr -= TPC
1009  *                  - if (!remPwr)
1010  *                    - If already added, remove from toBeSchdLst
1011  *          - if (!toBeSchdUeCnt)
1012  *             - Remove the tpcRntiCb frm pucchGrpPwr/puschGrpPwr List
1013  *          - else, Move the tpcRntiCb to end of the list (not doing
1014  *             this)
1015  *
1016  *  @param[in]  RgSchCellCb  *cell
1017  *  @param[in]  RgSchDlSf    *dlSf
1018  *  @return  Void
1019  **/
1020 #ifdef ANSI
1021 PUBLIC Void rgSCHPwrGrpCntrlPucch
1022 (
1023 RgSchCellCb *cell,
1024 RgSchDlSf   *dlSf
1025 )
1026 #else
1027 PUBLIC Void rgSCHPwrGrpCntrlPucch(cell, dlSf)
1028 RgSchCellCb *cell;
1029 RgSchDlSf   *dlSf;
1030 #endif
1031 {
1032    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
1033    CmLListCp             *lst;
1034    CmLList               *lnk;
1035    RgSchPdcch            *pdcch;
1036    TRC2(rgSCHPwrGrpCntrlPucch);
1037
1038    lst = &cellPwr->pucchGrpPwr;
1039    lnk = lst->first;
1040    while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP))
1041    {
1042       RgSchCmnTpcRntiCb      *cb = (RgSchCmnTpcRntiCb *)lnk->node;
1043       Bool                    sched;
1044       lnk = lnk->next;
1045       rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, &sched);
1046       if (!sched)
1047       {
1048          rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
1049       }
1050       /* TPC RNTI would not have been removed if needs to
1051        * be scheduled again */
1052    }
1053
1054    RETVOID;
1055 }
1056
1057 /**
1058  * @brief Handles group power control for DCI formats 3/3A for Pusch and Pusch
1059  *
1060  * @details
1061  *
1062  *     Function : rgSCHPwrGrpCntrlPusch
1063  *
1064  *     Invoking Module Processing:
1065  *      - This shall be invoked to do group power control for
1066  *        all TPC RNTIs for which it is deemed necessary to
1067  *        do the same (group power control).
1068  *      - This function should only be invoked after all UEs
1069  *        have been scheduled for uplink (re)transmissions
1070  *        requiring DCI format 0 in the passed subframe.
1071  *
1072  *     Processing Steps:
1073  *     - For Pusch group power control
1074  *       - For each TPC-Pusch-RNTI in the puschGrpPwr List and 
1075  *          - Request for PDCCH, skip if not available
1076  *          - Form DCI format 3/3A information depending
1077  *            on the format type of the TPC-RNTI and add it to the sub-frame.
1078  *          - For each Ue in ueLst of TPC RNTI Cb
1079  *             - if (fmtType == 3A)
1080  *              - if (Ue not scheduled for dci format 0) and
1081  *                (remPwr >= 2 || remPwr <= -2))
1082  *                  - Determine TPC. Set puschTpc/puschTpc.
1083  *                  - remPwr -= TPC
1084  *                  - if (remPwr >= -1 && remPwr <= 1)
1085  *                    - If already added, remove from toBeSchdLst
1086  *              - else
1087  *                  - Toggle the remainig power value
1088  *             - else if (fmtType == 3)
1089  *              - if((Ue not scheduled for dci format 0) && (remPwr))
1090  *                  - Determine TPC. Set puschTpc.
1091  *                  - remPwr -= TPC
1092  *                  - if (!remPwr)
1093  *                    - If already added, remove from toBeSchdLst
1094  *          - if (!toBeSchdUeCnt)
1095  *             - Remove the tpcRntiCb frm puschGrpPwr/puschGrpPwr List
1096  *          - else, Move the tpcRntiCb to end of the list (not doing
1097  *            this now)
1098  *
1099  *  @param[in]  RgSchCellCb  *cell
1100  *  @param[in]  RgSchDlSf    *sf
1101  *  @return  Void
1102  **/
1103 #ifdef ANSI
1104 PUBLIC Void rgSCHPwrGrpCntrlPusch
1105 (
1106 RgSchCellCb *cell,
1107 RgSchDlSf   *dlSf,
1108 RgSchUlSf   *ulSf
1109 )
1110 #else
1111 PUBLIC Void rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf)
1112 RgSchCellCb *cell;
1113 RgSchDlSf   *dlSf;
1114 RgSchUlSf   *ulSf;
1115 #endif
1116 {
1117    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
1118    CmLListCp             *lst;
1119    CmLList               *lnk;
1120    RgSchPdcch            *pdcch;
1121    TRC2(rgSCHPwrGrpCntrlPusch);
1122
1123    lst = &cellPwr->puschGrpPwr;
1124    lnk = lst->first;
1125    while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP))
1126    {
1127       RgSchCmnTpcRntiCb      *cb = (RgSchCmnTpcRntiCb *)lnk->node;
1128       Bool                    sched;
1129       lnk = lnk->next;
1130       rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, &sched);
1131       if (!sched)
1132       {
1133          rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
1134       }
1135       /* TPC RNTI would not have been removed if needs to
1136        * be scheduled again */
1137    }
1138
1139    RETVOID;
1140 }
1141
1142 /***********************************************************
1143  *
1144  *     Func : rgSCHPwrSchedPucchRnti
1145  *
1146  *     Desc : Schedule TPC RNTI to be sent out
1147  *
1148  *     Ret  : Void
1149  *
1150  *     Notes:
1151  *
1152  *     File :
1153  *
1154  **********************************************************/
1155 #ifdef ANSI
1156 PRIVATE Void rgSCHPwrSchedPucchRnti
1157 (
1158 RgSchCellCb          *cell,
1159 RgSchCmnTpcRntiCb    *cb,
1160 RgSchPdcch           *pdcch,
1161 RgSchDlSf            *dlSf,
1162 Bool                 *sched
1163 )
1164 #else
1165 PRIVATE Void rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, sched)
1166 RgSchCellCb          *cell;
1167 RgSchCmnTpcRntiCb    *cb;
1168 RgSchPdcch           *pdcch;
1169 RgSchDlSf            *dlSf;
1170 Bool                 *sched;
1171 #endif
1172 {
1173    CmLListCp         *lst;
1174    CmLList           *lnk;
1175    U8                *tpcCmds;
1176    U8                 tpc;
1177    S8                 delta;
1178    Bool               atleastOne;
1179    TRC2(rgSCHPwrSchedPucchRnti);
1180
1181    pdcch->rnti = cb->tpcRnti;
1182
1183    if (cb->isFmt3a)
1184    {
1185       /* Go through all UEs for format 3A case */
1186       lst = &cb->cfgdUes;
1187       pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A;
1188       pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A];
1189       pdcch->dci.u.format3AInfo.isPucch = TRUE;
1190
1191       tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd;
1192       /* No need to memset zero initially as every TPC is going
1193        * to be filled up for every configured UE */
1194       for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1195       {
1196          RgSchUeCb             *ue    = (RgSchUeCb *)lnk->node;
1197          RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1198
1199          if ( ue->isDrxEnabled == TRUE && 
1200                !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1201          {
1202             /* UE is in its DRX time. So we cannot give command
1203              * to this UE.
1204              */
1205             continue;
1206          }
1207
1208          if (rgSCHPwrIsDlUeSched(cell, ue, dlSf))
1209          {
1210             /* UE already scheduled in downlink with PDCCH
1211              * carrying PUCCH pwr cmd. So don't care about
1212              * giving command to this UE. */
1213             continue;
1214          }
1215          rgSCHPwrGetPucchFmt3aTpcForUe(ue, &tpc, &delta);
1216          tpcCmds[uePwr->pucchIdx] = tpc;
1217          atleastOne = TRUE;
1218          rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta);
1219       }
1220    }
1221    else
1222    {
1223       /* Go through to-be-scheduled UEs for format 3 case */
1224       lst = &cb->toBeSchdUes;
1225       pdcch->dci.dciFormat = TFU_DCI_FORMAT_3;
1226       pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3];
1227       tpcCmds = pdcch->dci.u.format3Info.tpcCmd;
1228       pdcch->dci.u.format3Info.isPucch = TRUE;
1229
1230       /* Fill TPC 1 (corresponding to no power change) initially */
1231       cmMemset((U8 *)tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd));
1232
1233       for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1234       {
1235          RgSchUeCb             *ue    = (RgSchUeCb *)lnk->node;
1236          RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1237
1238          if ( ue->isDrxEnabled == TRUE && 
1239                !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1240          {
1241             /* UE is in its DRX time. So we cannot give command
1242              * to this UE.
1243              */
1244             continue;
1245          }
1246
1247          if (rgSCHPwrIsDlUeSched(cell, ue, dlSf))
1248          {
1249             /* UE already scheduled in downlink with PDCCH
1250              * carrying PUCCH pwr cmd. So don't care about
1251              * giving command to this UE. */
1252             continue;
1253          }
1254          rgSCHPwrGetPucchFmt3TpcForUe(ue, &tpc, &delta);
1255          tpcCmds[uePwr->pucchIdx] = tpc;
1256          atleastOne = TRUE;
1257          rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta);
1258       }
1259    }
1260
1261    *sched = atleastOne;
1262
1263    /* Check if no more UEs in TPC RNTI, and then remove
1264     * this TPC RNTI from scheduled list */
1265     if (cb->toBeSchdUes.count == 0)
1266     {
1267        rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb);
1268     }
1269
1270    RETVOID;
1271 }  /* rgSCHPwrSchedPucchRnti */
1272
1273 /***********************************************************
1274  *
1275  *     Func : rgSCHPwrSchedPuschRnti
1276  *
1277  *     Desc : Schedule TPC RNTI to be sent out
1278  *
1279  *     Ret  : Void
1280  *
1281  *     Notes:
1282  *
1283  *     File :
1284  *
1285  **********************************************************/
1286 #ifdef ANSI
1287 PRIVATE Void rgSCHPwrSchedPuschRnti
1288 (
1289 RgSchCellCb          *cell,
1290 RgSchCmnTpcRntiCb    *cb,
1291 RgSchPdcch           *pdcch,
1292 RgSchUlSf            *ulSf,
1293 Bool                 *sched
1294 )
1295 #else
1296 PRIVATE Void rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, sched)
1297 RgSchCellCb          *cell;
1298 RgSchCmnTpcRntiCb    *cb;
1299 RgSchPdcch           *pdcch;
1300 RgSchUlSf            *ulSf;
1301 Bool                 *sched;
1302 #endif
1303 {
1304    CmLListCp         *lst;
1305    CmLList           *lnk;
1306    U8                *tpcCmds;
1307    U8                 tpc;
1308    S8                 delta;
1309    Bool               atleastOne;
1310    TRC2(rgSCHPwrSchedPuschRnti);
1311
1312    pdcch->rnti = cb->tpcRnti;
1313
1314    if (cb->isFmt3a)
1315    {
1316       /* Go through all UEs for format 3A case */
1317       lst = &cb->cfgdUes;
1318       pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A;
1319       pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A];
1320       pdcch->dci.u.format3AInfo.isPucch = FALSE;
1321       tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd;
1322       /* No need to memset zero initially as every TPC is going
1323        * to be filled up for every configured UE */
1324       for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1325       {
1326          RgSchUeCb             *ue    = (RgSchUeCb *)lnk->node;
1327          RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1328          if (rgSCHPwrIsUlUeSched(cell, ue, ulSf))
1329          {
1330             /* UE already scheduled in uplink with DCI
1331              * format 0. So don't care about giving
1332              * command to this UE. */
1333             continue;
1334          }
1335
1336          if ( ue->isDrxEnabled == TRUE && 
1337                !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1338          {
1339             /* UE is in its DRX time. So we cannot give command
1340              * to this UE.
1341              */
1342             continue;
1343          }
1344
1345          rgSCHPwrGetPuschFmt3aTpcForUe(ue, &tpc, &delta);
1346          tpcCmds[uePwr->puschIdx] = tpc;
1347          atleastOne = TRUE;
1348          rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta);
1349       }
1350    }
1351    else
1352    {
1353       /* Go through to-be-scheduled UEs for format 3 case */
1354       lst = &cb->toBeSchdUes;
1355       pdcch->dci.dciFormat = TFU_DCI_FORMAT_3;
1356       pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3];
1357       pdcch->dci.u.format3Info.isPucch = FALSE;
1358       tpcCmds = pdcch->dci.u.format3Info.tpcCmd;
1359
1360       /* Fill TPC 1 (corresponding to no power change) initially */
1361       cmMemset((U8 *)tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd));
1362
1363       for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1364       {
1365          RgSchUeCb             *ue    = (RgSchUeCb *)lnk->node;
1366          RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1367          if (rgSCHPwrIsUlUeSched(cell, ue, ulSf))
1368          {
1369             /* UE already scheduled in uplink with DCI
1370              * format 0. So don't care about giving
1371              * command to this UE. */
1372             continue;
1373          }
1374
1375          if ( ue->isDrxEnabled == TRUE && 
1376                !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1377          {
1378             /* UE is in its DRX time. So we cannot give command
1379              * to this UE.
1380              */
1381             continue;
1382          }
1383
1384          rgSCHPwrGetPuschFmt3TpcForUe(ue, &tpc, &delta);
1385          tpcCmds[uePwr->puschIdx] = tpc;
1386          atleastOne = TRUE;
1387          rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta);
1388       }
1389    }
1390
1391    *sched = atleastOne;
1392
1393    /* Check if no more UEs in TPC RNTI, and then remove
1394     * this TPC RNTI from scheduled list */
1395     if (cb->toBeSchdUes.count == 0)
1396     {
1397        rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb);
1398     }
1399
1400    RETVOID;
1401 }  /* rgSCHPwrSchedPuschRnti */
1402
1403 /***********************************************************
1404  *
1405  *     Func : rgSCHPwrGetPucchFmt3TpcForUe
1406  *
1407  *     Desc : Gets 2 bit TPC cmd for PUCCH
1408  *
1409  *     Ret  : Void
1410  *
1411  *     Notes:
1412  *
1413  *     File :
1414  *
1415  **********************************************************/
1416 #ifdef ANSI
1417 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe
1418 (
1419 RgSchUeCb            *ue,
1420 U8                   *tpc,
1421 S8                   *delta
1422 )
1423 #else
1424 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe(ue, tpc, delta)
1425 RgSchUeCb            *ue;
1426 U8                   *tpc;
1427 S8                   *delta;
1428 #endif
1429 {
1430    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1431    TRC2(rgSCHPwrGetPucchFmt3TpcForUe);
1432
1433    rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, tpc, delta);
1434    RETVOID;
1435 }  /* rgSCHPwrGetPucchFmt3TpcForUe */
1436
1437 /***********************************************************
1438  *
1439  *     Func : rgSCHPwrGetPucchFmt3aTpcForUe
1440  *
1441  *     Desc : Gets 1 bit TPC cmd for PUCCH
1442  *
1443  *     Ret  : Void
1444  *
1445  *     Notes:
1446  *
1447  *     File :
1448  *
1449  **********************************************************/
1450 #ifdef ANSI
1451 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe
1452 (
1453 RgSchUeCb            *ue,
1454 U8                   *tpc,
1455 S8                   *delta
1456 )
1457 #else
1458 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe(ue, tpc, delta)
1459 RgSchUeCb            *ue;
1460 U8                   *tpc;
1461 S8                   *delta;
1462 #endif
1463 {
1464    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1465    TRC2(rgSCHPwrGetPucchFmt3aTpcForUe);
1466
1467    rgSCHPwrGetAcc1bitTpc(uePwr->remPucchPwr, tpc, delta);
1468    RETVOID;
1469 }  /* rgSCHPwrGetPucchFmt3aTpcForUe */
1470
1471 /***********************************************************
1472  *
1473  *     Func : rgSCHPwrGetPuschFmt3TpcForUe
1474  *
1475  *     Desc : Gets 2 bit TPC cmd for PUCCH
1476  *
1477  *     Ret  : Void
1478  *
1479  *     Notes:
1480  *
1481  *     File :
1482  *
1483  **********************************************************/
1484 #ifdef ANSI
1485 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe
1486 (
1487 RgSchUeCb            *ue,
1488 U8                   *tpc,
1489 S8                   *delta
1490 )
1491 #else
1492 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe(ue, tpc, delta)
1493 RgSchUeCb            *ue;
1494 U8                   *tpc;
1495 S8                   *delta;
1496 #endif
1497 {
1498    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1499    S8                     adj = RGSCH_MIN(uePwr->remPuschPwr, uePwr->phVal);
1500    TRC2(rgSCHPwrGetPuschFmt3TpcForUe);
1501
1502    rgSCHPwrGetAcc2bitTpc(adj, tpc, delta);
1503    RETVOID;
1504 }  /* rgSCHPwrGetPuschFmt3TpcForUe */
1505
1506 /***********************************************************
1507  *
1508  *     Func : rgSCHPwrGetPuschFmt3aTpcForUe
1509  *
1510  *     Desc : Gets 1 bit TPC cmd for PUCCH
1511  *
1512  *     Ret  : Void
1513  *
1514  *     Notes:
1515  *
1516  *     File :
1517  *
1518  **********************************************************/
1519 #ifdef ANSI
1520 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe
1521 (
1522 RgSchUeCb            *ue,
1523 U8                   *tpc,
1524 S8                   *delta
1525 )
1526 #else
1527 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe(ue, tpc, delta)
1528 RgSchUeCb            *ue;
1529 U8                   *tpc;
1530 S8                   *delta;
1531 #endif
1532 {
1533    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1534    TRC2(rgSCHPwrGetPuschFmt3aTpcForUe);
1535
1536    /* Don't attempt to look at headroom now, power
1537     * adjustment is small anyway */
1538    rgSCHPwrGetAcc1bitTpc(uePwr->remPuschPwr, tpc, delta);
1539    RETVOID;
1540 }  /* rgSCHPwrGetPuschFmt3aTpcForUe */
1541
1542 /***********************************************************
1543  *
1544  *     Func : rgSCHPwrGetAcc1bitTpc
1545  *
1546  *     Desc : Gets 1 bit TPC cmd
1547  *
1548  *     Ret  : Void
1549  *
1550  *     Notes:
1551  *
1552  *     File :
1553  *
1554  **********************************************************/
1555 #ifdef ANSI
1556 PRIVATE Void rgSCHPwrGetAcc1bitTpc
1557 (
1558 S8                    remPwr,
1559 U8                   *tpc,
1560 S8                   *delta
1561 )
1562 #else
1563 PRIVATE Void rgSCHPwrGetAcc1bitTpc(remPwr, tpc, delta)
1564 S8                    remPwr;
1565 U8                   *tpc;
1566 S8                   *delta;
1567 #endif
1568 {
1569    TRC2(rgSCHPwrGetAcc1bitTpc);
1570    /*
1571     * TPC   delta
1572     *  0     -1
1573     *  1      1
1574     */
1575    if (remPwr <= 0)
1576    {
1577       *delta = -1;
1578       *tpc = 0;
1579    }
1580    else
1581    {
1582       *delta = 1;
1583       *tpc = 1;
1584    }
1585    RETVOID;
1586 }  /* rgSCHPwrGetAcc1bitTpc */
1587
1588 /***********************************************************
1589  *
1590  *     Func : rgSCHPwrGetAcc2bitTpc
1591  *
1592  *     Desc : Allocate PDCCH for group power control
1593  *
1594  *     Ret  : Void
1595  *
1596  *     Notes:
1597  *
1598  *     File :
1599  *
1600  **********************************************************/
1601 #ifdef ANSI
1602 PRIVATE Void rgSCHPwrGetAcc2bitTpc
1603 (
1604 S8                   remPwr,
1605 U8                  *tpc,
1606 S8                  *delta
1607 )
1608 #else
1609 PRIVATE Void rgSCHPwrGetAcc2bitTpc(remPwr, tpc, delta)
1610 S8                   remPwr;
1611 U8                  *tpc;
1612 S8                  *delta;
1613 #endif
1614 {
1615    /*
1616     * TPC   delta
1617     *  0     -1
1618     *  1      0
1619     *  2      1
1620     *  3      3
1621     */
1622    U8            tpcs[3]   = {1, 2, 2};
1623    U8            deltas[3] = {0, 1, 1};
1624    TRC2(rgSCHPwrGetAcc2bitTpc);
1625    if (remPwr <= -1)
1626    {
1627       *tpc   = 0;
1628       *delta = -1;
1629    }
1630    else if (remPwr >= 3)
1631    {
1632       *tpc   = 3;
1633       *delta = 3;
1634    }
1635    else
1636    {
1637       *tpc   = tpcs[(U8)remPwr];
1638       *delta = deltas[(U8)remPwr];
1639    }
1640    RETVOID;
1641 }  /* rgSCHPwrGetAcc2bitTpc */
1642
1643 /***********************************************************
1644  *
1645  *     Func : rgSCHPwrGetAbsTpc
1646  *
1647  *     Desc : Allocate PDCCH for group power control
1648  *
1649  *     Ret  : Void
1650  *
1651  *     Notes:
1652  *
1653  *     File :
1654  *
1655  **********************************************************/
1656 #ifdef ANSI
1657 PRIVATE Void rgSCHPwrGetAbsTpc
1658 (
1659 S8                   remPwr,
1660 U8                  *tpc,
1661 S8                  *delta
1662 )
1663 #else
1664 PRIVATE Void rgSCHPwrGetAbsTpc(remPwr, tpc, delta)
1665 S8                   remPwr;
1666 U8                  *tpc;
1667 S8                  *delta;
1668 #endif
1669 {
1670    TRC2(rgSCHPwrGetAbsTpc);
1671    /*
1672     * TPC   delta
1673     *  0     -4
1674     *  1     -1
1675     *  2      1
1676     *  3      4
1677     */
1678    if (remPwr <= -3)
1679    {
1680       *tpc = 0;
1681       *delta = -4;
1682    }
1683    else if (remPwr < 1)
1684    {
1685       *tpc = 1;
1686       *delta = -1;
1687    }
1688    else if (remPwr < 4)
1689    {
1690       *tpc = 2;
1691       *delta = 1;
1692    }
1693    else
1694    {
1695       *tpc = 3;
1696       *delta = 4;
1697    }
1698    RETVOID;
1699 }  /* rgSCHPwrGetAbsTpc */
1700
1701 /***********************************************************
1702  *
1703  *     Func : rgSCHPwrOnPucchGrpPwrForUe
1704  *
1705  *     Desc : Processing on sending TPC for UE through group power
1706  *            control. Apart from updating remPwr, this only takes
1707  *            care of possibly removing UE from scheduled
1708  *            list in TPC RNTI.
1709  *            It does not take care of possibly removing TPC RNTI
1710  *            from scheduled list in cell. This is done
1711  *            in the caller after TPC for all UEs has been
1712  *            determined. (This is where it differs
1713  *            from the usual OnSendingPu[cs]ch TPC]
1714  *
1715  *     Ret  : ROK/RFAILED
1716  *
1717  *     Notes:
1718  *
1719  *     File :
1720  *
1721  **********************************************************/
1722 #ifdef ANSI
1723 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe 
1724 (
1725 RgSchCellCb          *cell,
1726 RgSchUeCb            *ue,
1727 S8                    delta
1728 )
1729 #else
1730 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta)
1731 RgSchCellCb          *cell;
1732 RgSchUeCb            *ue;
1733 S8                    delta;
1734 #endif
1735 {
1736    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1737    Bool                   rmvUe = FALSE;
1738
1739    UNUSED(cell);
1740
1741    TRC2(rgSCHPwrOnPucchGrpPwrForUe);
1742
1743    uePwr->remPucchPwr -= delta;
1744
1745    /* UE was already scheduled for PUCCH group power
1746     * control which is why we came here. Don't
1747     * again check for this. */
1748
1749    /* UE was scheduled for pucch grp pwr, sent TPC may
1750     * possibly cause it to be removed. */
1751       if (!uePwr->remPucchPwr)
1752       {
1753          rmvUe = TRUE;
1754       }
1755    if (rmvUe)
1756    {
1757       rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
1758       /* Not removing TPC RNTI from scheduled list,
1759        * this will happen in the caller once this
1760        * function is called for every UE scheduled. */
1761    }
1762    RETVOID;
1763 }
1764
1765 /***********************************************************
1766  *
1767  *     Func : rgSCHPwrOnPuschGrpPwrForUe
1768  *
1769  *     Desc : Processing on sending TPC for UE through group power
1770  *            control. Apart from updating remPwr, this only takes
1771  *            care of possibly removing UE from scheduled
1772  *            list in TPC RNTI.
1773  *            It does not take care of possibly removing TPC RNTI
1774  *            from scheduled list in cell. This is done
1775  *            in the caller after TPC for all UEs has been
1776  *            determined. (This is where it differs
1777  *            from the usual OnSendingPu[cs]ch TPC]
1778  *
1779  *     Ret  : ROK/RFAILED
1780  *
1781  *     Notes:
1782  *
1783  *     File :
1784  *
1785  **********************************************************/
1786 #ifdef ANSI
1787 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe 
1788 (
1789 RgSchCellCb          *cell,
1790 RgSchUeCb            *ue,
1791 S8                    delta
1792 )
1793 #else
1794 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta)
1795 RgSchCellCb          *cell;
1796 RgSchUeCb            *ue;
1797 S8                    delta;
1798 #endif
1799 {
1800    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1801    Bool                   rmvUe = FALSE;
1802
1803    UNUSED(cell);
1804    TRC2(rgSCHPwrOnPuschGrpPwrForUe);
1805
1806    uePwr->delta = delta;
1807    uePwr->remPuschPwr -= delta;
1808    if (uePwr->isPhrAvail)
1809    {
1810       uePwr->phVal -= uePwr->delta;
1811       uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
1812    }
1813
1814    /* UE was already scheduled for PUSCH group power
1815     * control which is why we came here. Don't
1816     * again check for this. */
1817
1818    /* UE was scheduled for pusch grp pwr, sent TPC may
1819     * possibly cause it to be removed. */
1820
1821       if (!uePwr->remPuschPwr)
1822       {
1823          rmvUe = TRUE;
1824       }
1825
1826    if (rmvUe)
1827    {
1828       rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
1829       /* Not removing TPC RNTI from scheduled list,
1830        * this will happen in the caller once this
1831        * function is called for every UE scheduled. */
1832    }
1833    RETVOID;
1834 }
1835
1836 /***********************************************************
1837  *
1838  *     Func : rgSCHPwrIsDlUeSched
1839  *
1840  *     Desc : Check if UE is scheduled in the passed DL SF
1841  *
1842  *     Ret  : Void
1843  *
1844  *     Notes:
1845  *
1846  *     File :
1847  *
1848  **********************************************************/
1849 #ifdef ANSI
1850 PRIVATE Bool rgSCHPwrIsDlUeSched
1851 (
1852 RgSchCellCb            *cell,
1853 RgSchUeCb            *ue,
1854 RgSchDlSf            *sf
1855 )
1856 #else
1857 PRIVATE Bool rgSCHPwrIsDlUeSched(cell, ue, sf)
1858 RgSchCellCb            *cell;
1859 RgSchUeCb            *ue;
1860 RgSchDlSf            *sf;
1861 #endif
1862 {
1863    RgSchDlHqEnt          *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
1864    RgSchDlHqProcCb      *proc    = rgSCHDhmLastSchedHqProc(hqEnt);
1865
1866    TRC2(rgSCHPwrIsDlUeSched);
1867
1868    if (proc == NULLP)
1869    {
1870       RETVALUE(FALSE);
1871    }
1872
1873    /*
1874     * The following subframe check is assumed enough, since
1875     * scheduled procs stay for a short time (until feedback
1876     * arrives), which typically is expected to have a
1877     * turnaround time of less than 8 subframes. So
1878     * we are probably never going to come across cases
1879     * where a process stays in the list for more than
1880     * 10 subframes, which would have otherwise caused
1881     * the check to succeed for a possibly older process.
1882     */
1883    if ((proc->tbInfo[0].timingInfo.slot == sf->sfNum) ||
1884        (proc->tbInfo[1].timingInfo.slot == sf->sfNum))
1885    {
1886       /*
1887        * Later, if a proc can be scheduled without having an
1888        * associated PDCCH, need to also check if PDCCH exists.
1889        * This is because for power, what matters is whether
1890        * TPC is going out for UE at this time or not, at least
1891        * that is what this function was introduced for.
1892        * Checking for PDCCH would have to be in common proc
1893        * the way things are now.
1894        */
1895       RETVALUE(TRUE);
1896    }
1897    else
1898    {
1899       RETVALUE(FALSE);
1900    }
1901 }  /* rgSCHPwrIsDlUeSched */
1902
1903 /***********************************************************
1904  *
1905  *     Func : rgSCHPwrIsUlUeSched
1906  *
1907  *     Desc : Check if UE is scheduled in the passed UL SF
1908  *
1909  *     Ret  : Void
1910  *
1911  *     Notes:
1912  *
1913  *     File :
1914  *
1915  **********************************************************/
1916 #ifdef ANSI
1917 PRIVATE Bool rgSCHPwrIsUlUeSched
1918 (
1919 RgSchCellCb          *cell,
1920 RgSchUeCb            *ue,
1921 RgSchUlSf            *sf
1922 )
1923 #else
1924 PRIVATE Bool rgSCHPwrIsUlUeSched(cell, ue, sf)
1925 RgSchCellCb          *cell;
1926 RgSchUeCb            *ue;
1927 RgSchUlSf            *sf;
1928 #endif
1929 {
1930    RgSchCmnUlCell      *cmnCell = RG_SCH_CMN_GET_UL_CELL(cell);
1931    RgSchUlHqProcCb     *proc = rgSCHUhmGetUlHqProc(cell, ue, cmnCell->schdHqProcIdx);
1932
1933    TRC2(rgSCHPwrIsUlUeSched);
1934
1935    UNUSED(sf);
1936
1937 #if (ERRCLASS & ERRCLS_DEBUG)
1938    if( proc == NULLP )
1939    {
1940       RETVALUE (FALSE);
1941    }
1942 #endif  
1943
1944    if (proc->alloc)
1945    {
1946       RETVALUE(TRUE);
1947    }
1948    else
1949    {
1950       RETVALUE(FALSE);
1951    }
1952 }  /* rgSCHPwrIsUlUeSched */
1953
1954 /**
1955  * @brief Handles Pucch power delta indication recieved from PHY
1956  *
1957  * @details
1958  *
1959  *     Function : rgSCHPwrPucchDeltaInd
1960  *
1961  *     Invoking Module Processing:
1962  *      - This shall be invoked on reception of Pucch power 
1963  *        delta indication from PHY.
1964  *        
1965  *     Processing Steps:
1966  *     - Update the remPucchPwr 
1967  *       ue->remPucchPwr = pwrDelta
1968  *     - If (ue->tpcPucchRntiCb)
1969  *       - If (fmtType = 3A)
1970  *          - if (remPucchPwr >= 2 || remPucchPwr <= -2 )
1971  *             - if (tpcPucchRntiCb is not in the pucchGrpPwr List)
1972  *               - Add tpcPucchRntiCb to the pucchGrpPwr list.
1973  *             - If not added, add to toBeSchdLst
1974  *          - else
1975  *             - If already added, remove from toBeSchdLst
1976  *       - else If (fmtType == 3) 
1977  *          - if (remPucchPwr)
1978  *             - if (tpcPucchRntiCb is not in the pucchGrpPwr List)
1979  *               - Add tpcPucchRntiCb to the pucchGrpPwr list.
1980  *             - If not added, add to toBeSchdLst
1981  *          - else
1982  *             - If already added, remove from toBeSchdLst
1983  *
1984  *  @param[in]  RgSchCellCb  *cell
1985  *  @param[in]  RgSchUeCb    *ue
1986  *  @param[in]  U8           pwrDelta
1987  *  @return  Void
1988  **/
1989 #ifdef ANSI
1990 PUBLIC Void rgSCHPwrPucchDeltaInd
1991 (
1992 RgSchCellCb *cell,
1993 RgSchUeCb   *ue,
1994 S8          pwrDelta
1995 )
1996 #else
1997 PUBLIC Void rgSCHPwrPucchDeltaInd(cell, ue, pwrDelta)
1998 RgSchCellCb *cell;
1999 RgSchUeCb   *ue;
2000 S8          pwrDelta;
2001 #endif
2002 {
2003    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2004    RgSchCmnTpcRntiCb     *cb;
2005    Bool                   toAdd;
2006    TRC2(rgSCHPwrPucchDeltaInd);
2007
2008    uePwr->remPucchPwr = pwrDelta;
2009    
2010    if ((cb = uePwr->tpcPucchRntiCb) == NULLP)
2011    {
2012       RETVOID;
2013    }
2014
2015    toAdd = FALSE;
2016
2017    if (0 != uePwr->remPucchPwr)
2018       {
2019          toAdd = TRUE;
2020       }
2021
2022
2023    if (toAdd)
2024    {
2025       rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue);
2026    }
2027    else
2028    {
2029       rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue);
2030    }
2031
2032    RETVOID;
2033 }
2034
2035 /**
2036  * @brief Does processing after TPC for Pucch has been sent
2037  *
2038  * @details
2039  *
2040  *     Function : rgSCHPwrOnSchedPucchTpc
2041  *
2042  *     Invoking Module Processing:
2043  *      - It shall be invoked after it is determined that PDCCH for UE
2044  *        is finalised to go out, and thus TPC for PUCCH is being
2045  *        sent out.
2046  *
2047  *     Processing Steps:
2048  *     - Update remPucchPwr with the delta
2049  *     - Do group power control related processing
2050  *
2051  *  @param[in]  RgSchCellCb       *cell
2052  *  @param[in]  RgSchUeCb         *ue
2053  *  @param[in]  S8                 delta
2054  *  @return  Void
2055  **/
2056 #ifdef ANSI
2057 PRIVATE Void rgSCHPwrOnSchedPucchTpc
2058 (
2059 RgSchCellCb           *cell,
2060 RgSchUeCb             *ue,
2061 S8                     delta
2062 )
2063 #else
2064 PRIVATE Void rgSCHPwrOnSchedPucchTpc(cell, ue, delta)
2065 RgSchCellCb           *cell;
2066 RgSchUeCb             *ue;
2067 S8                     delta;
2068 #endif
2069 {
2070    /* Similar to rgSCHPwrPucchDeltaInd.. not reusing
2071     * that since we use the fact that UE could only have
2072     * improved its remPwr as part of power control. */
2073    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2074    Bool                   rmvUe = FALSE;
2075    TRC2(rgSCHPwrOnSchedPucchTpc);
2076
2077    uePwr->remPucchPwr -= delta;
2078
2079    if (uePwr->schdPucchGrpLnk.node == NULLP)
2080    {
2081       RETVOID;
2082    }
2083
2084    /* UE was scheduled for TPC, sent TPC may
2085     * possibly cause it to be removed. */
2086
2087       if (!uePwr->remPucchPwr)
2088       {
2089          rmvUe = TRUE;
2090       }
2091
2092    if (rmvUe)
2093    {
2094       rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
2095       if (uePwr->tpcPucchRntiCb->toBeSchdUes.count == 0)
2096       {
2097          rgSCHPwrRmvSchdPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb);
2098       }
2099    }
2100    RETVOID;
2101 }
2102
2103
2104 /**
2105  * @brief Does processing after TPC for Pusch has been sent
2106  *
2107  * @details
2108  *
2109  *     Function : rgSCHPwrOnSchedPuschTpc
2110  *
2111  *     Processing Steps:
2112  *      - If accumulative
2113  *        - Update remPuschPwr with the delta
2114  *        - Do group power related processing if applicable
2115  *       
2116  *  @param[in]  RgSchCellCb       *cell
2117  *  @param[in]  RgSchUeCb         *ue
2118  *  @return  Void
2119  **/
2120 #ifdef ANSI
2121 PRIVATE Void rgSCHPwrOnSchedPuschTpc
2122 (
2123 RgSchCellCb           *cell,
2124 RgSchUeCb             *ue
2125 )
2126 #else
2127 PRIVATE Void rgSCHPwrOnSchedPuschTpc(cell, ue)
2128 RgSchCellCb           *cell;
2129 RgSchUeCb             *ue;
2130 #endif
2131 {
2132    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2133    Bool                   rmvUe = FALSE;
2134    TRC2(rgSCHPwrOnSchedPuschTpc);
2135
2136    /* Don't do anything for the case of absolute TPC commands */
2137    if (!uePwr->isAccumulated)
2138    {
2139       RETVOID;
2140    }
2141
2142    uePwr->remPuschPwr -= uePwr->delta;
2143    if (uePwr->isPhrAvail)
2144    {
2145       uePwr->phVal -= uePwr->delta;
2146       uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
2147    }
2148
2149    if (uePwr->schdPuschGrpLnk.node == NULLP)
2150    {
2151       RETVOID;
2152    }
2153
2154    /* UE was scheduled for pusch TPC, sent TPC may
2155     * possibly cause it to be removed. */
2156
2157       if (!uePwr->remPuschPwr)
2158       {
2159          rmvUe = TRUE;
2160       }
2161
2162    if (rmvUe)
2163    {
2164       rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
2165    }
2166
2167    RETVOID;
2168 }
2169
2170 /**
2171  * @brief Handles PHR updation for the UE
2172  *
2173  * @details
2174  *
2175  *     Function : rgSCHPwrUpdExtPhr
2176  *  @param[in]  RgSchCellCb         *cell
2177  *  @param[in]  RgSchUeCb           *ue
2178  *  @param[in]  RgInfExtPhrCEInfo   *extPhr
2179  *  @param[in]  RgSchCmnAllocRecord  allocInfo
2180  *  @return  Void
2181  **/
2182 #ifdef ANSI
2183 PUBLIC Void rgSCHPwrUpdExtPhr
2184 (
2185 RgSchCellCb           *cell,
2186 RgSchUeCb             *ue,
2187 RgInfExtPhrCEInfo     *extPhr,
2188 RgSchCmnAllocRecord   *allocInfo
2189 )
2190 #else
2191 PUBLIC Void rgSCHPwrUpdExtPhr(cell, ue, extPhr, allocInfo)
2192 RgSchCellCb           *cell;
2193 RgSchUeCb             *ue;
2194 RgInfExtPhrCEInfo     *extPhr;
2195 RgSchCmnAllocRecord   *allocInfo;
2196 #endif
2197 {
2198    U8 idx;
2199    RgInfExtPhrSCellInfo  *servCellPhr;
2200    S8                     pCMax;
2201
2202    TRC2(rgSCHPwrUpdExtPhr);
2203
2204    for (idx = 0; idx < extPhr->numServCells; idx++)
2205    {
2206       servCellPhr = &extPhr->servCellPhr[idx];
2207
2208       if (RG_SCH_REF_PCMAX == servCellPhr->pCmax)
2209       {
2210          pCMax = RG_SCH_CMN_PWR_USE_CFG_MAX_PWR;
2211       }
2212       else
2213       {
2214          pCMax = rgSCHPwrGetPCMaxValFromPCMax(servCellPhr->pCmax);
2215       }
2216       rgSCHPwrUpdPhr(ue->cellInfo[servCellPhr->sCellIdx]->cell,
2217             ue, servCellPhr->phr, allocInfo, pCMax);
2218    }
2219    RETVOID;
2220 }
2221
2222 /**
2223  * @brief Handles PHR updation for the UE
2224  *
2225  * @details
2226  *
2227  *     Function : rgSCHPwrUpdPhr
2228  *
2229  *     Invoking Module Processing:
2230  *      - This shall be invoked on reception of PHR from MAC to SCH. It shall
2231  *      pass the information of number of RBs, coding efficiency and TPC for 
2232  *      the Pusch transmission for which PHR has been reported.
2233  *
2234  *     Processing Steps:
2235  *     - Compute power per RB using the PHR report
2236  *        - ue_transmit_pwr = ue_max_pwr - PHR
2237  *        - if isDeltaMcs = TRUE
2238  *          - ue_transmit_pwr - 
2239  *            [10log(phr_num_rb) + 10log(2^ (1.25 * phr_coding_effeciency) -1)
2240  *            + phr_tpc(if absolute TPC)] = pwrPerRB
2241  *        - else
2242  *          - ue_transmit_pwr - [10log(phr_num_rb) + phr_tpc(if absolute TPC)]
2243  *            = pwrPerRB
2244  *        (Use the number of RBs and efficiency used by UE which caused the PHR
2245  *         report to happen)
2246  *     - Adjust PHR according to last allocation (take into account
2247  *       number of RBs granted in the last allocation)
2248  *     - Update the PHR report in the control block
2249  *     - Set isPhrAvail = TRUE
2250  *     - Do group power control related processing if applicable
2251  *
2252  *  @param[in]  RgSchCellCb         *cell
2253  *  @param[in]  RgSchUeCb           *ue
2254  *  @param[in]  U8                   phr
2255  *  @param[in]  RgSchCmnAllocRecord  allocInfo
2256  *  @param[in]  U8                   maxUePwr
2257  *  @return  Void
2258  **/
2259 #ifdef ANSI
2260 PUBLIC Void rgSCHPwrUpdPhr
2261 (
2262 RgSchCellCb           *cell,
2263 RgSchUeCb             *ue,
2264 U8                     phr,
2265 RgSchCmnAllocRecord   *allocInfo,
2266 S8                     maxUePwr 
2267 )
2268 #else
2269 PUBLIC Void rgSCHPwrUpdPhr(cell, ue, phr, allocInfo, maxUePwr)
2270 RgSchCellCb           *cell;
2271 RgSchUeCb             *ue;
2272 U8                     phr;
2273 RgSchCmnAllocRecord   *allocInfo;
2274 S8                     maxUePwr;
2275 #endif
2276 {
2277    RgSchCmnUeUlPwrCb     *uePwr   = RG_SCH_PWR_GETUEPWR(ue, cell);
2278    U8                     rbPwr;
2279    U8                     effPwr;
2280    RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
2281
2282    TRC2(rgSCHPwrUpdPhr);
2283
2284    uePwr->phVal = rgSCHPwrGetPhValFromPhr(phr);
2285   
2286    if (maxUePwr == RG_SCH_CMN_PWR_USE_CFG_MAX_PWR)
2287    {
2288       maxUePwr = uePwr->maxUePwr;
2289    }
2290    rbPwr = rgSCHPwrRbToPwr(cell,allocInfo->numRb);
2291    effPwr = rgSCHPwrGetCqiPwrForUe(cell, ue, allocInfo->cqi);
2292    uePwr->pwrPerRb = maxUePwr - uePwr->phVal - rbPwr - effPwr;
2293    /*if (!uePwr->isAccumulated)
2294    {
2295       uePwr->pwrPerRb -= rgSCHPwrGetDeltaFrmAbsTpc(allocInfo->tpc);
2296    }*/
2297
2298    /* Let headroom reflect remaining power according to last
2299     * allocated number of RBs. Intermediate TPCs not yet
2300     * taken care of (for accumulated case, it is anyway
2301     * not applicable for absolute commands). */
2302    uePwr->phVal -= (rgSCHPwrRbToPwr(cell, cellUl->sbSize)) - rbPwr;
2303    uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
2304    uePwr->isPhrAvail = TRUE;
2305
2306    rgSCHPwrOnPuschPwrUpd(cell, ue);
2307
2308    RLOG_ARG4(L_DEBUG,DBG_UEID,ue->ueId,
2309          "Output: Reported PHR[%d] cqi[%u] allocRb[%u] uePwr->pwrPerRb[%d]",
2310             uePwr->phVal,
2311             allocInfo->cqi,
2312             allocInfo->numRb,  
2313             uePwr->pwrPerRb); 
2314    RETVOID;
2315 }
2316
2317 /**
2318  * @brief Handles UL CQI indication
2319  *
2320  * @details
2321  *
2322  *     Function : rgSCHPwrUlCqiInd
2323  *
2324  *     Invoking Module Processing:
2325  *      - This shall be invoked when uplink CQI indication
2326  *        is receiving from PHY for a UE.
2327  *
2328  *     Processing Steps:
2329  *     - Update remPuschPwr.
2330  *     - Possibly schedule for group power control.
2331  *
2332  *  @param[in]  RgSchCellCb         *cell
2333  *  @param[in]  RgSchUeCb           *ue
2334  *  @param[in]  U8                   numRb
2335  *  @return  Void
2336  **/
2337 #ifdef ANSI
2338 PUBLIC Void rgSCHPwrUlCqiInd
2339 (
2340 RgSchCellCb           *cell,
2341 RgSchUeCb             *ue
2342 )
2343 #else
2344 PUBLIC Void rgSCHPwrUlCqiInd(cell, ue)
2345 RgSchCellCb           *cell;
2346 RgSchUeCb             *ue;
2347 #endif
2348 {
2349    RgSchCmnUlUe          *ueUl    = RG_SCH_CMN_GET_UL_UE(ue, cell);
2350    RgSchCmnUeUlPwrCb     *uePwr   = RG_SCH_PWR_GETUEPWR(ue, cell);
2351 #ifdef TFU_UPGRADE 
2352    S32  tmp;
2353 #endif
2354    TRC2(rgSCHPwrUlCqiInd);
2355
2356    /*
2357     * For absolute power cmd case, we could look at the time
2358     * at which CQI was received, determine if there was a
2359     * PUSCH TPC cmd for that time (this could come from
2360     * group power control too), and (if this
2361     * CQI report is indeed based on the the PUSCH tx)
2362     * then factor in that cmd here. Not doing
2363     * this as of now.
2364     */
2365
2366    /* See how much power needs to be adjusted based on cqi
2367     * differential */
2368    uePwr->remPuschPwr = 
2369 #ifdef TFU_UPGRADE
2370       rgSCHPwrGetDelta2FrmCqi(ueUl->validUlCqi, uePwr->trgCqi, ue, cell);
2371 #else
2372       rgSCHPwrGetDelta2FrmCqi(ueUl->crntUlCqi[0], uePwr->trgCqi, ue, cell);
2373 #endif
2374
2375    rgSCHPwrOnPuschPwrUpd(cell, ue);
2376 #ifdef TFU_UPGRADE
2377    if(uePwr->maxPwrDeltaByPhr < 0)
2378    {
2379       tmp = ueUl->validUlCqi;
2380       tmp = tmp + uePwr->maxPwrDeltaByPhr;
2381       if (tmp < 1 )
2382       {
2383          ueUl->validUlCqi = 1;
2384       }
2385       else
2386       {
2387          ueUl->validUlCqi = tmp;
2388       }
2389    }
2390 #endif 
2391
2392    RETVOID;
2393 }
2394
2395 /**
2396  * @brief Updates the stored last number of RBs allocated
2397  *
2398  * @details
2399  *
2400  *     Function : rgSCHPwrRecordRbAlloc
2401  *
2402  *     Invoking Module Processing:
2403  *      - This shall be invoked when uplink allocation is made for
2404  *        a UE.
2405  *      - Note: If outstanding TPCs are considered at the time
2406  *        of PHR report, the last numRb would also be known
2407  *        and then this API would not be needed. 
2408  *
2409  *     Processing Steps:
2410  *     - Adjust PHR according to now allocated number of RBs
2411  *     - Store the number of RBs
2412  *
2413  *  @param[in]  RgSchCellCb         *cell
2414  *  @param[in]  RgSchUeCb           *ue
2415  *  @param[in]  U8                   numRb
2416  *  @return  Void
2417  **/
2418 #ifdef ANSI
2419 PUBLIC Void rgSCHPwrRecordRbAlloc
2420 (
2421 RgSchCellCb           *cell,
2422 RgSchUeCb             *ue,
2423 U8                     numRb
2424 )
2425 #else
2426 PUBLIC Void rgSCHPwrRecordRbAlloc(cell, ue, numRb)
2427 RgSchCellCb           *cell;
2428 RgSchUeCb             *ue;
2429 U8                     numRb;
2430 #endif
2431 {
2432    RgSchCmnUeUlPwrCb     *uePwr   = RG_SCH_PWR_GETUEPWR(ue, cell);
2433    UNUSED(cell);
2434    TRC2(rgSCHPwrRecordRbAlloc);
2435    RETVOID; 
2436
2437    if (uePwr->isPhrAvail)
2438    {
2439       uePwr->phVal += rgSCHPwrRbToPwr(cell,numRb) - rgSCHPwrRbToPwr(cell,uePwr->numRb);
2440       uePwr->phVal = RGSCH_MIN(40, uePwr->phVal);
2441    }
2442    uePwr->numRb = numRb;
2443    RETVOID;
2444 }
2445
2446 /**
2447  * @brief Handles power related configuration for a cell
2448  *
2449  * @details
2450  *
2451  *     Function : rgSCHPwrCellCfg
2452  *
2453  *     Invoking Module Processing:
2454  *      - This shall be invoked during cell config
2455  *        
2456  *     Processing Steps:
2457  *      - Set pMax
2458  *      - Set target CQI
2459  *      - Update TPC-RNTI information for the cell for Pucch and Pusch.
2460  *      - For each TPC-Pucch-RNTI,
2461  *         - Call  rgSCHAddRntiToPucchRntiLst()
2462  *      - For each TPC-Pusch-RNTI,
2463  *         - Call  rgSCHAddRntiToPuschRntiLst()
2464  *      - Return ROK
2465  *
2466  *  @param[in]  RgSchCellCb  *cell
2467  *  @param[in]  RgrCellCfg   *cfg
2468  *  @return  S16
2469  *      -# ROK
2470  *      -# RFAILED
2471  **/
2472 #ifdef ANSI
2473 PUBLIC S16 rgSCHPwrCellCfg
2474 (
2475 RgSchCellCb          *cell,
2476 RgrCellCfg           *cfg
2477 )
2478 #else
2479 PUBLIC S16 rgSCHPwrCellCfg(cell, cfg)
2480 RgSchCellCb          *cell;
2481 RgrCellCfg           *cfg;
2482 #endif
2483 {
2484    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2485    CmLteRnti              rnti;
2486    CmLteRnti              startRnti;
2487    U16                    size;
2488    Bool                   isFmt3a;
2489    TRC2(rgSCHPwrCellCfg);
2490
2491    /* Right now, all UEs have fixed maximum power capability. So
2492     * we store cell wide pMax as minimum of configured pMax and
2493     * UE's max power */
2494    cellPwr->pMax = RGSCH_MIN(cfg->pMax, RG_SCH_PWR_UE_MAX_PWR);
2495
2496    /* trgUlCqi already validated by common */
2497    cellPwr->trgUlCqi = cfg->trgUlCqi.trgCqi;
2498
2499    /* Validate number of TPC RNTIs */
2500    if ((cfg->pwrCfg.pucchPwrFmt3.size + cfg->pwrCfg.pucchPwrFmt3a.size
2501             > RG_SCH_CMN_MAX_NUM_TPC_PUCCH_RNTI)
2502          || (cfg->pwrCfg.puschPwrFmt3.size + cfg->pwrCfg.puschPwrFmt3a.size
2503             > RG_SCH_CMN_MAX_NUM_TPC_PUSCH_RNTI))
2504    {
2505       RETVALUE(RFAILED);
2506    }
2507
2508    /* Now initialise TPC RNTIs */
2509
2510    /* Format 3 Pucch TPC RNTIs */
2511    isFmt3a = FALSE;
2512    startRnti = cfg->pwrCfg.pucchPwrFmt3.startTpcRnti;
2513    size = cfg->pwrCfg.pucchPwrFmt3.size;
2514    for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2515    {
2516       rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a);
2517    }
2518
2519    /* Format 3A Pucch TPC RNTIs */
2520    isFmt3a = TRUE;
2521    startRnti = cfg->pwrCfg.pucchPwrFmt3a.startTpcRnti;
2522    size = cfg->pwrCfg.pucchPwrFmt3a.size;
2523    for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2524    {
2525       rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a);
2526    }
2527
2528    /* Format 3 Pusch TPC RNTIs */
2529    isFmt3a = FALSE;
2530    startRnti = cfg->pwrCfg.puschPwrFmt3.startTpcRnti;
2531    size = cfg->pwrCfg.puschPwrFmt3.size;
2532    for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2533    {
2534       rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a);
2535    }
2536
2537    /* Format 3A Pusch TPC RNTIs */
2538    isFmt3a = TRUE;
2539    startRnti = cfg->pwrCfg.puschPwrFmt3a.startTpcRnti;
2540    size = cfg->pwrCfg.puschPwrFmt3a.size;
2541    for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2542    {
2543       rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a);
2544    }
2545
2546    RETVALUE(ROK);
2547 }
2548
2549 /**
2550  * @brief Handles power related re-configuration for a cell
2551  *
2552  * @details
2553  *
2554  *     Function : rgSCHPwrCellRecfg
2555  *
2556  *     Processing Steps:
2557  *     - NONE
2558  *
2559  *  @param[in]  RgSchCellCb  *cell
2560  *  @param[in]  RgrCellRecfg *recfg
2561  *  @return  S16
2562  *      -# ROK
2563  **/
2564 #ifdef ANSI
2565 PUBLIC S16 rgSCHPwrCellRecfg
2566 (
2567 RgSchCellCb          *cell,
2568 RgrCellRecfg         *recfg
2569 )
2570 #else
2571 PUBLIC S16 rgSCHPwrCellRecfg(cell, recfg)
2572 RgSchCellCb          *cell;
2573 RgrCellRecfg         *recfg;
2574 #endif
2575 {
2576    UNUSED(cell);
2577    UNUSED(recfg);
2578    TRC2(rgSCHPwrCellRecfg);
2579
2580    /* Not doing anything for power reconfig, so such structure
2581     * in RGR */
2582    RETVALUE(ROK);
2583 }
2584
2585 /**
2586  * @brief Frees power related data structures in cell
2587  *
2588  * @details
2589  *
2590  *     Function : rgSCHPwrCellDel
2591  *
2592  *     Processing Steps:
2593  *      - NONE
2594  *
2595  *  @param[in]  RgSchCellCb  *cell
2596  *  @return  Void
2597  **/
2598 #ifdef ANSI
2599 PUBLIC Void rgSCHPwrCellDel
2600 (
2601 RgSchCellCb *cell
2602 )
2603 #else
2604 PUBLIC Void rgSCHPwrCellDel(cell)
2605 RgSchCellCb *cell;
2606 #endif
2607 {
2608    UNUSED(cell);
2609    TRC2(rgSCHPwrCellDel);
2610
2611    /* There is no allocated memory, so do nothing */
2612    RETVOID;
2613 }
2614
2615
2616 #ifdef LTE_ADV
2617 /**
2618  * @brief Configures ULPC CB for a SCELL being added
2619  *
2620  * @details
2621  *
2622  *     Function : rgSCHPwrUeSCellCfg
2623  *
2624  *  @param[in]  RgSchCellCb  *cell
2625  *  @param[in]  RgSchUeCb    *ue
2626  *  @param[in]  RgrUeCfg     *cfg
2627  *  @return  S16
2628  *      -# ROK
2629  *      -# RFAILED
2630  **/
2631 #ifdef ANSI
2632 PUBLIC S16 rgSCHPwrUeSCellCfg
2633 (
2634 RgSchCellCb *cell,
2635 RgSchUeCb   *ue,
2636 RgrUeSecCellCfg  *sCellInfoCfg
2637 )
2638 #else
2639 PUBLIC S16 rgSCHPwrUeSCellCfg(cell, ue, sCellInfoCfg)
2640 RgSchCellCb *cell;
2641 RgSchUeCb   *ue;
2642 RgrUeSecCellCfg  *sCellInfoCfg;
2643 #endif
2644 {
2645    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2646    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2647    RgSchCmnUeUlPwrCb     *uePwrPCell = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
2648    RgSchCmnUlUe          *ueUl        = RG_SCH_CMN_GET_UL_UE(ue, cell);
2649
2650    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
2651
2652    TRC2(rgSCHPwrUeSCellCfg);
2653
2654    uePwr->maxUePwr = cellPwr->pMax;
2655    uePwr->trgCqi   = cellPwr->trgUlCqi; /* Overriding with UE's happens later */
2656    uePwr->numRb    = 1;
2657
2658    uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize];
2659
2660    uePwr->isPhrAvail  = FALSE;
2661    uePwr->phVal       = 40;
2662    uePwr->maxUlRbs    = RGSCH_MAX_DL_BW;
2663    uePwr->delta       = 0;
2664    uePwr->puschTpc    = 1;
2665    uePwr->remPuschPwr = 0;
2666
2667    /* Rest of the vars update and group power control related
2668     * config happens in the function below */
2669    uePwr->isAccumulated = sCellInfoCfg->ueSCellUlDedPwrCfg.isAccumulated;
2670    uePwr->deltaMcsEnbld = sCellInfoCfg->ueSCellUlDedPwrCfg.isDeltaMCSEnabled;
2671
2672    uePwr->trgCqi = uePwrPCell->trgCqi;
2673
2674    if (ueUl->maxUlCqi < uePwr->trgCqi)
2675    {
2676       uePwr->trgCqi = ueUl->maxUlCqi;
2677    }
2678    uePwr->p0UePusch = sCellInfoCfg->ueSCellUlDedPwrCfg.p0UePusch;
2679
2680    RETVALUE(ROK);
2681 }
2682 #endif
2683
2684 /**
2685  * @brief Handles power related configuration for a UE
2686  *
2687  * @details
2688  *
2689  *     Function : rgSCHPwrUeCfg
2690  *
2691  *     Processing Steps:
2692  *      - If Pusch group power configuration exists && accumulation enabled,
2693  *        - Fetch the TPC-Pusch-RNTI control block for the configured
2694  *        TPC-Pusch-RNTI. Call rgSCHGetRntiFrmPuschRntiLst(). If it does not
2695  *        exist, return RFAILED.
2696  *        - Add Ue to the ueLst of TPC-Pusch-RNTI control block.
2697  *        - Update tpcPuschRntiCb pointer in UE.
2698  *        - Update the puschIdx value.
2699  *      - If Pucch group power configuration exists && accumulation enabled,
2700  *        - Fetch the TPC-Pucch-RNTI control block for the configured
2701  *        TPC-Pucch-RNTI. Call rgSCHGetRntiFrmPucchRntiLst(). If it does not
2702  *        exist, return RFAILED.
2703  *        - Add Ue to the ueLst of TPC-Pucch-RNTI control block.
2704  *        - Update tpcPucchRntiCb pointer in UE.
2705  *        - Update the pucchIdx value.
2706  *      - Update isAccumulated and isDeltaMcs variables.
2707  *      - maxUlRbs = configured maximum UL bandwidth value per UE.
2708  *      - trgUlCqi = configured value, if any, else cell-wide default trg CQI value.
2709  *      - If format type is format 3A, update remaining power to +1
2710  *      - Update TPC-RNTI information for the cell for Pucch and Pusch.
2711  *      - Return ROK
2712  *
2713  *  @param[in]  RgSchCellCb  *cell
2714  *  @param[in]  RgSchUeCb    *ue
2715  *  @param[in]  RgrUeCfg     *cfg
2716  *  @return  S16
2717  *      -# ROK
2718  *      -# RFAILED
2719  **/
2720 #ifdef ANSI
2721 PUBLIC S16 rgSCHPwrUeCfg
2722 (
2723 RgSchCellCb *cell,
2724 RgSchUeCb   *ue,
2725 RgrUeCfg    *cfg
2726 )
2727 #else
2728 PUBLIC S16 rgSCHPwrUeCfg(cell, ue, cfg)
2729 RgSchCellCb *cell;
2730 RgSchUeCb   *ue;
2731 RgrUeCfg    *cfg;
2732 #endif
2733 {
2734    S16                    ret;
2735    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2736    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2737
2738    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
2739
2740    TRC2(rgSCHPwrUeCfg);
2741
2742    uePwr->maxUePwr = cellPwr->pMax;
2743    uePwr->trgCqi   = cellPwr->trgUlCqi; /* Overriding with UE's happens later */
2744    uePwr->numRb    = 1;
2745
2746    uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize];
2747
2748    rgSCHPwrUeResetPucch(cell, ue);
2749    rgSCHPwrUeResetPusch(cell, ue);
2750
2751    /* Rest of the vars update and group power control related
2752     * config happens in the function below */
2753    ret = rgSCHPwrApplyUePwrCfg(cell, ue, &cfg->ueUlPwrCfg);
2754
2755    RETVALUE(ret);
2756 }
2757
2758 /**
2759  * @brief Handles power related re-configuration for a UE
2760  *
2761  * @details
2762  *
2763  *     Function : rgSCHPwrUeRecfg
2764  *
2765  *     Invoking Module Processing:
2766  *      - This shall be invoked by SCH_GOM at UE re-configuration.
2767  *        
2768  *     Processing Steps:
2769  *      - If change in TPC-RNTI, update the pointer and the TPC RNTI Cb appropriately.
2770  *      - If accumulation disabled, remove the UE from TPC-RNTI lists of UE, if
2771  *      it exists.
2772  *      - If group power configuration disabled, remove the UE from TPC-RNTI lists of UE, if
2773  *      it exists.
2774  *
2775  *  @param[in]  RgSchCellCb  *cell
2776  *  @param[in]  RgSchUeCb    *ue
2777  *  @param[in]  RgrUeRecfg   *recfg
2778  *
2779  *  @return  S16
2780  *      -# ROK
2781  *      -# RFAILED
2782  **/
2783 #ifdef ANSI
2784 PUBLIC S16 rgSCHPwrUeRecfg
2785 (
2786 RgSchCellCb   *cell,
2787 RgSchUeCb     *ue,
2788 RgrUeRecfg    *recfg
2789 )
2790 #else
2791 PUBLIC S16 rgSCHPwrUeRecfg(cell, ue, recfg)
2792 RgSchCellCb *cell;
2793 RgSchUeCb   *ue;
2794 RgrUeRecfg  *recfg;
2795 #endif
2796 {
2797    S16                    ret;
2798    RgSchCmnUeUlPwrCb     *uePwr       = RG_SCH_PWR_GETUEPWR(ue, cell);
2799    RgrUeUlPwrCfg         *pwrCfg = &recfg->ueUlPwrRecfg;
2800    TRC2(rgSCHPwrUeRecfg);
2801
2802    if (pwrCfg->p0UePucch != uePwr->p0UePucch)
2803    {
2804       rgSCHPwrUeResetPucch(cell, ue);
2805    }
2806    if ((pwrCfg->isAccumulated != uePwr->isAccumulated)
2807          || (pwrCfg->p0UePusch != uePwr->p0UePusch))
2808    {
2809       rgSCHPwrUeResetPusch(cell, ue);
2810    }
2811    ret = rgSCHPwrApplyUePwrCfg(cell, ue, &recfg->ueUlPwrRecfg);
2812
2813    RETVALUE(ret);
2814 }
2815
2816 /***********************************************************
2817  *
2818  *     Func : rgSCHPwrApplyUePwrCfg
2819  *
2820  *     Desc : Applies power config for UE. Meants to be
2821  *            used during both power config and reconfig.
2822  *
2823  *     Ret  : ROK/RFAILED
2824  *
2825  *     Notes:
2826  *
2827  *     File :
2828  *
2829  **********************************************************/
2830 #ifdef ANSI
2831 PRIVATE S16 rgSCHPwrApplyUePwrCfg 
2832 (
2833 RgSchCellCb          *cell,
2834 RgSchUeCb            *ue,
2835 RgrUeUlPwrCfg        *pwrCfg
2836 )
2837 #else
2838 PRIVATE S16 rgSCHPwrApplyUePwrCfg(cell, ue, pwrCfg)
2839 RgSchCellCb          *cell;
2840 RgSchUeCb            *ue;
2841 RgrUeUlPwrCfg        *pwrCfg;
2842 #endif
2843 {
2844    S16                    ret;
2845    RgSchCmnUlUe          *ueUl        = RG_SCH_CMN_GET_UL_UE(ue, cell);
2846    RgSchCmnUeUlPwrCb     *uePwr       = RG_SCH_PWR_GETUEPWR(ue, cell);
2847    RgSchCmnTpcRntiCb     *pucchRntiCb = NULLP;
2848    RgSchCmnTpcRntiCb     *puschRntiCb = NULLP;
2849    U8                     pucchIdx    = 0;
2850    U8                     puschIdx    = 0;
2851    TRC2(rgSCHPwrApplyUePwrCfg);
2852
2853    /* Validate Pucch group power control config */
2854    if (pwrCfg->uePucchPwr.pres)
2855    {
2856       pucchRntiCb =
2857          rgSCHPwrGetPucchRntiCb(cell, pwrCfg->uePucchPwr.tpcRnti);
2858       if (pucchRntiCb == NULLP)
2859       {
2860          RETVALUE(RFAILED);
2861       }
2862       pucchIdx = pwrCfg->uePucchPwr.idx;
2863       ret = rgSCHPwrChkPucchTpcRntiIdx(pucchRntiCb, pucchIdx);
2864       if (ret != ROK)
2865       {
2866          RETVALUE(ret);
2867       }
2868    }
2869
2870    /* Validate Pusch group power control config */
2871    if (pwrCfg->uePuschPwr.pres)
2872    {
2873       puschRntiCb =
2874          rgSCHPwrGetPuschRntiCb(cell, pwrCfg->uePuschPwr.tpcRnti);
2875       if (puschRntiCb == NULLP)
2876       {
2877          RETVALUE(RFAILED);
2878       }
2879       puschIdx = pwrCfg->uePuschPwr.idx;
2880       ret = rgSCHPwrChkPuschTpcRntiIdx(puschRntiCb, puschIdx);
2881       if (ret != ROK)
2882       {
2883          RETVALUE(ret);
2884       }
2885    }
2886
2887    /* Apply Pucch group power control config */
2888    if (pucchRntiCb)
2889    {
2890       if (uePwr->tpcPucchRntiCb != pucchRntiCb) /* This part for recfg */
2891       {
2892          if (uePwr->tpcPucchRntiCb)
2893          {
2894             rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
2895          }
2896          uePwr->tpcPucchRntiCb = pucchRntiCb;
2897          rgSCHPwrAddUeToPucchTpcRntiCb(cell, pucchRntiCb, ue);
2898       }
2899       uePwr->pucchIdx = pucchIdx;
2900 #ifndef ALIGN_64BIT
2901       RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2902                "<GRP_PWR>PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d",
2903                pucchRntiCb->cfgdUes.count,((U32)pucchRntiCb->cfgdUes.first),
2904                ((U32)pucchRntiCb->cfgdUes.last),ue->ueId);
2905       RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
2906                "UEID:%d isFmt3a(%u) ueNode(%ld)",
2907                ue->ueId,pucchRntiCb->isFmt3a,
2908                pucchRntiCb->schdLnk.node);
2909       RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2910                "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)", 
2911                pucchRntiCb->toBeSchdUes.count, 
2912                ((U32)pucchRntiCb->toBeSchdUes.first),
2913                ((U32)pucchRntiCb->toBeSchdUes.last), 
2914                pucchRntiCb->tpcRnti);
2915 #else
2916       RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2917                "<GRP_PWR>PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d",
2918                pucchRntiCb->cfgdUes.count,((U64)pucchRntiCb->cfgdUes.first),
2919                ((U64)pucchRntiCb->cfgdUes.last),ue->ueId);
2920       RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
2921                "UEID:%d isFmt3a(%u) ueNode(%ld)",
2922                ue->ueId,pucchRntiCb->isFmt3a,
2923                pucchRntiCb->schdLnk.node);
2924       RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2925                "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)", 
2926                pucchRntiCb->toBeSchdUes.count, 
2927                ((U64)pucchRntiCb->toBeSchdUes.first),
2928                ((U64)pucchRntiCb->toBeSchdUes.last), 
2929                pucchRntiCb->tpcRnti);
2930
2931 #endif
2932    }
2933
2934    /* Apply Pusch group power control config */
2935    if (puschRntiCb)
2936    {
2937       if (uePwr->tpcPuschRntiCb != puschRntiCb) /* This part for recfg */
2938       {
2939          if (uePwr->tpcPuschRntiCb)
2940          {
2941             rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
2942          }
2943          uePwr->tpcPuschRntiCb = puschRntiCb;
2944          rgSCHPwrAddUeToPuschTpcRntiCb(puschRntiCb, ue);
2945       }
2946       uePwr->puschIdx = puschIdx;
2947    }
2948
2949    /* Update vars */
2950    uePwr->isAccumulated = pwrCfg->isAccumulated;
2951    uePwr->deltaMcsEnbld = pwrCfg->isDeltaMCSEnabled;
2952    if (pwrCfg->trgCqi)
2953    {
2954       uePwr->trgCqi = pwrCfg->trgCqi;
2955    }
2956    if (ueUl->maxUlCqi < uePwr->trgCqi)
2957    {
2958       uePwr->trgCqi = ueUl->maxUlCqi;
2959    }
2960    uePwr->p0UePusch = pwrCfg->p0UePusch;
2961    uePwr->p0UePucch = pwrCfg->p0UePucch;
2962
2963    RETVALUE(ROK);
2964 }
2965
2966
2967 /**
2968  * @brief Deletes power related information for UE
2969  *
2970  * @details
2971  *
2972  *     Function : rgSCHPwrUeDel
2973  *
2974  *     Invoking Module Processing:
2975  *      - This shall be invoked by at the time of UE deletion.
2976  *        
2977  *     Processing Steps:
2978  *     - if (ue->tpcPucchRntiCb)
2979  *       - delete UE from tpcPucchRntiCb->ueLst
2980  *       - ue->tpcPucchRntiCb = NULLP
2981  *       - If in (ue->tpcPucchRntiCb->toBeSchdLst) 
2982  *         - remove from the list.
2983  *     - if (ue->tpcPuschRntiCb)
2984  *       - delete UE from tpcPuschRntiCb->ueLst
2985  *       - ue->tpcPuschRntiCb = NULLP
2986  *       - If in (ue->tpcPuschRntiCb->toBeSchdLst) 
2987  *         - remove from the list.
2988  *
2989  *  @param[in]  RgSchCellCb     *cell
2990  *  @param[in]  RgSchUeCb       *ue
2991  *  @return  Void
2992  **/
2993 #ifdef ANSI
2994 PUBLIC Void rgSCHPwrUeDel
2995 (
2996 RgSchCellCb           *cell,
2997 RgSchUeCb             *ue
2998 )
2999 #else
3000 PUBLIC Void rgSCHPwrUeDel(cell, ue)
3001 RgSchCellCb           *cell;
3002 RgSchUeCb             *ue;
3003 #endif
3004 {
3005    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
3006    TRC2(rgSCHPwrUeDel);
3007
3008    if (uePwr->tpcPucchRntiCb)
3009    {
3010       rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
3011       uePwr->tpcPucchRntiCb = NULLP;
3012    }
3013    if (uePwr->tpcPuschRntiCb)
3014    {
3015       rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
3016       uePwr->tpcPuschRntiCb = NULLP;
3017    }
3018    RETVOID;
3019 }
3020
3021 /**
3022  * @brief Resets UE's power state
3023  *
3024  * @details
3025  *
3026  *     Function : rgSCHPwrUeReset
3027  *
3028  *     Invoking Module Processing:
3029  *      - This shall be invoked by at the time PDCCH order.
3030  *
3031  *     Processing Steps:
3032  *     - Reset PUSCH power state
3033  *     - Reset PUCCH power state
3034  *
3035  *  @param[in]  RgSchCellCb     *cell
3036  *  @param[in]  RgSchUeCb       *ue
3037  *  @return  Void
3038  **/
3039 #ifdef ANSI
3040 PUBLIC Void rgSCHPwrUeReset
3041 (
3042 RgSchCellCb           *cell,
3043 RgSchUeCb             *ue
3044 )
3045 #else
3046 PUBLIC Void rgSCHPwrUeReset(cell, ue)
3047 RgSchCellCb           *cell;
3048 RgSchUeCb             *ue;
3049 #endif
3050 {
3051    TRC2(rgSCHPwrUeReset);
3052
3053    rgSCHPwrUeResetPucch(cell, ue);
3054    rgSCHPwrUeResetPusch(cell, ue);
3055    RETVOID;
3056 }
3057
3058 /***********************************************************
3059  *
3060  *     Func : rgSCHPwrUeResetPucch
3061  *
3062  *     Desc : This function is called to reset UE
3063  *            to initial PUCCH power state.
3064  *
3065  *     Ret  : Void
3066  *
3067  *     Notes:
3068  *
3069  *     File :
3070  *
3071  **********************************************************/
3072 #ifdef ANSI
3073 PRIVATE Void rgSCHPwrUeResetPucch 
3074 (
3075 RgSchCellCb          *cell,
3076 RgSchUeCb            *ue
3077 )
3078 #else
3079 PRIVATE Void rgSCHPwrUeResetPucch(cell, ue)
3080 RgSchCellCb          *cell;
3081 RgSchUeCb            *ue;
3082 #endif
3083 {
3084    RgSchCmnUeUlPwrCb     *uePwr       = RG_SCH_PWR_GETUEPWR(ue, cell);
3085    TRC2(rgSCHPwrUeResetPucch);
3086
3087    uePwr->pucchTpc    = 1;
3088    uePwr->remPucchPwr = 0;
3089    if (uePwr->tpcPucchRntiCb)
3090    {
3091       rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
3092    }
3093
3094    /* Stack Crash problem for TRACE5 changes. Added the line below */
3095   RETVOID;
3096  
3097 }
3098
3099 /***********************************************************
3100  *
3101  *     Func : rgSCHPwrUeResetPusch
3102  *
3103  *     Desc : This function is called to reset UE
3104  *            to initial PUSCH power state.
3105  *
3106  *     Ret  : Void
3107  *
3108  *     Notes:
3109  *
3110  *     File :
3111  *
3112  **********************************************************/
3113 #ifdef ANSI
3114 PRIVATE Void rgSCHPwrUeResetPusch 
3115 (
3116 RgSchCellCb          *cell,
3117 RgSchUeCb            *ue
3118 )
3119 #else
3120 PRIVATE Void rgSCHPwrUeResetPusch(cell, ue)
3121 RgSchCellCb          *cell;
3122 RgSchUeCb            *ue;
3123 #endif
3124 {
3125    RgSchCmnUeUlPwrCb     *uePwr       = RG_SCH_PWR_GETUEPWR(ue, cell);
3126    TRC2(rgSCHPwrUeResetPusch);
3127
3128    uePwr->isPhrAvail  = FALSE;
3129    uePwr->phVal       = 40;
3130    uePwr->maxUlRbs    = RGSCH_MAX_DL_BW;
3131    uePwr->delta       = 0;
3132    uePwr->puschTpc    = 1;
3133    uePwr->remPuschPwr = 0;
3134    if (uePwr->tpcPuschRntiCb)
3135    {
3136       rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
3137    }
3138    RETVOID;
3139 }
3140
3141 /***********************************************************
3142  *
3143  *     Func : rgSCHPwrOnPuschPwrUpd
3144  *
3145  *     Desc : This function is called whenever 'remPuschPwr'
3146  *            is updated
3147  *
3148  *     Ret  : Void
3149  *
3150  *     Notes:
3151  *
3152  *     File :
3153  *
3154  **********************************************************/
3155 #ifdef ANSI
3156 PRIVATE Void rgSCHPwrOnPuschPwrUpd 
3157 (
3158 RgSchCellCb          *cell,
3159 RgSchUeCb            *ue
3160 )
3161 #else
3162 PRIVATE Void rgSCHPwrOnPuschPwrUpd(cell, ue)
3163 RgSchCellCb          *cell;
3164 RgSchUeCb            *ue;
3165 #endif
3166 {
3167    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
3168    RgSchCmnTpcRntiCb     *cb;
3169    Bool                   toAdd;
3170    TRC2(rgSCHPwrOnPuschPwrUpd);
3171
3172    if ((cb = uePwr->tpcPuschRntiCb) == NULLP)
3173    {
3174       RETVOID;
3175    }
3176
3177    /* Not checking for uwPwr->isPhrAvail as uePwr->phVal
3178     * is set to a large value initially */
3179    toAdd = FALSE;
3180
3181
3182    if ((uePwr->phVal != 0) && (uePwr->remPuschPwr != 0))
3183       {
3184          toAdd = TRUE;
3185       }
3186
3187
3188    if (toAdd)
3189    {
3190       rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue);
3191    }
3192    else
3193    {
3194       rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue);
3195    }
3196
3197    RETVOID;
3198 }
3199
3200
3201 /***********************************************************
3202  *
3203  *     Func : rgSCHPwrAddRntiToPucchRntiLst
3204  *
3205  *
3206  *     Desc : Adds RNTI to Pucch Rnti list and updates requisite
3207  *            information. 
3208  *
3209  *     Ret  : Void
3210  *
3211  *     Notes: Assumed that array bounds are checked
3212  *            in caller before adding.
3213  *
3214  *     File :
3215  *
3216  **********************************************************/
3217 #ifdef ANSI
3218 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst 
3219 (
3220 RgSchCellCb          *cell,
3221 CmLteRnti             rnti,
3222 Bool                  isFmt3a
3223 )
3224 #else
3225 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a)
3226 RgSchCellCb          *cell;
3227 CmLteRnti             rnti;
3228 Bool                  isFmt3a;
3229 #endif
3230 {
3231    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3232    TRC2(rgSCHPwrAddRntiToPucchRntiLst);
3233
3234    rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPucchRntiLst[cellPwr->tpcPucchRntiCnt++],
3235        rnti, isFmt3a);
3236    RETVOID;
3237 }
3238
3239 /***********************************************************
3240  *
3241  *     Func : rgSCHPwrAddRntiToPuschRntiLst
3242  *
3243  *
3244  *     Desc : Adds RNTI to Pusch Rnti list and updates requisite
3245  *            information. 
3246  *
3247  *     Ret  : Void
3248  *
3249  *     Notes: Assumed that array bounds are checked
3250  *            in caller before adding.
3251  *
3252  *     File :
3253  *
3254  **********************************************************/
3255 #ifdef ANSI
3256 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst 
3257 (
3258 RgSchCellCb          *cell,
3259 CmLteRnti             rnti,
3260 Bool                  isFmt3a
3261 )
3262 #else
3263 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a)
3264 RgSchCellCb          *cell;
3265 CmLteRnti             rnti;
3266 Bool                  isFmt3a;
3267 #endif
3268 {
3269    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3270    TRC2(rgSCHPwrAddRntiToPuschRntiLst);
3271
3272    rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPuschRntiLst[cellPwr->tpcPuschRntiCnt++], 
3273        rnti, isFmt3a);
3274    RETVOID;
3275 }
3276
3277 /***********************************************************
3278  *
3279  *     Func : rgSCHPwrInitTpcRntiCb
3280  *
3281  *
3282  *     Desc : Initialises a TPC RNTI CB
3283  *
3284  *     Ret  : Void
3285  *
3286  *     Notes:
3287  *
3288  *     File :
3289  *
3290  **********************************************************/
3291 #ifdef ANSI
3292 PRIVATE Void rgSCHPwrInitTpcRntiCb 
3293 (
3294 RgSchCmnTpcRntiCb    *cb,
3295 CmLteRnti             rnti,
3296 Bool                  isFmt3a
3297 )
3298 #else
3299 PRIVATE Void rgSCHPwrInitTpcRntiCb(cb, rnti, isFmt3a)
3300 RgSchCmnTpcRntiCb    *cb;
3301 CmLteRnti             rnti;
3302 Bool                  isFmt3a;
3303 #endif
3304 {
3305    TRC2(rgSCHPwrInitTpcRntiCb);
3306
3307    cmMemset((U8 *)cb, 0, sizeof(*cb));
3308    cb->tpcRnti = rnti;
3309    cb->isFmt3a = isFmt3a;
3310    /* Not initialising lists as memset 0 takes care of it */
3311    /* cb->schdLnk.node is set when this rnti is to be scheduled */
3312    RETVOID;
3313 }
3314
3315 /***********************************************************
3316  *
3317  *     Func : rgSCHPwrGetPucchRntiCb
3318  *
3319  *
3320  *     Desc : Gets TPC RNTI control block from Pucch rnti list 
3321  *
3322  *     Ret  : RgSchCmnTpcRntiCb * - Success
3323  *            NULLP - Fail
3324  *
3325  *     Notes:
3326  *
3327  *     File :
3328  *
3329  **********************************************************/
3330 #ifdef ANSI
3331 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb
3332 (
3333 RgSchCellCb *cell,
3334 CmLteRnti   tpcRnti
3335 )
3336 #else
3337 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb(cell, tpcRnti)
3338 RgSchCellCb *cell;
3339 CmLteRnti   tpcRnti;
3340 #endif
3341 {
3342    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3343    U16                    idx;
3344    TRC2(rgSCHPwrGetPucchRntiCb);
3345
3346    if (!cellPwr->tpcPucchRntiCnt)
3347    {
3348       RETVALUE(NULLP);
3349    }
3350    for (idx = 0; idx < cellPwr->tpcPucchRntiCnt; ++idx)
3351    {
3352       if (cellPwr->tpcPucchRntiLst[idx].tpcRnti == tpcRnti)
3353       {
3354          RETVALUE(&cellPwr->tpcPucchRntiLst[idx]);
3355       }
3356    }
3357    RETVALUE(NULLP);
3358 }
3359
3360 /***********************************************************
3361  *
3362  *     Func : rgSCHPwrGetPuschRntiCb
3363  *
3364  *
3365  *     Desc : Gets TPC RNTI control block from Pusch rnti list 
3366  *
3367  *     Ret  : RgSchCmnTpcRntiCb * - Success
3368  *            NULLP - Fail
3369  *
3370  *     Notes:
3371  *
3372  *     File :
3373  *
3374  **********************************************************/
3375 #ifdef ANSI
3376 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb
3377 (
3378 RgSchCellCb *cell,
3379 CmLteRnti   tpcRnti
3380 )
3381 #else
3382 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb(cell, tpcRnti)
3383 RgSchCellCb *cell;
3384 CmLteRnti   tpcRnti;
3385 #endif
3386 {
3387    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3388    U16                    idx;
3389    TRC2(rgSCHPwrGetPuschRntiCb);
3390
3391    if (!cellPwr->tpcPuschRntiCnt)
3392    {
3393       RETVALUE(NULLP);
3394    }
3395    for (idx = 0; idx < cellPwr->tpcPuschRntiCnt; ++idx)
3396    {
3397       if (cellPwr->tpcPuschRntiLst[idx].tpcRnti == tpcRnti)
3398       {
3399          RETVALUE(&cellPwr->tpcPuschRntiLst[idx]);
3400       }
3401    }
3402    RETVALUE(NULLP);
3403 }
3404
3405
3406 /***********************************************************
3407  *
3408  *     Func : rgSCHPwrAddUeToPucchTpcRntiCb
3409  *
3410  *
3411  *     Desc : Add UE to cfgd list of UEs in rnti cb
3412  *
3413  *     Ret  :
3414  *
3415  *     Notes:
3416  *
3417  *     File :
3418  *
3419  **********************************************************/
3420 #ifdef ANSI
3421 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb
3422 (
3423 RgSchCellCb           *cell,
3424 RgSchCmnTpcRntiCb     *cb,
3425 RgSchUeCb             *ue
3426 )
3427 #else
3428 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb(cell, cb, ue)
3429 RgSchCellCb           *cell;
3430 RgSchCmnTpcRntiCb     *cb;
3431 RgSchUeCb             *ue;
3432 #endif
3433 {
3434    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3435    UNUSED(cell);
3436    TRC2(rgSCHPwrAddUeToPucchTpcRntiCb);
3437
3438    cmLListAdd2Tail(&cb->cfgdUes, &uePwr->pucchGrpLnk);
3439    uePwr->pucchGrpLnk.node = (PTR)ue;
3440    RETVOID;
3441 }
3442
3443 /***********************************************************
3444  *
3445  *     Func : rgSCHPwrDelUeFrmPucchTpcRntiCb
3446  *
3447  *
3448  *     Desc : Remove UE from Pucch TPC RNTI CB
3449  *
3450  *     Ret  :
3451  *
3452  *     Notes:
3453  *
3454  *     File :
3455  *
3456  **********************************************************/
3457 #ifdef ANSI
3458 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb
3459 (
3460 RgSchCellCb           *cell,
3461 RgSchCmnTpcRntiCb     *cb,
3462 RgSchUeCb             *ue
3463 )
3464 #else
3465 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, cb, ue)
3466 RgSchCellCb           *cell;
3467 RgSchCmnTpcRntiCb     *cb;
3468 RgSchUeCb             *ue;
3469 #endif
3470 {
3471    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3472    TRC2(rgSCHPwrDelUeFrmPucchTpcRntiCb);
3473
3474    rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue);
3475    cmLListDelFrm(&cb->cfgdUes, &uePwr->pucchGrpLnk);
3476    uePwr->pucchGrpLnk.node = NULLP;
3477    RETVOID;
3478 }
3479
3480 /***********************************************************
3481  *
3482  *     Func : rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb
3483  *
3484  *
3485  *     Desc : Remove UE from to-be-scheduled list of UEs
3486  *            in Pusch RNTI CB
3487  *
3488  *     Ret  :
3489  *
3490  *     Notes:
3491  *
3492  *     File :
3493  *
3494  **********************************************************/
3495 #ifdef ANSI
3496 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb
3497 (
3498 RgSchCellCb           *cell,
3499 RgSchCmnTpcRntiCb     *cb,
3500 RgSchUeCb             *ue
3501 )
3502 #else
3503 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue)
3504 RgSchCellCb           *cell;
3505 RgSchCmnTpcRntiCb     *cb;
3506 RgSchUeCb             *ue;
3507 #endif
3508 {
3509    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3510    TRC2(rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb);
3511
3512    if (uePwr->schdPucchGrpLnk.node == NULLP)
3513    {
3514       RETVOID;
3515    }
3516    rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue);
3517    if (!cb->toBeSchdUes.count)
3518    {
3519       rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb);
3520    }
3521    RETVOID;
3522 }
3523
3524 /***********************************************************
3525  *
3526  *     Func : rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb
3527  *
3528  *     Desc : Remove UE from to-be-scheduled list of UEs
3529  *            in Pucch RNTI CB. Do not both about
3530  *            possibly removing Pucch RNTI CB from
3531  *            the cell wide to-be-scheduled list.
3532  *
3533  *     Ret  :
3534  *
3535  *     Notes:
3536  *
3537  *     File :
3538  *
3539  **********************************************************/
3540 #ifdef ANSI
3541 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb
3542 (
3543 RgSchCellCb           *cell,
3544 RgSchCmnTpcRntiCb     *cb,
3545 RgSchUeCb             *ue
3546 )
3547 #else
3548 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue)
3549 RgSchCellCb           *cell;
3550 RgSchCmnTpcRntiCb     *cb;
3551 RgSchUeCb             *ue;
3552 #endif
3553 {
3554    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3555    TRC2(rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb);
3556
3557    if (uePwr->schdPucchGrpLnk.node != NULLP)
3558    {
3559       cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk);
3560       uePwr->schdPucchGrpLnk.node = NULLP;
3561    }
3562    RETVOID;
3563 }
3564
3565 /***********************************************************
3566  *
3567  *     Func : rgSCHPwrRmvSchdPucchTpcRntiCb
3568  *
3569  *     Desc : Remove Pucch TPC RNTI CB from to-be-scheduled
3570  *            list in cell
3571  *
3572  *     Ret  : Void
3573  *
3574  *     Notes:
3575  *
3576  *     File :
3577  *
3578  **********************************************************/
3579 #ifdef ANSI
3580 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb
3581 (
3582 RgSchCellCb           *cell,
3583 RgSchCmnTpcRntiCb     *cb
3584 )
3585 #else
3586 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb)
3587 RgSchCellCb           *cell;
3588 RgSchCmnTpcRntiCb     *cb;
3589 #endif
3590 {
3591    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3592    TRC2(rgSCHPwrRmvSchdPucchTpcRntiCb);
3593
3594    if (cb->schdLnk.node == NULLP)
3595    {
3596       RETVOID;
3597    }
3598    cmLListDelFrm(&cellPwr->pucchGrpPwr, &cb->schdLnk);
3599    cb->schdLnk.node = NULLP;
3600    RETVOID;
3601 }
3602
3603 /***********************************************************
3604  *
3605  *     Func : rgSCHPwrAddSchdUeToPucchTpcRntiCb
3606  *
3607  *     Desc : Add UE to to-be-scheduled list of UEs
3608  *            in Pucch RNTI CB
3609  *
3610  *     Ret  :
3611  *
3612  *     Notes:
3613  *
3614  *     File :
3615  *
3616  **********************************************************/
3617 #ifdef ANSI
3618 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb
3619 (
3620 RgSchCellCb           *cell,
3621 RgSchCmnTpcRntiCb     *cb,
3622 RgSchUeCb             *ue
3623 )
3624 #else
3625 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue)
3626 RgSchCellCb           *cell;
3627 RgSchCmnTpcRntiCb     *cb;
3628 RgSchUeCb             *ue;
3629 #endif
3630 {
3631    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3632    TRC2(rgSCHPwrAddSchdUeToPucchTpcRntiCb);
3633
3634    if (uePwr->schdPucchGrpLnk.node != NULLP)
3635    {
3636       /* UE is already in the list */
3637       RETVOID;
3638    }
3639    cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk);
3640    uePwr->schdPucchGrpLnk.node = (PTR)ue;
3641    if (cb->toBeSchdUes.count == 1)
3642    {
3643       /* This is first UE, so queue up this TPC RNTI
3644        * for scheduling */
3645       rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb);
3646    }
3647    RETVOID;
3648 }
3649
3650 /***********************************************************
3651  *
3652  *     Func : rgSCHPwrAddSchdPucchTpcRntiCb
3653  *
3654  *     Desc : Add Pucch TPC RNTI CB from to-be-scheduled
3655  *            list in cell
3656  *
3657  *     Ret  : Void
3658  *
3659  *     Notes:
3660  *
3661  *     File :
3662  *
3663  **********************************************************/
3664 #ifdef ANSI
3665 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb
3666 (
3667 RgSchCellCb           *cell,
3668 RgSchCmnTpcRntiCb     *cb
3669 )
3670 #else
3671 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb)
3672 RgSchCellCb           *cell;
3673 RgSchCmnTpcRntiCb     *cb;
3674 #endif
3675 {
3676    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3677    TRC2(rgSCHPwrAddSchdPucchTpcRntiCb);
3678
3679    cmLListAdd2Tail(&cellPwr->pucchGrpPwr, &cb->schdLnk);
3680    cb->schdLnk.node = (PTR)cb;
3681    RETVOID;
3682 }
3683
3684
3685 /***********************************************************
3686  *
3687  *     Func : rgSCHPwrAddUeToPuschTpcRntiCb
3688  *
3689  *
3690  *     Desc : Add UE to cfgd list of UEs in rnti cb
3691  *
3692  *     Ret  :
3693  *
3694  *     Notes:
3695  *
3696  *     File :
3697  *
3698  **********************************************************/
3699 #ifdef ANSI
3700 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb
3701 (
3702 RgSchCmnTpcRntiCb     *cb,
3703 RgSchUeCb             *ue
3704 )
3705 #else
3706 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb(cb, ue)
3707 RgSchCmnTpcRntiCb     *cb;
3708 RgSchUeCb             *ue;
3709 #endif
3710 {
3711    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3712    TRC2(rgSCHPwrAddUeToPuschTpcRntiCb);
3713
3714    cmLListAdd2Tail(&cb->cfgdUes, &uePwr->puschGrpLnk);
3715    uePwr->puschGrpLnk.node = (PTR)ue;
3716    RETVOID;
3717 }
3718
3719 /***********************************************************
3720  *
3721  *     Func : rgSCHPwrAddSchdUeToPuschTpcRntiCb
3722  *
3723  *     Desc : Add UE to to-be-scheduled list of UEs
3724  *            in Pusch RNTI CB
3725  *
3726  *     Ret  :
3727  *
3728  *     Notes:
3729  *
3730  *     File :
3731  *
3732  **********************************************************/
3733 #ifdef ANSI
3734 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb
3735 (
3736 RgSchCellCb           *cell,
3737 RgSchCmnTpcRntiCb     *cb,
3738 RgSchUeCb             *ue
3739 )
3740 #else
3741 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue)
3742 RgSchCellCb           *cell;
3743 RgSchCmnTpcRntiCb     *cb;
3744 RgSchUeCb             *ue;
3745 #endif
3746 {
3747    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3748    TRC2(rgSCHPwrAddSchdUeToPuschTpcRntiCb);
3749
3750    if (uePwr->schdPuschGrpLnk.node != NULLP)
3751    {
3752       /* UE is already in the list */
3753       RETVOID;
3754    }
3755    cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk);
3756    uePwr->schdPuschGrpLnk.node = (PTR)ue;
3757    if (cb->toBeSchdUes.count == 1)
3758    {
3759       /* This is first UE, so queue up this TPC RNTI
3760        * for scheduling */
3761       rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb);
3762    }
3763    RETVOID;
3764 }
3765
3766 /***********************************************************
3767  *
3768  *     Func : rgSCHPwrDelUeFrmPuschTpcRntiCb
3769  *
3770  *
3771  *     Desc : Add UE to cfgd list of UEs in rnti cb
3772  *
3773  *     Ret  :
3774  *
3775  *     Notes:
3776  *
3777  *     File :
3778  *
3779  **********************************************************/
3780 #ifdef ANSI
3781 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb
3782 (
3783 RgSchCellCb           *cell,
3784 RgSchCmnTpcRntiCb     *cb,
3785 RgSchUeCb             *ue
3786 )
3787 #else
3788 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, cb, ue)
3789 RgSchCellCb           *cell;
3790 RgSchCmnTpcRntiCb     *cb;
3791 RgSchUeCb             *ue;
3792 #endif
3793 {
3794    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3795    TRC2(rgSCHPwrDelUeFrmPuschTpcRntiCb);
3796
3797    rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue);
3798    cmLListDelFrm(&cb->cfgdUes, &uePwr->puschGrpLnk);
3799    uePwr->puschGrpLnk.node = NULLP;
3800    RETVOID;
3801 }
3802
3803 /***********************************************************
3804  *
3805  *     Func : rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb
3806  *
3807  *     Desc : Remove UE from to-be-scheduled list of UEs
3808  *            in Pusch RNTI CB
3809  *
3810  *     Ret  :
3811  *
3812  *     Notes:
3813  *
3814  *     File :
3815  *
3816  **********************************************************/
3817 #ifdef ANSI
3818 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb
3819 (
3820 RgSchCellCb           *cell,
3821 RgSchCmnTpcRntiCb     *cb,
3822 RgSchUeCb             *ue
3823 )
3824 #else
3825 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue)
3826 RgSchCellCb           *cell;
3827 RgSchCmnTpcRntiCb     *cb;
3828 RgSchUeCb             *ue;
3829 #endif
3830 {
3831    RgSchCmnUeUlPwrCb     *uePwr       = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3832    TRC2(rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb);
3833
3834    if (uePwr->schdPuschGrpLnk.node == NULLP)
3835    {
3836       RETVOID;
3837    }
3838    rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue);
3839    if (!cb->toBeSchdUes.count)
3840    {
3841       rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb);
3842    }
3843    RETVOID;
3844 }
3845
3846 /***********************************************************
3847  *
3848  *     Func : rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb
3849  *
3850  *     Desc : Remove UE from to-be-scheduled list of UEs
3851  *            in Pusch RNTI CB. Do not both about
3852  *            possibly removing Pusch RNTI CB from
3853  *            the cell wide to-be-scheduled list.
3854  *
3855  *     Ret  :
3856  *
3857  *     Notes:
3858  *
3859  *     File :
3860  *
3861  **********************************************************/
3862 #ifdef ANSI
3863 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb
3864 (
3865 RgSchCellCb           *cell,
3866 RgSchCmnTpcRntiCb     *cb,
3867 RgSchUeCb             *ue
3868 )
3869 #else
3870 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue)
3871 RgSchCellCb           *cell;
3872 RgSchCmnTpcRntiCb     *cb;
3873 RgSchUeCb             *ue;
3874 #endif
3875 {
3876    RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3877    TRC2(rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb);
3878
3879    if (uePwr->schdPuschGrpLnk.node != NULLP)
3880    {
3881       cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk);
3882       uePwr->schdPuschGrpLnk.node = NULLP;
3883    }
3884    RETVOID;
3885 }
3886
3887 /***********************************************************
3888  *
3889  *     Func : rgSCHPwrAddSchdPuschTpcRntiCb
3890  *
3891  *     Desc : Add Pusch TPC RNTI CB from to-be-scheduled
3892  *            list in cell
3893  *
3894  *     Ret  : Void
3895  *
3896  *     Notes:
3897  *
3898  *     File :
3899  *
3900  **********************************************************/
3901 #ifdef ANSI
3902 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb
3903 (
3904 RgSchCellCb           *cell,
3905 RgSchCmnTpcRntiCb     *cb
3906 )
3907 #else
3908 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb)
3909 RgSchCellCb           *cell;
3910 RgSchCmnTpcRntiCb     *cb;
3911 #endif
3912 {
3913    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3914    TRC2(rgSCHPwrAddSchdPuschTpcRntiCb);
3915
3916    cmLListAdd2Tail(&cellPwr->puschGrpPwr, &cb->schdLnk);
3917    cb->schdLnk.node = (PTR)cb;
3918    RETVOID;
3919 }
3920
3921 /***********************************************************
3922  *
3923  *     Func : rgSCHPwrRmvSchdPuschTpcRntiCb
3924  *
3925  *     Desc : Remove Pusch TPC RNTI CB from to-be-scheduled
3926  *            list in cell
3927  *
3928  *     Ret  : Void
3929  *
3930  *     Notes:
3931  *
3932  *     File :
3933  *
3934  **********************************************************/
3935 #ifdef ANSI
3936 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb
3937 (
3938 RgSchCellCb           *cell,
3939 RgSchCmnTpcRntiCb     *cb
3940 )
3941 #else
3942 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb)
3943 RgSchCellCb           *cell;
3944 RgSchCmnTpcRntiCb     *cb;
3945 #endif
3946 {
3947    RgSchCmnUlPwrCb       *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3948    TRC2(rgSCHPwrRmvSchdPuschTpcRntiCb);
3949
3950    if (cb->schdLnk.node == NULLP)
3951    {
3952       RETVOID;
3953    }
3954    cmLListDelFrm(&cellPwr->puschGrpPwr, &cb->schdLnk);
3955    cb->schdLnk.node = NULLP;
3956    RETVOID;
3957 }
3958
3959 /***********************************************************
3960  *
3961  *     Func : rgSCHPwrChkPucchTpcRntiIdx
3962  *
3963  *     Desc : Validate that the given index is OK to
3964  *            be assigned to a new UE for the Pucch TPC
3965  *            RNTI
3966  *
3967  *     Ret  :
3968  *
3969  *     Notes:
3970  *
3971  *     File :
3972  *
3973  **********************************************************/
3974 #ifdef ANSI
3975 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx
3976 (
3977 RgSchCmnTpcRntiCb     *cb,
3978 U8                     idx
3979 )
3980 #else
3981 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx(cb, idx)
3982 RgSchCmnTpcRntiCb     *cb;
3983 U8                     idx;
3984 #endif
3985 {
3986    TRC2(rgSCHPwrChkPucchTpcRntiIdx);
3987
3988    if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK)
3989    {
3990       RETVALUE(RFAILED);
3991    }
3992    if (rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx) != ROK)
3993    {
3994       RETVALUE(RFAILED);
3995    }
3996    RETVALUE(ROK);
3997 }
3998
3999 /***********************************************************
4000  *
4001  *     Func : rgSCHPwrChkPuschTpcRntiIdx
4002  *
4003  *     Desc : Validate that the given index is OK to
4004  *            be assigned to a new UE for the Pusch TPC
4005  *            RNTI
4006  *
4007  *     Ret  :
4008  *
4009  *     Notes:
4010  *
4011  *     File :
4012  *
4013  **********************************************************/
4014 #ifdef ANSI
4015 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx
4016 (
4017 RgSchCmnTpcRntiCb     *cb,
4018 U8                     idx
4019 )
4020 #else
4021 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx(cb, idx)
4022 RgSchCmnTpcRntiCb     *cb;
4023 U8                     idx;
4024 #endif
4025 {
4026    TRC2(rgSCHPwrChkPuschTpcRntiIdx);
4027
4028    if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK)
4029    {
4030       RETVALUE(RFAILED);
4031    }
4032    if (rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx) != ROK)
4033    {
4034       RETVALUE(RFAILED);
4035    }
4036    RETVALUE(ROK);
4037 }
4038
4039 /***********************************************************
4040  *
4041  *     Func : rgSCHPwrChkUniqPucchTpcRntiIdx
4042  *
4043  *     Desc : Validate index against format type of TPC RNTI
4044  *
4045  *     Ret  :
4046  *
4047  *     Notes:
4048  *
4049  *     File :
4050  *
4051  **********************************************************/
4052 #ifdef ANSI
4053 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx
4054 (
4055 RgSchCmnTpcRntiCb     *cb,
4056 U8                     idx
4057 )
4058 #else
4059 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx)
4060 RgSchCmnTpcRntiCb     *cb;
4061 U8                     idx;
4062 #endif
4063 {
4064    CmLList           *lnk;
4065    TRC2(rgSCHPwrChkUniqPucchTpcRntiIdx);
4066
4067    for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next)
4068    {
4069       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
4070       RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
4071       if (uePwr->pucchIdx == idx)
4072       {
4073          RETVALUE(RFAILED);
4074       }
4075    }
4076    RETVALUE(ROK);
4077 }
4078
4079 /***********************************************************
4080  *
4081  *     Func : rgSCHPwrChkUniqPuschTpcRntiIdx
4082  *
4083  *     Desc : Validate index against format type of TPC RNTI
4084  *
4085  *     Ret  :
4086  *
4087  *     Notes:
4088  *
4089  *     File :
4090  *
4091  **********************************************************/
4092 #ifdef ANSI
4093 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx
4094 (
4095 RgSchCmnTpcRntiCb     *cb,
4096 U8                     idx
4097 )
4098 #else
4099 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx)
4100 RgSchCmnTpcRntiCb     *cb;
4101 U8                     idx;
4102 #endif
4103 {
4104    CmLList           *lnk;
4105    TRC2(rgSCHPwrChkUniqPuschTpcRntiIdx);
4106
4107    for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next)
4108    {
4109       RgSchUeCb             *ue = (RgSchUeCb *)lnk->node;
4110       RgSchCmnUeUlPwrCb     *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
4111       if (uePwr->puschIdx == idx)
4112       {
4113          RETVALUE(RFAILED);
4114       }
4115    }
4116    RETVALUE(ROK);
4117 }
4118
4119 /***********************************************************
4120  *
4121  *     Func : rgSCHPwrChkTpcRntiIdx
4122  *
4123  *     Desc : Validate index against format type of TPC RNTI.
4124  *
4125  *     Ret  :
4126  *
4127  *     Notes:
4128  *
4129  *     File :
4130  *
4131  **********************************************************/
4132 #ifdef ANSI
4133 PRIVATE S16 rgSCHPwrChkTpcRntiIdx
4134 (
4135 RgSchCmnTpcRntiCb     *cb,
4136 U8                     idx
4137 )
4138 #else
4139 PRIVATE S16 rgSCHPwrChkTpcRntiIdx(cb, idx)
4140 RgSchCmnTpcRntiCb     *cb;
4141 U8                     idx;
4142 #endif
4143 {
4144    TRC2(rgSCHPwrChkTpcRntiIdx);
4145
4146    if (cb->isFmt3a)
4147    {
4148       if (idx >= TFU_MAX_1BIT_TPC)
4149       {
4150          RETVALUE(RFAILED);
4151       }
4152    }
4153    else
4154    {
4155       if (idx >= TFU_MAX_2BIT_TPC)
4156       {
4157          RETVALUE(RFAILED);
4158       }
4159    }
4160    RETVALUE(ROK);
4161 }
4162 /* Warning Fix: Commenting out as not used */
4163
4164 /***********************************************************
4165  *
4166  *     Func : rgSCHPwrGetPCMaxValFromPCMax
4167  *
4168  *     Desc : Returns the power headroom in dB
4169  *            corresponding to a power headroom
4170  *            report
4171  *
4172  *     Ret  : S8
4173  *
4174  *     Notes:
4175  *
4176  *     File :
4177  *
4178  **********************************************************/
4179 #ifdef ANSI
4180 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax
4181 (
4182 U8                    pCMax
4183 )
4184 #else
4185 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax(pCMax)
4186 U8                    pCMax;
4187 #endif
4188 {
4189    TRC2(rgSCHPwrGetPCMaxValFromPCMax);
4190    RETVALUE((pCMax & 63) - 30);
4191 }
4192
4193
4194
4195 /***********************************************************
4196  *
4197  *     Func : rgSCHPwrGetPhValFromPhr
4198  *
4199  *     Desc : Returns the power headroom in dB
4200  *            corresponding to a power headroom
4201  *            report
4202  *
4203  *     Ret  : S8
4204  *
4205  *     Notes:
4206  *
4207  *     File :
4208  *
4209  **********************************************************/
4210 #ifdef ANSI
4211 PRIVATE S8 rgSCHPwrGetPhValFromPhr
4212 (
4213 U8                    phr
4214 )
4215 #else
4216 PRIVATE S8 rgSCHPwrGetPhValFromPhr(phr)
4217 U8                    phr;
4218 #endif
4219 {
4220    TRC2(rgSCHPwrGetPhValFromPhr);
4221    RETVALUE((phr & 63) - 23);
4222 }
4223
4224
4225 \f
4226 /**********************************************************************
4227  
4228          End of file
4229 **********************************************************************/