Compare commits

...

3 Commits

Author SHA1 Message Date
Bartosz Podrygajlo
8455388fe0 Handle n_TimingAdvanceOffset on the gNB 2025-03-07 06:47:12 +01:00
Bartosz Podrygajlo
182f69f73c Handle changing N_TA_offset on the UE correctly in higher layers
Send new N_TA_offset in config_request to PHY. Remove N_TA_offset update
from ta_command.
2025-03-07 06:39:29 +01:00
Bartosz Podrygajlo
45bec4d271 Handle changing N_TA_offset correctly
Handle N_TA_offset update the same way timing advance changes are handled:
modify writeBlockSize to ensure continuous transmission. Also address possible
data races by making sure the new timing_advance/N_TA_offset is only read
once from global memory.
2025-03-07 06:29:33 +01:00
13 changed files with 52 additions and 32 deletions

View File

@@ -946,7 +946,6 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
int setup_RU_buffers(RU_t *ru) {
int i,j;
int card,ant;
//uint16_t N_TA_offset = 0;
NR_DL_FRAME_PARMS *fp;
nfapi_nr_config_request_scf_t *config = &ru->config;
@@ -958,8 +957,8 @@ int setup_RU_buffers(RU_t *ru) {
int mu = config->ssb_config.scs_common.value;
int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
ru->N_TA_offset = set_default_nta_offset(fp->freq_range, fp->samples_per_subframe);
int N_TA_offset[] = {0, 25600, 39936, 13792};
ru->N_TA_offset = (N_TA_offset[config->cell_config.n_timing_advance_offset.value] * fp->samples_per_subframe) / (4096 * 480);
LOG_I(PHY,
"RU %d Setting N_TA_offset to %d samples (UL Freq %d, N_RB %d, mu %d)\n",
ru->idx, ru->N_TA_offset, config->carrier_config.uplink_frequency.value, N_RB, mu);

View File

@@ -147,6 +147,19 @@ static void *nrL1_UE_stats_thread(void *param)
return NULL;
}
static int determine_N_TA_offset(PHY_VARS_NR_UE *ue) {
if (ue->sl_mode == 2)
return 0;
else {
int N_TA_offset = ue->nrUE_config.cell_config.N_TA_offset;
if (N_TA_offset == -1) {
return set_default_nta_offset(ue->frame_parms.freq_range, ue->frame_parms.samples_per_subframe);
} else {
return (N_TA_offset * ue->frame_parms.samples_per_subframe) / (4096 * 480);
}
}
}
void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id)
{
int nb_connected_gNB = 1;
@@ -867,6 +880,7 @@ void *UE_thread(void *arg)
initNotifiedFIFO_nothreadSafe(&freeBlocks);
int timing_advance = UE->timing_advance;
UE->N_TA_offset = determine_N_TA_offset(UE);
NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id);
bool syncRunning = false;
@@ -1093,9 +1107,16 @@ void *UE_thread(void *arg)
// but use current UE->timing_advance value to compute writeBlockSize
int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply;
if (UE->timing_advance != timing_advance) {
writeBlockSize -= UE->timing_advance - timing_advance;
timing_advance = UE->timing_advance;
int new_timing_advance = UE->timing_advance;
if (new_timing_advance != timing_advance) {
writeBlockSize -= new_timing_advance- timing_advance;
timing_advance = new_timing_advance;
}
int new_N_TA_offset = determine_N_TA_offset(UE);
if (new_N_TA_offset != UE->N_TA_offset) {
LOG_I(PHY, "N_TA_offset changed from %d to %d\n", UE->N_TA_offset, new_N_TA_offset);
writeBlockSize -= new_N_TA_offset - UE->N_TA_offset;
UE->N_TA_offset = new_N_TA_offset;
}
if (curMsg.proc.nr_slot_tx == 0)

View File

@@ -834,6 +834,13 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
end,
&pack_uint8_tlv_value);
numTLVs++;
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG,
&(pNfapiMsg->cell_config.n_timing_advance_offset),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
// END Cell Configuration
// START SSB Configuration
@@ -1155,6 +1162,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
{NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG, &(pNfapiMsg->carrier_config.frequency_shift_7p5khz), &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), &unpack_uint16_tlv_value},
{NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG, &(pNfapiMsg->cell_config.n_timing_advance_offset), &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), &unpack_uint32_tlv_value},
{NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, &(pNfapiMsg->ssb_config.bch_payload), &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), &unpack_uint8_tlv_value},

View File

@@ -551,7 +551,6 @@ typedef struct {
int ta_frame;
int ta_slot;
int ta_command;
int ta_offset;
bool is_rar;
} fapi_nr_ta_command_pdu;
@@ -616,6 +615,7 @@ typedef struct
{
uint8_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
uint8_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
uint32_t N_TA_offset;
} fapi_nr_cell_config_t;

View File

@@ -295,6 +295,7 @@ typedef struct
#define NFAPI_NR_CONFIG_PHY_CELL_ID_TAG 0x100C
#define NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG 0x100D
#define NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG 0x104A
#define NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG 0x100E
#define NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG 0x100F
@@ -351,6 +352,7 @@ typedef struct
{
nfapi_uint16_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
nfapi_uint8_tlv_t n_timing_advance_offset;
} nfapi_nr_cell_config_t;

View File

