Commit 48d68f7d authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

Fix a bug where if BWP size is not exactly maximum BWP size for a bandwidth...

Fix a bug where if BWP size is not exactly maximum BWP size for a bandwidth power control code asserts.
This assert and assumption is incorrect, according to 38.101-1 UE channel is defined only by the BWP size
and BWP size can be any value supported by the RRC parameters defining the BWP.
To determine the UE channel the smallest bandwidth supporting the BWP is selected. This is an assumption based
on references in the same document to UE channel bandwidth being equal to one of the values in set
 {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100}.
Also:
 - calculated P_CMIN during BWP setup since the parameter doesn't depend on DCI.
 - initiialize uniqCfg structure in test_nr_ue_power_procedures main function which enables LOG prints during tests
parent f0f0cf80
...@@ -105,6 +105,16 @@ int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs) ...@@ -105,6 +105,16 @@ int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs)
return (-1); // not found return (-1); // not found
} }
int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs)
{
int scs_index = scs + frequency_range;
for (int i = 0; i < 12; i++) {
if (n_rbs <= tables_5_3_2[scs_index][i])
return i;
}
return -1; // not found
}
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) // Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) // Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
// Notes: // Notes:
...@@ -299,64 +309,30 @@ void check_ssb_raster(uint64_t freq, int band, int scs) ...@@ -299,64 +309,30 @@ void check_ssb_raster(uint64_t freq, int band, int scs)
band); band);
} }
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb) int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index)
{ {
int bw_index = get_supported_band_index(scs, frequency_range, nb_rb);
if (frequency_range == FR1) { if (frequency_range == FR1) {
switch (bw_index) { int bandwidth_index_to_mhz[] = {5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100};
case 0 : AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
return 5; // 5MHz "Bandwidth index %d is invalid\n",
case 1 : bw_index);
return 10; return bandwidth_index_to_mhz[bw_index];
case 2 : } else {
return 15; int bandwidth_index_to_mhz[] = {50, 100, 200, 400};
case 3 : AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
return 20; "Bandwidth index %d is invalid\n",
case 4 : bw_index);
return 25; return bandwidth_index_to_mhz[bw_index];
case 5 :
return 30;
case 6 :
return 40;
case 7 :
return 50;
case 8 :
return 60;
case 9 :
return 80;
case 10 :
return 90;
case 11 :
return 100;
default :
AssertFatal(false, "Invalid band index for FR1 %d\n", bw_index);
}
}
else {
switch (bw_index) {
case 0 :
return 50; // 50MHz
case 1 :
return 100;
case 2 :
return 200;
case 3 :
return 400;
default :
AssertFatal(false, "Invalid band index for FR2 %d\n", bw_index);
}
} }
} }
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type) bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type)
{ {
// 38.101-1 section 6.2.2 // 38.101-1 section 6.2.2
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands // Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
int index = get_nr_table_idx(nr_band, scs); int index = get_nr_table_idx(nr_band, scs);
int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, nb_ul) * 1000;
float limit = frame_type == TDD ? 0.04 : 0.03; float limit = frame_type == TDD ? 0.04 : 0.03;
float rel_bw = (float) (band_size_khz) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min); float rel_bw = (float) (2 * channel_bandwidth * 1000) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min);
return rel_bw > limit; return rel_bw > limit;
} }
......
...@@ -224,8 +224,8 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports); ...@@ -224,8 +224,8 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports);
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols); uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
int get_nb_periods_per_frame(uint8_t tdd_period); int get_nb_periods_per_frame(uint8_t tdd_period);
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS); long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type); bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type);
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb); int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index);
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs); int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
void get_samplerate_and_bw(int mu, void get_samplerate_and_bw(int mu,
int n_rb, int n_rb,
...@@ -248,6 +248,7 @@ int get_scan_ssb_first_sc(const double fc, ...@@ -248,6 +248,7 @@ int get_scan_ssb_first_sc(const double fc,
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]); nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
void check_ssb_raster(uint64_t freq, int band, int scs); void check_ssb_raster(uint64_t freq, int band, int scs);
int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs);
#define CEILIDIV(a,b) ((a+b-1)/b) #define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
......
...@@ -518,7 +518,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, ...@@ -518,7 +518,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
} }
fp->threequarter_fs = 0; fp->threequarter_fs = 0;
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL); frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1;
int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
nr_init_frame_parms(gNB_config, fp); nr_init_frame_parms(gNB_config, fp);
......
...@@ -161,8 +161,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, ...@@ -161,8 +161,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
if (mu>2) fp->nr_band = 257; if (mu>2) fp->nr_band = 257;
else fp->nr_band = 78; else fp->nr_band = 78;
fp->threequarter_fs= 0; fp->threequarter_fs= 0;
frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1;
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL); int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
fp->ofdm_offset_divisor = UINT_MAX; fp->ofdm_offset_divisor = UINT_MAX;
nr_init_frame_parms(gNB_config, fp); nr_init_frame_parms(gNB_config, fp);
......
...@@ -573,6 +573,10 @@ typedef struct NR_UE_UL_BWP { ...@@ -573,6 +573,10 @@ typedef struct NR_UE_UL_BWP {
nr_dci_format_t dci_format; nr_dci_format_t dci_format;
int max_fb_time; int max_fb_time;
long *p0_NominalWithGrant; long *p0_NominalWithGrant;
// UE Channel bandwidth according to 38.101 5.3.2
int channel_bandwidth;
// Minimum transmission power according to 38.101 6.3.1
float P_CMIN;
} NR_UE_UL_BWP_t; } NR_UE_UL_BWP_t;
// non-BWP serving cell configuration // non-BWP serving cell configuration
......
...@@ -118,9 +118,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, ...@@ -118,9 +118,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL; NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL;
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n"); AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR; mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); mac->frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) * uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
...@@ -139,9 +141,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, ...@@ -139,9 +141,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL; NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); mac->frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
if (frequencyInfoUL->absoluteFrequencyPointA == NULL) if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency; cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
...@@ -260,9 +264,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, ...@@ -260,9 +264,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology); mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2; mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, mac->frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band, cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
*scc->ssbSubcarrierSpacing, *scc->ssbSubcarrierSpacing,
...@@ -284,9 +289,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, ...@@ -284,9 +289,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, mac->frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
long *UL_pointA = NULL; long *UL_pointA = NULL;
if (frequencyInfoUL->absoluteFrequencyPointA) if (frequencyInfoUL->absoluteFrequencyPointA)
...@@ -1488,6 +1494,11 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up ...@@ -1488,6 +1494,11 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
bwp->cyclicprefix = ul_genericParameters->cyclicPrefix; bwp->cyclicprefix = ul_genericParameters->cyclicPrefix;
bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE); bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
// For power calculations assume the UE channel is the smallest channel that can support the BWP
int bw_index = get_smallest_supported_bandwidth_index(bwp->scs, mac->frequency_range, bwp->BWPSize);
bwp->channel_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
// Minumum transmission power depends on bandwidth, precalculate it here
bwp->P_CMIN = nr_get_Pcmin(bw_index);
if (bwp_id == 0) { if (bwp_id == 0) {
mac->sc_info.initial_ul_BWPSize = bwp->BWPSize; mac->sc_info.initial_ul_BWPSize = bwp->BWPSize;
mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; mac->sc_info.initial_ul_BWPStart = bwp->BWPStart;
......
...@@ -138,7 +138,8 @@ static void sl_prepare_phy_config(int module_id, ...@@ -138,7 +138,8 @@ static void sl_prepare_phy_config(int module_id,
AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL"); AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL");
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, carriercfg->subcarrierSpacing, carriercfg->carrierBandwidth); int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing, FR1, carriercfg->carrierBandwidth);
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index);
phycfg->sl_carrier_config.sl_frequency = phycfg->sl_carrier_config.sl_frequency =
from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz
......
...@@ -248,6 +248,7 @@ float nr_get_Pcmax(int p_Max, ...@@ -248,6 +248,7 @@ float nr_get_Pcmax(int p_Max,
uint16_t nr_band, uint16_t nr_band,
frame_type_t frame_type, frame_type_t frame_type,
frequency_range_t frequency_range, frequency_range_t frequency_range,
int channel_bandwidth_index,
int Qm, int Qm,
bool powerBoostPi2BPSK, bool powerBoostPi2BPSK,
int scs, int scs,
...@@ -256,7 +257,7 @@ float nr_get_Pcmax(int p_Max, ...@@ -256,7 +257,7 @@ float nr_get_Pcmax(int p_Max,
int n_prbs, int n_prbs,
int start_prb); int start_prb);
float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL); float nr_get_Pcmin(int bandwidth_index);
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
......
...@@ -91,6 +91,7 @@ void init_RA(NR_UE_MAC_INST_t *mac, ...@@ -91,6 +91,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_type,
mac->frequency_range, mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
2, 2,
false, false,
prach_scs, prach_scs,
......
...@@ -66,16 +66,16 @@ static int get_deltatf(uint16_t nb_of_prbs, ...@@ -66,16 +66,16 @@ static int get_deltatf(uint16_t nb_of_prbs,
int O_UCI); int O_UCI);
// ∆MPR according to Table 6.2.2-3 38.101-1 // ∆MPR according to Table 6.2.2-3 38.101-1
static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int N_RB_UL, int n_prbs, int start_prb, int power_class) static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class)
{ {
if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { if (compare_relative_ul_channel_bw(nr_band, scs, channel_bandwidth, frame_type)) {
if (power_class == 3) { if (power_class == 3) {
if ((nr_band == 28 || nr_band == 83) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 30) { if ((nr_band == 28 || nr_band == 83) && channel_bandwidth == 30) {
return 0.5f; return 0.5f;
} }
} }
if (power_class == 3 || power_class == 2) { if (power_class == 3 || power_class == 2) {
if ((nr_band == 40 || nr_band == 97) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 100) { if ((nr_band == 40 || nr_band == 97) && channel_bandwidth == 100) {
return 1.0f; return 1.0f;
} }
} }
...@@ -168,6 +168,7 @@ float nr_get_Pcmax(int p_Max, ...@@ -168,6 +168,7 @@ float nr_get_Pcmax(int p_Max,
uint16_t nr_band, uint16_t nr_band,
frame_type_t frame_type, frame_type_t frame_type,
frequency_range_t frequency_range, frequency_range_t frequency_range,
int channel_bandwidth,
int Qm, int Qm,
bool powerBoostPi2BPSK, bool powerBoostPi2BPSK,
int scs, int scs,
...@@ -197,7 +198,7 @@ float nr_get_Pcmax(int p_Max, ...@@ -197,7 +198,7 @@ float nr_get_Pcmax(int p_Max,
int delta_TC = 0; int delta_TC = 0;
float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class); float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class);
float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, N_RB_UL, n_prbs, start_prb, power_class); float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, n_prbs, start_prb, power_class);
int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1) int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1)
int delta_rx_SRS = 0; // TODO for SRS int delta_rx_SRS = 0; // TODO for SRS
int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements
...@@ -216,7 +217,13 @@ float nr_get_Pcmax(int p_Max, ...@@ -216,7 +217,13 @@ float nr_get_Pcmax(int p_Max,
} }
// TODO we need a strategy to select a value between minimum and maximum allowed PC_max // TODO we need a strategy to select a value between minimum and maximum allowed PC_max
float pcmax = (pcmax_low + pcmax_high) / 2; float pcmax = (pcmax_low + pcmax_high) / 2;
LOG_D(MAC, "Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm \n", pcmax_low, pcmax, pcmax_high); LOG_D(MAC,
"Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm MPR=%.2f deltaMPR=%.2f\n",
pcmax_low,
pcmax,
pcmax_high,
MPR,
delta_MPR);
return pcmax; return pcmax;
} else { } else {
// FR2 TODO it is even more complex because it is radiated power // FR2 TODO it is even more complex because it is radiated power
...@@ -224,12 +231,11 @@ float nr_get_Pcmax(int p_Max, ...@@ -224,12 +231,11 @@ float nr_get_Pcmax(int p_Max,
} }
} }
float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL) { float nr_get_Pcmin(int bandwidth_index) {
int band_index = get_supported_band_index(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL);
const float table_38101_6_3_1_1[] = { const float table_38101_6_3_1_1[] = {
-40, -40, -40, -40, -39, -38.2, -37.5, -37, -36.5, -35.2, -34.6, -34, -33.5, -33 -40, -40, -40, -40, -39, -38.2, -37.5, -37, -36.5, -35.2, -34.6, -34, -33.5, -33
}; };
return table_38101_6_3_1_1[band_index]; return table_38101_6_3_1_1[bandwidth_index];
} }
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback // This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
...@@ -341,6 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -341,6 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_type,
mac->frequency_range, mac->frequency_range,
current_UL_BWP->channel_bandwidth,
2, 2,
false, false,
mac->current_UL_BWP->scs, mac->current_UL_BWP->scs,
...@@ -348,7 +355,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -348,7 +355,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
format_type == 2, format_type == 2,
1, 1,
start_prb); start_prb);
int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize); float P_CMIN = current_UL_BWP->P_CMIN;
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) { if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
...@@ -522,6 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -522,6 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
mac->nr_band, mac->nr_band,
mac->frame_type, mac->frame_type,
mac->frequency_range, mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
qm, qm,
false, false,
mac->current_UL_BWP->scs, mac->current_UL_BWP->scs,
...@@ -553,7 +561,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -553,7 +561,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// TODO: compute pathoss using correct reference // TODO: compute pathoss using correct reference
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); 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); int P_CMIN = mac->current_UL_BWP->P_CMIN;
float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF; float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
......
...@@ -44,24 +44,27 @@ TEST(test_pcmax, test_mpr) ...@@ -44,24 +44,27 @@ TEST(test_pcmax, test_mpr)
int nr_band = 20; int nr_band = 20;
float expected_power = 23 - (1.5 / 2); float expected_power = 23 - (1.5 / 2);
frame_type_t frame_type = TDD; frame_type_t frame_type = TDD;
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); int channel_bandwidth = 20;
EXPECT_EQ(expected_power,
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
// Outer PRB, MPR = 3, no delta MPR // Outer PRB, MPR = 3, no delta MPR
prb_start = 0; prb_start = 0;
expected_power = 23 - (3.0 / 2); expected_power = 23 - (3.0 / 2);
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); EXPECT_EQ(expected_power,
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
// Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB // Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB
N_RB_UL = 78; N_RB_UL = 78;
nr_band = 28; nr_band = 28;
expected_power = 23 - ((3.0 + 0.5) / 2); expected_power = 23 - ((3.0 + 0.5) / 2);
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 100, prb_start)); EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 30, 2, false, 1, N_RB_UL, false, 100, prb_start));
} }
TEST(test_pcmax, test_not_implemented) TEST(test_pcmax, test_not_implemented)
{ {
int N_RB_UL = 51; int N_RB_UL = 51;
EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 20, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet");
} }
TEST(test_pcmax, test_pucch_max_power) TEST(test_pcmax, test_pucch_max_power)
...@@ -70,11 +73,12 @@ TEST(test_pcmax, test_pucch_max_power) ...@@ -70,11 +73,12 @@ TEST(test_pcmax, test_pucch_max_power)
int prb_start = 0; int prb_start = 0;
int N_RB_UL = 51; // 10Mhz int N_RB_UL = 51; // 10Mhz
float expected_power = 23 - (1.0 / 2); float expected_power = 23 - (1.0 / 2);
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, true, 1, prb_start)); int channel_bandwidth = 20;
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, true, 1, prb_start));
// Other fromats, no transform precoding, MPR = 3 // Other fromats, no transform precoding, MPR = 3
expected_power = 23 - (3.0 / 2); expected_power = 23 - (3.0 / 2);
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, false, 1, prb_start)); EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 1, prb_start));
} }
TEST(test_pucch_power_state, test_accumulated_delta_pucch) TEST(test_pucch_power_state, test_accumulated_delta_pucch)
...@@ -108,6 +112,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) ...@@ -108,6 +112,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth,
2, 2,
false, false,
current_UL_BWP.scs, current_UL_BWP.scs,
...@@ -177,9 +182,9 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch) ...@@ -177,9 +182,9 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
TEST(pc_min, check_all_bw_indexes) TEST(pc_min, check_all_bw_indexes)
{ {
const int NB_RB_UL[] = {11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273}; const int bws[] = {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100};
for (auto i = 0U; i < sizeof(NB_RB_UL) / sizeof(NB_RB_UL[0]); i++) { for (auto i = 0U; i < sizeofArray(bws); i++) {
(void)nr_get_Pcmin(1, 20, NB_RB_UL[i]); (void)nr_get_Pcmin(i);
} }
} }
...@@ -189,6 +194,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) ...@@ -189,6 +194,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
NR_UE_UL_BWP_t current_UL_BWP = {0}; NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1; current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106; current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP; mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
...@@ -218,6 +224,7 @@ TEST(pusch_power_control, pusch_power_control_msg3) ...@@ -218,6 +224,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth,
Qm, Qm,
false, false,
current_UL_BWP.scs, current_UL_BWP.scs,
...@@ -286,6 +293,7 @@ TEST(pusch_power_control, pusch_power_data) ...@@ -286,6 +293,7 @@ TEST(pusch_power_control, pusch_power_data)
NR_UE_UL_BWP_t current_UL_BWP = {0}; NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1; current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106; current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP; mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
...@@ -317,6 +325,7 @@ TEST(pusch_power_control, pusch_power_data) ...@@ -317,6 +325,7 @@ TEST(pusch_power_control, pusch_power_data)
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth,
Qm, Qm,
false, false,
current_UL_BWP.scs, current_UL_BWP.scs,
...@@ -365,6 +374,7 @@ TEST(pusch_power_control, pusch_power_control_state_initialization) ...@@ -365,6 +374,7 @@ TEST(pusch_power_control, pusch_power_control_state_initialization)
NR_UE_UL_BWP_t current_UL_BWP = {0}; NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1; current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106; current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP; mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
...@@ -412,6 +422,7 @@ TEST(pusch_power_control, pusch_power_control_state) ...@@ -412,6 +422,7 @@ TEST(pusch_power_control, pusch_power_control_state)
NR_UE_UL_BWP_t current_UL_BWP = {0}; NR_UE_UL_BWP_t current_UL_BWP = {0};
current_UL_BWP.scs = 1; current_UL_BWP.scs = 1;
current_UL_BWP.BWPSize = 106; current_UL_BWP.BWPSize = 106;
current_UL_BWP.channel_bandwidth = 40;
mac.current_UL_BWP = &current_UL_BWP; mac.current_UL_BWP = &current_UL_BWP;
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon; current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
...@@ -443,6 +454,7 @@ TEST(pusch_power_control, pusch_power_control_state) ...@@ -443,6 +454,7 @@ TEST(pusch_power_control, pusch_power_control_state)
mac.nr_band, mac.nr_band,
mac.frame_type, mac.frame_type,
FR1, FR1,
current_UL_BWP.channel_bandwidth,
Qm, Qm,
false, false,
current_UL_BWP.scs, current_UL_BWP.scs,
...@@ -569,9 +581,25 @@ TEST(pusch_power_control, pusch_power_100_rb) ...@@ -569,9 +581,25 @@ TEST(pusch_power_control, pusch_power_100_rb)
EXPECT_GT(power_100_prbs, power); EXPECT_GT(power_100_prbs, power);
} }
TEST(test_pcmax, test_non_obvious_bwp_size)
{
// Inner PRB, MPR = 1.5, no delta MPR
int prb_start = 4;
int N_RB_UL = 48;
int nr_band = 20;
frame_type_t frame_type = TDD;
int channel_bandwidth = 10;
float expected_power = 23 - 1.5 / 2;
EXPECT_EQ(expected_power,
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
logInit(); logInit();
uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
g_log->log_component[MAC].level = OAILOG_DEBUG;
g_log->log_component[NR_MAC].level = OAILOG_DEBUG;
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
...@@ -280,9 +280,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant ...@@ -280,9 +280,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
// Carrier configuration // Carrier configuration
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, frequency_range_t frequency_range = *frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1;
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary
cfg->num_tlv++; cfg->num_tlv++;
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value); LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value);
...@@ -308,9 +310,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant ...@@ -308,9 +310,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
} }
} }
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
cfg->num_tlv++; cfg->num_tlv++;
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value); LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value);
...@@ -343,7 +347,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant ...@@ -343,7 +347,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
} }
uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band < 100 ? FR1 : FR2; frequency_range = band < 100 ? FR1 : FR2;
frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
nrmac->common_channels[0].frame_type = frame_type; nrmac->common_channels[0].frame_type = frame_type;
......
...@@ -529,7 +529,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig, ...@@ -529,7 +529,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig,
NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL; NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL;
if (fs) { if (fs) {
const int bw_mhz = get_supported_bw_mhz(freq_range, scs, bw_size); const int bw_mhz = get_supported_bw_mhz(freq_range, get_supported_band_index(scs, freq_range, bw_size));
// go through UL feature sets and look for one with current SCS // go through UL feature sets and look for one with current SCS
for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) { for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) {
NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i]; NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i];
......
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