Commit 2d163fc7 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/pusch-power-control-state' into integration_2024_w28

parents 23ed53da 373b7d9e
......@@ -359,7 +359,6 @@ typedef struct
//beamforming
nfapi_nr_ue_ul_beamforming_t beamforming;
//OAI specific
int8_t absolute_delta_PUSCH;
int16_t tx_power;
fapi_nr_tx_request_body_t tx_request_body;
} nfapi_nr_ue_pusch_pdu_t;
......
......@@ -1128,7 +1128,6 @@ int main(int argc, char *argv[])
pusch_config_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
pusch_config_pdu->nrOfLayers = precod_nbr_layers;
pusch_config_pdu->dmrs_ports = ((1 << precod_nbr_layers) - 1);
pusch_config_pdu->absolute_delta_PUSCH = 0;
pusch_config_pdu->target_code_rate = code_rate;
pusch_config_pdu->tbslbrm = tbslbrm;
pusch_config_pdu->ldpcBaseGraph = get_BG(TBS, code_rate);
......
......@@ -872,14 +872,21 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
nr_ue_decode_mib(mac, cc_idP);
}
static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
static void setup_puschpowercontrol(NR_UE_MAC_INST_t *mac, NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
{
UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long);
UPDATE_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t);
if (source->p0_NominalWithoutGrant)
UPDATE_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long);
if (source->p0_AlphaSets)
if (source->p0_AlphaSets) {
UPDATE_IE(target->p0_AlphaSets, source->p0_AlphaSets, struct NR_PUSCH_PowerControl__p0_AlphaSets);
if (target->p0_AlphaSets->list.array[0]->alpha) {
mac->f_b_f_c = 0;
}
if (target->p0_AlphaSets->list.array[0]->p0) {
mac->f_b_f_c = 0;
}
}
UPDATE_IE(target->twoPUSCH_PC_AdjustmentStates, source->twoPUSCH_PC_AdjustmentStates, long);
UPDATE_IE(target->deltaMCS, source->deltaMCS, long);
if (source->pathlossReferenceRSToReleaseList) {
......@@ -901,6 +908,7 @@ static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_Po
sri_PUSCH_PowerControlId);
}
if (source->sri_PUSCH_MappingToAddModList) {
LOG_E(NR_MAC, "NR_SRI_PUSCH_PowerControl not implemented, power control will not work as intended\n");
if (!target->sri_PUSCH_MappingToAddModList)
target->sri_PUSCH_MappingToAddModList = calloc(1, sizeof(*target->sri_PUSCH_MappingToAddModList));
ADDMOD_IE_FROMLIST(source->sri_PUSCH_MappingToAddModList,
......@@ -910,7 +918,7 @@ static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_Po
}
}
static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target)
static void setup_puschconfig(NR_UE_MAC_INST_t *mac, NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target)
{
UPDATE_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long);
UPDATE_IE(target->txConfig, source->txConfig, long);
......@@ -927,7 +935,7 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ
if (source->pusch_PowerControl) {
if (!target->pusch_PowerControl)
target->pusch_PowerControl = calloc(1, sizeof(*target->pusch_PowerControl));
setup_puschpowercontrol(source->pusch_PowerControl, target->pusch_PowerControl);
setup_puschpowercontrol(mac, source->pusch_PowerControl, target->pusch_PowerControl);
}
UPDATE_IE(target->frequencyHopping, source->frequencyHopping, long);
if (source->frequencyHoppingOffsetLists)
......@@ -1415,7 +1423,7 @@ static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP
if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_setup) {
if (!bwp->pusch_Config)
bwp->pusch_Config = calloc(1, sizeof(*bwp->pusch_Config));
setup_puschconfig(ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config);
setup_puschconfig(mac, ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config);
}
}
if(ul_dedicated->srs_Config) {
......
......@@ -593,6 +593,8 @@ typedef struct NR_UE_MAC_INST_s {
// PUCCH closed loop power control state
int G_b_f_c;
bool pucch_power_control_initialized;
int f_b_f_c;
bool pusch_power_control_initialized;
} NR_UE_MAC_INST_t;
/*@}*/
......
......@@ -84,6 +84,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
mac->pucch_power_control_initialized = false;
mac->pusch_power_control_initialized = false;
}
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
......
......@@ -522,12 +522,12 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
mac->nr_band,
mac->frame_type,
mac->frequency_range,
2,
qm,
false,
mac->current_UL_BWP->scs,
mac->current_UL_BWP->BWPSize,
transform_precoding,
1,
num_rb,
start_prb);
int P_O_PUSCH = P_O_NOMINAL_PUSCH + P_O_UE_PUSCH;
......@@ -553,12 +553,28 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// TODO: compute pathoss using correct reference
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize);
float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
int f_b_f_c = 0;
if (has_pusch_power_control_config && pusch_Config->pusch_PowerControl->tpc_Accumulation) {
f_b_f_c = delta_pusch;
} else {
// TODO: PUSCH power control state
if (!mac->pusch_power_control_initialized && is_rar_tx_retx) {
NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources;
float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
float DELTA_P_rampup = P_CMAX - (P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + delta_pusch);
DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup));
mac->f_b_f_c = DELTA_P_rampup + delta_pusch;
mac->pusch_power_control_initialized = true;
} else {
if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) ||
(pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) {
mac->f_b_f_c += delta_pusch;
}
}
f_b_f_c = mac->f_b_f_c;
}
LOG_D(NR_MAC,
"PUSCH tx power components P_O_PUSCH=%d, M_pusch_component=%d, alpha*pathloss=%f, delta_TF=%f, f_b_f_c=%d\n",
......
......@@ -793,20 +793,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_data.rv_index = dci->rv;
/* HARQ_PROCESS_NUMBER */
pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid;
/* TPC_PUSCH */
// according to TS 38.213 Table Table 7.1.1-1
if (dci->tpc == 0) {
pusch_config_pdu->absolute_delta_PUSCH = -4;
}
if (dci->tpc == 1) {
pusch_config_pdu->absolute_delta_PUSCH = -1;
}
if (dci->tpc == 2) {
pusch_config_pdu->absolute_delta_PUSCH = 1;
}
if (dci->tpc == 3) {
pusch_config_pdu->absolute_delta_PUSCH = 4;
}
if (NR_DMRS_ulconfig != NULL)
add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
......@@ -913,6 +899,22 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
}
/* TPC_PUSCH */
int delta_pusch = 0;
if (dci) {
bool stateless_pusch_power_control = mac->current_UL_BWP->pusch_Config != NULL
&& mac->current_UL_BWP->pusch_Config->pusch_PowerControl != NULL
&& mac->current_UL_BWP->pusch_Config->pusch_PowerControl->tpc_Accumulation != NULL;
int table_38_213_7_1_1_1[2][4] = {{-1, 0, 1, 3}, {-4, -1, 1, 4}};
if (stateless_pusch_power_control) {
delta_pusch = table_38_213_7_1_1_1[1][dci->tpc];
} else {
// TODO: This is not entirely correct. In case there is a prevously scheduled PUSCH for a future slot
// we should apply its TPC now.
delta_pusch = table_38_213_7_1_1_1[0][dci->tpc];
}
}
bool is_rar_tx_retx = rnti_type == TYPE_TC_RNTI_;
pusch_config_pdu->tx_power = get_pusch_tx_power_ue(mac,
......@@ -925,7 +927,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->target_code_rate,
pusch_config_pdu->pusch_uci.beta_offset_csi1,
pusch_config_pdu->pusch_data.tb_size << 3,
pusch_config_pdu->absolute_delta_PUSCH,
delta_pusch,
is_rar_tx_retx,
pusch_config_pdu->transform_precoding);
......
......@@ -198,6 +198,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
NR_PUSCH_PowerControl pusch_PowerControl = {0};
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
pusch_PowerControl.tpc_Accumulation = (long*)1;
mac.pusch_power_control_initialized = true;
mac.frame_type = TDD;
// msg3 cofiguration as in 5g_rfsimulator testcase
......@@ -358,6 +359,216 @@ TEST(pusch_power_control, pusch_power_data)
EXPECT_EQ(power, P_CMAX) << "Expecting max tx power because of deltaMCS with CSI-only";
}
TEST(pusch_power_control, pusch_power_control_state_initialization)
{
NR_UE_MAC_INST_t mac = {0};
NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106;
mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
NR_PUSCH_Config_t pusch_Config = {0};
current_UL_BWP.pusch_Config = &pusch_Config;
NR_PUSCH_PowerControl pusch_PowerControl = {0};
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
mac.pusch_power_control_initialized = false;
// msg3 cofiguration as in 5g_rfsimulator testcase
int num_rb = 8;
int start_prb = 0;
uint16_t nb_symb_sch = 3;
uint16_t nb_dmrs_prb = 12;
uint16_t nb_ptrs_prb = 0;
uint16_t Qm = 2;
uint16_t R = 1570;
uint16_t beta_offset_csi1 = 0;
uint32_t sum_bits_in_codeblocks = 56;
int delta_pusch = 0;
bool is_rar_tx_retx = true;
long preambleReceivedTargetPower = -96;
nr_rach_ConfigCommon.rach_ConfigGeneric.preambleReceivedTargetPower = preambleReceivedTargetPower;
get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
false);
EXPECT_EQ(mac.pusch_power_control_initialized, true);
}
TEST(pusch_power_control, pusch_power_control_state)
{
NR_UE_MAC_INST_t mac = {0};
NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106;
mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
mac.f_b_f_c = 0;
mac.pusch_power_control_initialized = true;
bool is_rar_tx_retx = false;
int num_rb = 5;
int start_prb = 0;
uint16_t nb_symb_sch = 3;
uint16_t nb_dmrs_prb = 6;
uint16_t nb_ptrs_prb = 0;
uint16_t Qm = 2;
uint16_t R = 6790;
uint16_t beta_offset_csi1 = 0;
uint32_t sum_bits_in_codeblocks = 192;
int delta_pusch = 1;
bool transform_precoding = false;
NR_PUSCH_Config_t pusch_Config = {0};
current_UL_BWP.pusch_Config = &pusch_Config;
NR_PUSCH_PowerControl pusch_PowerControl = {0};
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
long p0_NominalWithGrant = 0;
current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
mac.frame_type = TDD;
int P_CMAX = nr_get_Pcmax(23,
mac.nr_band,
mac.frame_type,
FR1,
Qm,
false,
current_UL_BWP.scs,
current_UL_BWP.BWPSize,
transform_precoding,
num_rb,
start_prb);
int power = get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
transform_precoding);
EXPECT_LE(power, P_CMAX);
EXPECT_EQ(power, 11);
for (int i = 0; i < 20; i++) {
int increased_power = get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
transform_precoding);
EXPECT_GE(increased_power, power);
EXPECT_LE(increased_power, P_CMAX);
power = increased_power;
}
delta_pusch = -1;
for (int i = 0; i < 20; i++) {
int reduced_power = get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
transform_precoding);
EXPECT_LE(reduced_power, power);
EXPECT_LE(reduced_power, P_CMAX);
power = reduced_power;
}
}
TEST(pusch_power_control, pusch_power_100_rb)
{
NR_UE_MAC_INST_t mac = {0};
NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106;
mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
mac.f_b_f_c = 0;
mac.pusch_power_control_initialized = true;
bool is_rar_tx_retx = false;
int num_rb = 5;
int start_prb = 0;
uint16_t nb_symb_sch = 3;
uint16_t nb_dmrs_prb = 6;
uint16_t nb_ptrs_prb = 0;
uint16_t Qm = 2;
uint16_t R = 6790;
uint16_t beta_offset_csi1 = 0;
uint32_t sum_bits_in_codeblocks = 192;
int delta_pusch = 1;
bool transform_precoding = false;
NR_PUSCH_Config_t pusch_Config = {0};
current_UL_BWP.pusch_Config = &pusch_Config;
NR_PUSCH_PowerControl pusch_PowerControl = {0};
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
long p0_NominalWithGrant = 0;
current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
int power = get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
transform_precoding);
num_rb = 100;
sum_bits_in_codeblocks = nr_compute_tbs(Qm, R, num_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1);
int power_100_prbs = get_pusch_tx_power_ue(&mac,
num_rb,
start_prb,
nb_symb_sch,
nb_dmrs_prb,
nb_ptrs_prb,
Qm,
R,
beta_offset_csi1,
sum_bits_in_codeblocks,
delta_pusch,
is_rar_tx_retx,
transform_precoding);
EXPECT_GT(power_100_prbs, power);
}
int main(int argc, char** argv)
{
logInit();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment