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