@@ -74,6 +74,9 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap
FILL_TLV(nfapi_resp->cell_config.frame_duplex_type, NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, 1 /* TDD */);
nfapi_resp->num_tlv++;
FILL_TLV(nfapi_resp->cell_config.n_timing_advance_offset, NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG, 0);
nfapi_resp->num_tlv++;
FILL_TLV(nfapi_resp->ssb_config.ss_pbch_power, NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, (int32_t)rand32());
nfapi_resp->num_tlv++;
@@ -326,6 +329,8 @@ static void fill_config_request_tlv_fdd(nfapi_nr_config_request_scf_t *req)
req->num_tlv++;
FILL_TLV(req->cell_config.frame_duplex_type, NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, 0 /* FDD */);
req->num_tlv++;
FILL_TLV(req->cell_config.n_timing_advance_offset, NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG, 0);
req->num_tlv++;
/* SSB config */
FILL_TLV(req->ssb_config.ss_pbch_power, NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, -25);

View File

@@ -495,19 +495,8 @@ void clean_UE_harq(PHY_VARS_NR_UE *UE)
void init_N_TA_offset(PHY_VARS_NR_UE *ue)
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
// No timing offset for Sidelink, refer to 3GPP 38.211 Section 8.5
if (ue->sl_mode == 2)
ue->N_TA_offset = 0;
else
ue->N_TA_offset = set_default_nta_offset(fp->freq_range, fp->samples_per_subframe);
ue->ta_frame = -1;
ue->ta_slot = -1;
LOG_I(PHY,
"UE %d Setting N_TA_offset to %d samples (UL Freq %lu, N_RB %d, mu %d)\n",
ue->Mod_id, ue->N_TA_offset, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index);
}
void phy_init_nr_top(PHY_VARS_NR_UE *ue) {

View File

@@ -419,15 +419,6 @@ static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_
LOG_D(PHY,
"TA command received in %d.%d Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n",
ta_command_pdu->ta_frame, ta_command_pdu->ta_slot, ue->ta_frame, ue->ta_slot);
if (ta_command_pdu->ta_offset != -1) {
// ta_offset_samples : ta_offset = samples_per_subframe : (Δf_max x N_f / 1000)
// As described in Section 4.3.1 in 38.211
int ta_offset_samples = (ta_command_pdu->ta_offset * samples_per_subframe) / (4096 * 480);
ue->N_TA_offset = ta_offset_samples;
LOG_D(PHY, "Received N_TA offset %d from upper layers. Corresponds to %d samples.\n",
ta_command_pdu->ta_offset, ta_offset_samples);
}
}
static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac,

View File

@@ -1744,7 +1744,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si
AssertFatal(scc, "SIB1 SCC should not be NULL\n");
UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t);
configure_si_schedulingInfo(mac, si_SchedulingInfo, si_SchedulingInfo_v1700);
mac->n_ta_offset = get_ta_offset(scc->n_TimingAdvanceOffset);
mac->phy_config.config_req.cell_config.N_TA_offset = get_ta_offset(scc->n_TimingAdvanceOffset);
config_common_ue_sa(mac, scc, cc_idP);
configure_common_BWP_dl(mac,
@@ -1813,7 +1813,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
if (reconfWithSync->spCellConfigCommon) {
NR_ServingCellConfigCommon_t *scc = reconfWithSync->spCellConfigCommon;
mac->n_ta_offset = get_ta_offset(scc->n_TimingAdvanceOffset);
mac->phy_config.config_req.cell_config.N_TA_offset = get_ta_offset(scc->n_TimingAdvanceOffset);
if (scc->physCellId)
mac->physCellId = *scc->physCellId;
mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position;

View File

@@ -633,7 +633,6 @@ typedef struct NR_UE_MAC_INST_s {
int dmrs_TypeA_Position;
int p_Max;
int p_Max_alt;
int n_ta_offset; // -1 not present, otherwise value to be applied
ntn_timing_advance_componets_t ntn_ta;

View File

@@ -68,7 +68,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
mac->uecap_maxMIMO_PUSCH_layers_nocb = 0;
mac->p_Max = INT_MIN;
mac->p_Max_alt = INT_MIN;
mac->n_ta_offset = -1;
mac->phy_config.config_req.cell_config.N_TA_offset = -1;
mac->ntn_ta.ntn_params_changed = false;
reset_mac_inst(mac);

View File

@@ -3626,7 +3626,6 @@ static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MA
fapi_nr_ta_command_pdu *ta = &dl_config->dl_config_list[dl_config->number_pdus].ta_command_pdu;
ta->ta_frame = ul_time_alignment->frame;
ta->ta_slot = ul_time_alignment->slot;
ta->ta_offset = mac->n_ta_offset;
ta->is_rar = ul_time_alignment->ta_apply == rar_ta;
ta->ta_command = ul_time_alignment->ta_command;
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_CONFIG_TA_COMMAND;

View File

@@ -488,6 +488,13 @@ static void config_common(gNB_MAC_INST *nrmac,
cfg->cell_config.frame_duplex_type.tl.tag = NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG;
cfg->num_tlv++;
uint8_t n_timing_advance_offset = frequency_range == FR1 ? 1 : 3;
if (scc->n_TimingAdvanceOffset)
n_timing_advance_offset = *scc->n_TimingAdvanceOffset;
cfg->cell_config.n_timing_advance_offset.value = n_timing_advance_offset;
cfg->cell_config.n_timing_advance_offset.tl.tag = NFAPI_NR_CONFIG_N_TIMING_ADVANCE_OFFSET_TAG;
cfg->num_tlv++;
// SSB configuration
cfg->ssb_config.ss_pbch_power.value = scc->ss_PBCH_BlockPower;
cfg->ssb_config.ss_pbch_power.tl.tag = NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG;