1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for power control functionality
29 **********************************************************************/
31 /** @file rg_sch_pwr.c
32 @brief This module handles schedulers' power control functionality
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"
45 #include "rg_sch_inf.h"
46 #include "rg_sch_err.h"
48 #include "rg_sch_cmn.h"
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"
62 /* Current specs have 23 dBm as max tx power capability for UEs */
63 #define RG_SCH_PWR_UE_MAX_PWR 23
65 #define RG_SCH_REF_PCMAX 0xFF
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
74 typedef S8 RgSchCmnUlPwrCqiToPwrTbl[RG_SCH_CMN_UL_NUM_CQI];
76 PRIVATE RgSchCmnUlPwrCqiToPwrTbl rgSchPwrCqiToPwrTbl;
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 uint8_t 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
95 /* This table maps power (in dB) to number of RBs */
96 /* The array size comes from max power in rgSchPwrRbToPwrTbl */
97 CONSTANT uint8_t 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
104 PRIVATE S8 rgSCHPwrGetCqiPwr ARGS((
107 PRIVATE S8 rgSCHPwrGetCqiPwrForUe ARGS((
112 PRIVATE S8 rgSCHPwrCalcEfficncyPwr ARGS((
115 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi ARGS((
121 PRIVATE Void rgSCHPwrGetPuschTpc ARGS((
128 PRIVATE uint8_t rgSCHPwrGetMaxRb ARGS((
132 PRIVATE uint8_t rgSCHPwrRbToPwr ARGS((
136 PRIVATE Void rgSCHPwrSchedPucchRnti ARGS((
138 RgSchCmnTpcRntiCb *cb,
143 PRIVATE Void rgSCHPwrPuschCntrl ARGS((
147 PRIVATE Void rgSCHPwrPucchCntrl ARGS((
151 PRIVATE Void rgSCHPwrSchedPuschRnti ARGS((
153 RgSchCmnTpcRntiCb *cb,
158 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe ARGS((
163 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe ARGS((
168 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe ARGS((
173 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe ARGS((
178 PRIVATE Void rgSCHPwrGetAcc1bitTpc ARGS((
183 PRIVATE Void rgSCHPwrGetAcc2bitTpc ARGS((
188 PRIVATE Void rgSCHPwrGetAbsTpc ARGS((
193 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe ARGS((
198 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe ARGS((
203 PRIVATE Bool rgSCHPwrIsDlUeSched ARGS((
208 PRIVATE Bool rgSCHPwrIsUlUeSched ARGS((
213 PRIVATE Void rgSCHPwrOnSchedPucchTpc ARGS((
218 PRIVATE Void rgSCHPwrOnSchedPuschTpc ARGS((
222 PRIVATE S16 rgSCHPwrApplyUePwrCfg ARGS((
225 RgrUeUlPwrCfg *pwrCfg
227 PRIVATE Void rgSCHPwrUeResetPucch ARGS((
231 PRIVATE Void rgSCHPwrUeResetPusch ARGS((
235 PRIVATE Void rgSCHPwrOnPuschPwrUpd ARGS((
239 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst ARGS((
244 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst ARGS((
249 PRIVATE Void rgSCHPwrInitTpcRntiCb ARGS((
250 RgSchCmnTpcRntiCb *cb,
254 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb ARGS((
258 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb ARGS((
262 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb ARGS((
264 RgSchCmnTpcRntiCb *cb,
267 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb ARGS((
269 RgSchCmnTpcRntiCb *cb,
272 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb ARGS((
274 RgSchCmnTpcRntiCb *cb,
277 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb ARGS((
279 RgSchCmnTpcRntiCb *cb,
282 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb ARGS((
284 RgSchCmnTpcRntiCb *cb
286 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb ARGS((
288 RgSchCmnTpcRntiCb *cb,
291 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb ARGS((
293 RgSchCmnTpcRntiCb *cb
295 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb ARGS((
296 RgSchCmnTpcRntiCb *cb,
299 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb ARGS((
301 RgSchCmnTpcRntiCb *cb,
304 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb ARGS((
306 RgSchCmnTpcRntiCb *cb,
309 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb ARGS((
311 RgSchCmnTpcRntiCb *cb,
314 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb ARGS((
316 RgSchCmnTpcRntiCb *cb,
319 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb ARGS((
321 RgSchCmnTpcRntiCb *cb
323 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb ARGS((
325 RgSchCmnTpcRntiCb *cb
327 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx ARGS((
328 RgSchCmnTpcRntiCb *cb,
331 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx ARGS((
332 RgSchCmnTpcRntiCb *cb,
335 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx ARGS((
336 RgSchCmnTpcRntiCb *cb,
339 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx ARGS((
340 RgSchCmnTpcRntiCb *cb,
343 PRIVATE S16 rgSCHPwrChkTpcRntiIdx ARGS((
344 RgSchCmnTpcRntiCb *cb,
347 PRIVATE S8 rgSCHPwrGetPhValFromPhr ARGS((
350 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax ARGS((
358 * @brief Does power related initialisation (not cell specific).
363 * Function : rgSCHPwrInit
366 * - This shall precompute coding efficiency to power
367 * mappings (assuming beta of 1).
382 rgSchPwrCqiToPwrTbl[0] = 0; /* This should never be used anyway */
383 for (idx = 1; idx < RG_SCH_CMN_UL_NUM_CQI; ++idx)
385 rgSchPwrCqiToPwrTbl[idx] = rgSCHPwrCalcEfficncyPwr(rgSchCmnUlCqiTbl[idx].eff);
390 /***********************************************************
392 * Func : rgSCHPwrGetCqiPwr
394 * Desc : Returns power corresponding to coding efficiency
395 * when beta pusch is assumed 1.
403 **********************************************************/
405 PRIVATE S8 rgSCHPwrGetCqiPwr
410 PRIVATE S8 rgSCHPwrGetCqiPwr(cqi)
415 return (rgSchPwrCqiToPwrTbl[cqi]);
416 } /* rgSCHPwrGetCqiPwr */
418 /***********************************************************
420 * Func : rgSCHPwrGetCqiPwrForUe
422 * Desc : If MCS control is enabled for UE, returns
423 * power corresponding to CQI, else 0.
431 **********************************************************/
433 PRIVATE S8 rgSCHPwrGetCqiPwrForUe
440 PRIVATE S8 rgSCHPwrGetCqiPwrForUe(cell, ue, cqi)
446 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
448 if (!uePwr->deltaMcsEnbld)
452 return (rgSCHPwrGetCqiPwr(cqi));
453 } /* rgSCHPwrGetCqiPwrForUe */
455 /***********************************************************
457 * Func : rgSCHPwrCalcEfficncyPwr
459 * Desc : Computes power corresponding to a coding
464 * Notes: Assumes beta pusch to be 1
468 **********************************************************/
470 PRIVATE S8 rgSCHPwrCalcEfficncyPwr
475 PRIVATE S8 rgSCHPwrCalcEfficncyPwr(eff)
479 F64 ks = 1.25; /* or F64 */
480 F64 tmp = cmPow(2, ks*eff/1024) - 1;
484 return ((S8)(10 * cmLog10(tmp)));
485 } /* rgSCHPwrCalcEfficncyPwr */
489 * @brief Returns TPC to be sent in UL allocation
493 * Function : rgSCHPwrPuschTpcForUe
495 * Invoking Module Processing:
496 * - After allocation for UE, this function shall
497 * be invoked to retrieve TPC.
498 * - This assumes that rgSCHPwrGetMaxUlRb() was
499 * invoked prior to final allocation for UE.
502 * - Just return TPC that was determined
504 * - After this, do necessary updates.
506 * @param[in] RgSchCellCb *cell
507 * @param[in] RgSchUeCb *ue
511 uint8_t rgSCHPwrPuschTpcForUe
517 uint8_t rgSCHPwrPuschTpcForUe(cell, ue)
522 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue,cell);
526 rgSCHPwrOnSchedPuschTpc(cell, ue);
527 return (uePwr->puschTpc);
531 * @brief Handles Pusch power control for DCI format 0
535 * Function : rgSCHPwrGetMaxUlRb
537 * Invoking Module Processing:
538 * - This shall be invoked to determine maximum
539 * number of UL RBs for scheduling.
540 * - This is expected to be invoked every time
541 * priority to attempt at UE allocation. Later
542 * TPC retrieval depends on it.
545 * - Returns maximum allowed UL RBs to be granted
546 * after invoking Pusch power control.
548 * @param[in] RgSchCellCb *cell
549 * @param[in] RgSchUeCb *ue
553 uint8_t rgSCHPwrGetMaxUlRb
559 uint8_t rgSCHPwrGetMaxUlRb(cell, ue)
564 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
566 rgSCHPwrPuschCntrl(cell, ue); /* This stores tpc, delta and maxRb
568 return (uePwr->maxUlRbs);
572 * @brief Handles Pusch power control for DCI format 0
576 * Function : rgSCHPwrPuschCntrl
578 * Invoking Module Processing:
579 * - This shall be invoked to determine TPC
580 * and maximum number of UL RBs for scheduling
581 * (through DCI format 0).
584 * - 'remPuschPwr' is the final delta power that the UE
585 * should apply to get to target CQI.
586 * - The available headroom (availPwr) is determined.
587 * - Power command is given by considering remPuschPwr and
589 * - After factoring in the power command into availPwr, the
590 * maximum number of RBs that can be supported is determined
591 * assuming that UE is going to use transmission efficiency
592 * corresponding to current CQI.
593 * - The results determined in this function are stored
594 * in the UE power control block.
595 * - [Not doing anything of power control of msg3
596 * retransmissions now]
598 * @param[in] RgSchCellCb *cell
599 * @param[in] RgSchUeCb *ue
603 PRIVATE Void rgSCHPwrPuschCntrl
609 PRIVATE Void rgSCHPwrPuschCntrl(cell, ue)
614 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
615 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
616 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
619 uint8_t cqi = ueUl->validUlCqi;
622 uint8_t cqi = ueUl->crntUlCqi[0];
624 Bool isAcc = uePwr->isAccumulated;
631 if (!uePwr->isPhrAvail)
633 availPwr = 60; /* setting a large value so that availPwr does
634 * not constrain delta */
638 availPwr = uePwr->maxUePwr - uePwr->pwrPerRb;
639 availPwr -= rgSCHPwrGetCqiPwrForUe(cell, ue, cqi);
641 delta = uePwr->remPuschPwr;
642 rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, &tpc, &delta);
645 maxRb = rgSCHPwrGetMaxRb(cell,availPwr);
647 /* Store the results in ue power control block to be used later */
648 if(maxRb < cellUl->sbSize)
650 maxRb = cellUl->sbSize;
652 if(uePwr->maxPwrDeltaByPhr < 0)
654 tmp = ueUl->validUlCqi;
655 tmp = tmp + uePwr->maxPwrDeltaByPhr;
658 ueUl->validUlCqi = 1;
662 ueUl->validUlCqi = tmp;
667 RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
668 "UEID:%d Output Max Rb (%d), phVal (%d) AvailPwr (%d) ",
669 ue->ueId, maxRb, uePwr->phVal, availPwr);
670 RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
671 "UEID:%d pwrPerRb %d remPuschPwr %d",
675 uePwr->delta = delta;
676 uePwr->maxUlRbs = maxRb;
677 uePwr->puschTpc = tpc;
682 * @brief Returns TPC to be sent in DL allocation
686 * Function : rgSCHPwrPucchTpcForUe
688 * Invoking Module Processing:
689 * - After DL allocation for UE, this function shall
690 * be invoked to obtain TPC.
693 * - Do Pucch power control processing
696 * @param[in] RgSchCellCb *cell
697 * @param[in] RgSchUeCb *ue
701 uint8_t rgSCHPwrPucchTpcForUe
707 uint8_t rgSCHPwrPucchTpcForUe(cell, ue)
712 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
714 rgSCHPwrPucchCntrl(cell, ue);
715 return (uePwr->pucchTpc);
718 /***********************************************************
720 * Func : rgSCHPwrGetDelta2FrmCqi
722 * Desc : Get power to be applied to achieve
723 * target CQI (the power returned is
724 * twice is actual power)
732 **********************************************************/
734 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi
743 PRIVATE S8 rgSCHPwrGetDelta2FrmCqi(crntCqi, trgCqi)
750 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
752 if (uePwr->isPhrAvail)
754 //uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb - uePwr->remPuschPwr;
755 uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb;
759 uePwr->maxPwrDeltaByPhr = 0;
762 if (uePwr->maxPwrDeltaByPhr < 0 && (trgCqi - crntCqi) *
763 RG_SCH_UL_CQI_DB_STEP_2 > 0)
767 return (RGSCH_MIN(uePwr->maxPwrDeltaByPhr,
768 (trgCqi - crntCqi) * RG_SCH_UL_CQI_DB_STEP_2));
769 } /* rgSCHPwrGetDelta2FrmCqi */
771 /***********************************************************
773 * Func : rgSCHPwrGetPuschTpc
775 * Desc : Based on whether accumulation is enabled or
776 * not, this returns an applicable power delta
777 * to be applied based on the input delta.
785 **********************************************************/
787 PRIVATE Void rgSCHPwrGetPuschTpc
796 PRIVATE Void rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, tpc, tpcDelta)
805 delta = RGSCH_MIN(delta, availPwr);
807 /* As of now, the functions below possibly cause delta
808 * to be breached by 1 only. So calling these as is. */
811 rgSCHPwrGetAcc2bitTpc(delta, tpc, tpcDelta);
815 rgSCHPwrGetAbsTpc(delta, tpc, tpcDelta);
818 } /* rgSCHPwrGetPuschTpc */
820 /***********************************************************
822 * Func : rgSCHPwrGetMaxRb
824 * Desc : Get the maximum number of RBs that can be
825 * expected to be supported by the passed
834 **********************************************************/
836 PRIVATE uint8_t rgSCHPwrGetMaxRb
842 PRIVATE uint8_t rgSCHPwrGetMaxRb(cell, pwr)
847 RgSchCmnUlCell *cellUl;
849 cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
852 /* Give 4 RBS so that UE can report changed power status*/
853 /* [ccpu00119916] Mod -return 0th index of rgSchPwrToRbTbl when pwr <=0
854 * Change the Macros from RGSCH_MAX_DL_BW to RGSCH_MAX_UL_BW*/
855 return (rgSchPwrToRbTbl[0]);
857 if (pwr > rgSchPwrRbToPwrTbl[cellUl->maxUlBwPerUe])
859 return (cellUl->maxUlBwPerUe);
861 return (RGSCH_MIN(cellUl->maxUlBwPerUe,rgSchPwrToRbTbl[(uint8_t)pwr]));
862 } /* rgSCHPwrGetMaxRb */
864 /***********************************************************
866 * Func : rgSCHPwrRbToPwr
868 * Desc : Get the power corresponding to number of RBs
876 **********************************************************/
878 PRIVATE uint8_t rgSCHPwrRbToPwr
884 PRIVATE uint8_t rgSCHPwrRbToPwr(cell,numRb)
890 RgSchCmnUlCell *cellUl;
892 #if (ERRCLASS & ERRCLS_DEBUG)
893 cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
894 if (numRb > cellUl->maxUlBwPerUe)
896 numRb = cellUl->maxUlBwPerUe;
899 return (rgSchPwrRbToPwrTbl[numRb]);
900 } /* rgSCHPwrRbToPwr */
904 * @brief Handles Pucch power control for DCI formats 1A/1B/1D/1/2A/2
908 * Function : rgSCHPwrPucchCntrl
911 * - Determine 2 bit TPC to be sent using remPucchPwr.
912 * - Update remPucchPwr appropriately
914 * @param[in] RgSchCellCb *cell
915 * @param[in] RgSchUeCb *ue
919 PRIVATE Void rgSCHPwrPucchCntrl
925 PRIVATE Void rgSCHPwrPucchCntrl(cell, ue)
931 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
933 rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, &uePwr->pucchTpc, &delta);
934 rgSCHPwrOnSchedPucchTpc(cell, ue, delta);
939 * @brief Handles group power control for DCI formats 3/3A for Pucch and Pusch
943 * Function : rgSCHPwrGrpCntrlPucch
945 * Invoking Module Processing:
946 * - This shall be invoked to do group power control for
947 * all TPC RNTIs for which it is deemed necessary to
948 * do the same (group power control).
949 * - This function should only be invoked after all UEs
950 * have been scheduled for uplink (re)transmissions
951 * requiring DL DCI format in the passed subframe.
954 * - For Pucch group power control
955 * - For each TPC-Pucch-RNTI in the pucchGrpPwr List and
956 * TPC-Pusch-RNTI in the puschGrpPwr List,
957 * - Request for PDCCH, skip if not available
958 * - Form DCI format 3/3A information depending
959 * on the format type of the TPC-RNTI and add it to the sub-frame.
960 * - For each Ue in ueLst of TPC RNTI Cb
961 * - if (fmtType == 3A)
962 * - if((Ue not scheduled DL dci formats)
963 * && (remPwr >= 2 || remPwr <= -2))
964 * - Determine TPC. Set puschTpc/pucchTpc.
966 * - if (remPwr >= -1 && remPwr <= 1)
967 * - If already added, remove from toBeSchdLst
969 * - Toggle the remainig power value
970 * - else if (fmtType == 3)
971 * - if((Ue not scheduled DL dci formats)
973 * - Determine TPC. Set puschTpc/pucchTpc.
976 * - If already added, remove from toBeSchdLst
977 * - if (!toBeSchdUeCnt)
978 * - Remove the tpcRntiCb frm pucchGrpPwr/puschGrpPwr List
979 * - else, Move the tpcRntiCb to end of the list (not doing
982 * @param[in] RgSchCellCb *cell
983 * @param[in] RgSchDlSf *dlSf
987 Void rgSCHPwrGrpCntrlPucch
993 Void rgSCHPwrGrpCntrlPucch(cell, dlSf)
998 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
1003 lst = &cellPwr->pucchGrpPwr;
1005 while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP))
1007 RgSchCmnTpcRntiCb *cb = (RgSchCmnTpcRntiCb *)lnk->node;
1010 rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, &sched);
1013 rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
1015 /* TPC RNTI would not have been removed if needs to
1016 * be scheduled again */
1023 * @brief Handles group power control for DCI formats 3/3A for Pusch and Pusch
1027 * Function : rgSCHPwrGrpCntrlPusch
1029 * Invoking Module Processing:
1030 * - This shall be invoked to do group power control for
1031 * all TPC RNTIs for which it is deemed necessary to
1032 * do the same (group power control).
1033 * - This function should only be invoked after all UEs
1034 * have been scheduled for uplink (re)transmissions
1035 * requiring DCI format 0 in the passed subframe.
1038 * - For Pusch group power control
1039 * - For each TPC-Pusch-RNTI in the puschGrpPwr List and
1040 * - Request for PDCCH, skip if not available
1041 * - Form DCI format 3/3A information depending
1042 * on the format type of the TPC-RNTI and add it to the sub-frame.
1043 * - For each Ue in ueLst of TPC RNTI Cb
1044 * - if (fmtType == 3A)
1045 * - if (Ue not scheduled for dci format 0) and
1046 * (remPwr >= 2 || remPwr <= -2))
1047 * - Determine TPC. Set puschTpc/puschTpc.
1049 * - if (remPwr >= -1 && remPwr <= 1)
1050 * - If already added, remove from toBeSchdLst
1052 * - Toggle the remainig power value
1053 * - else if (fmtType == 3)
1054 * - if((Ue not scheduled for dci format 0) && (remPwr))
1055 * - Determine TPC. Set puschTpc.
1058 * - If already added, remove from toBeSchdLst
1059 * - if (!toBeSchdUeCnt)
1060 * - Remove the tpcRntiCb frm puschGrpPwr/puschGrpPwr List
1061 * - else, Move the tpcRntiCb to end of the list (not doing
1064 * @param[in] RgSchCellCb *cell
1065 * @param[in] RgSchDlSf *sf
1069 Void rgSCHPwrGrpCntrlPusch
1076 Void rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf)
1082 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
1087 lst = &cellPwr->puschGrpPwr;
1089 while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP))
1091 RgSchCmnTpcRntiCb *cb = (RgSchCmnTpcRntiCb *)lnk->node;
1094 rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, &sched);
1097 rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch);
1099 /* TPC RNTI would not have been removed if needs to
1100 * be scheduled again */
1106 /***********************************************************
1108 * Func : rgSCHPwrSchedPucchRnti
1110 * Desc : Schedule TPC RNTI to be sent out
1118 **********************************************************/
1120 PRIVATE Void rgSCHPwrSchedPucchRnti
1123 RgSchCmnTpcRntiCb *cb,
1129 PRIVATE Void rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, sched)
1131 RgSchCmnTpcRntiCb *cb;
1144 pdcch->rnti = cb->tpcRnti;
1148 /* Go through all UEs for format 3A case */
1150 pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A;
1151 pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A];
1152 pdcch->dci.u.format3AInfo.isPucch = TRUE;
1154 tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd;
1155 /* No need to memset zero initially as every TPC is going
1156 * to be filled up for every configured UE */
1157 for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1159 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
1160 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1162 if ( ue->isDrxEnabled == TRUE &&
1163 !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1165 /* UE is in its DRX time. So we cannot give command
1171 if (rgSCHPwrIsDlUeSched(cell, ue, dlSf))
1173 /* UE already scheduled in downlink with PDCCH
1174 * carrying PUCCH pwr cmd. So don't care about
1175 * giving command to this UE. */
1178 rgSCHPwrGetPucchFmt3aTpcForUe(ue, &tpc, &delta);
1179 tpcCmds[uePwr->pucchIdx] = tpc;
1181 rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta);
1186 /* Go through to-be-scheduled UEs for format 3 case */
1187 lst = &cb->toBeSchdUes;
1188 pdcch->dci.dciFormat = TFU_DCI_FORMAT_3;
1189 pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3];
1190 tpcCmds = pdcch->dci.u.format3Info.tpcCmd;
1191 pdcch->dci.u.format3Info.isPucch = TRUE;
1193 /* Fill TPC 1 (corresponding to no power change) initially */
1194 memset(tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd));
1196 for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1198 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
1199 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1201 if ( ue->isDrxEnabled == TRUE &&
1202 !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1204 /* UE is in its DRX time. So we cannot give command
1210 if (rgSCHPwrIsDlUeSched(cell, ue, dlSf))
1212 /* UE already scheduled in downlink with PDCCH
1213 * carrying PUCCH pwr cmd. So don't care about
1214 * giving command to this UE. */
1217 rgSCHPwrGetPucchFmt3TpcForUe(ue, &tpc, &delta);
1218 tpcCmds[uePwr->pucchIdx] = tpc;
1220 rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta);
1224 *sched = atleastOne;
1226 /* Check if no more UEs in TPC RNTI, and then remove
1227 * this TPC RNTI from scheduled list */
1228 if (cb->toBeSchdUes.count == 0)
1230 rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb);
1234 } /* rgSCHPwrSchedPucchRnti */
1236 /***********************************************************
1238 * Func : rgSCHPwrSchedPuschRnti
1240 * Desc : Schedule TPC RNTI to be sent out
1248 **********************************************************/
1250 PRIVATE Void rgSCHPwrSchedPuschRnti
1253 RgSchCmnTpcRntiCb *cb,
1259 PRIVATE Void rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, sched)
1261 RgSchCmnTpcRntiCb *cb;
1274 pdcch->rnti = cb->tpcRnti;
1278 /* Go through all UEs for format 3A case */
1280 pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A;
1281 pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A];
1282 pdcch->dci.u.format3AInfo.isPucch = FALSE;
1283 tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd;
1284 /* No need to memset zero initially as every TPC is going
1285 * to be filled up for every configured UE */
1286 for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1288 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
1289 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1290 if (rgSCHPwrIsUlUeSched(cell, ue, ulSf))
1292 /* UE already scheduled in uplink with DCI
1293 * format 0. So don't care about giving
1294 * command to this UE. */
1298 if ( ue->isDrxEnabled == TRUE &&
1299 !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1301 /* UE is in its DRX time. So we cannot give command
1307 rgSCHPwrGetPuschFmt3aTpcForUe(ue, &tpc, &delta);
1308 tpcCmds[uePwr->puschIdx] = tpc;
1310 rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta);
1315 /* Go through to-be-scheduled UEs for format 3 case */
1316 lst = &cb->toBeSchdUes;
1317 pdcch->dci.dciFormat = TFU_DCI_FORMAT_3;
1318 pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3];
1319 pdcch->dci.u.format3Info.isPucch = FALSE;
1320 tpcCmds = pdcch->dci.u.format3Info.tpcCmd;
1322 /* Fill TPC 1 (corresponding to no power change) initially */
1323 memset(tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd));
1325 for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next)
1327 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
1328 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1329 if (rgSCHPwrIsUlUeSched(cell, ue, ulSf))
1331 /* UE already scheduled in uplink with DCI
1332 * format 0. So don't care about giving
1333 * command to this UE. */
1337 if ( ue->isDrxEnabled == TRUE &&
1338 !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb))
1340 /* UE is in its DRX time. So we cannot give command
1346 rgSCHPwrGetPuschFmt3TpcForUe(ue, &tpc, &delta);
1347 tpcCmds[uePwr->puschIdx] = tpc;
1349 rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta);
1353 *sched = atleastOne;
1355 /* Check if no more UEs in TPC RNTI, and then remove
1356 * this TPC RNTI from scheduled list */
1357 if (cb->toBeSchdUes.count == 0)
1359 rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb);
1363 } /* rgSCHPwrSchedPuschRnti */
1365 /***********************************************************
1367 * Func : rgSCHPwrGetPucchFmt3TpcForUe
1369 * Desc : Gets 2 bit TPC cmd for PUCCH
1377 **********************************************************/
1379 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe
1386 PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe(ue, tpc, delta)
1392 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1394 rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, tpc, delta);
1396 } /* rgSCHPwrGetPucchFmt3TpcForUe */
1398 /***********************************************************
1400 * Func : rgSCHPwrGetPucchFmt3aTpcForUe
1402 * Desc : Gets 1 bit TPC cmd for PUCCH
1410 **********************************************************/
1412 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe
1419 PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe(ue, tpc, delta)
1425 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1427 rgSCHPwrGetAcc1bitTpc(uePwr->remPucchPwr, tpc, delta);
1429 } /* rgSCHPwrGetPucchFmt3aTpcForUe */
1431 /***********************************************************
1433 * Func : rgSCHPwrGetPuschFmt3TpcForUe
1435 * Desc : Gets 2 bit TPC cmd for PUCCH
1443 **********************************************************/
1445 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe
1452 PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe(ue, tpc, delta)
1458 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1459 S8 adj = RGSCH_MIN(uePwr->remPuschPwr, uePwr->phVal);
1461 rgSCHPwrGetAcc2bitTpc(adj, tpc, delta);
1463 } /* rgSCHPwrGetPuschFmt3TpcForUe */
1465 /***********************************************************
1467 * Func : rgSCHPwrGetPuschFmt3aTpcForUe
1469 * Desc : Gets 1 bit TPC cmd for PUCCH
1477 **********************************************************/
1479 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe
1486 PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe(ue, tpc, delta)
1492 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1494 /* Don't attempt to look at headroom now, power
1495 * adjustment is small anyway */
1496 rgSCHPwrGetAcc1bitTpc(uePwr->remPuschPwr, tpc, delta);
1498 } /* rgSCHPwrGetPuschFmt3aTpcForUe */
1500 /***********************************************************
1502 * Func : rgSCHPwrGetAcc1bitTpc
1504 * Desc : Gets 1 bit TPC cmd
1512 **********************************************************/
1514 PRIVATE Void rgSCHPwrGetAcc1bitTpc
1521 PRIVATE Void rgSCHPwrGetAcc1bitTpc(remPwr, tpc, delta)
1543 } /* rgSCHPwrGetAcc1bitTpc */
1545 /***********************************************************
1547 * Func : rgSCHPwrGetAcc2bitTpc
1549 * Desc : Allocate PDCCH for group power control
1557 **********************************************************/
1559 PRIVATE Void rgSCHPwrGetAcc2bitTpc
1566 PRIVATE Void rgSCHPwrGetAcc2bitTpc(remPwr, tpc, delta)
1579 uint8_t tpcs[3] = {1, 2, 2};
1580 uint8_t deltas[3] = {0, 1, 1};
1586 else if (remPwr >= 3)
1593 *tpc = tpcs[(uint8_t)remPwr];
1594 *delta = deltas[(uint8_t)remPwr];
1597 } /* rgSCHPwrGetAcc2bitTpc */
1599 /***********************************************************
1601 * Func : rgSCHPwrGetAbsTpc
1603 * Desc : Allocate PDCCH for group power control
1611 **********************************************************/
1613 PRIVATE Void rgSCHPwrGetAbsTpc
1620 PRIVATE Void rgSCHPwrGetAbsTpc(remPwr, tpc, delta)
1638 else if (remPwr < 1)
1643 else if (remPwr < 4)
1654 } /* rgSCHPwrGetAbsTpc */
1656 /***********************************************************
1658 * Func : rgSCHPwrOnPucchGrpPwrForUe
1660 * Desc : Processing on sending TPC for UE through group power
1661 * control. Apart from updating remPwr, this only takes
1662 * care of possibly removing UE from scheduled
1664 * It does not take care of possibly removing TPC RNTI
1665 * from scheduled list in cell. This is done
1666 * in the caller after TPC for all UEs has been
1667 * determined. (This is where it differs
1668 * from the usual OnSendingPu[cs]ch TPC]
1676 **********************************************************/
1678 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe
1685 PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta)
1691 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1696 uePwr->remPucchPwr -= delta;
1698 /* UE was already scheduled for PUCCH group power
1699 * control which is why we came here. Don't
1700 * again check for this. */
1702 /* UE was scheduled for pucch grp pwr, sent TPC may
1703 * possibly cause it to be removed. */
1704 if (!uePwr->remPucchPwr)
1710 rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
1711 /* Not removing TPC RNTI from scheduled list,
1712 * this will happen in the caller once this
1713 * function is called for every UE scheduled. */
1718 /***********************************************************
1720 * Func : rgSCHPwrOnPuschGrpPwrForUe
1722 * Desc : Processing on sending TPC for UE through group power
1723 * control. Apart from updating remPwr, this only takes
1724 * care of possibly removing UE from scheduled
1726 * It does not take care of possibly removing TPC RNTI
1727 * from scheduled list in cell. This is done
1728 * in the caller after TPC for all UEs has been
1729 * determined. (This is where it differs
1730 * from the usual OnSendingPu[cs]ch TPC]
1738 **********************************************************/
1740 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe
1747 PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta)
1753 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
1758 uePwr->delta = delta;
1759 uePwr->remPuschPwr -= delta;
1760 if (uePwr->isPhrAvail)
1762 uePwr->phVal -= uePwr->delta;
1763 uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
1766 /* UE was already scheduled for PUSCH group power
1767 * control which is why we came here. Don't
1768 * again check for this. */
1770 /* UE was scheduled for pusch grp pwr, sent TPC may
1771 * possibly cause it to be removed. */
1773 if (!uePwr->remPuschPwr)
1780 rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
1781 /* Not removing TPC RNTI from scheduled list,
1782 * this will happen in the caller once this
1783 * function is called for every UE scheduled. */
1788 /***********************************************************
1790 * Func : rgSCHPwrIsDlUeSched
1792 * Desc : Check if UE is scheduled in the passed DL SF
1800 **********************************************************/
1802 PRIVATE Bool rgSCHPwrIsDlUeSched
1809 PRIVATE Bool rgSCHPwrIsDlUeSched(cell, ue, sf)
1815 RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
1816 RgSchDlHqProcCb *proc = rgSCHDhmLastSchedHqProc(hqEnt);
1824 * The following subframe check is assumed enough, since
1825 * scheduled procs stay for a short time (until feedback
1826 * arrives), which typically is expected to have a
1827 * turnaround time of less than 8 subframes. So
1828 * we are probably never going to come across cases
1829 * where a process stays in the list for more than
1830 * 10 subframes, which would have otherwise caused
1831 * the check to succeed for a possibly older process.
1833 if ((proc->tbInfo[0].timingInfo.slot == sf->sfNum) ||
1834 (proc->tbInfo[1].timingInfo.slot == sf->sfNum))
1837 * Later, if a proc can be scheduled without having an
1838 * associated PDCCH, need to also check if PDCCH exists.
1839 * This is because for power, what matters is whether
1840 * TPC is going out for UE at this time or not, at least
1841 * that is what this function was introduced for.
1842 * Checking for PDCCH would have to be in common proc
1843 * the way things are now.
1851 } /* rgSCHPwrIsDlUeSched */
1853 /***********************************************************
1855 * Func : rgSCHPwrIsUlUeSched
1857 * Desc : Check if UE is scheduled in the passed UL SF
1865 **********************************************************/
1867 PRIVATE Bool rgSCHPwrIsUlUeSched
1874 PRIVATE Bool rgSCHPwrIsUlUeSched(cell, ue, sf)
1880 RgSchCmnUlCell *cmnCell = RG_SCH_CMN_GET_UL_CELL(cell);
1881 RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, cmnCell->schdHqProcIdx);
1885 #if (ERRCLASS & ERRCLS_DEBUG)
1900 } /* rgSCHPwrIsUlUeSched */
1903 * @brief Handles Pucch power delta indication recieved from PHY
1907 * Function : rgSCHPwrPucchDeltaInd
1909 * Invoking Module Processing:
1910 * - This shall be invoked on reception of Pucch power
1911 * delta indication from PHY.
1914 * - Update the remPucchPwr
1915 * ue->remPucchPwr = pwrDelta
1916 * - If (ue->tpcPucchRntiCb)
1917 * - If (fmtType = 3A)
1918 * - if (remPucchPwr >= 2 || remPucchPwr <= -2 )
1919 * - if (tpcPucchRntiCb is not in the pucchGrpPwr List)
1920 * - Add tpcPucchRntiCb to the pucchGrpPwr list.
1921 * - If not added, add to toBeSchdLst
1923 * - If already added, remove from toBeSchdLst
1924 * - else If (fmtType == 3)
1925 * - if (remPucchPwr)
1926 * - if (tpcPucchRntiCb is not in the pucchGrpPwr List)
1927 * - Add tpcPucchRntiCb to the pucchGrpPwr list.
1928 * - If not added, add to toBeSchdLst
1930 * - If already added, remove from toBeSchdLst
1932 * @param[in] RgSchCellCb *cell
1933 * @param[in] RgSchUeCb *ue
1934 * @param[in] uint8_t pwrDelta
1938 Void rgSCHPwrPucchDeltaInd
1945 Void rgSCHPwrPucchDeltaInd(cell, ue, pwrDelta)
1951 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
1952 RgSchCmnTpcRntiCb *cb;
1955 uePwr->remPucchPwr = pwrDelta;
1957 if ((cb = uePwr->tpcPucchRntiCb) == NULLP)
1964 if (0 != uePwr->remPucchPwr)
1972 rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue);
1976 rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue);
1983 * @brief Does processing after TPC for Pucch has been sent
1987 * Function : rgSCHPwrOnSchedPucchTpc
1989 * Invoking Module Processing:
1990 * - It shall be invoked after it is determined that PDCCH for UE
1991 * is finalised to go out, and thus TPC for PUCCH is being
1995 * - Update remPucchPwr with the delta
1996 * - Do group power control related processing
1998 * @param[in] RgSchCellCb *cell
1999 * @param[in] RgSchUeCb *ue
2000 * @param[in] S8 delta
2004 PRIVATE Void rgSCHPwrOnSchedPucchTpc
2011 PRIVATE Void rgSCHPwrOnSchedPucchTpc(cell, ue, delta)
2017 /* Similar to rgSCHPwrPucchDeltaInd.. not reusing
2018 * that since we use the fact that UE could only have
2019 * improved its remPwr as part of power control. */
2020 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2023 uePwr->remPucchPwr -= delta;
2025 if (uePwr->schdPucchGrpLnk.node == NULLP)
2030 /* UE was scheduled for TPC, sent TPC may
2031 * possibly cause it to be removed. */
2033 if (!uePwr->remPucchPwr)
2040 rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
2041 if (uePwr->tpcPucchRntiCb->toBeSchdUes.count == 0)
2043 rgSCHPwrRmvSchdPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb);
2051 * @brief Does processing after TPC for Pusch has been sent
2055 * Function : rgSCHPwrOnSchedPuschTpc
2059 * - Update remPuschPwr with the delta
2060 * - Do group power related processing if applicable
2062 * @param[in] RgSchCellCb *cell
2063 * @param[in] RgSchUeCb *ue
2067 PRIVATE Void rgSCHPwrOnSchedPuschTpc
2073 PRIVATE Void rgSCHPwrOnSchedPuschTpc(cell, ue)
2078 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2081 /* Don't do anything for the case of absolute TPC commands */
2082 if (!uePwr->isAccumulated)
2087 uePwr->remPuschPwr -= uePwr->delta;
2088 if (uePwr->isPhrAvail)
2090 uePwr->phVal -= uePwr->delta;
2091 uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
2094 if (uePwr->schdPuschGrpLnk.node == NULLP)
2099 /* UE was scheduled for pusch TPC, sent TPC may
2100 * possibly cause it to be removed. */
2102 if (!uePwr->remPuschPwr)
2109 rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
2116 * @brief Handles PHR updation for the UE
2120 * Function : rgSCHPwrUpdExtPhr
2121 * @param[in] RgSchCellCb *cell
2122 * @param[in] RgSchUeCb *ue
2123 * @param[in] RgInfExtPhrCEInfo *extPhr
2124 * @param[in] RgSchCmnAllocRecord allocInfo
2128 Void rgSCHPwrUpdExtPhr
2132 RgInfExtPhrCEInfo *extPhr,
2133 RgSchCmnAllocRecord *allocInfo
2136 Void rgSCHPwrUpdExtPhr(cell, ue, extPhr, allocInfo)
2139 RgInfExtPhrCEInfo *extPhr;
2140 RgSchCmnAllocRecord *allocInfo;
2144 RgInfExtPhrSCellInfo *servCellPhr;
2147 for (idx = 0; idx < extPhr->numServCells; idx++)
2149 servCellPhr = &extPhr->servCellPhr[idx];
2151 if (RG_SCH_REF_PCMAX == servCellPhr->pCmax)
2153 pCMax = RG_SCH_CMN_PWR_USE_CFG_MAX_PWR;
2157 pCMax = rgSCHPwrGetPCMaxValFromPCMax(servCellPhr->pCmax);
2159 rgSCHPwrUpdPhr(ue->cellInfo[servCellPhr->sCellIdx]->cell,
2160 ue, servCellPhr->phr, allocInfo, pCMax);
2166 * @brief Handles PHR updation for the UE
2170 * Function : rgSCHPwrUpdPhr
2172 * Invoking Module Processing:
2173 * - This shall be invoked on reception of PHR from MAC to SCH. It shall
2174 * pass the information of number of RBs, coding efficiency and TPC for
2175 * the Pusch transmission for which PHR has been reported.
2178 * - Compute power per RB using the PHR report
2179 * - ue_transmit_pwr = ue_max_pwr - PHR
2180 * - if isDeltaMcs = TRUE
2181 * - ue_transmit_pwr -
2182 * [10log(phr_num_rb) + 10log(2^ (1.25 * phr_coding_effeciency) -1)
2183 * + phr_tpc(if absolute TPC)] = pwrPerRB
2185 * - ue_transmit_pwr - [10log(phr_num_rb) + phr_tpc(if absolute TPC)]
2187 * (Use the number of RBs and efficiency used by UE which caused the PHR
2189 * - Adjust PHR according to last allocation (take into account
2190 * number of RBs granted in the last allocation)
2191 * - Update the PHR report in the control block
2192 * - Set isPhrAvail = TRUE
2193 * - Do group power control related processing if applicable
2195 * @param[in] RgSchCellCb *cell
2196 * @param[in] RgSchUeCb *ue
2197 * @param[in] uint8_t phr
2198 * @param[in] RgSchCmnAllocRecord allocInfo
2199 * @param[in] uint8_t maxUePwr
2208 RgSchCmnAllocRecord *allocInfo,
2212 Void rgSCHPwrUpdPhr(cell, ue, phr, allocInfo, maxUePwr)
2216 RgSchCmnAllocRecord *allocInfo;
2220 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2223 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
2225 uePwr->phVal = rgSCHPwrGetPhValFromPhr(phr);
2227 if (maxUePwr == RG_SCH_CMN_PWR_USE_CFG_MAX_PWR)
2229 maxUePwr = uePwr->maxUePwr;
2231 rbPwr = rgSCHPwrRbToPwr(cell,allocInfo->numRb);
2232 effPwr = rgSCHPwrGetCqiPwrForUe(cell, ue, allocInfo->cqi);
2233 uePwr->pwrPerRb = maxUePwr - uePwr->phVal - rbPwr - effPwr;
2234 /*if (!uePwr->isAccumulated)
2236 uePwr->pwrPerRb -= rgSCHPwrGetDeltaFrmAbsTpc(allocInfo->tpc);
2239 /* Let headroom reflect remaining power according to last
2240 * allocated number of RBs. Intermediate TPCs not yet
2241 * taken care of (for accumulated case, it is anyway
2242 * not applicable for absolute commands). */
2243 uePwr->phVal -= (rgSCHPwrRbToPwr(cell, cellUl->sbSize)) - rbPwr;
2244 uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal);
2245 uePwr->isPhrAvail = TRUE;
2247 rgSCHPwrOnPuschPwrUpd(cell, ue);
2249 RLOG_ARG4(L_DEBUG,DBG_UEID,ue->ueId,
2250 "Output: Reported PHR[%d] cqi[%u] allocRb[%u] uePwr->pwrPerRb[%d]",
2259 * @brief Handles UL CQI indication
2263 * Function : rgSCHPwrUlCqiInd
2265 * Invoking Module Processing:
2266 * - This shall be invoked when uplink CQI indication
2267 * is receiving from PHY for a UE.
2270 * - Update remPuschPwr.
2271 * - Possibly schedule for group power control.
2273 * @param[in] RgSchCellCb *cell
2274 * @param[in] RgSchUeCb *ue
2275 * @param[in] uint8_t numRb
2279 Void rgSCHPwrUlCqiInd
2285 Void rgSCHPwrUlCqiInd(cell, ue)
2290 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
2291 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2297 * For absolute power cmd case, we could look at the time
2298 * at which CQI was received, determine if there was a
2299 * PUSCH TPC cmd for that time (this could come from
2300 * group power control too), and (if this
2301 * CQI report is indeed based on the the PUSCH tx)
2302 * then factor in that cmd here. Not doing
2306 /* See how much power needs to be adjusted based on cqi
2308 uePwr->remPuschPwr =
2310 rgSCHPwrGetDelta2FrmCqi(ueUl->validUlCqi, uePwr->trgCqi, ue, cell);
2312 rgSCHPwrGetDelta2FrmCqi(ueUl->crntUlCqi[0], uePwr->trgCqi, ue, cell);
2315 rgSCHPwrOnPuschPwrUpd(cell, ue);
2317 if(uePwr->maxPwrDeltaByPhr < 0)
2319 tmp = ueUl->validUlCqi;
2320 tmp = tmp + uePwr->maxPwrDeltaByPhr;
2323 ueUl->validUlCqi = 1;
2327 ueUl->validUlCqi = tmp;
2336 * @brief Updates the stored last number of RBs allocated
2340 * Function : rgSCHPwrRecordRbAlloc
2342 * Invoking Module Processing:
2343 * - This shall be invoked when uplink allocation is made for
2345 * - Note: If outstanding TPCs are considered at the time
2346 * of PHR report, the last numRb would also be known
2347 * and then this API would not be needed.
2350 * - Adjust PHR according to now allocated number of RBs
2351 * - Store the number of RBs
2353 * @param[in] RgSchCellCb *cell
2354 * @param[in] RgSchUeCb *ue
2355 * @param[in] uint8_t numRb
2359 Void rgSCHPwrRecordRbAlloc
2366 Void rgSCHPwrRecordRbAlloc(cell, ue, numRb)
2372 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2376 if (uePwr->isPhrAvail)
2378 uePwr->phVal += rgSCHPwrRbToPwr(cell,numRb) - rgSCHPwrRbToPwr(cell,uePwr->numRb);
2379 uePwr->phVal = RGSCH_MIN(40, uePwr->phVal);
2381 uePwr->numRb = numRb;
2386 * @brief Handles power related configuration for a cell
2390 * Function : rgSCHPwrCellCfg
2392 * Invoking Module Processing:
2393 * - This shall be invoked during cell config
2398 * - Update TPC-RNTI information for the cell for Pucch and Pusch.
2399 * - For each TPC-Pucch-RNTI,
2400 * - Call rgSCHAddRntiToPucchRntiLst()
2401 * - For each TPC-Pusch-RNTI,
2402 * - Call rgSCHAddRntiToPuschRntiLst()
2405 * @param[in] RgSchCellCb *cell
2406 * @param[in] RgrCellCfg *cfg
2418 S16 rgSCHPwrCellCfg(cell, cfg)
2423 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2425 CmLteRnti startRnti;
2429 /* Right now, all UEs have fixed maximum power capability. So
2430 * we store cell wide pMax as minimum of configured pMax and
2432 cellPwr->pMax = RGSCH_MIN(cfg->pMax, RG_SCH_PWR_UE_MAX_PWR);
2434 /* trgUlCqi already validated by common */
2435 cellPwr->trgUlCqi = cfg->trgUlCqi.trgCqi;
2437 /* Validate number of TPC RNTIs */
2438 if ((cfg->pwrCfg.pucchPwrFmt3.size + cfg->pwrCfg.pucchPwrFmt3a.size
2439 > RG_SCH_CMN_MAX_NUM_TPC_PUCCH_RNTI)
2440 || (cfg->pwrCfg.puschPwrFmt3.size + cfg->pwrCfg.puschPwrFmt3a.size
2441 > RG_SCH_CMN_MAX_NUM_TPC_PUSCH_RNTI))
2446 /* Now initialise TPC RNTIs */
2448 /* Format 3 Pucch TPC RNTIs */
2450 startRnti = cfg->pwrCfg.pucchPwrFmt3.startTpcRnti;
2451 size = cfg->pwrCfg.pucchPwrFmt3.size;
2452 for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2454 rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a);
2457 /* Format 3A Pucch TPC RNTIs */
2459 startRnti = cfg->pwrCfg.pucchPwrFmt3a.startTpcRnti;
2460 size = cfg->pwrCfg.pucchPwrFmt3a.size;
2461 for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2463 rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a);
2466 /* Format 3 Pusch TPC RNTIs */
2468 startRnti = cfg->pwrCfg.puschPwrFmt3.startTpcRnti;
2469 size = cfg->pwrCfg.puschPwrFmt3.size;
2470 for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2472 rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a);
2475 /* Format 3A Pusch TPC RNTIs */
2477 startRnti = cfg->pwrCfg.puschPwrFmt3a.startTpcRnti;
2478 size = cfg->pwrCfg.puschPwrFmt3a.size;
2479 for (rnti = startRnti; (rnti < startRnti + size); ++rnti)
2481 rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a);
2488 * @brief Handles power related re-configuration for a cell
2492 * Function : rgSCHPwrCellRecfg
2497 * @param[in] RgSchCellCb *cell
2498 * @param[in] RgrCellRecfg *recfg
2503 S16 rgSCHPwrCellRecfg
2509 S16 rgSCHPwrCellRecfg(cell, recfg)
2511 RgrCellRecfg *recfg;
2517 /* Not doing anything for power reconfig, so such structure
2523 * @brief Frees power related data structures in cell
2527 * Function : rgSCHPwrCellDel
2532 * @param[in] RgSchCellCb *cell
2536 Void rgSCHPwrCellDel
2541 Void rgSCHPwrCellDel(cell)
2547 /* There is no allocated memory, so do nothing */
2554 * @brief Configures ULPC CB for a SCELL being added
2558 * Function : rgSCHPwrUeSCellCfg
2560 * @param[in] RgSchCellCb *cell
2561 * @param[in] RgSchUeCb *ue
2562 * @param[in] RgrUeCfg *cfg
2568 S16 rgSCHPwrUeSCellCfg
2572 RgrUeSecCellCfg *sCellInfoCfg
2575 S16 rgSCHPwrUeSCellCfg(cell, ue, sCellInfoCfg)
2578 RgrUeSecCellCfg *sCellInfoCfg;
2581 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2582 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2583 RgSchCmnUeUlPwrCb *uePwrPCell = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
2584 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
2586 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
2589 uePwr->maxUePwr = cellPwr->pMax;
2590 uePwr->trgCqi = cellPwr->trgUlCqi; /* Overriding with UE's happens later */
2593 uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize];
2595 uePwr->isPhrAvail = FALSE;
2597 uePwr->maxUlRbs = RGSCH_MAX_DL_BW;
2599 uePwr->puschTpc = 1;
2600 uePwr->remPuschPwr = 0;
2602 /* Rest of the vars update and group power control related
2603 * config happens in the function below */
2604 uePwr->isAccumulated = sCellInfoCfg->ueSCellUlDedPwrCfg.isAccumulated;
2605 uePwr->deltaMcsEnbld = sCellInfoCfg->ueSCellUlDedPwrCfg.isDeltaMCSEnabled;
2607 uePwr->trgCqi = uePwrPCell->trgCqi;
2609 if (ueUl->maxUlCqi < uePwr->trgCqi)
2611 uePwr->trgCqi = ueUl->maxUlCqi;
2613 uePwr->p0UePusch = sCellInfoCfg->ueSCellUlDedPwrCfg.p0UePusch;
2620 * @brief Handles power related configuration for a UE
2624 * Function : rgSCHPwrUeCfg
2627 * - If Pusch group power configuration exists && accumulation enabled,
2628 * - Fetch the TPC-Pusch-RNTI control block for the configured
2629 * TPC-Pusch-RNTI. Call rgSCHGetRntiFrmPuschRntiLst(). If it does not
2630 * exist, return RFAILED.
2631 * - Add Ue to the ueLst of TPC-Pusch-RNTI control block.
2632 * - Update tpcPuschRntiCb pointer in UE.
2633 * - Update the puschIdx value.
2634 * - If Pucch group power configuration exists && accumulation enabled,
2635 * - Fetch the TPC-Pucch-RNTI control block for the configured
2636 * TPC-Pucch-RNTI. Call rgSCHGetRntiFrmPucchRntiLst(). If it does not
2637 * exist, return RFAILED.
2638 * - Add Ue to the ueLst of TPC-Pucch-RNTI control block.
2639 * - Update tpcPucchRntiCb pointer in UE.
2640 * - Update the pucchIdx value.
2641 * - Update isAccumulated and isDeltaMcs variables.
2642 * - maxUlRbs = configured maximum UL bandwidth value per UE.
2643 * - trgUlCqi = configured value, if any, else cell-wide default trg CQI value.
2644 * - If format type is format 3A, update remaining power to +1
2645 * - Update TPC-RNTI information for the cell for Pucch and Pusch.
2648 * @param[in] RgSchCellCb *cell
2649 * @param[in] RgSchUeCb *ue
2650 * @param[in] RgrUeCfg *cfg
2663 S16 rgSCHPwrUeCfg(cell, ue, cfg)
2670 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
2671 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2673 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
2675 uePwr->maxUePwr = cellPwr->pMax;
2676 uePwr->trgCqi = cellPwr->trgUlCqi; /* Overriding with UE's happens later */
2679 uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize];
2681 rgSCHPwrUeResetPucch(cell, ue);
2682 rgSCHPwrUeResetPusch(cell, ue);
2684 /* Rest of the vars update and group power control related
2685 * config happens in the function below */
2686 ret = rgSCHPwrApplyUePwrCfg(cell, ue, &cfg->ueUlPwrCfg);
2692 * @brief Handles power related re-configuration for a UE
2696 * Function : rgSCHPwrUeRecfg
2698 * Invoking Module Processing:
2699 * - This shall be invoked by SCH_GOM at UE re-configuration.
2702 * - If change in TPC-RNTI, update the pointer and the TPC RNTI Cb appropriately.
2703 * - If accumulation disabled, remove the UE from TPC-RNTI lists of UE, if
2705 * - If group power configuration disabled, remove the UE from TPC-RNTI lists of UE, if
2708 * @param[in] RgSchCellCb *cell
2709 * @param[in] RgSchUeCb *ue
2710 * @param[in] RgrUeRecfg *recfg
2724 S16 rgSCHPwrUeRecfg(cell, ue, recfg)
2731 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2732 RgrUeUlPwrCfg *pwrCfg = &recfg->ueUlPwrRecfg;
2734 if (pwrCfg->p0UePucch != uePwr->p0UePucch)
2736 rgSCHPwrUeResetPucch(cell, ue);
2738 if ((pwrCfg->isAccumulated != uePwr->isAccumulated)
2739 || (pwrCfg->p0UePusch != uePwr->p0UePusch))
2741 rgSCHPwrUeResetPusch(cell, ue);
2743 ret = rgSCHPwrApplyUePwrCfg(cell, ue, &recfg->ueUlPwrRecfg);
2748 /***********************************************************
2750 * Func : rgSCHPwrApplyUePwrCfg
2752 * Desc : Applies power config for UE. Meants to be
2753 * used during both power config and reconfig.
2761 **********************************************************/
2763 PRIVATE S16 rgSCHPwrApplyUePwrCfg
2767 RgrUeUlPwrCfg *pwrCfg
2770 PRIVATE S16 rgSCHPwrApplyUePwrCfg(cell, ue, pwrCfg)
2773 RgrUeUlPwrCfg *pwrCfg;
2777 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
2778 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2779 RgSchCmnTpcRntiCb *pucchRntiCb = NULLP;
2780 RgSchCmnTpcRntiCb *puschRntiCb = NULLP;
2781 uint8_t pucchIdx = 0;
2782 uint8_t puschIdx = 0;
2784 /* Validate Pucch group power control config */
2785 if (pwrCfg->uePucchPwr.pres)
2788 rgSCHPwrGetPucchRntiCb(cell, pwrCfg->uePucchPwr.tpcRnti);
2789 if (pucchRntiCb == NULLP)
2793 pucchIdx = pwrCfg->uePucchPwr.idx;
2794 ret = rgSCHPwrChkPucchTpcRntiIdx(pucchRntiCb, pucchIdx);
2801 /* Validate Pusch group power control config */
2802 if (pwrCfg->uePuschPwr.pres)
2805 rgSCHPwrGetPuschRntiCb(cell, pwrCfg->uePuschPwr.tpcRnti);
2806 if (puschRntiCb == NULLP)
2810 puschIdx = pwrCfg->uePuschPwr.idx;
2811 ret = rgSCHPwrChkPuschTpcRntiIdx(puschRntiCb, puschIdx);
2818 /* Apply Pucch group power control config */
2821 if (uePwr->tpcPucchRntiCb != pucchRntiCb) /* This part for recfg */
2823 if (uePwr->tpcPucchRntiCb)
2825 rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
2827 uePwr->tpcPucchRntiCb = pucchRntiCb;
2828 rgSCHPwrAddUeToPucchTpcRntiCb(cell, pucchRntiCb, ue);
2830 uePwr->pucchIdx = pucchIdx;
2832 RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2833 "<GRP_PWR>PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d",
2834 pucchRntiCb->cfgdUes.count,((uint32_t)pucchRntiCb->cfgdUes.first),
2835 ((uint32_t)pucchRntiCb->cfgdUes.last),ue->ueId);
2836 RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
2837 "UEID:%d isFmt3a(%u) ueNode(%ld)",
2838 ue->ueId,pucchRntiCb->isFmt3a,
2839 pucchRntiCb->schdLnk.node);
2840 RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2841 "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)",
2842 pucchRntiCb->toBeSchdUes.count,
2843 ((uint32_t)pucchRntiCb->toBeSchdUes.first),
2844 ((uint32_t)pucchRntiCb->toBeSchdUes.last),
2845 pucchRntiCb->tpcRnti);
2847 RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2848 "<GRP_PWR>PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d",
2849 pucchRntiCb->cfgdUes.count,((uint64_t)pucchRntiCb->cfgdUes.first),
2850 ((uint64_t)pucchRntiCb->cfgdUes.last),ue->ueId);
2851 RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId,
2852 "UEID:%d isFmt3a(%u) ueNode(%ld)",
2853 ue->ueId,pucchRntiCb->isFmt3a,
2854 pucchRntiCb->schdLnk.node);
2855 RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId,
2856 "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)",
2857 pucchRntiCb->toBeSchdUes.count,
2858 ((uint64_t)pucchRntiCb->toBeSchdUes.first),
2859 ((uint64_t)pucchRntiCb->toBeSchdUes.last),
2860 pucchRntiCb->tpcRnti);
2865 /* Apply Pusch group power control config */
2868 if (uePwr->tpcPuschRntiCb != puschRntiCb) /* This part for recfg */
2870 if (uePwr->tpcPuschRntiCb)
2872 rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
2874 uePwr->tpcPuschRntiCb = puschRntiCb;
2875 rgSCHPwrAddUeToPuschTpcRntiCb(puschRntiCb, ue);
2877 uePwr->puschIdx = puschIdx;
2881 uePwr->isAccumulated = pwrCfg->isAccumulated;
2882 uePwr->deltaMcsEnbld = pwrCfg->isDeltaMCSEnabled;
2885 uePwr->trgCqi = pwrCfg->trgCqi;
2887 if (ueUl->maxUlCqi < uePwr->trgCqi)
2889 uePwr->trgCqi = ueUl->maxUlCqi;
2891 uePwr->p0UePusch = pwrCfg->p0UePusch;
2892 uePwr->p0UePucch = pwrCfg->p0UePucch;
2899 * @brief Deletes power related information for UE
2903 * Function : rgSCHPwrUeDel
2905 * Invoking Module Processing:
2906 * - This shall be invoked by at the time of UE deletion.
2909 * - if (ue->tpcPucchRntiCb)
2910 * - delete UE from tpcPucchRntiCb->ueLst
2911 * - ue->tpcPucchRntiCb = NULLP
2912 * - If in (ue->tpcPucchRntiCb->toBeSchdLst)
2913 * - remove from the list.
2914 * - if (ue->tpcPuschRntiCb)
2915 * - delete UE from tpcPuschRntiCb->ueLst
2916 * - ue->tpcPuschRntiCb = NULLP
2917 * - If in (ue->tpcPuschRntiCb->toBeSchdLst)
2918 * - remove from the list.
2920 * @param[in] RgSchCellCb *cell
2921 * @param[in] RgSchUeCb *ue
2931 Void rgSCHPwrUeDel(cell, ue)
2936 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
2938 if (uePwr->tpcPucchRntiCb)
2940 rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
2941 uePwr->tpcPucchRntiCb = NULLP;
2943 if (uePwr->tpcPuschRntiCb)
2945 rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
2946 uePwr->tpcPuschRntiCb = NULLP;
2952 * @brief Resets UE's power state
2956 * Function : rgSCHPwrUeReset
2958 * Invoking Module Processing:
2959 * - This shall be invoked by at the time PDCCH order.
2962 * - Reset PUSCH power state
2963 * - Reset PUCCH power state
2965 * @param[in] RgSchCellCb *cell
2966 * @param[in] RgSchUeCb *ue
2970 Void rgSCHPwrUeReset
2976 Void rgSCHPwrUeReset(cell, ue)
2982 rgSCHPwrUeResetPucch(cell, ue);
2983 rgSCHPwrUeResetPusch(cell, ue);
2987 /***********************************************************
2989 * Func : rgSCHPwrUeResetPucch
2991 * Desc : This function is called to reset UE
2992 * to initial PUCCH power state.
3000 **********************************************************/
3002 PRIVATE Void rgSCHPwrUeResetPucch
3008 PRIVATE Void rgSCHPwrUeResetPucch(cell, ue)
3013 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
3015 uePwr->pucchTpc = 1;
3016 uePwr->remPucchPwr = 0;
3017 if (uePwr->tpcPucchRntiCb)
3019 rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue);
3022 /* Stack Crash problem for TRACE5 changes. Added the line below */
3027 /***********************************************************
3029 * Func : rgSCHPwrUeResetPusch
3031 * Desc : This function is called to reset UE
3032 * to initial PUSCH power state.
3040 **********************************************************/
3042 PRIVATE Void rgSCHPwrUeResetPusch
3048 PRIVATE Void rgSCHPwrUeResetPusch(cell, ue)
3053 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
3055 uePwr->isPhrAvail = FALSE;
3057 uePwr->maxUlRbs = RGSCH_MAX_DL_BW;
3059 uePwr->puschTpc = 1;
3060 uePwr->remPuschPwr = 0;
3061 if (uePwr->tpcPuschRntiCb)
3063 rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue);
3068 /***********************************************************
3070 * Func : rgSCHPwrOnPuschPwrUpd
3072 * Desc : This function is called whenever 'remPuschPwr'
3081 **********************************************************/
3083 PRIVATE Void rgSCHPwrOnPuschPwrUpd
3089 PRIVATE Void rgSCHPwrOnPuschPwrUpd(cell, ue)
3094 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell);
3095 RgSchCmnTpcRntiCb *cb;
3098 if ((cb = uePwr->tpcPuschRntiCb) == NULLP)
3103 /* Not checking for uwPwr->isPhrAvail as uePwr->phVal
3104 * is set to a large value initially */
3108 if ((uePwr->phVal != 0) && (uePwr->remPuschPwr != 0))
3116 rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue);
3120 rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue);
3127 /***********************************************************
3129 * Func : rgSCHPwrAddRntiToPucchRntiLst
3132 * Desc : Adds RNTI to Pucch Rnti list and updates requisite
3137 * Notes: Assumed that array bounds are checked
3138 * in caller before adding.
3142 **********************************************************/
3144 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst
3151 PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a)
3157 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3159 rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPucchRntiLst[cellPwr->tpcPucchRntiCnt++],
3164 /***********************************************************
3166 * Func : rgSCHPwrAddRntiToPuschRntiLst
3169 * Desc : Adds RNTI to Pusch Rnti list and updates requisite
3174 * Notes: Assumed that array bounds are checked
3175 * in caller before adding.
3179 **********************************************************/
3181 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst
3188 PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a)
3194 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3196 rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPuschRntiLst[cellPwr->tpcPuschRntiCnt++],
3201 /***********************************************************
3203 * Func : rgSCHPwrInitTpcRntiCb
3206 * Desc : Initialises a TPC RNTI CB
3214 **********************************************************/
3216 PRIVATE Void rgSCHPwrInitTpcRntiCb
3218 RgSchCmnTpcRntiCb *cb,
3223 PRIVATE Void rgSCHPwrInitTpcRntiCb(cb, rnti, isFmt3a)
3224 RgSchCmnTpcRntiCb *cb;
3230 memset(cb, 0, sizeof(*cb));
3232 cb->isFmt3a = isFmt3a;
3233 /* Not initialising lists as memset 0 takes care of it */
3234 /* cb->schdLnk.node is set when this rnti is to be scheduled */
3238 /***********************************************************
3240 * Func : rgSCHPwrGetPucchRntiCb
3243 * Desc : Gets TPC RNTI control block from Pucch rnti list
3245 * Ret : RgSchCmnTpcRntiCb * - Success
3252 **********************************************************/
3254 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb
3260 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb(cell, tpcRnti)
3265 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3268 if (!cellPwr->tpcPucchRntiCnt)
3272 for (idx = 0; idx < cellPwr->tpcPucchRntiCnt; ++idx)
3274 if (cellPwr->tpcPucchRntiLst[idx].tpcRnti == tpcRnti)
3276 return (&cellPwr->tpcPucchRntiLst[idx]);
3282 /***********************************************************
3284 * Func : rgSCHPwrGetPuschRntiCb
3287 * Desc : Gets TPC RNTI control block from Pusch rnti list
3289 * Ret : RgSchCmnTpcRntiCb * - Success
3296 **********************************************************/
3298 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb
3304 PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb(cell, tpcRnti)
3309 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3312 if (!cellPwr->tpcPuschRntiCnt)
3316 for (idx = 0; idx < cellPwr->tpcPuschRntiCnt; ++idx)
3318 if (cellPwr->tpcPuschRntiLst[idx].tpcRnti == tpcRnti)
3320 return (&cellPwr->tpcPuschRntiLst[idx]);
3327 /***********************************************************
3329 * Func : rgSCHPwrAddUeToPucchTpcRntiCb
3332 * Desc : Add UE to cfgd list of UEs in rnti cb
3340 **********************************************************/
3342 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb
3345 RgSchCmnTpcRntiCb *cb,
3349 PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb(cell, cb, ue)
3351 RgSchCmnTpcRntiCb *cb;
3355 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3358 cmLListAdd2Tail(&cb->cfgdUes, &uePwr->pucchGrpLnk);
3359 uePwr->pucchGrpLnk.node = (PTR)ue;
3363 /***********************************************************
3365 * Func : rgSCHPwrDelUeFrmPucchTpcRntiCb
3368 * Desc : Remove UE from Pucch TPC RNTI CB
3376 **********************************************************/
3378 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb
3381 RgSchCmnTpcRntiCb *cb,
3385 PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, cb, ue)
3387 RgSchCmnTpcRntiCb *cb;
3391 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3393 rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue);
3394 cmLListDelFrm(&cb->cfgdUes, &uePwr->pucchGrpLnk);
3395 uePwr->pucchGrpLnk.node = NULLP;
3399 /***********************************************************
3401 * Func : rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb
3404 * Desc : Remove UE from to-be-scheduled list of UEs
3413 **********************************************************/
3415 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb
3418 RgSchCmnTpcRntiCb *cb,
3422 PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue)
3424 RgSchCmnTpcRntiCb *cb;
3428 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3430 if (uePwr->schdPucchGrpLnk.node == NULLP)
3434 rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue);
3435 if (!cb->toBeSchdUes.count)
3437 rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb);
3442 /***********************************************************
3444 * Func : rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb
3446 * Desc : Remove UE from to-be-scheduled list of UEs
3447 * in Pucch RNTI CB. Do not both about
3448 * possibly removing Pucch RNTI CB from
3449 * the cell wide to-be-scheduled list.
3457 **********************************************************/
3459 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb
3462 RgSchCmnTpcRntiCb *cb,
3466 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue)
3468 RgSchCmnTpcRntiCb *cb;
3472 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3474 if (uePwr->schdPucchGrpLnk.node != NULLP)
3476 cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk);
3477 uePwr->schdPucchGrpLnk.node = NULLP;
3482 /***********************************************************
3484 * Func : rgSCHPwrRmvSchdPucchTpcRntiCb
3486 * Desc : Remove Pucch TPC RNTI CB from to-be-scheduled
3495 **********************************************************/
3497 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb
3500 RgSchCmnTpcRntiCb *cb
3503 PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb)
3505 RgSchCmnTpcRntiCb *cb;
3508 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3510 if (cb->schdLnk.node == NULLP)
3514 cmLListDelFrm(&cellPwr->pucchGrpPwr, &cb->schdLnk);
3515 cb->schdLnk.node = NULLP;
3519 /***********************************************************
3521 * Func : rgSCHPwrAddSchdUeToPucchTpcRntiCb
3523 * Desc : Add UE to to-be-scheduled list of UEs
3532 **********************************************************/
3534 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb
3537 RgSchCmnTpcRntiCb *cb,
3541 PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue)
3543 RgSchCmnTpcRntiCb *cb;
3547 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3549 if (uePwr->schdPucchGrpLnk.node != NULLP)
3551 /* UE is already in the list */
3554 cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk);
3555 uePwr->schdPucchGrpLnk.node = (PTR)ue;
3556 if (cb->toBeSchdUes.count == 1)
3558 /* This is first UE, so queue up this TPC RNTI
3560 rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb);
3565 /***********************************************************
3567 * Func : rgSCHPwrAddSchdPucchTpcRntiCb
3569 * Desc : Add Pucch TPC RNTI CB from to-be-scheduled
3578 **********************************************************/
3580 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb
3583 RgSchCmnTpcRntiCb *cb
3586 PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb)
3588 RgSchCmnTpcRntiCb *cb;
3591 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3593 cmLListAdd2Tail(&cellPwr->pucchGrpPwr, &cb->schdLnk);
3594 cb->schdLnk.node = (PTR)cb;
3599 /***********************************************************
3601 * Func : rgSCHPwrAddUeToPuschTpcRntiCb
3604 * Desc : Add UE to cfgd list of UEs in rnti cb
3612 **********************************************************/
3614 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb
3616 RgSchCmnTpcRntiCb *cb,
3620 PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb(cb, ue)
3621 RgSchCmnTpcRntiCb *cb;
3625 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3627 cmLListAdd2Tail(&cb->cfgdUes, &uePwr->puschGrpLnk);
3628 uePwr->puschGrpLnk.node = (PTR)ue;
3632 /***********************************************************
3634 * Func : rgSCHPwrAddSchdUeToPuschTpcRntiCb
3636 * Desc : Add UE to to-be-scheduled list of UEs
3645 **********************************************************/
3647 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb
3650 RgSchCmnTpcRntiCb *cb,
3654 PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue)
3656 RgSchCmnTpcRntiCb *cb;
3660 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3662 if (uePwr->schdPuschGrpLnk.node != NULLP)
3664 /* UE is already in the list */
3667 cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk);
3668 uePwr->schdPuschGrpLnk.node = (PTR)ue;
3669 if (cb->toBeSchdUes.count == 1)
3671 /* This is first UE, so queue up this TPC RNTI
3673 rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb);
3678 /***********************************************************
3680 * Func : rgSCHPwrDelUeFrmPuschTpcRntiCb
3683 * Desc : Add UE to cfgd list of UEs in rnti cb
3691 **********************************************************/
3693 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb
3696 RgSchCmnTpcRntiCb *cb,
3700 PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, cb, ue)
3702 RgSchCmnTpcRntiCb *cb;
3706 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3708 rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue);
3709 cmLListDelFrm(&cb->cfgdUes, &uePwr->puschGrpLnk);
3710 uePwr->puschGrpLnk.node = NULLP;
3714 /***********************************************************
3716 * Func : rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb
3718 * Desc : Remove UE from to-be-scheduled list of UEs
3727 **********************************************************/
3729 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb
3732 RgSchCmnTpcRntiCb *cb,
3736 PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue)
3738 RgSchCmnTpcRntiCb *cb;
3742 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3744 if (uePwr->schdPuschGrpLnk.node == NULLP)
3748 rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue);
3749 if (!cb->toBeSchdUes.count)
3751 rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb);
3756 /***********************************************************
3758 * Func : rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb
3760 * Desc : Remove UE from to-be-scheduled list of UEs
3761 * in Pusch RNTI CB. Do not both about
3762 * possibly removing Pusch RNTI CB from
3763 * the cell wide to-be-scheduled list.
3771 **********************************************************/
3773 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb
3776 RgSchCmnTpcRntiCb *cb,
3780 PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue)
3782 RgSchCmnTpcRntiCb *cb;
3786 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3788 if (uePwr->schdPuschGrpLnk.node != NULLP)
3790 cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk);
3791 uePwr->schdPuschGrpLnk.node = NULLP;
3796 /***********************************************************
3798 * Func : rgSCHPwrAddSchdPuschTpcRntiCb
3800 * Desc : Add Pusch TPC RNTI CB from to-be-scheduled
3809 **********************************************************/
3811 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb
3814 RgSchCmnTpcRntiCb *cb
3817 PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb)
3819 RgSchCmnTpcRntiCb *cb;
3822 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3824 cmLListAdd2Tail(&cellPwr->puschGrpPwr, &cb->schdLnk);
3825 cb->schdLnk.node = (PTR)cb;
3829 /***********************************************************
3831 * Func : rgSCHPwrRmvSchdPuschTpcRntiCb
3833 * Desc : Remove Pusch TPC RNTI CB from to-be-scheduled
3842 **********************************************************/
3844 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb
3847 RgSchCmnTpcRntiCb *cb
3850 PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb)
3852 RgSchCmnTpcRntiCb *cb;
3855 RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell);
3857 if (cb->schdLnk.node == NULLP)
3861 cmLListDelFrm(&cellPwr->puschGrpPwr, &cb->schdLnk);
3862 cb->schdLnk.node = NULLP;
3866 /***********************************************************
3868 * Func : rgSCHPwrChkPucchTpcRntiIdx
3870 * Desc : Validate that the given index is OK to
3871 * be assigned to a new UE for the Pucch TPC
3880 **********************************************************/
3882 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx
3884 RgSchCmnTpcRntiCb *cb,
3888 PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx(cb, idx)
3889 RgSchCmnTpcRntiCb *cb;
3894 if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK)
3898 if (rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx) != ROK)
3905 /***********************************************************
3907 * Func : rgSCHPwrChkPuschTpcRntiIdx
3909 * Desc : Validate that the given index is OK to
3910 * be assigned to a new UE for the Pusch TPC
3919 **********************************************************/
3921 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx
3923 RgSchCmnTpcRntiCb *cb,
3927 PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx(cb, idx)
3928 RgSchCmnTpcRntiCb *cb;
3933 if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK)
3937 if (rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx) != ROK)
3944 /***********************************************************
3946 * Func : rgSCHPwrChkUniqPucchTpcRntiIdx
3948 * Desc : Validate index against format type of TPC RNTI
3956 **********************************************************/
3958 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx
3960 RgSchCmnTpcRntiCb *cb,
3964 PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx)
3965 RgSchCmnTpcRntiCb *cb;
3971 for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next)
3973 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
3974 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
3975 if (uePwr->pucchIdx == idx)
3983 /***********************************************************
3985 * Func : rgSCHPwrChkUniqPuschTpcRntiIdx
3987 * Desc : Validate index against format type of TPC RNTI
3995 **********************************************************/
3997 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx
3999 RgSchCmnTpcRntiCb *cb,
4003 PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx)
4004 RgSchCmnTpcRntiCb *cb;
4010 for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next)
4012 RgSchUeCb *ue = (RgSchUeCb *)lnk->node;
4013 RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell);
4014 if (uePwr->puschIdx == idx)
4022 /***********************************************************
4024 * Func : rgSCHPwrChkTpcRntiIdx
4026 * Desc : Validate index against format type of TPC RNTI.
4034 **********************************************************/
4036 PRIVATE S16 rgSCHPwrChkTpcRntiIdx
4038 RgSchCmnTpcRntiCb *cb,
4042 PRIVATE S16 rgSCHPwrChkTpcRntiIdx(cb, idx)
4043 RgSchCmnTpcRntiCb *cb;
4049 if (idx >= TFU_MAX_1BIT_TPC)
4056 if (idx >= TFU_MAX_2BIT_TPC)
4063 /* Warning Fix: Commenting out as not used */
4065 /***********************************************************
4067 * Func : rgSCHPwrGetPCMaxValFromPCMax
4069 * Desc : Returns the power headroom in dB
4070 * corresponding to a power headroom
4079 **********************************************************/
4081 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax
4086 PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax(pCMax)
4090 return ((pCMax & 63) - 30);
4095 /***********************************************************
4097 * Func : rgSCHPwrGetPhValFromPhr
4099 * Desc : Returns the power headroom in dB
4100 * corresponding to a power headroom
4109 **********************************************************/
4111 PRIVATE S8 rgSCHPwrGetPhValFromPhr
4116 PRIVATE S8 rgSCHPwrGetPhValFromPhr(phr)
4120 return ((phr & 63) - 23);
4125 /**********************************************************************
4128 **********************************************************************/