diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 1f7c25c2f0..aba54a07ef 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -152,6 +152,32 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_ return -1; // not found } +// Table 5.4.3.3-1 38-101 +uint8_t set_ssb_case(int scs, int nr_band) +{ + uint8_t ssb_case = 0; + switch (scs) { + case 0: + ssb_case = 0; // case A + break; + case 1: + if (nr_band == 5 || nr_band == 24 || nr_band == 66 || nr_band == 255) + ssb_case = 1; // case B + else + ssb_case = 2; // case C + break; + case 3: + ssb_case = 3; // case D + break; + case 4: + ssb_case = 4; // case E + break; + default: + AssertFatal(false, "Invalid sub-carrier spacing for SSB\n"); + } + return ssb_case; +} + // Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) (Rel.17) // Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) // Notes: diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 3d9f5fbc7e..93e3296e67 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -288,7 +288,7 @@ static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(uint64_t dl_CarrierFreq); - +uint8_t set_ssb_case(int scs, int nr_band); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 481f704da1..1b1b31d74d 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -675,15 +675,15 @@ typedef struct typedef struct { uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 - uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB - uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 - uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 + uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] fapi_nr_ssb_mask_size_2_t ssb_mask_list[2]; fapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64 - uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled - uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled - + uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + uint8_t ssb_case; // 0: case A 1: case B 2: case C 3: case D 4: case E } fapi_nr_ssb_table_t; typedef struct diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index d6043775af..f49493cb32 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -29,73 +29,6 @@ static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; static const uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; -// Table 5.4.3.3-1 38-101 -static const int nr_ssb_table[][3] = { - {1, 15, nr_ssb_type_A}, - {2, 15, nr_ssb_type_A}, - {3, 15, nr_ssb_type_A}, - {5, 15, nr_ssb_type_A}, - {5, 30, nr_ssb_type_B}, - {7, 15, nr_ssb_type_A}, - {8, 15, nr_ssb_type_A}, - {12, 15, nr_ssb_type_A}, - {13, 15, nr_ssb_type_A}, - {14, 15, nr_ssb_type_A}, - {18, 15, nr_ssb_type_A}, - {20, 15, nr_ssb_type_A}, - {24, 15, nr_ssb_type_A}, - {24, 30, nr_ssb_type_B}, - {25, 15, nr_ssb_type_A}, - {26, 15, nr_ssb_type_A}, - {28, 15, nr_ssb_type_A}, - {29, 15, nr_ssb_type_A}, - {30, 15, nr_ssb_type_A}, - {34, 15, nr_ssb_type_A}, - {34, 30, nr_ssb_type_C}, - {38, 15, nr_ssb_type_A}, - {38, 30, nr_ssb_type_C}, - {39, 15, nr_ssb_type_A}, - {39, 30, nr_ssb_type_C}, - {40, 30, nr_ssb_type_C}, - {41, 15, nr_ssb_type_A}, - {41, 30, nr_ssb_type_C}, - {46, 30, nr_ssb_type_C}, - {48, 30, nr_ssb_type_C}, - {50, 30, nr_ssb_type_C}, - {51, 15, nr_ssb_type_A}, - {53, 15, nr_ssb_type_A}, - {53, 30, nr_ssb_type_C}, - {65, 15, nr_ssb_type_A}, - {66, 15, nr_ssb_type_A}, - {66, 30, nr_ssb_type_B}, - {67, 15, nr_ssb_type_A}, - {70, 15, nr_ssb_type_A}, - {71, 15, nr_ssb_type_A}, - {74, 15, nr_ssb_type_A}, - {75, 15, nr_ssb_type_A}, - {76, 15, nr_ssb_type_A}, - {77, 30, nr_ssb_type_C}, - {78, 30, nr_ssb_type_C}, - {79, 30, nr_ssb_type_C}, - {85, 15, nr_ssb_type_A}, - {90, 15, nr_ssb_type_A}, - {90, 30, nr_ssb_type_C}, - {91, 15, nr_ssb_type_A}, - {92, 15, nr_ssb_type_A}, - {93, 15, nr_ssb_type_A}, - {94, 15, nr_ssb_type_A}, - {96, 30, nr_ssb_type_C}, - {100, 15, nr_ssb_type_A}, - {101, 15, nr_ssb_type_A}, - {101, 30, nr_ssb_type_C}, - {102, 30, nr_ssb_type_C}, - {104, 30, nr_ssb_type_C}, - {254, 15, nr_ssb_type_A}, - {254, 30, nr_ssb_type_C}, - {255, 15, nr_ssb_type_A}, - {255, 30, nr_ssb_type_B}, - {256, 15, nr_ssb_type_A}}; - void set_Lmax(NR_DL_FRAME_PARMS *fp) { // definition of Lmax according to ts 38.213 section 4.1 if (fp->dl_CarrierFreq < 6e9) { @@ -150,55 +83,34 @@ int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb) return symbol; } -void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) +static void set_scs_parameters(NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL, int ssb_case) { - int idx = 0; switch(mu) { case NR_MU_0: //15kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0]; - fp->ssb_type = nr_ssb_type_A; - while (nr_ssb_table[idx][0] != fp->nr_band) - idx++; - AssertFatal(nr_ssb_table[idx][1] == 15,"SCS %d not applicable to band %d\n", - fp->subcarrier_spacing,fp->nr_band); break; - case NR_MU_1: //30kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1]; - while(nr_ssb_table[idx][0] != fp->nr_band || - nr_ssb_table[idx][1] != 30) { - AssertFatal(nr_ssb_table[idx][0] <= fp->nr_band, - "SCS %d not applicable to band %d\n", - fp->subcarrier_spacing, - fp->nr_band); - idx++; - } - fp->ssb_type = nr_ssb_table[idx][2]; break; - case NR_MU_2: //60kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; break; - case NR_MU_3: fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; - fp->ssb_type = nr_ssb_type_D; break; - case NR_MU_4: fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4]; - fp->ssb_type = nr_ssb_type_E; break; - default: - AssertFatal(1==0,"Invalid numerology index %d", mu); + AssertFatal(false, "Invalid numerology index %d", mu); } + fp->ssb_type = ssb_case; // Start with FFT size 512 fp->ofdm_symbol_size = 512; @@ -231,7 +143,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) fp->ofdm_symbol_size); } -void sl_set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_SL) +void sl_set_scs_parameters(NR_DL_FRAME_PARMS *fp, int mu, int N_RB_SL) { AssertFatal(mu >= NR_MU_0 && mu <= NR_MU_4,"Invalid numerology index %d", mu); @@ -402,7 +314,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; - set_scs_parameters(fp, mu, fp->N_RB_DL); + set_scs_parameters(fp, mu, fp->N_RB_DL, cfg->ssb_table.case_v3.value); fp->slots_per_frame = 10* fp->slots_per_subframe; @@ -435,9 +347,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->print_ue_help_cmdline_log = true; } -int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, - fapi_nr_config_request_t* config, - uint16_t nr_band) +int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* config, uint16_t nr_band) { uint8_t nb_ant_ports_gNB = 1; @@ -488,7 +398,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Ncp = Ncp; int N_RB = fp->N_RB_DL; - set_scs_parameters(fp, fp->numerology_index, N_RB); + set_scs_parameters(fp, fp->numerology_index, N_RB, config->ssb_table.ssb_case); fp->slots_per_frame = 10* fp->slots_per_subframe; fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats @@ -553,7 +463,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_p frame_parms->frame_type = get_frame_type(frame_parms->nr_band, frame_parms->numerology_index); frame_parms->Ncp = NORMAL; - set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL); + set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL, set_ssb_case(mu, nr_band)); set_Lmax(frame_parms); frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b3195894a4..053908e8de 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -229,6 +229,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo cfg->ssb_table.ssb_offset_point_a = frequencyInfoDL->offsetToPointA; cfg->ssb_table.ssb_period = scc->ssb_PeriodicityServingCell; cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; + cfg->ssb_table.ssb_case = set_ssb_case(mac->numerology, mac->nr_band); if (mac->frequency_range == FR1){ cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24; @@ -546,6 +547,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; // NSA -> take ssb offset from SCS cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling); + cfg->ssb_table.ssb_case = set_ssb_case(*scc->ssbSubcarrierSpacing, mac->nr_band); } switch (scc->ssb_PositionsInBurst->present) { diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 005ad05720..eea50555c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -397,8 +397,9 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR nrmac->common_channels[0].ServingCellConfigCommon = scc; // Carrier configuration - struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - frequency_range_t frequency_range = get_freq_range_from_band(*frequencyInfoDL->frequencyBandList.list.array[0]); + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_FreqBandIndicatorNR_t nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]; + frequency_range_t frequency_range = get_freq_range_from_band(nr_band); int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, frequency_range, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); @@ -406,7 +407,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary cfg->num_tlv++; - cfg->carrier_config.dl_frequency.value = from_nrarfcn(*frequencyInfoDL->frequencyBandList.list.array[0], + cfg->carrier_config.dl_frequency.value = from_nrarfcn(nr_band, *scc->ssbSubcarrierSpacing, frequencyInfoDL->absoluteFrequencyPointA) / 1000; // freq in kHz @@ -462,8 +463,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR } } - NR_FreqBandIndicatorNR_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; - frame_type_t frame_type = get_frame_type(band, *scc->ssbSubcarrierSpacing); + frame_type_t frame_type = get_frame_type(nr_band, *scc->ssbSubcarrierSpacing); nrmac->common_channels[0].frame_type = frame_type; // Cell configuration @@ -508,7 +508,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR else { // If absent, use SCS as derived from the prach-ConfigurationIndex (for 839) int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; - int frame_type = get_frame_type(band, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); + int frame_type = get_frame_type(nr_band, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); int format = get_nr_prach_format_from_index(config_index, UL_pointA, frame_type) & 0xff; cfg->prach_config.prach_sub_c_spacing.value = get_delta_f_RA_long(format); } @@ -606,6 +606,10 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->num_tlv++; + cfg->ssb_table.case_v3.value = set_ssb_case(*scc->ssbSubcarrierSpacing, nr_band); + cfg->ssb_table.case_v3.tl.tag = NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG; + cfg->num_tlv++; + uint8_t *mib_payload = nrmac->common_channels[0].MIB_pdu; uint32_t mib = (mib_payload[2] << 16) | (mib_payload[1] << 8) | mib_payload[0]; cfg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG; @@ -742,7 +746,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR carr_ul - carr_dl, bw, mu, - band, + nr_band, 12 * prb_offset + sc_offset, get_softmodem_params()->threequarter_fs ? "-E" : ""); } else { @@ -751,7 +755,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR carr_dl, bw, mu, - band, + nr_band, 12 * prb_offset + sc_offset, get_softmodem_params()->threequarter_fs ? "-E" : ""); }