Reuse new power control functionality for PUCCH

This commit is contained in:
Robert Schmidt
2026-03-25 09:03:49 +01:00
parent cd0051dea1
commit 27a5a75685
8 changed files with 33 additions and 47 deletions
@@ -82,7 +82,7 @@ bool read_mac_sm(void* data)
rd->ul_aggr_sdus = UE->mac_stats.ul.num_mac_sdu;
rd->pusch_snr = sched_ctrl->pusch_pc.avg_snr; //: float = -64;
rd->pucch_snr = (float) sched_ctrl->pucch_snrx10 / 10; //: float = -64;
rd->pucch_snr = sched_ctrl->pucch_pc.avg_snr; //: float = -64;
rd->wb_cqi = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
rd->dl_mcs1 = sched_ctrl->dl_bler_stats.mcs;
@@ -1348,6 +1348,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
prepare_dci_pdu(pdcch_pdu_rel15, scc, sched_ctrl->search_space, coreset, aggregation_level, CCEIndex, fapi_beam, rnti);
pdcch_pdu_rel15->numDlDci++;
int tpc = 1; // 0dB change, don't know how to determine this.
dci_pdu_rel15_t dci_payload = prepare_dci_dl_payload(nr_mac,
UE,
rnti_type,
@@ -1355,6 +1356,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
pdsch_pdu_rel15,
sched_pdsch,
pucch,
tpc,
current_harq_pid,
tb_scaling,
false);
@@ -1918,9 +1920,6 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
tb_scaling,
pduindex);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
sched_ctrl->tpc1 = 1;
// Add padding header and zero rest out if there is space left
if (ra->mac_pdu_length < harq->tb_size) {
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[ra->mac_pdu_length];
@@ -405,6 +405,7 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac,
pdsch_pdu_rel15,
pdsch,
NULL,
1,
0,
0,
is_sib1);
@@ -1095,6 +1095,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
harq->is_waiting = true;
}
UE->mac_stats.dl.rounds[harq->round]++;
int tpc = nr_mac_get_tpc(&sched_ctrl->pucch_pc);
LOG_D(NR_MAC,
"%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
frame,
@@ -1117,7 +1118,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
pucch ? pucch->frame : 0,
pucch ? pucch->ul_slot : 0,
sched_pdsch->pucch_allocation,
sched_ctrl->tpc1);
tpc);
DevAssert(sched_pdsch->rbSize > 0);
const int bwp_id = current_BWP->bwp_id;
@@ -1195,12 +1196,11 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
pdsch_pdu,
sched_pdsch,
pucch,
tpc,
current_harq_pid,
0,
false);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
sched_ctrl->tpc1 = 1;
NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config;
AssertFatal(pdsch_Config == NULL
|| pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
@@ -869,6 +869,7 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu,
const NR_sched_pdsch_t *sched_pdsch,
const NR_sched_pucch_t *pucch,
int tpc,
int harq_pid,
int tb_scaling,
bool is_sib1)
@@ -902,7 +903,7 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac,
const NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID;
dci_payload.antenna_ports.val = sched_pdsch->dmrs_parms.dmrs_ports_id;
dci_payload.tpc = sched_ctrl->tpc1;
dci_payload.tpc = tpc;
const NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid];
AssertFatal(harq, "HARQ process should be available for DCI with RNTI %s\n", rnti_types(rnti_type));
dci_payload.harq_pid.val = harq_pid;
@@ -2983,6 +2984,9 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->ta_update = 31;
nr_mac_set_target_snrx10(&sched_ctrl->pucch_pc, config->pucch.target_snrx10);
sched_ctrl->pucch_pc.avg_snr = config->pucch.target_snrx10 / 10.0f; // set initial SNR to what we would expect on average
nr_mac_set_rssi_threshold(&sched_ctrl->pucch_pc, config->pucch.rssi_threshold);
nr_mac_set_target_snrx10(&sched_ctrl->pusch_pc, config->pusch.target_snrx10);
sched_ctrl->pusch_pc.avg_snr = config->pusch.target_snrx10 / 10.0f; // set initial SNR to what we would expect on average
nr_mac_set_rssi_threshold(&sched_ctrl->pusch_pc, config->pusch.rssi_threshold);
@@ -3125,19 +3129,6 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
nr_release_ra_UE(nr_mac, rnti);
}
// all values passed to this function are in dB x10
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr, int tx_power)
{
// al values passed to this function are x10
int snrx10 = (cqi * 5) - 640 - (tx_power * 10);
LOG_D(NR_MAC, "tpc : target %d, cqi %d, snrx10 %d, tx_power %d\n", target, ((int)cqi * 5) - 640, snrx10, tx_power);
if (snrx10 > target + incr) return 0; // decrease 1dB
if (snrx10 < target - (3*incr)) return 3; // increase 3dB
if (snrx10 < target - incr) return 2; // increase 1dB
LOG_D(NR_MAC,"tpc : target %d, snrx10 %d\n",target,snrx10);
return 1; // no change
}
/**
* @brief Returns the number of dBs for given transmit power control (TPC)
* command. Asserts on illegal TPC.
@@ -3163,7 +3154,7 @@ static int tpc_to_db(int tpc)
* @param rssi_threshold RSSI threshold in 0.1 dBm/dBFS, range -1280 to 0
* @return The adjusted TPC command after applying the RSSI threshold check.
*/
uint8_t nr_limit_tpc(int tpc, int rssi, int rssi_threshold)
static uint8_t nr_limit_tpc(int tpc, int rssi, int rssi_threshold)
{
if (rssi == 0xFFFF) {
// RSSI not available, keep tpc
+18 -20
View File
@@ -879,7 +879,6 @@ static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, in
void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01)
{
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
int rssi_threshold = nrmac->radio_config.pucch.rssi_threshold;
NR_SCHED_LOCK(&nrmac->sched_lock);
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, uci_01->rnti);
bool is_ra = false;
@@ -925,25 +924,26 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con
return;
}
}
if (harq_confidence == 1)
if (harq_confidence == 1) {
UE->mac_stats.pucch0_DTX++;
// DTX for each _bit_, but maybe once for PUCCH is enough? not sure
nr_mac_signal_dtx(&sched_ctrl->pucch_pc);
}
}
// tpc (power control) only if we received AckNack
if (uci_01->harq.harq_confidence_level == 0 && uci_01->ul_cqi != 0xff) {
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
sched_ctrl->tpc1 = nr_get_tpc(nrmac->radio_config.pucch.target_snrx10, uci_01->ul_cqi, 30, 0);
} else
sched_ctrl->tpc1 = 1;
sched_ctrl->tpc1 = nr_limit_tpc(sched_ctrl->tpc1, uci_01->rssi, rssi_threshold);
int pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
nr_mac_pc_snr(&sched_ctrl->pucch_pc, pucch_snrx10, uci_01->rssi);
T(T_GNB_MAC_PUCCH_POWER_CONTROL,
T_INT(uci_01->rnti),
T_INT(frame),
T_INT(slot),
T_INT(sched_ctrl->pucch_snrx10),
T_INT(sched_ctrl->tpc1),
T_INT(uci_01->rssi));
T(T_GNB_MAC_PUCCH_POWER_CONTROL,
T_INT(uci_01->rnti),
T_INT(frame),
T_INT(slot),
T_INT(pucch_snrx10),
T_INT(1),
T_INT(uci_01->rssi));
}
}
// check scheduling request result, confidence_level == 0 is good
@@ -962,7 +962,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c
{
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
NR_SCHED_LOCK(&nrmac->sched_lock);
int rssi_threshold = nrmac->radio_config.pucch.rssi_threshold;
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, uci_234->rnti);
if (!UE) {
@@ -976,16 +975,15 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c
// tpc (power control)
// TODO PUCCH2 SNR computation is not correct -> ignore the following
if (uci_234->ul_cqi != 0xff) {
sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
sched_ctrl->tpc1 = nr_get_tpc(nrmac->radio_config.pucch.target_snrx10, uci_234->ul_cqi, 30, 0);
sched_ctrl->tpc1 = nr_limit_tpc(sched_ctrl->tpc1, uci_234->rssi, rssi_threshold);
int pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
nr_mac_pc_snr(&sched_ctrl->pucch_pc, pucch_snrx10, uci_234->rssi);
T(T_GNB_MAC_PUCCH_POWER_CONTROL,
T_INT(uci_234->rnti),
T_INT(frame),
T_INT(slot),
T_INT(sched_ctrl->pucch_snrx10),
T_INT(sched_ctrl->tpc1),
T_INT(pucch_snrx10),
T_INT(1),
T_INT(uci_234->rssi));
}
+1 -3
View File
@@ -169,6 +169,7 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu,
const NR_sched_pdsch_t *sched_pdsch,
const NR_sched_pucch_t *pucch,
int tpc,
int harq_pid,
int tb_scaling,
bool is_sib1);
@@ -285,9 +286,6 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
const NR_tda_info_t *tda_info,
const int Layers);
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr, int tx_power);
uint8_t nr_limit_tpc(int tpc, int rssi, int rssi_threshold);
int get_spf(nfapi_nr_config_request_scf_t *cfg);
int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
+1 -2
View File
@@ -673,8 +673,6 @@ typedef struct {
uint16_t ta_frame;
int16_t ta_update;
bool ta_apply;
uint8_t tpc1;
int pucch_snrx10;
int pusch_consecutive_dtx_cnt;
int pucch_consecutive_dtx_cnt;
bool ul_failure;
@@ -719,6 +717,7 @@ typedef struct {
float pdcch_cl_adjust;
nr_power_control_t pusch_pc;
nr_power_control_t pucch_pc;
} NR_UE_sched_ctrl_t;
typedef struct NR_mac_dir_stats {