Fix MIMO antenna muting: copy SSB to active antennas when TX0 muted

When antenna 0 is muted but other antennas are active, SSB data
(generated only on port 0) is now copied to remaining active antennas.
This ensures UE can still detect cell with partial antenna muting.

Behavior:
- TX mask 0x03: Full 2x2 MIMO
- TX mask 0x02: TX1 only, SSB copied from TX0
- TX mask 0x01: TX0 only, normal SSB
- TX mask 0x00: All muted, UE loses sync (correct)
This commit is contained in:
2026-01-05 16:50:37 +00:00
parent 16fa6e766d
commit 85fef10860
+35 -9
View File
@@ -200,6 +200,9 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
// O-RAN compliant antenna muting (MPLANE-TRX-CONTROL) // O-RAN compliant antenna muting (MPLANE-TRX-CONTROL)
nr_antenna_state_t *ant_state = &gNB->antenna_state; nr_antenna_state_t *ant_state = &gNB->antenna_state;
// Check if ALL TX antennas are muted (complete transmission stop)
int active_tx_count = nr_get_active_tx_antenna_count(ant_state);
// If there is no digital beamforming we just need to copy the data to RU // If there is no digital beamforming we just need to copy the data to RU
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) { if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
for (int b = 0; b < ru->num_beams_period; b++) { for (int b = 0; b < ru->num_beams_period; b++) {
@@ -213,10 +216,23 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
fp->samples_per_slot_wCP * sizeof(int32_t)); fp->samples_per_slot_wCP * sizeof(int32_t));
LOG_D(PHY, "[ANTENNA_MUTE] TX antenna %d muted in slot %d\n", i, slot_tx); LOG_D(PHY, "[ANTENNA_MUTE] TX antenna %d muted in slot %d\n", i, slot_tx);
} else { } else {
// Normal copy for active antennas // Active antenna: copy data
memcpy((void*)ru->common.txdataF_BF[tx_idx], // If antenna 0 is muted but this antenna is active, we need to copy
(void*)&gNB->common_vars.txdataF[b][i][txdataF_offset], // SSB/common data from antenna 0's source to ensure SSB is transmitted
fp->samples_per_slot_wCP * sizeof(int32_t)); // on at least one active antenna (SSB is generated on port 0)
if (i > 0 && !nr_is_tx_antenna_active(ant_state, 0) && active_tx_count > 0) {
// Antenna 0 is muted, copy antenna 0's data to this active antenna
// This ensures SSB is transmitted on at least one antenna
memcpy((void*)ru->common.txdataF_BF[tx_idx],
(void*)&gNB->common_vars.txdataF[b][0][txdataF_offset],
fp->samples_per_slot_wCP * sizeof(int32_t));
LOG_D(PHY, "[ANTENNA_MUTE] Copying SSB from ant0 to active ant%d in slot %d\n", i, slot_tx);
} else {
// Normal copy for active antennas
memcpy((void*)ru->common.txdataF_BF[tx_idx],
(void*)&gNB->common_vars.txdataF[b][i][txdataF_offset],
fp->samples_per_slot_wCP * sizeof(int32_t));
}
} }
} }
} }
@@ -253,6 +269,7 @@ void nr_feptx(void *arg)
PHY_VARS_gNB *gNB = ru->gNB_list[0]; PHY_VARS_gNB *gNB = ru->gNB_list[0];
nr_antenna_state_t *ant_state = &gNB->antenna_state; nr_antenna_state_t *ant_state = &gNB->antenna_state;
bool antenna_muted = !nr_is_tx_antenna_active(ant_state, aa); bool antenna_muted = !nr_is_tx_antenna_active(ant_state, aa);
int active_tx_count = nr_get_active_tx_antenna_count(ant_state);
if (antenna_muted) { if (antenna_muted) {
// Zero the output buffer for muted antenna - transmission blanking // Zero the output buffer for muted antenna - transmission blanking
@@ -269,11 +286,20 @@ void nr_feptx(void *arg)
} }
// If there is no digital beamforming we just need to copy the data to RU // If there is no digital beamforming we just need to copy the data to RU
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset], // If antenna 0 is muted but this antenna is active, copy SSB from antenna 0
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset], // SSB is generated only on antenna port 0
numSamples * sizeof(int32_t)); if (aa > 0 && !nr_is_tx_antenna_active(ant_state, 0) && active_tx_count > 0) {
else { memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][0][txdataF_offset],
numSamples * sizeof(int32_t));
LOG_D(PHY, "[ANTENNA_MUTE] Copying SSB from ant0 to active ant%d, slot %d\n", aa, slot);
} else {
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
numSamples * sizeof(int32_t));
}
} else {
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n"); AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
} }
} }