Merge remote-tracking branch 'origin/oran_beamforming' into integration_2025_w43 (!3605)

Support beam index in OAI 7.2 Fronthaul Interface

This branch supports beam index in OAI 7.2 Fronthaul Interface.

- For CP DL (PDSCH), nBeamIndex of the corresponding prbMapElm is set
  when sending IQ data in oran_fh_if4p5_south_out. nBeamIndex of the
  corresponding prbMapElm is set when sending IQ data in
  oran_fh_if4p5_south_out.
- For CP UL (PUSCH and PRACH), nBeamIndex of the corresponding prbMapElm
  is set in oran_fh_if4p5_south_out.

In addition, it fixes a couple of issues

- XRAN hardcodes nBeamIndex of PRACH to zero. Modify XRAN to support
  setting of nBeamIndex of PRACH and update xran F release patch.
- Fix the bug in calculating fh_config->neAxc where num_beams_period is
  multiplified twice

Testing methodology: Use Benetel O_RU for testing even though it does
not support beamforming. With successful registration and data transfer,
one could check the pcap on the fronthaul interface to see if CP packets
are with the right beam index.

Results:

1. Verified that CP-packets for SSB, DCI, PDSCH, PRACH, PDSCH, PUSCH,
   CSI-RS and SRS are with the right beam index
2. Verified that there is no side-effect on Benetel O_RU. UE could
   register properly.
3. Verified 4 SSB with ssb_PositionsInBurst_Bitmap = 85. Could see SSB
   and PRACH with 4 different indices.
This commit is contained in:
Robert Schmidt
2025-10-21 09:09:03 +02:00
10 changed files with 195 additions and 78 deletions
+4 -2
View File
@@ -175,8 +175,10 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
if (cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) {
common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*));
for (int i = 0; i < common_vars->num_beams_period; i++)
common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
for (int i = 0; i < common_vars->num_beams_period; i++) {
common_vars->beam_id[i] = (int*)malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
memset(common_vars->beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
}
}
common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
for (int i = 0; i < common_vars->num_beams_period; i++) {
+4 -2
View File
@@ -53,8 +53,10 @@ void nr_phy_init_RU(RU_t *ru)
int nb_rx_streams = ru->nb_rx * ru->num_beams_period;
LOG_I(NR_PHY, "nb_tx_streams %d, nb_rx_streams %d, num_Beams_period %d\n", nb_tx_streams, nb_rx_streams, ru->num_beams_period);
ru->common.beam_id = malloc16_clear(ru->num_beams_period * sizeof(int*));
for(int i = 0; i < ru->num_beams_period; i++)
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
for(int i = 0; i < ru->num_beams_period; i++) {
ru->common.beam_id[i] = malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
memset(ru->common.beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
}
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
+3 -3
View File
@@ -185,9 +185,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
start_meas(&ru->precoding_stats);
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
return;
if (gNB->common_vars.analog_bf) {
for (int i = 0; i < ru->num_beams_period; i++) {
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
@@ -196,6 +193,9 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
}
}
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
return;
// 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) {
for (int b = 0; b < ru->num_beams_period; b++) {