Merge remote-tracking branch 'origin/NR_fix_ssbpos_ho' into integration_2026_w10 (!3929)
UE: Fix if target cell during handover has SSB at a different offset as in source cell These changes fixed these observed issues: - If target cell has a different SSB position compared to source cell during ho - sync was not successful. - RAR does not get decoded if SSB position has changed on the target cell compared to source cell.
This commit is contained in:
+13
-2
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user