diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 4c5a480386..c071bd99a6 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -486,12 +486,13 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) UE->UE_scan_carrier = false; UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; - const fapi_nr_ue_carrier_config_t *cfg = &UE->nrUE_config.carrier_config; + const fapi_nr_config_request_t *config = &UE->nrUE_config; + const fapi_nr_ue_carrier_config_t *cfg = &config->carrier_config; uint64_t dl_CarrierFreq = get_carrier_frequency(fp->N_RB_DL, fp->numerology_index, cfg->dl_frequency); uint64_t ul_CarrierFreq = get_carrier_frequency(fp->N_RB_UL, fp->numerology_index, cfg->uplink_frequency); if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) { LOG_I(NR_PHY, - "[UE %d] RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", + "[UE %d] SYNC REQ: RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", UE->Mod_id, fp->dl_CarrierFreq, dl_CarrierFreq, @@ -505,6 +506,16 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) init_symbol_rotation(fp); } + int ssb_start_subcarrier = nr_get_ssb_start_sc(fp->numerology_index, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); + // SSB location can change during for ex: handover on the target cell + if (ssb_start_subcarrier != fp->ssb_start_subcarrier) { + fp->ssb_start_subcarrier = ssb_start_subcarrier; + LOG_I(NR_PHY, "SYNC REQ: SSB location changed:%d\n", fp->ssb_start_subcarrier); + } + // Apply Doppler based on NTN-Config for target cell if (UE->nrUE_config.ntn_config.is_targetcell) apply_ntn_timing_advance_and_doppler(UE, fp, -1); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 66f766571d..0e39e19d9e 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -24,6 +24,7 @@ #include "common/utils/LOG/log.h" #include "executables/softmodem-common.h" #include "PHY/MODULATION/nr_modulation.h" +#include "PHY/nr_phy_common/inc/nr_phy_common.h" /// Subcarrier spacings in Hz indexed by numerology index static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; @@ -421,16 +422,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq); - uint8_t sco = 0; - if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) || - ((fp->freq_range == FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) { - if (fp->freq_range == FR1) - sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common; - else - sco = config->ssb_table.ssb_subcarrier_offset; - } + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(config->ssb_config.scs_common, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); - fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); set_Lmax(fp); fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index b4c0e1239c..67bed6eef4 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -389,4 +389,9 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, const uint8_t cdm_type, c16_t **dataF); +int nr_get_ssb_start_sc(int scs, + int ssb_offset_point_a, + int ssb_sco, + frequency_range_t freq_range); + #endif diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index a723780f94..c29a3a4936 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -481,3 +481,26 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, con mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14); #endif } + +/*! +* Setting the first subcarrier +* 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2 +* for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS +* for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the SCS provided +* by the higher-layer parameter subCarrierSpacingCommon +*/ +int nr_get_ssb_start_sc(int scs, int ssb_offset_point_a, int ssb_sco, frequency_range_t freq_range) +{ + const int prb_offset = + (freq_range == FR1) ? ssb_offset_point_a >> scs : ssb_offset_point_a >> (scs - 2); + const int sc_offset = + (freq_range == FR1) ? ssb_sco >> scs : ssb_sco; + + int ssb_start_subcarrier = (12 * prb_offset + sc_offset); + + LOG_D(NR_PHY, "prb_offset:%d, ssb_subcarrier_offset:%d,scs :%d, Fr:%d, ssb_start_subcarrier:%d\n", + prb_offset, ssb_sco, scs, freq_range, ssb_start_subcarrier); + + return ssb_start_subcarrier; + +} diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e304fe3dc9..baccacbf26 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -118,9 +118,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n // by the higher-layer parameter subCarrierSpacingCommon nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const int scs = cfg->ssb_config.scs_common.value; - const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2); - const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset; - fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(scs, + pdu->ssbOffsetPointA, + pdu->SsbSubcarrierOffset, + fp->freq_range); if (fp->print_ue_help_cmdline_log && IS_SA_MODE(get_softmodem_params())) { fp->print_ue_help_cmdline_log = false; @@ -142,15 +143,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n fp->ssb_start_subcarrier, fp->threequarter_fs ? "-E" : ""); } - LOG_D(PHY, - "ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n", - pdu->ssbOffsetPointA, - pdu->SsbSubcarrierOffset, - prb_offset, - sc_offset, - scs, - fp->ssb_start_subcarrier); - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; c16_t ***txdataF = gNB->common_vars.txdataF; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2a5c8e041d..5dcdf6a725 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -537,16 +537,15 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t // SSB Table config if (frequencyInfoDL && frequencyInfoDL->absoluteFrequencySSB) { - int scs_scaling = 1 << (cfg->ssb_config.scs_common); - if (frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling * 3; - if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling >> 2; - uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a = absolute_diff / (12 * scs_scaling) - 10; + cfg->ssb_table.ssb_offset_point_a = get_ssb_offset_to_pointA(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common, + mac->frequency_range); 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_subcarrier_offset = get_ssb_subcarrier_offset(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common); cfg->ssb_table.ssb_case = set_ssb_case(*scc->ssbSubcarrierSpacing, mac->nr_band); } @@ -2107,18 +2106,24 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, configure_common_BWP_dl(mac, bwp_id, scc->downlinkConfigCommon->initialDownlinkBWP); if (scc->uplinkConfigCommon) configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); + + // Update PDCCH config as MAC configuration has changed + if (IS_SA_MODE(get_softmodem_params())) + update_pdcch_config(mac); } mac->state = UE_NOT_SYNC_RECONF; ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); + // PHY CONFIG request should be sent, ahead of SYNC request + // As SYNC request processes the new config + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; mac->synch_request.Mod_id = mac->ue_id; mac->synch_request.CC_id = cc_idP; mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; mac->if_module->synch_request(&mac->synch_request); - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config.config_req.ntn_config.params_changed = false; } static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9ee1bfab28..e502d08f1f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -377,4 +377,5 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id); ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config); +void update_pdcch_config(NR_UE_MAC_INST_t *mac); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 8dbce0032c..43aab362f3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -422,6 +422,38 @@ static bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, return false; } +void update_pdcch_config(NR_UE_MAC_INST_t *mac) +{ + int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : mac->numerology; + const int slots_per_frame = get_slots_per_frame_from_scs(scs); + int ssb_sc_offset_norm; + if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) + ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; + else + ssb_sc_offset_norm = mac->ssb_subcarrier_offset; + uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; + int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, + mac->mib_frame, + mac->mib, + slots_per_frame, + ssb_sc_offset_norm, + ssb_start_symbol, + scs, + mac->frequency_range, + mac->nr_band, + 273, // at this point UE in principle doesn't know the grid size (we assume the largest) + mac->mib_ssb, + 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame + ssb_offset_point_a); + if (mac->search_space_zero == NULL) + mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); + if (mac->coreset0 == NULL) + mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); +} + void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; @@ -430,37 +462,14 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl int scs = current_DL_BWP ? current_DL_BWP->scs : mac->numerology; const int slots_per_frame = get_slots_per_frame_from_scs(scs); if (mac->get_sib1) { - int ssb_sc_offset_norm; - if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) - ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; - else - ssb_sc_offset_norm = mac->ssb_subcarrier_offset; - uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; - int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); - get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, - mac->mib_frame, - mac->mib, - slots_per_frame, - ssb_sc_offset_norm, - ssb_start_symbol, - scs, - mac->frequency_range, - mac->nr_band, - 273, // at this point UE in principle doesn't know the grid size (we assume the largest) - mac->mib_ssb, - 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame - ssb_offset_point_a); - if (mac->search_space_zero == NULL) - mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); - if (mac->coreset0 == NULL) - mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) { + update_pdcch_config(mac); + bool is_occasion = is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero); + if (is_occasion) { LOG_D(NR_MAC_DCI, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot); config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero); } } + for (int i = 0; i < MAX_SI_GROUPS; i++) { if (!mac->get_otherSI[i]) continue;